작업 전 확인
어느 조치를 하든 여기서 시작한다. SSH로 접속하고, 계정에 sudo 권한이 있어야 한다.
웹서버 종류와 버전을 확인한다.
ps -ef | grep -E 'nginx' | grep -v grep # nginx 프로세스 확인
nginx -v # 버전 (예: nginx/1.24.0)
nginx -V 2>&1 | tr ' ' '\n' | grep -i openssl # OpenSSL 버전 — TLS 1.3 가능 여부
TLS 1.3을 쓰려면 nginx 1.13.0 이상과 OpenSSL 1.1.1 이상이 둘 다 필요하다(ssl_protocols 공식 문서의 TLSv1.3 (1.13.0) 표기).
설정 파일 위치를 찾는다.
nginx -t # 설정 루트가 출력됨 (보통 /etc/nginx/nginx.conf)
nginx -T | grep -n "ssl_certificate\|ssl_protocols\|server_name" # 현재 적용값 전체 덤프
nginx -T는 실제로 로드되는 설정의 전부다. include가 얽혀 있어도 이걸 보면 어느 파일 몇째 줄인지 나온다. 여기 나온 ssl_certificate, ssl_certificate_key 값이 지금 쓰고 있는 인증서 파일 경로다.
TLS 1.0, 1.1 끄고 TLS 1.3 켜기
해당 도메인의 server 블록(443)에 넣는다.
ssl_protocols TLSv1.2 TLSv1.3; # 1.0·1.1 제거, 1.3 활성
OpenSSL이 1.1.1 미만이라 TLS 1.3이 안 되면 TLSv1.2만이라도 남긴다.
ssl_protocols TLSv1.2;
TLS 1.1로 붙어 보고 막히는지 확인한다.
openssl s_client -connect 도메인:443 -tls1_1 </dev/null 2>&1 | grep -q "handshake failure\|no protocols" && echo "1.1 차단 OK"
보안 헤더
HSTS, CSP, nosniff, 클릭재킹 방어, Referrer-Policy 헤더를 server 블록(443)에 넣는다.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# CSP 는 사이트 구조에 맞춰 조정 — 우선 Report-Only 로 관찰 후 강제 권장
add_header Content-Security-Policy "default-src 'self'" always;
HTTP → HTTPS 리다이렉트
80 포트 server 블록을 이렇게 바꾼다.
server {
listen 80;
server_name 도메인;
return 301 https://$host$request_uri;
}
약한 키나 서명이면 인증서 교체
RSA 2048 미만이거나 SHA-1 서명이면 재발급해야 한다. 교체는 Nginx 인증서 교체와 무중단 리로드 순서대로 한다.
신규 도메인 인증서 설치
발급과 파일 준비는 발급 공통 가이드에서 먼저 끝낸다.
fullchain과 개인키를 /etc/nginx/ssl/ 같은 곳에 두고, 개인키는 chmod 600으로 막는다. 그다음 conf.d/새도메인.conf에 server 블록을 추가한다.
server {
listen 443 ssl;
http2 on; # 1.25.1+ (이전 버전: listen 443 ssl http2;)
server_name 새도메인;
ssl_certificate /etc/nginx/ssl/fullchain.pem; # leaf+중간 — fullchain 필수
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# ... root/proxy 설정
}
server {
listen 80;
server_name 새도메인;
return 301 https://$host$request_uri;
}
openssl s_client -connect 새도메인:443 -servername 새도메인이나 진단 툴로 확인한다. -verify_return_error를 붙여 0 (ok)가 나오는지 본다. fullchain이 빠졌으면 여기서 걸린다.
재검사
진단 툴에 도메인을 넣어 등급이 올라갔는지 확인한다. 검사 결과는 최대 10분 캐시된다.
공식 문서
- ngx_http_ssl_module: ssl_protocols, ssl_certificate
- ngx_http_headers_module: add_header 상속 규칙 원문 “These directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level.”
- ngx_http_v2_module: http2 지시자 (1.25.1)