웹사이트 검색

Ubuntu 14.04에서 Let's Encrypt로 HAProxy를 보호하는 방법


소개

Let’s Encrypt는 무료 TLS/SSL 인증서를 얻고 설치하여 웹 서버에서 암호화된 HTTPS를 활성화하는 쉬운 방법을 제공하는 새로운 인증 기관(CA)입니다. 대부분의 필요한 단계를 자동화하려고 시도하는 소프트웨어 클라이언트인 Certbot을 제공하여 프로세스를 단순화합니다. 현재 인증서를 얻고 설치하는 전체 프로세스는 Apache 웹 서버에서만 완전히 자동화됩니다. 그러나 Certbot을 사용하면 웹 서버 소프트웨어 선택에 관계없이 수동으로 설치할 수 있는 무료 SSL 인증서를 쉽게 얻을 수 있습니다.

이 자습서에서는 Certbot을 사용하여 무료 SSL 인증서를 얻고 Ubuntu 14.04에서 HAProxy와 함께 사용하는 방법을 보여줍니다. 또한 SSL 인증서를 자동으로 갱신하는 방법도 알려드립니다.

전제 조건

이 튜토리얼을 따르기 전에 몇 가지가 필요합니다.

sudo 권한이 있는 루트가 아닌 사용자가 있는 Ubuntu 14.04 서버가 있어야 합니다. Ubuntu 14.04의 초기 서버 설정에서 1-3단계를 수행하여 이러한 사용자 계정을 설정하는 방법을 배울 수 있습니다.

인증서를 사용하려는 등록된 도메인 이름을 소유하거나 제어해야 합니다. 아직 등록된 도메인 이름이 없는 경우 많은 도메인 이름 등록 기관(예: Namecheap, GoDaddy 등) 중 하나에 등록할 수 있습니다.

아직 만들지 않았다면 도메인을 서버의 공용 IP 주소로 가리키는 A 레코드를 만드십시오. 이는 Let’s Encrypt가 인증서를 발급하는 도메인을 소유하고 있음을 확인하는 방법 때문에 필요합니다. 예를 들어 example.com에 대한 인증서를 얻으려면 유효성 검사 프로세스가 작동하려면 해당 도메인이 서버로 확인되어야 합니다. 설정에서는 example.comwww.example.com을 도메인 이름으로 사용하므로 두 DNS 레코드가 모두 필요합니다.

모든 필수 구성 요소가 준비되면 Let’s Encrypt 클라이언트 소프트웨어인 certbot 설치로 이동하겠습니다.

1단계 - Let’s Encrypt 클라이언트 설치

SSL 인증서를 얻기 위해 Let’s Encrypt를 사용하는 첫 번째 단계는 서버에 certbot 소프트웨어를 설치하는 것입니다. Certbot 개발자는 최신 버전의 소프트웨어가 포함된 저장소를 제공합니다. 이제 해당 리포지토리를 패키지 관리자에 추가해 보겠습니다.

  1. sudo add-apt-repository ppa:certbot/certbot

추가를 확인하라는 메시지가 표시됩니다. 계속하려면 ENTER를 누르십시오. 그런 다음 패키지 캐시를 업데이트하여 새 패키지 목록을 선택합니다.

  1. sudo apt-get update

마지막으로 certbot 패키지를 설치합니다.

  1. sudo apt-get install certbot

이제 certbot이 설치되었으므로 SSL 인증서를 받을 준비가 되었습니다.

2단계 - 인증서 받기

Let’s Encrypt는 다양한 플러그인을 통해 SSL 인증서를 얻을 수 있는 다양한 방법을 제공합니다. 다른 자습서에서 다루는 Apache 플러그인과 달리 대부분의 플러그인은 사용할 웹 서버를 수동으로 구성해야 하는 인증서를 얻는 데만 도움이 됩니다. 인증서를 받기만 하고 설치하지 않는 플러그인은 서버에서 인증서를 발급해야 하는지 여부를 인증하는 데 사용되기 때문에 "인증자\라고 합니다.

Standalone 플러그인을 사용하여 SSL 인증서를 얻는 방법을 보여드리겠습니다.

포트 80이 열려 있는지 확인

Standalone 플러그인은 SSL 인증서를 얻는 매우 간단한 방법을 제공합니다. Let’s Encrypt CA가 인증서를 발급하기 전에 연결하고 서버의 신원을 확인할 수 있는 서버의 작은 웹 서버(기본적으로 포트 80에서)를 임시로 실행하여 작동합니다. 따라서 이 방법을 사용하려면 포트 80이 사용 중이 아니어야 합니다. 즉, 이 플러그인을 사용하기 전에 포트 80(예: http)을 사용하는 경우 일반 웹 서버를 중지해야 합니다.

