리눅스

Nginx HTTP 보안 헤더 설정

변군이글루 2025. 10. 31. 14:12
반응형

Nginx HTTP 보안 헤더 설정

1. 핵심 보안 헤더(필수 6개)

헤더 권장 값 설명
Content-Security-Policy default-src 'self'; script-src 'self' 'strict-dynamic' 'nonce-{{nonce}}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; upgrade-insecure-requests; XSS  인라인 스크립트 실행 차단
X-Frame-Options DENY 클릭재킹 방지. CSP의 frame-ancestors와 중복 적용 가능
X-Content-Type-Options nosniff MIME 타입 스니핑 방지
Referrer-Policy strict-origin-when-cross-origin 민감한 리퍼러 정보 노출 방지
Permissions-Policy geolocation=(), microphone=(), camera=(), payment=() 브라우저 기능 접근 제한
Strict-Transport-Security max-age=31536000; includeSubDomains; preload HTTPS 강제(HSTS, 1년, 서브도메인 포함)

보안 헤더 설정 파일

vim /etc/nginx/conf.d/securityheaders.configuration
# ==============================
#  보안 헤더 기본 세트 (권장)
# ==============================
add_header Content-Security-Policy "style-src 'self' 'unsafe-inline' https:; " always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

Nginx 전역 설정

vim /etc/nginx/nginx.conf
# nginx.conf
user www-data www-data;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    charset utf-8;

    add_header X-Served-By webServer111 always;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_prefer_server_ciphers on;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
...
    include /etc/nginx/conf.d/*.conf;
}

Nginx 가상 호스트 설정

vim /etc/nginx/conf.d/www.scbyun.com.conf
server {
    listen 80;
    server_name scbyun.com www.scbyun.com; 
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name scbyun.com www.scbyun.com;
    root /app/www/public;
    index index.php;

    access_log /var/log/nginx/www.scbyun.com-access.log;
    error_log /var/log/nginx/www.scbyun.com-error.log;
...
    # 보안 헤더 추가
    include /etc/nginx/conf.d/securityheaders.configuration;    

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

Nginx 설정 검증

nginx -t

Nginx 리로드

nginx -s reload
728x90

보안 점수(SecurityHeaders.com 기준)

설정 헤더 점수
모든 헤더 적용 Strict-Transport-Security X-Frame-Options X-Content-Type-Options Referrer-Policy Permissions-Policy Content-Security-Policy A+
CSP 미적용 Strict-Transport-Security X-Frame-Options X-Content-Type-Options Referrer-Policy Permissions-Policy B~C 등급
HSTS 미적용 X-Frame-Options X-Content-Type-Options Referrer-Policy Permissions-Policy B 등급

Missing Headers

Strict-Transport-Security : HTTP Strict Transport Security는 사이트에서 지원해야 할 탁월한 기능으로, 사용자 에이전트가 HTTPS 사용을 강제하도록 하여 TLS 구현을 강화합니다. 권장 값: "Strict-Transport-Security: max-age=31536000; includeSubDomains".

Content-Security-Policy : 콘텐츠 보안 정책(CSP)은 사이트를 XSS 공격으로부터 보호하는 효과적인 방법입니다. 승인된 콘텐츠의 출처를 화이트리스트에 등록함으로써 브라우저가 악성 자산을 로드하는 것을 방지할 수 있습니다.

X-Frame-Options : X-Frame-Options는 사이트가 프레임에 포함되는 것을 허용할지 여부를 브라우저에 알립니다. 브라우저가 사이트를 프레임에 포함하는 것을 방지함으로써 클릭재킹과 같은 공격으로부터 방어할 수 있습니다. 권장 값은 "X-Frame-Options: SAMEORIGIN"입니다.

X-Content-Type-Options : X-Content-Type-Options는 브라우저가 콘텐츠 유형을 MIME 스니핑(MIME-sniff)하는 것을 차단하고 선언된 콘텐츠 유형을 따르도록 강제합니다. 이 헤더의 유일한 유효한 값은 "X-Content-Type-Options: nosniff"입니다.

Referrer-Policy : 리퍼러 정책은 사이트가 문서에서 벗어나 이동할 때 브라우저가 포함하는 정보의 양을 제어할 수 있도록 하는 새로운 헤더로, 모든 사이트에서 설정해야 합니다.

Permissions-Policy : 권한 정책은 사이트가 브라우저에서 사용 가능한 기능 및 API를 제어할 수 있도록 하는 새로운 헤더입니다.

기본 보안(추천)

add_header Content-Security-Policy "default-src https:;" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always;

테스트 도구

Security Headers

https://securityheaders.com

 

CSP Evaluator(Google)

https://csp-evaluator.withgoogle.com

CSP란 무엇인가?

Content Security Policy(CSP)는 브라우저가 허용된 리소스(스크립트, 이미지, 스타일 등)만 로드하도록 제한하는 보안 정책입니다.

이를 통해 XSS, 코드 인젝션, 클릭재킹 등의 공격을 원천 차단할 수 있습니다.

CSP는 정상적인 스크립트 실행까지 차단할 수 있으므로, 실제 서비스 반영 전 Report-Only 모드로 테스트하는 것이 좋습니다.

 

HTTP Strict Transport Security(HSTS)

https://hstspreload.org

 

cURL 점검

curl -sI "https://www.scbyun.com" \
| grep -i -E "content-security-policy|x-frame-options|x-content-type-options|referrer-policy|strict-transport-security|permissions-policy|cross-origin"
x-content-type-options: nosniff
strict-transport-security: max-age=31536000 ; includeSubDomains

스크립트

vim securityheadercheck.sh
#!/bin/bash
URL="https://www.scbyun.com"

echo "=== 보안 헤더 점검: $URL ==="
curl -sI "$URL" | grep -i -E "content-security-policy|x-frame-options|x-content-type-options|referrer-policy|strict-transport-security|permissions-policy|cross-origin"
chmod +x securityheadercheck.sh && ./securityheadercheck.sh
content-security-policy: default-src 'self'; script-src 'self'
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
strict-transport-security: max-age=31536000; includeSubDomains; preload
permissions-policy: geolocation=(), microphone=(), camera=()

 

728x90
반응형