개발자Tech2021. 8. 14. 19:56

개발자에 종사하다 보니, 새로운 서비스 개발을 맞게되었는데 요구사항이 여러 서브 도메인을 운영하거나, 고객들이 보유하고 있는 도메인을 자사서비스에 적용할 수 있는 스팩이 포함되어있었다. 관련해서 공부할 겸 기록을 남겨둔다.

 

* nginx + certbot 조합이 아닌, Caddy를 사용한 이유

 

 1. ACME를 지원하는 것은 다양하다. 하지만 대부분의 ACME 클라이언트의 경우 OS 환경에 따라 구축하기 어려울 수 있다.

  - 대표적으로 let's encrypt 인증서를 쉽게 발급해주는 certbot의 경우 윈도우, 우분투 등은 잘 지원하나, CentOS 등에서 호환성이 아쉽다.

 

 2. Nginx의 경우 domain by domain으로 개별 도메인에 인증서를 전부 연결해야하며, 연결된 모든 도메인의 인증서를 관리해야한다.

  - certbot을 통하여 관리할 수 있으나, 보유중이지 않은 도메인, 쉽게 말해 내가 관리할 수 없는 도메인들은 인증서 발급이 까다롭다. (와일드카드 인증서는 절대 발급 못받는다)

 

 3. 이것은 나한테만 해당되는 것인데 현재 개발중인 서비스는 연결될 도메인이 고객이 소유한 도메인인 관계로 제어할 수 없으며, 특히 DNS 레코드 설정 등이 즉시 구성될 수 없는 환경인 관계로 대응하기가 어렵다.

 

 Caddy의 경우  On-Demand TLS 라고 하는 새로운 기능이 추가되었다. 이 기능은 처음 접속 시 TLS handShake 하는 과정 중에 새 인증서를 동적으로 가져온다는 것이고 이는 서비스 구성시 미리 도메인 이름을 지정할 필요가 없다는 것이다.

 

 물론 다른웹엔진 + certbot으로도 구현할 수 있지만 이 방법이 지금 이 순간에는 가장 편한방법인 것 같다.

 

 

 * Caddy 2 설치하기

 

 우선 최신으로 업데이트를 하고 시작한다.

sudo yum update -y

 

 그 다음 go언어를 설치한다.

yum install -y golang

 go가 잘 설치되었는지 확인한다.

go version

위와 같이 버전이 나오면 완료

 

 Caddy를 설치할 폴더로 이동해서, Caddy를 쉽게 설치해주는 XCaddy를 다운받는다. (저장소를 통해 설치도 가능하지만 그러면 데비안계열을 제외하고 원하는 플러그인을 쓸 수 없다.) Caddy의 소스코드를 다운받을 필요는 없다.

wget https://github.com/caddyserver/xcaddy/releases/download/v0.1.9/xcaddy_0.1.9_linux_amd64.tar.gz
tar -vxf xcaddy_0.1.9_linux_amd64.tar.gz

 필요한 플러그인을 추가해서 빌드한다. (필자는 프록시가 필요하여 프록시도 같이 빌드 함)

./xcaddy build --with github.com/caddyserver/ntlm-transport --with github.com/mastercactapus/caddy2-proxyprotocol

 

 설치 이후에는 caddy 명령어를 통해서 서버를 실행시켜본다.

./caddy run

 

 접속해보면 "404 Not Found" 라는 창이 나올 것이다. 그렇다면 caddy는 정상적으로 설치되서 실행중이나, 아직 인덱스 파일을 만들지 않아서 실행되지 않는 것이다.

 

 이제 On-Demand TLS를 위해 설정파일을 만든다.

 sudo vim ./Caddyfile

 

# 상용에 아래 코드를 절때 안전장치 없이 배포하면 안됨
# Caddy는 모든 클라이언트의 TLS 핸드셰이크 과정에 있는 모든 ServerName에 대한 인증서를 얻으려고 시도 함.
# 서버를 위험에 빠뜨릴 수 있음. 
{
  email user@examplemail.com
}

https://

tls {
    on_demand
}
reverse_proxy localhost:8081

 * 주의사항

 위의 코드는 상용서버에 적용하면 대단히 위험함. 이유는 모든 클라이언트를 신뢰할 수 없으며, 클라이언트 중 공격을 시도하는 해커들이 존재할 수 있음.

 

 상용에서는 아래 예제와 같이 구현하는 것이 보다 안전함.

# 상용 예제
# ask에 응답할 내부 포인트가 필요함 - 별도의 인증 서비스 구성 필요
# Caddy는 http://localhost:14331/check?domain=example.com 과 같이 호출할 것임.
# 200 OK 를 리턴하면 인증서를 발급함, 따라서 그 외에는 403에러 등을 발생시키면 됨.
# interval 변수로 정한 시간당 burst 변수에 정해진 횟수까지만 인증서 요청이 가능 - 예제) 2분당 5회까지

{
    email user@examplemail.com
    on_demand_tls {
        ask      http://localhost:14331/check
        interval 2m
        burst    5
    }
}

https://

tls {
    on_demand
}
reverse_proxy localhost:8081

 

 이제 설정파일을 만들었으니 실행해봄

sudo ./caddy run --config ./Caddyfile

 DNS서버에 아무거나 세팅해서 해당 서버에 연결하면, 무엇을 연결하던 TLS로 접속하는 것을 확인할 수 있다.

 

 여기까지 마쳤다면 Caddy를 통한 Automation-TLS > On-Demand TLS 서비스를 구현한 것이다.

Posted by Gerry.