예를 들어 HAProxy를 사용 중인 경우 다음 명령을 실행하여 중지할 수 있습니다.

  1. sudo service haproxy stop

포트 80이 사용 중인지 확실하지 않은 경우 다음 명령을 실행할 수 있습니다.

netstat -na | grep ':80.*LISTEN'

이 명령을 실행할 때 출력이 없으면 Standalone 플러그인을 사용할 수 있습니다.

Certbot 실행

이제 다음 명령을 실행하여 Standalone 플러그인을 사용하십시오.

  1. sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d example.com -d www.example.com

이메일 주소를 입력하고 Let’s Encrypt 서비스 약관에 동의하라는 메시지가 표시됩니다. 그 후 http 챌린지가 실행됩니다. 모든 것이 성공하면 certbot은 다음과 같은 출력 메시지를 인쇄합니다.

Output:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2017-09-06. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

위의 예제 출력에서 강조 표시된 인증서의 경로와 만료 날짜를 기록해 두는 것이 좋습니다.

참고: 도메인이 CloudFlare와 같은 DNS 서비스를 통해 라우팅되는 경우 인증서를 얻을 때까지 일시적으로 비활성화해야 합니다.

인증서 파일

인증서를 받으면 다음과 같은 PEM 인코딩 파일을 갖게 됩니다.

  • cert.pem: 도메인 인증서
  • chain.pem: Let’s Encrypt 체인 인증서
  • fullchain.pem: cert.pemchain.pem 결합
  • privkey.pem: 인증서의 개인 키

웹 서버 구성에서 사용할 수 있도록 방금 만든 인증서 파일의 위치를 알고 있어야 합니다. 파일 자체는 /etc/letsencrypt/archive의 하위 디렉토리에 있습니다. 그러나 Certbot은 /etc/letsencrypt/live/your_domain_name 디렉토리에 가장 최근의 인증서 파일에 대한 심볼릭 링크를 생성합니다.

다음 명령을 실행하여 파일이 존재하는지 확인할 수 있습니다(도메인 이름으로 대체).

  1. sudo ls /etc/letsencrypt/live/your_domain_name

출력은 앞에서 언급한 4개의 인증서 파일이어야 합니다.

fullchain.pem과 privkey.pem 결합

SSL 종료를 수행하도록 HAProxy를 구성할 때 자체와 최종 사용자 간의 트래픽을 암호화하므로 fullchain.pemprivkey.pem을 단일 파일로 결합해야 합니다.

먼저 결합된 파일이 배치될 디렉토리인 /etc/haproxy/certs를 생성합니다.

  1. sudo mkdir -p /etc/haproxy/certs

다음으로 이 cat 명령으로 결합된 파일을 만듭니다(강조 표시된 example.com을 도메인 이름으로 대체).

  1. DOMAIN='example.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'

다음 명령을 사용하여 개인 키가 포함된 결합된 파일에 대한 보안 액세스:

  1. sudo chmod -R go-rwx /etc/haproxy/certs

이제 HAProxy에서 SSL 인증서와 개인 키를 사용할 준비가 되었습니다.

3단계 - HAProxy 설치

이 단계에서는 HAProxy 설치를 다룹니다. 서버에 이미 설치되어 있으면 이 단계를 건너뜁니다.

기본 Ubuntu 리포지토리에 없는 HAProxy 1.6을 설치합니다. 그러나 다음 명령으로 PPA를 사용하는 경우 패키지 관리자를 사용하여 HAProxy 1.6을 설치할 수 있습니다.

  1. sudo add-apt-repository ppa:vbernat/haproxy-1.6

로드 밸런서에서 로컬 패키지 인덱스를 업데이트하고 다음을 입력하여 HAProxy를 설치합니다.

  1. sudo apt-get update
  2. sudo apt-get install haproxy

이제 HAProxy가 설치되었지만 구성해야 합니다.

4단계 - HAProxy 구성

이 섹션에서는 SSL 설정으로 기본 HAProxy를 구성하는 방법을 보여줍니다. 또한 Let’s Encrypt 인증서를 자동 갱신할 수 있도록 HAProxy를 구성하는 방법도 다룹니다.

