DevOps

Caddy로 도메인 없이 HTTPS 연결하기

주인 완 2024. 12. 3. 22:00

지난 10월, 동아리에서 활동했던 디자이너의 졸업작품을 위해 간단한 서버를 배포해야 했었다. 문제는, 프런트가 Vercel을 통해 배포를 진행했기에, 서버도 마찬가지로 SSL 인증을 통한 HTTPS 연결을 구성해줘야 했었다.

 

이때 선택지는 2개였는데,

  1. 가장 싼 도메인을 사서 Nginx를 통해 HTTPS 구성하기
  2. Caddy를 통한 리버스 프록시로 HTTPS 구성하기

난 후자를 선택했다. 왜냐하면 돈도 없었을뿐더러, Nginx를 설정하는 데에 드는 시간적 리소스 또한 만만치 않다고 판단했기 때문이다. 그리고 Caddy를 선택한 것은 최고의 선택이었다. 쉽고 빨랐기 때문이다.

 

Caddy

Caddy는 모든 도메인에 대해 자동으로 SSL 연결을 지원해주는 오픈소스이다. Caddyfile이라는 설정 파일을 통해 편리하게 환경 설정을 진행해 줄 수 있으며, 인증서 갱신까지 자동으로 진행해 준다. 도메인 연결이 필요한 게 아니라면, Caddy를 굳이 쓰지 않을 이유가 없었다.

 

 

Caddy - The Ultimate Server with Automatic HTTPS

Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go

caddyserver.com

 

인바운드 규칙 변경 

Caddy를 쓰기에 앞서서, 기초적인 인스턴스 설정 작업이 완료되어 있다는 가정 하에 글이 진행될 것이다.

그리고 보안 그룹에서 SSL 연결을 위해 꼭 인바운드 규칙에 443 포트는 열어주어야 한다! 이유는 즉 모든 HTTPS 연결은 HTTP와 다르게 443 포트로 진행되기 때문이다.

 

인스턴스에 Caddy 설치

 

Caddy - The Ultimate Server with Automatic HTTPS

Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go

caddyserver.com

 

데비안 계열인 우분투 리눅스나, 아마존 리눅스를 사용하는 사람들을 위한 설치 방식이며, 아마 대부분이 해당 방식을 통해 Caddy를 설치할 수 있을 것이다.

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

 

이후 caddy --version 명령어를 통해 다음과 같은 결과가 나오면, 정상적으로 설치된 것이다.

$ caddy --version
v2.8.4 h1:~~~~~~~~~~~~

 

 

Caddyfile 수정

Caddyfile을 수정하여 우리가 원하는 HTTPS 연결을 설정해 줄 수 있다.

sudo vim /etc/caddy/Caddyfile

 

해당 명령어를 통해 Caddyfile로 이동할 수 있다. 파일을 vim 에디터로 열어보면, 수많은 내용들이 존재하는데 과감히 전부 지우고 다음과 같이 내용을 덮어씌워준다.

 

{
    admin 0.0.0.0:2020
}
퍼블릭IP.nip.io {
    reverse_proxy 127.0.0.1:포트번호
}

 

admin

 

Tcp 127.0.0.1:2019: bind: address already in use

Oh, sorry Matt i forgot add Caddyfile ( when i restart machine first read config from Caddyfile then my app post to /loads json config. ) { # debug admin 0.0.0.0:2019 } (redirect) { @http { protocol http } redir @http https://{hostport}{uri} 302 } domain.t

caddy.community

오류 해결 방법

admin 경로에 대한 포트를 지정해주는 이유는 다음과 같다.

알 수 없는 이유로, 포트 번호가 충돌이 나면서 Caddy 서비스가 정상적으로 실행이 되지 않는 오류가 발생한기 때문이다.

이와 관련해 다른 Caddy 사용자가 해결 방법을 올려두었으니, 해당 예시처럼 적용해 주면 정상적으로 Caddy 서비스가 작동된다.

 

리버스 프록시

리버스 프록시는 간단히 말해 서버로 요청이 들어올 때, WAS 앞단에 놓여 있는 프록시가 들어오는 모든 요청/응답을 처리하는 것이다.

이를 통해 우리는 모든 요청/응답을 SSL로 진행할 수 있게 된다.

퍼블릭IP.nip.io {
    reverse_proxy 127.0.0.1:포트번호
}

따라서 해당 설정에서는 Caddy를 통해 퍼블릭IP.nip.io 가 프록시 역할을 하게 된다.

 

포트 번호의 경우, 자신이 사용하는 WAS의 포트 번호를 입력해 주면 된다.

나 같은 경우, FastAPI를 사용했기에 8000번을 입력해 주었다.

nip.io

nip.io는 대부분(사실상 모든) IP주소에 대해서 DNS를 발급해 주는 와일드카드 서비스이다.

 

 

nip.io - wildcard DNS for any IP Address

Dead simple wildcard DNS for any IP Address Stop editing your etc/hosts file with custom hostname and IP address mappings. nip.io allows you to do that by mapping any IP Address to a hostname using the following formats: Without a name: 10.0.0.1.nip.io map

nip.io

 

caddy.service 생성

다음과 같이 caddy.service 파일을 생성하거나 이동한다.

sudo vim /etc/systemd/system/caddy.service

 

이후 다음과 같은 내용을 그대로 덮어씌워준다.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

 

다음과 같이 caddy.service를 별도로 작성해 주는 이유는, Caddy를 systemd로 관리할 때, Caddy에서 지정해 주는 공식 systemd 유닛 파일로 동작하도록 설정하기 위함이다.

 

Caddy - The Ultimate Server with Automatic HTTPS

Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go

caddyserver.com

 

Caddy 실행하기

이제 모든 설정 파일을 구성했으니, systemctl을 최신화하고 Caddy를 시작하면 된다.

sudo systemctl daemon-reload
sudo systemctl enable --now caddy

 

이후 Caddy가 작동하고 있는지 확인하고, 실행하면 된다.

systemctl status caddy
sudo caddy start

 

정상적으로 실행이 되면, 다음과 같이 상태를 확인할 수 있다.

제대로 동작하고 있는 Caddy

 

Caddy 엔드포인트

Caddyfile에서 등록한 리버스 프록시 주소로 API 요청이 가능하다!

따라서 https://퍼블릭IP.nip.io 경로가 최종 서버 단 엔드포인트가 되겠다.

인증서 확인

 

참고

 

Caddy - The Ultimate Server with Automatic HTTPS

Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go

caddyserver.com

 

Tcp 127.0.0.1:2019: bind: address already in use

Hi, i have a problem with caddy api endpoint. I changed the port of end point to 0.0.0.0:2019 for remote connection. then i give permittion for only spesific ips can be use it. everything works fine only i have when i post to 0.0.0.0/load 1. Caddy version

caddy.community