TechNote · NGINX · 06
보안 베이스라인: “운영 포털”을 안전하게 기본 세팅하는 최소 세트
운영 포털을 안전하게 운영하기 위해, 꼭 필요한 최소 보안 기본값(헤더·TLS·정책·로그)을 한 번에 정리해 드립니다.
이 글의 목표
운영 포털/대시보드는 “내부망이라 괜찮다”가 아니라,
기본 보안 헤더 + 접근 제한 + 요청 제한 + 안전한 TLS를
프록시 레벨에서 표준화해서 사고 확률을 낮추는 겁니다.
운영 포털/대시보드는 “내부망이라 괜찮다”가 아니라,
기본 보안 헤더 + 접근 제한 + 요청 제한 + 안전한 TLS를
프록시 레벨에서 표준화해서 사고 확률을 낮추는 겁니다.
1) HTTPS 강제 + HSTS
1-1) 80 → 443 리다이렉트
server {
listen 80;
server_name portal.example.com;
return 301 https://$host$request_uri;
}
1-2) HSTS(주의해서 적용)
HSTS는 브라우저에게 “앞으로는 HTTPS로만 접속하라”는 정책을 심어줍니다. 운영자 입장에선 보안 효과가 크지만, 잘못 적용하면 복구가 어렵습니다(특히 preload). :contentReference[oaicite:13]{index=13}
# HTTPS server{} 안에
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
운영자 팁
add_header는 상태코드에 따라 적용이 누락될 수 있어 always를 습관처럼 붙이는 게 안전합니다.
add_header는 상태코드에 따라 적용이 누락될 수 있어 always를 습관처럼 붙이는 게 안전합니다.
2) 보안 헤더 기본 세트(add_header always)
운영 포털 보안 베이스라인(레이어 개념도)
운영 포털의 “기본 방어선”으로 아래를 추천합니다.
# /etc/nginx/conf.d/60-security-headers.conf
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "no-referrer" always;
# 필요 시(조직 정책/서비스 특성에 맞게 조정)
# add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
3) CSP는 “Report-Only → 점진 적용”이 정답
CSP(Content-Security-Policy)는 XSS/리소스 로딩을 강력하게 제한합니다. 하지만 운영 포털은 SPA/외부 CDN/내부 API가 섞여 있어서, 처음부터 강하게 걸면 화면이 깨지기 쉽습니다.
3-1) 먼저 Report-Only로 관측부터
# 우선은 Report-Only로 시작(깨짐 방지)
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self';" always;
3-2) 안정화되면 enforce로 전환
# 안정화 후에만!
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self';" always;
참고: CSP는 add_header로 설정하는 게 일반적인 패턴입니다.
4) 접근 제어: allow/deny로 “관리망만 허용”
내부 운영 포털은 외부에 열지 않더라도, 접근 가능한 대역을 최소화하는 것만으로 사고 확률이 크게 줄어듭니다. allow/deny는 NGINX 표준 모듈로 지원됩니다.
# 예: 특정 대역만 허용
location / {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
# 통과한 요청만 upstream으로
proxy_pass http://127.0.0.1:3000;
}
운영자 팁
“인증(RBAC)”이 있어도, 접근 대역을 줄이면 공격 표면이 더 줄어듭니다.
둘 중 하나만 하라고 하면? 가능하면 둘 다.
“인증(RBAC)”이 있어도, 접근 대역을 줄이면 공격 표면이 더 줄어듭니다.
둘 중 하나만 하라고 하면? 가능하면 둘 다.
5) 요청/업로드/타임아웃 제한(운영자 실전)
5-1) 업로드 제한(대시보드/정책 자동화에서 필수)
# server{} 또는 location /api/ {} 안에
client_max_body_size 50m;
5-2) 타임아웃(느린 클라/느린 백엔드에서 “좀비 연결” 방지)
# 클라이언트가 헤더를 너무 늦게 보내면 끊기
client_header_timeout 15s;
# 백엔드가 오래 걸릴 수 있는 작업(리포트 생성 등)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
참고: client_header_timeout 같은 코어 타임아웃은 http/server 레벨에서 사용합니다.
5-3) Rate limit(로그인/토큰 경로 최소 방어)
레이트리밋은 NGINX 표준 모듈(leaky bucket)로 제공됩니다.
# http{} 레벨
limit_req_zone $binary_remote_addr zone=login_zone:10m rate=5r/s;
# login/인증 관련 경로
location /oauth2/ {
limit_req zone=login_zone burst=10 nodelay;
proxy_pass http://127.0.0.1:4180;
}
6) 검증 커맨드(체크리스트)
# 1) 헤더 확인(HSTS/CSP/기본헤더)
curl -kI https://portal.example.com/ | egrep -i 'strict-transport|content-security|x-frame|x-content-type|referrer'
# 2) http → https 리다이렉트 확인
curl -I http://portal.example.com/ | egrep -i 'HTTP/|Location'
# 3) 접근제어 확인(허용되지 않은 네트워크에서 403/444 등)
curl -kI https://portal.example.com/ | egrep -i 'HTTP/'
'Tech Note > 서버-Nginx' 카테고리의 다른 글
| 8. 장애 케이스 모음(현업 디버깅 플레이북) (0) | 2025.12.28 |
|---|---|
| 7. 운영자가 그대로 가져다 쓰는 “완성 템플릿” (portal.conf) (0) | 2025.12.28 |
| 5. 운영 로그로 APM 만들기: “느림”을 3분해해서 원인 좁히기 (0) | 2025.12.28 |
| 4. 인증/권한(RBAC) 붙이기: auth_request + 헤더 계약 + 경로별 정책 (0) | 2025.12.28 |
| 3. 구현 사례 예시 2개(포털 / 정책자동화) (0) | 2025.12.28 |