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
보안 점수(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
CSP Evaluator(Google)
https://csp-evaluator.withgoogle.com
CSP란 무엇인가?
Content Security Policy(CSP)는 브라우저가 허용된 리소스(스크립트, 이미지, 스타일 등)만 로드하도록 제한하는 보안 정책입니다.
이를 통해 XSS, 코드 인젝션, 클릭재킹 등의 공격을 원천 차단할 수 있습니다.
CSP는 정상적인 스크립트 실행까지 차단할 수 있으므로, 실제 서비스 반영 전 Report-Only 모드로 테스트하는 것이 좋습니다.
HTTP Strict Transport Security(HSTS)
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=()
'리눅스' 카테고리의 다른 글
| 우분투 24.04에서 Redis 클러스터를 구성하고 HAProxy + Keepalived로 고가용성을 확보하는 방법 (0) | 2025.11.04 |
|---|---|
| MySQL에서 Binary Log를 설정하는 방법 (0) | 2025.11.04 |
| Zabbix 에이전트에서 로그인된 사용자 계정 정보를 가져오는 방법 (0) | 2025.10.31 |
| 리눅스에서 터미널 세션을 종료하는 방법 (0) | 2025.10.29 |
| 우분투 24.04에서 nc 명령어를 사용하기 위한 방법 (0) | 2025.10.22 |