텍스트 편집기에서 haproxy.cfg를 엽니다.

  1. sudo nano /etc/haproxy/haproxy.cfg

다음 여러 섹션에서 편집할 때 이 파일을 열어 두십시오.

글로벌 섹션

global 섹션 아래에 몇 가지 기본 설정을 추가해 보겠습니다.

가장 먼저 할 일은 maxconn을 적당한 숫자로 설정하는 것입니다. 이는 HAProxy가 허용하는 동시 연결 수에 영향을 미치므로 QoS에 영향을 미치고 너무 많은 요청을 처리하려는 웹 서버 충돌을 방지할 수 있습니다. 당신은 당신의 환경에 맞는 것을 찾기 위해 그것을 가지고 놀아야 할 것입니다. 전역 섹션에 다음 줄(합리적이라고 생각하는 값 포함)을 추가합니다.

   maxconn 2048

다음으로 이 줄을 추가하여 생성되는 임시 DHE 키의 최대 크기를 구성합니다.

   tune.ssl.default-dh-param 2048

기본값 섹션

defaults 섹션 아래에 다음 줄을 추가합니다.

   option forwardfor
   option http-server-close

forwardfor 옵션은 각 요청에 X-Forwarded-For 헤더를 추가하도록 HAProxy를 설정하고, http-server-close 옵션은 연결을 닫음으로써 HAProxy와 사용자 간의 대기 시간을 줄이지만 keep-alive 유지.

프런트엔드 섹션

이제 frontend 섹션을 정의할 준비가 되었습니다.

첫 번째로 추가하고 싶은 것은 들어오는 HTTP 연결을 처리하고 기본 백엔드로 보내는 프런트엔드입니다(나중에 정의할 것임). 파일 끝에 www-http라는 프런트엔드를 추가해 보겠습니다. haproxy_public_IP를 HAProxy 서버의 공용 IP 주소로 바꾸십시오.

frontend www-http
   bind haproxy_www_public_IP:80
   reqadd X-Forwarded-Proto:\ http
   default_backend www-backend

다음으로 들어오는 HTTPS 연결을 처리하기 위해 프런트엔드를 추가합니다. 파일 끝에 www-https라는 프런트엔드를 추가합니다. haproxy_www_public_IP를 HAProxy 서버의 공용 IP로 바꾸십시오. 또한 example.com을 도메인 이름(이전에 만든 인증서 파일과 일치해야 함)으로 바꿔야 합니다.

frontend www-https
   bind haproxy_www_public_IP:443 ssl crt /etc/haproxy/certs/example.com.pem
   reqadd X-Forwarded-Proto:\ https
   acl letsencrypt-acl path_beg /.well-known/acme-challenge/
   use_backend letsencrypt-backend if letsencrypt-acl
   default_backend www-backend

이 프런트엔드는 ACL(letsencrypt-acl)을 사용하여 Let's Encrypt 유효성 검사 요청(/.well-known/acme-challenge용)을 letsencrypt-backend에 보냅니다. 백엔드를 사용하여 HAProxy 서비스를 중지하지 않고 인증서를 갱신할 수 있습니다. 다른 모든 요청은 웹 애플리케이션 또는 사이트를 제공할 백엔드인 www-backend로 전달됩니다.

백엔드 섹션

프런트엔드 구성을 마친 후 다음 줄을 추가하여 www-backend 백엔드를 추가합니다. 강조 표시된 단어를 웹 서버의 각 사설 IP 주소로 바꾸십시오(보유한 백엔드 서버 수와 일치하도록 server 줄 수 조정).

backend www-backend
   redirect scheme https if !{ ssl_fc }
   server www-1 www_1_private_IP:80 check
   server www-2 www_2_private_IP:80 check

이 백엔드가 수신하는 모든 트래픽은 HTTP(포트 80)를 통해 server 항목 간에 균형을 이룹니다.

마지막으로 다음 줄을 추가하여 letsencrypt-backend 백엔드를 추가합니다.

backend letsencrypt-backend
   server letsencrypt 127.0.0.1:54321

인증서 요청 및 갱신에 사용되는 Let’s Encrypt ACME 챌린지만 처리하는 이 백엔드는 포트 54321에서 localhost로 트래픽을 보냅니다. Let’s Encrypt SSL 인증서를 갱신할 때 80443 대신 이 포트를 사용합니다.

이제 HAProxy를 시작할 준비가 되었습니다.

  1. sudo service haproxy restart

