update .env for docker-compose.yml
parent
cf14f5a0fd
commit
356e54b60b
|
|
@ -1,8 +1,4 @@
|
|||
PROJECT_DIR=django_sample
|
||||
WORKERS=4
|
||||
GUNICORN_PORT=8000
|
||||
REQUIREMENTS=./requirements.txt
|
||||
PROJECT_NAME=django_sample
|
||||
LOG_DRIVER=json-file
|
||||
LOG_OPT_MAXF=5
|
||||
LOG_OPT_MAXS=100m
|
||||
|
|
|
|||
|
|
@ -1,774 +0,0 @@
|
|||
# Nginx HTTPS 설정 검토 보고서
|
||||
|
||||
## 요약
|
||||
|
||||
본 보고서는 `sample_nginx_https.conf` (템플릿)와 `https.conf` (code.devspoon.com의 운영 설정)을 비교하고, 현재 설정의 운영 준비 상태를 평가합니다.
|
||||
|
||||
**종합 평가**: `https.conf`는 샘플 템플릿보다 훨씬 더 운영 환경에 적합하며, 최신 보안 헤더와 우수한 설정을 갖추고 있습니다. 그러나 일부 개선 사항이 권장됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 설정 비교 분석
|
||||
|
||||
### 1.1 HTTP 서버 블록 (포트 80)
|
||||
|
||||
#### 샘플 설정의 문제점:
|
||||
```nginx
|
||||
server {
|
||||
listen portnumber;
|
||||
server_name domain www.domain;
|
||||
|
||||
rewrite ^ https://$host$request_uri permanent;
|
||||
|
||||
# if ($host !~* ^(domain\.com|www\.domain\.com)$) {
|
||||
# return 444;
|
||||
# }
|
||||
}
|
||||
```
|
||||
|
||||
**문제점:**
|
||||
- 일반적인 플레이스홀더 사용 (`portnumber`, `domain`)
|
||||
- `return 301` 대신 더 이상 권장되지 않는 `rewrite` 지시어 사용
|
||||
- 호스트 검증이 주석 처리됨
|
||||
- Let's Encrypt ACME 챌린지 location 누락
|
||||
|
||||
#### 운영 설정 (https.conf) - 올바름:
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name code.devspoon.com www.code.devspoon.com;
|
||||
|
||||
# 리다이렉트 전 호스트 검증
|
||||
if ($host !~* ^(code\.devspoon\.com|www\.code\.devspoon\.com)$) {
|
||||
return 444;
|
||||
}
|
||||
|
||||
# 리다이렉트 전 ACME 챌린지
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /www/certbot;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# HTTPS로 리다이렉트
|
||||
location / {
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**장점:**
|
||||
✅ `return 301` 사용 (rewrite보다 효율적)
|
||||
✅ 호스트 검증 활성화
|
||||
✅ 리다이렉트 전 ACME 챌린지 적절히 처리
|
||||
✅ location 블록으로 더 나은 구조
|
||||
✅ `$host` 대신 `$server_name` 사용 (더 안전함)
|
||||
|
||||
---
|
||||
|
||||
### 1.2 HTTPS 서버 블록 (포트 443)
|
||||
|
||||
#### SSL/TLS 설정
|
||||
|
||||
**샘플 설정 - 구식:**
|
||||
```nginx
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
|
||||
```
|
||||
|
||||
**운영 설정 - 최신 & 올바름:**
|
||||
```nginx
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers off; # TLSv1.3에서는 OFF
|
||||
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;
|
||||
```
|
||||
|
||||
**분석:**
|
||||
- ✅ 운영 설정에서 `ssl_prefer_server_ciphers off` 사용 - TLSv1.3에 **올바름** (클라이언트 선호가 더 나음)
|
||||
- ✅ 일반적인 약칭 대신 명시적이고 최신 암호화 스위트 사용
|
||||
- ✅ 모바일 장치 최적화를 위한 CHACHA20-POLY1305 포함
|
||||
|
||||
---
|
||||
|
||||
### 1.3 보안 헤더
|
||||
|
||||
**샘플 설정 - 누락:**
|
||||
- 보안 헤더가 전혀 없음
|
||||
|
||||
**운영 설정 - 우수:**
|
||||
```nginx
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header X-Frame-Options DENY always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss: ws:;" always;
|
||||
```
|
||||
|
||||
**평가:**
|
||||
✅ **HSTS** (preload 포함) - 다운그레이드 공격 방지
|
||||
✅ **X-Frame-Options** - 클릭재킹 방지
|
||||
✅ **X-Content-Type-Options** - MIME 스니핑 방지
|
||||
✅ **X-XSS-Protection** - 레거시 XSS 보호
|
||||
✅ **Referrer-Policy** - 리퍼러 정보 제어
|
||||
✅ **CSP** - XSS 방지를 위한 콘텐츠 보안 정책
|
||||
✅ 모든 헤더에 `always` 플래그 사용 - 오류 응답에도 헤더 보장
|
||||
|
||||
---
|
||||
|
||||
### 1.4 OCSP 스테이플링
|
||||
|
||||
**샘플 설정 - 누락**
|
||||
|
||||
**운영 설정 - 구현됨:**
|
||||
```nginx
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/code.devspoon.com/chain.pem;
|
||||
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
```
|
||||
|
||||
**평가:**
|
||||
✅ OCSP 스테이플링으로 SSL 핸드셰이크 성능 향상
|
||||
✅ Cloudflare (1.1.1.1)와 Google (8.8.8.8) DNS 리졸버 사용
|
||||
✅ OCSP 경고에 대한 유용한 주석 포함
|
||||
|
||||
---
|
||||
|
||||
### 1.5 프록시 설정
|
||||
|
||||
**샘플 설정 - 기본:**
|
||||
```nginx
|
||||
location / {
|
||||
autoindex off;
|
||||
proxy_pass http://appname:serviceport;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
```
|
||||
|
||||
**운영 설정 - 포괄적:**
|
||||
```nginx
|
||||
location / {
|
||||
proxy_pass http://code-server:8443;
|
||||
|
||||
# WebSocket 지원
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# 완전한 프록시 헤더
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
# 최적화된 타임아웃
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 버퍼 설정
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
proxy_set_header Accept-Encoding gzip;
|
||||
}
|
||||
```
|
||||
|
||||
**평가:**
|
||||
✅ WebSocket 지원 (code-server에 필수)
|
||||
✅ 포괄적인 forwarded 헤더
|
||||
✅ 적절한 타임아웃 설정
|
||||
✅ 대화형 애플리케이션에 최적화된 버퍼 설정
|
||||
⚠️ 샘플에는 WebSocket 지원이 완전히 없음
|
||||
|
||||
---
|
||||
|
||||
### 1.6 정적 파일 처리
|
||||
|
||||
**샘플 설정 - 존재:**
|
||||
```nginx
|
||||
location /media {
|
||||
autoindex off;
|
||||
gzip_static on;
|
||||
expires max;
|
||||
alias /www/webroot/media;
|
||||
}
|
||||
|
||||
location /static {
|
||||
autoindex off;
|
||||
gzip_static on;
|
||||
expires max;
|
||||
alias /www/webroot/static;
|
||||
}
|
||||
```
|
||||
|
||||
**운영 설정 - 누락:**
|
||||
- /media 또는 /static location 없음
|
||||
|
||||
**평가:**
|
||||
⚠️ **누락** - 애플리케이션이 정적 파일을 제공하는 경우 `https.conf`에 추가해야 함
|
||||
ℹ️ code-server의 경우, 내부적으로 정적 파일을 처리하므로 의도적일 수 있음
|
||||
⚠️ **권장사항**: Django/Flask 백엔드를 추가하는 경우 정적 파일 location 포함
|
||||
|
||||
---
|
||||
|
||||
### 1.7 Let's Encrypt ACME 챌린지
|
||||
|
||||
**샘플 설정:**
|
||||
```nginx
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /www/webroot;
|
||||
}
|
||||
```
|
||||
|
||||
**운영 설정:**
|
||||
```nginx
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /www/certbot;
|
||||
try_files $uri =404; # 보안 추가
|
||||
}
|
||||
```
|
||||
|
||||
**평가:**
|
||||
✅ 운영 설정에 `try_files $uri =404` 추가 - 디렉토리 순회 방지
|
||||
✅ 전용 `/www/certbot` 디렉토리 사용
|
||||
|
||||
---
|
||||
|
||||
### 1.8 보안 블록 Location
|
||||
|
||||
**샘플 설정:**
|
||||
```nginx
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~* \.(log|binary|pem|enc|crt|conf|cnf|sql|sh|key|yml|lock)$ {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~* (composer\.json|...) {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
**운영 설정 - 향상됨:**
|
||||
```nginx
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off; # 차단된 시도는 로그에 남기지 않음
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
location ~* \.(log|binary|pem|enc|crt|conf|cnf|sql|sh|key|yml|lock)$ {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
location ~* (composer\.json|...) {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
```
|
||||
|
||||
**평가:**
|
||||
✅ 운영 설정에서 차단된 요청에 대한 로깅 비활성화 - 로그 노이즈 감소
|
||||
✅ 스캐너 시도를 로그에 남기지 않아 성능 향상
|
||||
|
||||
---
|
||||
|
||||
## 2. https.conf에 누락된 운영 준비 기능
|
||||
|
||||
### 2.1 속도 제한 - **누락**
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
# http 블록 또는 server 블록에 추가
|
||||
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
|
||||
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
||||
|
||||
# location 블록에
|
||||
location / {
|
||||
limit_req zone=general burst=20 nodelay;
|
||||
limit_conn addr 10;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**영향:** DDoS 및 무차별 대입 공격으로부터 보호
|
||||
|
||||
---
|
||||
|
||||
### 2.2 클라이언트 본문 크기 제한 - **누락**
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
client_max_body_size 10M; # 애플리케이션 요구사항에 따라 조정
|
||||
client_body_buffer_size 128k;
|
||||
client_body_timeout 60s;
|
||||
```
|
||||
|
||||
**영향:** 메모리 고갈 공격 방지
|
||||
|
||||
---
|
||||
|
||||
### 2.3 연결 제한 - **누락**
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
keepalive_timeout 65;
|
||||
keepalive_requests 100;
|
||||
send_timeout 60s;
|
||||
```
|
||||
|
||||
**영향:** 더 나은 리소스 관리
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Gzip 압축 - **누락**
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
|
||||
gzip_disable "msie6";
|
||||
```
|
||||
|
||||
**영향:** 대역폭 사용량을 크게 감소
|
||||
|
||||
---
|
||||
|
||||
### 2.5 오류 페이지 - **누락**
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
error_page 404 /404.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
location = /404.html {
|
||||
internal;
|
||||
root /www/error_pages;
|
||||
}
|
||||
|
||||
location = /50x.html {
|
||||
internal;
|
||||
root /www/error_pages;
|
||||
}
|
||||
```
|
||||
|
||||
**영향:** 더 나은 사용자 경험 및 정보 노출 방지
|
||||
|
||||
---
|
||||
|
||||
### 2.6 요청 메서드 제한 - **누락**
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
location / {
|
||||
limit_except GET POST HEAD OPTIONS {
|
||||
deny all;
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**영향:** HTTP 동사 변조 공격 방지
|
||||
|
||||
---
|
||||
|
||||
### 2.7 버전 정보 숨김 - **누락**
|
||||
|
||||
**권장사항: 추가** (http 블록에)
|
||||
```nginx
|
||||
server_tokens off;
|
||||
more_clear_headers 'Server';
|
||||
more_clear_headers 'X-Powered-By';
|
||||
```
|
||||
|
||||
**영향:** 정보 노출 감소
|
||||
|
||||
---
|
||||
|
||||
## 3. SSL/TLS 모범 사례 검증
|
||||
|
||||
### 현재 설정 평가:
|
||||
|
||||
| 설정 | 현재 값 | 상태 | 권장사항 |
|
||||
|------|---------|------|----------|
|
||||
| ssl_protocols | TLSv1.2 TLSv1.3 | ✅ 올바름 | 현재 유지 |
|
||||
| ssl_prefer_server_ciphers | off | ✅ 올바름 | 유지 (TLSv1.3 모범 사례) |
|
||||
| ssl_session_cache | shared:SSL:20m | ✅ 좋음 | 트래픽이 많으면 50m 고려 |
|
||||
| ssl_session_timeout | 10m | ✅ 좋음 | 현재 유지 |
|
||||
| ssl_session_tickets | off | ✅ 올바름 | 유지 (더 나은 보안) |
|
||||
| ssl_stapling | on | ✅ 올바름 | 현재 유지 |
|
||||
| ssl_dhparam | 4096-bit | ✅ 우수 | 현재 유지 |
|
||||
| HSTS max-age | 31536000 | ✅ 올바름 | 유지 (1년) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 성능 최적화 격차
|
||||
|
||||
### 4.1 캐싱 헤더 누락
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 열린 파일 캐시 누락
|
||||
|
||||
**권장사항: 추가**
|
||||
```nginx
|
||||
open_file_cache max=1000 inactive=20s;
|
||||
open_file_cache_valid 30s;
|
||||
open_file_cache_min_uses 2;
|
||||
open_file_cache_errors on;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 로깅 개선
|
||||
|
||||
### 현재 설정:
|
||||
```nginx
|
||||
access_log /log/nginx/code.devspoon.com.nginx.log main;
|
||||
error_log /log/nginx/code.devspoon.com.nginx_error.log warn;
|
||||
```
|
||||
|
||||
**권장사항:**
|
||||
```nginx
|
||||
# I/O 감소를 위한 버퍼 추가
|
||||
access_log /log/nginx/code.devspoon.com.nginx.log main buffer=32k flush=5s;
|
||||
error_log /log/nginx/code.devspoon.com.nginx_error.log warn;
|
||||
|
||||
# 더 많은 세부 정보를 포함한 로그 형식 추가
|
||||
log_format detailed '$remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" '
|
||||
'$request_time $upstream_response_time '
|
||||
'$upstream_addr $upstream_status';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 권장 최종 설정 구조
|
||||
|
||||
```nginx
|
||||
# HTTP 블록 (포트 80)
|
||||
server {
|
||||
listen 80;
|
||||
server_name code.devspoon.com www.code.devspoon.com;
|
||||
|
||||
# 호스트 검증
|
||||
if ($host !~* ^(code\.devspoon\.com|www\.code\.devspoon\.com)$) {
|
||||
return 444;
|
||||
}
|
||||
|
||||
# ACME 챌린지
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /www/certbot;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# HTTPS로 리다이렉트
|
||||
location / {
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS 블록 (포트 443)
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name code.devspoon.com www.code.devspoon.com;
|
||||
|
||||
# SSL 인증서
|
||||
ssl_certificate /etc/letsencrypt/live/code.devspoon.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/code.devspoon.com/privkey.pem;
|
||||
ssl_dhparam /etc/ssl/certs/code.devspoon.com/dhparam.pem;
|
||||
|
||||
# 최신 SSL 설정
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_session_tickets off;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers off;
|
||||
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;
|
||||
ssl_ecdh_curve secp384r1;
|
||||
|
||||
# OCSP 스테이플링
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/code.devspoon.com/chain.pem;
|
||||
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
# 보안 헤더
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header X-Frame-Options DENY always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss: ws:;" always;
|
||||
|
||||
# 신규: 보안 설정
|
||||
server_tokens off;
|
||||
client_max_body_size 10M;
|
||||
client_body_buffer_size 128k;
|
||||
client_body_timeout 60s;
|
||||
|
||||
# 신규: 성능 설정
|
||||
keepalive_timeout 65;
|
||||
keepalive_requests 100;
|
||||
send_timeout 60s;
|
||||
|
||||
# 신규: Gzip 압축
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;
|
||||
|
||||
# 신규: 파일 캐시
|
||||
open_file_cache max=1000 inactive=20s;
|
||||
open_file_cache_valid 30s;
|
||||
open_file_cache_min_uses 2;
|
||||
open_file_cache_errors on;
|
||||
|
||||
# 버퍼링을 사용한 로깅
|
||||
access_log /log/nginx/code.devspoon.com.nginx.log main buffer=32k flush=5s;
|
||||
error_log /log/nginx/code.devspoon.com.nginx_error.log warn;
|
||||
|
||||
# 호스트 검증
|
||||
if ($host !~* ^(code\.devspoon\.com|www\.code\.devspoon\.com)$) {
|
||||
return 444;
|
||||
}
|
||||
|
||||
# 나쁜 봇 차단
|
||||
if ($bad_bot) {
|
||||
return 403;
|
||||
}
|
||||
|
||||
# 메인 애플리케이션
|
||||
location / {
|
||||
# 신규: 속도 제한
|
||||
limit_req zone=general burst=20 nodelay;
|
||||
limit_conn addr 10;
|
||||
|
||||
# 신규: 메서드 제한
|
||||
limit_except GET POST HEAD OPTIONS {
|
||||
deny all;
|
||||
}
|
||||
|
||||
proxy_pass http://code-server:8443;
|
||||
|
||||
# WebSocket 지원
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# 프록시 헤더
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
# 타임아웃
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 버퍼 설정
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_set_header Accept-Encoding gzip;
|
||||
}
|
||||
|
||||
# ACME 챌린지
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
root /www/certbot;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# 신규: 정적 파일 캐싱 (필요시)
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# 닷 파일 차단
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 민감한 파일 차단
|
||||
location ~* \.(log|binary|pem|enc|crt|conf|cnf|sql|sh|key|yml|lock)$ {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 민감한 설정 파일 차단
|
||||
location ~* (composer\.json|composer\.lock|composer\.phar|contributing\.md|license\.txt|readme\.rst|readme\.md|readme\.txt|copyright|artisan|gulpfile\.js|package\.json|phpunit\.xml|access_log|error_log|gruntfile\.js)$ {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 파비콘 및 robots
|
||||
location = /favicon.ico {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
allow all;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 우선순위 실행 항목
|
||||
|
||||
### 긴급 (즉시 구현)
|
||||
1. ✅ **이미 존재**: 보안 헤더 (HSTS, CSP 등)
|
||||
2. ✅ **이미 존재**: OCSP 스테이플링
|
||||
3. ⚠️ **추가**: 속도 제한 설정
|
||||
4. ⚠️ **추가**: `server_tokens off`
|
||||
5. ⚠️ **추가**: `client_max_body_size` 제한
|
||||
|
||||
### 높은 우선순위 (권장)
|
||||
6. ⚠️ **추가**: Gzip 압축
|
||||
7. ⚠️ **추가**: 열린 파일 캐시
|
||||
8. ⚠️ **추가**: 오류 페이지 처리
|
||||
9. ⚠️ **추가**: HTTP 메서드 제한
|
||||
10. ⚠️ **추가**: 로깅 버퍼 설정
|
||||
|
||||
### 중간 우선순위 (선택 사항)
|
||||
11. ⚠️ **추가**: 정적 파일 캐싱 헤더
|
||||
12. ⚠️ **고려**: SSL 세션 캐시 크기 증가
|
||||
13. ⚠️ **고려**: 향상된 로깅 형식
|
||||
14. ⚠️ **검토**: 특정 애플리케이션 요구사항에 맞는 CSP 정책
|
||||
|
||||
---
|
||||
|
||||
## 8. 설정 의존성
|
||||
|
||||
### nginx.conf (http 블록)에 필요:
|
||||
```nginx
|
||||
# 서버 블록 전에 정의되어야 함
|
||||
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
|
||||
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
||||
|
||||
# 나쁜 봇 탐지 맵
|
||||
map $http_user_agent $bad_bot {
|
||||
default 0;
|
||||
~*malicious 1;
|
||||
~*scrapy 1;
|
||||
~*bot 1;
|
||||
~*crawler 1;
|
||||
}
|
||||
|
||||
# WebSocket 업그레이드 맵
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
# 로그 형식
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. SSL/TLS 테스트 권장사항
|
||||
|
||||
변경 사항 구현 후 다음으로 테스트:
|
||||
|
||||
1. **SSL Labs**: https://www.ssllabs.com/ssltest/
|
||||
- 목표 등급: A+
|
||||
|
||||
2. **Mozilla Observatory**: https://observatory.mozilla.org/
|
||||
- 목표 점수: A+ 또는 100+
|
||||
|
||||
3. **Security Headers**: https://securityheaders.com/
|
||||
- 목표 등급: A+
|
||||
|
||||
4. **OpenSSL CLI**:
|
||||
```bash
|
||||
openssl s_client -connect code.devspoon.com:443 -tls1_2
|
||||
openssl s_client -connect code.devspoon.com:443 -tls1_3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 요약
|
||||
|
||||
### https.conf에서 이미 우수한 점:
|
||||
✅ 최신 SSL/TLS 설정
|
||||
✅ 포괄적인 보안 헤더
|
||||
✅ OCSP 스테이플링
|
||||
✅ WebSocket 지원
|
||||
✅ 적절한 ACME 챌린지 처리
|
||||
✅ 향상된 프록시 설정
|
||||
✅ 로깅 최적화가 적용된 보안 블록 location
|
||||
|
||||
### 추가해야 할 사항:
|
||||
⚠️ 속도 제한
|
||||
⚠️ 클라이언트 본문 크기 제한
|
||||
⚠️ Gzip 압축
|
||||
⚠️ 열린 파일 캐시
|
||||
⚠️ 서버 토큰 숨김
|
||||
⚠️ 오류 페이지 처리
|
||||
⚠️ HTTP 메서드 제한
|
||||
|
||||
### 결론:
|
||||
**https.conf는 sample_nginx_https.conf보다 훨씬 우수하며** 최신 모범 사례를 따릅니다. 샘플 파일은 구식이고 중요한 보안 기능이 누락되어 있습니다. 위의 권장 추가 사항을 적용하면 `https.conf`는 운영 등급의 엔터프라이즈 준비 nginx 설정이 될 것입니다.
|
||||
|
||||
---
|
||||
|
||||
## 11. 다음 단계
|
||||
|
||||
1. 긴급 우선순위 항목 검토 및 구현
|
||||
2. 설정 테스트: `nginx -t`
|
||||
3. 변경 사항 적용 전 현재 설정 백업
|
||||
4. 변경 사항을 점진적으로 적용
|
||||
5. 문제가 있는지 로그 모니터링
|
||||
6. A+ 등급 확인을 위한 SSL/TLS 테스트 실행
|
||||
7. 속도 제한 및 성능 메트릭 모니터링 설정
|
||||
|
||||
---
|
||||
|
||||
**보고서 생성**: sample_nginx_https.conf vs https.conf 비교 기반
|
||||
**기준선**: https.conf (code.devspoon.com의 운영 설정)
|
||||
**평가**: 권장 개선 사항을 포함한 운영 준비 완료
|
||||
Loading…
Reference in New Issue