← Log

Nginx SSL/TLS 발급과 자동 갱신

Ubuntu 홈서버 구축기· 9 / 15
  1. 1 — 홈서버 구축 과정 정리
  2. 2 — 운영체제 선택과 설치
  3. 3 — Rufus로 Ubuntu USB 부팅 디스크 만들기
  4. 4 — Windows 디스크 파티셔닝과 Ubuntu 설치
  5. 5 — SSH 원격 접속 설정
  6. 6 — 방화벽 설정
  7. 7 — Cloudflare DNS 설정
  8. 8 — Nginx 설치와 리버스 프록시
  9. 9 — Nginx SSL/TLS 발급과 자동 갱신
  10. 10 — MySQL 설치와 설정
  11. 11 — Node.js 설치와 백엔드 애플리케이션 실행
  12. 12 — DHCP Reservation으로 내부 IP 고정
  13. 13 — 포트 포워딩
  14. 14 — 동적 DNS(DDNS) 개념과 테스트
  15. 15 — ddclient으로 동적 DNS(DDNS) 자동화

이번 문서에서는 앞서 설치한 Nginx에 SSL/TLS 설정을 추가한다. 블로그 내에 이미 SSL/TLS 설정과 관련한 기록이 있지만, 이번에는 일부 설정을 다르게 구성한 부분이 있어 다시 정리해본다.

인증서 발급 준비

SSL/TLS 인증서 발급 시 도메인 소유권 인증을 받아야 하는데, DNS-01 챌린지 방식으로 처리할 수 있다. Cloudflare를 이용한 DNS 인증을 위해서는 Cloudflare의 API 토큰을 서버에 등록하는 과정이 필요하다.

  • Cloudflare API 토큰 발급

    API 토큰 발급은 아래 경로로 접근할 수 있다.

    Cloudflare 홈 > [내 프로필] > [API 토큰]

    Cloudflare 사용자 API 토큰 페이지에서 토큰 생성 버튼이 강조된 화면

    사용자 설정 토큰 생성 화면에서 권한을 영역 - SSL 및 인증서 - 편집으로 지정하는 화면

    생성된 영역 DNS 편집 API 토큰이 활성 상태로 목록에 표시된 화면

    토큰 발급 직후에 보여주는 토큰값은 다시 확인할 수 없으므로 미리 복사해두어야 한다.

  • 서버 환경변수로 Cloudflare API 토큰 설정

    vim ~/.keys/cloudflare.ini
    dns_cloudflare_api_token = ExAMpLE2Oeya1nwmp559q3rk57smz0O3w5z

    글로벌 API 키를 사용하는 것이 아닌 특정 용도의 API 토큰을 발행해서 사용했을 경우, dns_cloudflare_api_key 및 dns_cloudflare_email이 아닌 dns_cloudflare_api_token으로 변수명을 설정해야 한다.

Let’s Encrypt - Certbot 설치 및 설정

Cloudflare API 토큰을 준비했다면, 인증서 발급 도구인 certbot과 Cloudflare DNS 플러그인을 설치한다.

  • 패키지 및 플러그인 설치

    sudo apt install certbot python3-certbot-dns-cloudflare
  • SSL/TLS 인증서 발급

    sudo certbot certonly --preferred-challenges dns-01 --dns-cloudflare --dns-cloudflare-credentials ~/.keys/cloudflare.ini -d api.domain.com

    발급된 인증서는 기본적으로 /etc/letsencrypt/live 경로에 저장된다. 또한, 인증서가 발급되면 certbot 서비스가 실행되고, 자동으로 인증서를 갱신하기 위해 설정된 타이머에 따라 정기적으로 갱신 작업이 수행된다.

  • 자동 갱신 타이머 확인

    systemctl list-timers
    NEXT                          LEFT      LAST                          PASSED  UNIT                ACTIVATES
    Tue 2024-10-23 23:55:39 KST   5h 2min   Tue 2024-10-23 05:18:05 KST   13h     ago certbot.timer   certbot.service

    서버 시스템의 타이머에서 certbot.service가 등록되어 있는 것을 확인해볼 수 있다.

Nginx 설정

마지막으로 Nginx에 SSL/TLS 설정을 추가한다.

  • 서버 블록 수정

    sudo vim /etc/nginx/sites-available/api.domain.com
    # api.domain.com 내용
    
    server {
      listen 443 ssl; # 443 포트에서 SSL 사용
      server_name api.domain.com; # 요청 Host 헤더가 해당 도메인일 경우의 서버 블록
    
      # SSL 인증서 및 키 경로
      ssl_certificate /etc/letsencrypt/live/api.domain.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/api.domain.com/privkey.pem;
    
      ssl_protocols TLSv1.2 TLSv1.3; # TLS 프로토콜 버전
      ssl_prefer_server_ciphers on; # 서버의 암호화 스위트 우선 사용
    
      location / {
        proxy_pass http://127.0.0.1:3000; # 로컬 3000 포트(백엔드 앱)로 프록시
        proxy_http_version 1.1; # HTTP/1.1 사용(디폴트)
    
        # 헤더 정보 추가
        proxy_set_header Host $host; # 클라이언트 도메인 주소를 Host 헤더에 설정
        proxy_set_header X-Real-IP $remote_addr; # 클라이언트의 IP 주소를 X-Real-IP 헤더에 설정
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 클라이언트의 IP 주소를 X-Forwarded-For 헤더에 설정
        proxy_set_header X-Forwarded-Proto $scheme; # 요청 프로토콜을 X-Forwarded-Proto 헤더에 설정
        proxy_set_header Upgrade $http_upgrade; # WebSocket 요청일 경우 사용
        proxy_set_header Connection 'upgrade'; # WebSocket 요청일 경우 사용
    
        proxy_cache_bypass $http_upgrade;  # WebSocket 요청에 대한 캐시 우회
      }
    }
    
    server {
      listen 443 ssl default_server; # 443 포트에서 SSL을 사용 및 기본 서버로 설정
      server_name _; # 모든 요청을 처리하는 catch-all 서버 블록
    
      ssl_certificate /etc/letsencrypt/live/api.domain.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/api.domain.com/privkey.pem;
    
      location / {
        return 403;  # 요청에 대해 403 Forbidden 응답 반환
      }
    }

    이렇게 서버 블록을 나누어 두면, api.domain.com로 들어온 요청에 대해서만 프록시를 수행하고, 그외 모든 요청에 대해서는 403 Forbidden을 반환함으로써 보안을 강화할 수 있다.

    보통 80번 포트로 들어온 요청은 443 포트로 리디렉션하지만, 해당 프록시는 일반 사용자가 직접 요청할 일이 없는 백엔드 서버이므로 보안을 위해 리디렉션을 제외했다.

  • 서버 블록을 심볼릭 링크로 추가

    생성한 서버 블록 설정 파일을 /etc/nginx/sites-enabled 위치에 심볼릭 링크로 추가해 서버 블록을 활성화한다.

    sudo ln -s /etc/nginx/sites-available/api.domain.com /etc/nginx/sites-enabled

    이미 설정 파일이 존재할 경우, 삭제 후 다시 추가한다.

    sudo rm /etc/nginx/sites-enabled/api.domain.com
  • Nginx 재시작

    설정이 모두 완료되면, Nginx를 재시작해 SSL/TLS 적용을 마친다.

    sudo systemctl restart nginx

참고 자료

  • [1] Let's encrypt SSL 인증서 자동 갱신하기 (Cloudflare) - j911
목차