참고: haproxy.cfg 구성 파일에 문제가 있는 경우 이 GitHub Gist에서 예제를 확인하세요.

이제 Let’s Encrypt TLS/SSL 인증서가 준비되었으며 자동 갱신 스크립트를 설정할 준비가 되었습니다. 이 시점에서 웹 브라우저에서 도메인을 방문하여 TLS/SSL 인증서가 작동하는지 테스트해야 합니다.

5단계 - 자동 갱신 설정

Let’s Encrypt 인증서는 90일 동안만 유효하므로 갱신 프로세스를 자동화하는 것이 중요합니다.

인증서가 오래되지 않도록 하는 실용적인 방법은 갱신 프로세스를 자동으로 처리하는 크론 작업을 만드는 것입니다. cronjob은 매일 certbot을 실행하고 만료 30일 이내인 경우 인증서를 갱신합니다. certbot은 성공적인 갱신 후 특별한 renew-hook 스크립트도 실행합니다. 이 갱신 스크립트를 사용하여 결합된 .pem 파일을 업데이트하고 haproxy를 다시 로드합니다.

이제 해당 스크립트를 만든 다음 테스트해 보겠습니다.

갱신 스크립트 만들기

루트로 /usr/local/bin에서 새 파일을 엽니다.

  1. sudo nano /usr/local/bin/renew.sh

이것은 새로운 빈 텍스트 파일이 됩니다. 다음 짧은 스크립트를 붙여넣고 강조 표시된 도메인 이름을 자신의 이름으로 업데이트하십시오.

#!/bin/sh

SITE=example.com

# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE

# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > /etc/haproxy/certs/$SITE.pem

# reload haproxy
service haproxy reload

파일을 저장하고 닫습니다. 이 스크립트는 올바른 Let’s Encrypt 디렉터리로 이동하고 cat 명령을 실행하여 두 개의 .pem 파일을 하나로 연결한 다음 haproxy를 다시 로드합니다.

다음으로 스크립트를 실행 가능하게 만듭니다.

  1. sudo chmod u+x /usr/local/bin/renew.sh

그런 다음 스크립트를 실행합니다.

  1. sudo /usr/local/bin/renew.sh

오류 없이 실행되어야 합니다. haproxy 다시 로드에 대한 일부 출력이 표시됩니다. 다음으로 Certbot을 업데이트하고 이 갱신 스크립트를 실행하도록 구성합니다.

certbot 구성 업데이트

인증서를 갱신하는 데 사용할 certbot renew 명령은 certbot을 처음 실행할 때 생성된 구성 파일을 읽습니다. 이 파일을 열고 certbot이 독립 실행형 http 서버를 실행하는 데 사용하는 포트를 업데이트하여 haproxy(이미 포트 80 및 443에서 수신 대기 중임)와 충돌하지 않도록 해야 합니다. 텍스트 편집기에서 구성 파일을 엽니다.

  1. sudo nano /etc/letsencrypt/renewal/example.com.conf

http01_port 줄을 변경해야 합니다. 이렇게 하면 다음과 같습니다.

http01_port = 54321

파일을 저장하고 닫습니다. 이제 실제로 아무것도 갱신하지 않도록 --dry-run을 지정하여 갱신 프로세스를 테스트합니다.

  1. sudo certbot renew --dry-run

Certbot은 갱신 챌린지를 위해 포트 54321에서 수신 대기하고 haproxy는 포트 80에서 54321로 요청을 프록시합니다.

크론 작업 생성

다음으로 crontab을 편집하여 매일 certbot renew 명령을 실행할 새 작업을 만듭니다. 루트 사용자의 crontab을 편집하려면 다음을 실행하십시오.

  1. sudo crontab -e

파일 맨 아래에 다음을 추가합니다.

30 2 * * * /usr/bin/certbot renew --renew-hook "/usr/local/bin/renew.sh" >> /var/log/le-renewal.log

저장 및 종료. 이렇게 하면 매일 오전 2시 30분에 certbot renew 명령을 실행할 새 크론 작업이 생성됩니다. 명령으로 생성된 출력은 /var/log/le-renewal.log에 있는 로그 파일로 파이프됩니다. 인증서가 실제로 갱신되면 --renew-hook 스크립트가 실행되어 결합된 PEM 파일을 생성하고 haproxy를 다시 로드합니다.

결론

그게 다야! HAProxy는 이제 무료 Let's Encrypt TLS/SSL 인증서를 사용하여 HTTPS 트래픽을 안전하게 제공합니다.