Nginx HTTPS(SSL) 인증서 적용 가이드

Ma_Seokjae·2025년 6월 2일
post-thumbnail

이번 글에서는 Nginx를 사용하는 리눅스 서버에 SSL 인증서를 수동 등록하여 HTTPS를 적용하는 과정을 정리해 보았습니다.
모두 함께 HTTP 서비스를 HTTPS로 전환하는 방법을 알아봅시다 :)

이 가이드는 다음과 같은 환경을 기준으로 작성되었습니다:

  • OS: Amazon Linux, Ubuntu, CentOS 등
  • 웹 서버: Nginx
  • 인증서: 발급받은 PEM/CRT/KEY 형식의 인증서 파일
  • 예시 도메인: example.com

✅ 1. SSL 인증서 준비

인증서를 발급받고 나면 보통 다음 3개의 파일을 받습니다:
저같은 경우에는,, 외주를 했던 기관의 정보 인프라팀에서 신청 후 제공 받았습니다.

파일명설명
example.com.crt 또는 .pem서버 인증서
example.com.key개인 키 파일 (절대 외부 유출 금지)
chainca.crt 또는 ca_bundle.crt체인 인증서 (중간 인증기관)

💡 인증서 파일은 모두 .pem 또는 .crt, .key 형태여야 하며, Nginx는 JKS나 PFX 포맷을 지원하지 않음.


✅ 2. 인증서 파일 서버에 배치

sudo mkdir -p /etc/nginx/ssl
sudo cp example.com.crt /etc/nginx/ssl/
sudo cp example.com.key /etc/nginx/ssl/
sudo cp chainca.crt     /etc/nginx/ssl/

# 개인 키 보안 권한 설정
sudo chmod 600 /etc/nginx/ssl/example.com.key
sudo chown root:root /etc/nginx/ssl/example.com.key

✅ 3. Nginx 설정 파일 작성

설정 파일은 /etc/nginx/conf.d/reverse-proxy.conf 또는 프로젝트별 설정 파일로 저장합니다.

✨ 예시: /etc/nginx/conf.d/reverse-proxy.conf

##########################################
# 1. HTTP 요청을 HTTPS로 강제 리다이렉션
##########################################
server {
    listen 80;
    server_name example.com;

    return 301 https://$host$request_uri;
}

##########################################
# 2. HTTPS 설정 (SSL 인증서 적용)
##########################################
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate           /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key       /etc/nginx/ssl/example.com.key;
    ssl_trusted_certificate   /etc/nginx/ssl/chainca.crt;

    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_ciphers               HIGH:!aNULL:!MD5;

    ##########################################
    # 3. 프론트엔드 요청 프록시 처리
    ##########################################
    location / {
        proxy_pass http://localhost:3000;  # 프론트엔드 서비스가 도는 포트
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # ✅ 보안 헤더 설정
        add_header Content-Security-Policy "
            default-src 'self';
            script-src 'self' 'unsafe-inline' https://accounts.google.com;
            style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
            font-src 'self' https://fonts.gstatic.com;
            img-src 'self' data:;
            connect-src 'self';
        " always;

        add_header X-Frame-Options "DENY" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer" always;
        add_header Permissions-Policy "geolocation=(), microphone=()" always;
    }

    ##########################################
    # 4. 백엔드 API 요청 분리 프록시
    ##########################################
    location /api/v1/ {
        proxy_pass http://10.0.0.2:8080/api/v1/;  # 내부 백엔드 프라이빗 IP
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

🔍 각 블록 상세 설명

블록설명
server_name이 서버 블록이 응답해야 하는 도메인을 지정합니다. 실제로 서비스할 도메인 이름(example.com)으로 바꿔야 하며, 인증서의 CN(Common Name)과 일치해야 정상적으로 HTTPS가 작동합니다.
listen 443 ssl;Nginx가 443번 포트(HTTPS 표준 포트)에서 SSL을 활성화한 상태로 클라이언트 요청을 수신하도록 설정합니다. 반드시 ssl 키워드가 포함되어야 SSL 인증서가 작동합니다.
ssl_certificate, ssl_certificate_key발급받은 서버 인증서(.crt)와 개인 키(.key)의 절대 경로를 지정합니다. .key는 유출되면 보안상 치명적이므로 접근 권한을 제한해야 하며, .crt는 공개 인증서입니다.
ssl_trusted_certificate중간 인증기관에서 발급한 체인 인증서의 경로를 지정합니다. 루트 CA → 중간 CA → 서버 인증서로 이어지는 신뢰 체인을 구성해야 브라우저가 인증서를 신뢰합니다. 보통 chainca.crt 또는 ca_bundle.crt 형식입니다.
location /클라이언트가 도메인 루트(https://example.com/)에 접근했을 때 요청을 내부의 프론트엔드 서버(Nginx가 설치된 동일 서버의 3000번 포트 등)로 전달(proxy)합니다. Next.js, React 등의 정적 서버 실행 포트에 맞춰 조정합니다.
location /api/v1/API 요청(/api/v1/*)은 내부 백엔드 서버(예: Spring Boot 등)로 전달됩니다. proxy_pass 대상은 일반적으로 같은 VPC의 프라이빗 IP와 포트를 사용합니다. 라우팅 경로가 중복되지 않도록 끝에 슬래시(/)도 유의합니다.
add_headerHTTP 응답에 보안 관련 헤더를 추가하여 XSS, 클릭재킹, MIME 타입 위장 등 공격을 방지합니다. 예: Content-Security-Policy, X-Frame-Options, Referrer-Policy 등. 필요 시 정책을 서비스 환경에 맞게 수정 가능합니다.

✅ 4. 설정 적용

sudo nginx -t               # 문법 검사
sudo systemctl restart nginx  # 적용

✅ 5. HTTPS 적용 확인

  • 브라우저에서 https://example.com 접속 후 🔒 자물쇠 확인
  • 또는 CLI:
curl -I https://example.com

응답에 200 OK 또는 301 Moved Permanently가 뜨면 성공입니다.

📌 주의: 서버가 AWS EC2 인스턴스인 경우, 보안 그룹(Security Group)에서 443 포트(TCP)에 대해 외부 접근이 허용되어 있어야 합니다.
만약 인증서 적용과 설정이 모두 정확한데도 접속이 되지 않는다면, 보안 그룹 인바운드 규칙에 443 포트 허용이 누락되었는지 반드시 확인해야 합니다.


📌 참고 팁

  • 인증서는 보통 1년 또는 90일 유효이며, 갱신 후 동일 경로에 교체하면 됨
  • .key 파일은 절대 외부 유출 금지 (권한 600 필수)
  • CSP 등 보안 헤더는 서비스 상황에 맞게 커스터마이징 가능
  • nginx -t 없이 무작정 재시작하면 오류 시 전체 서비스 중단될 수 있음

✅ 마무리 체크리스트

  • 인증서 3종 서버에 배치 (.crt, .key, chainca.crt)
  • 개인 키 파일 권한 설정
  • /etc/nginx/conf.d/*.conf에 HTTPS 설정
  • nginx -trestart 적용
  • 브라우저에서 HTTPS 접속 확인
profile
Why not change the code?

0개의 댓글