Nginx ๋ณด์ ์ค์
๊ฐ์
Nginx ๋ณด์ ์ค์ ์ ์๋ฒ ์ ๋ณด ์จ๊ธฐ๊ธฐ, ์ ๊ทผ ์ ์ด, ๋ณด์ ํค๋, DDoS ๋ฐฉ์ด, SSL ๊ฐํ ๋ฑ์ ํตํด ์น ์๋ฒ๋ฅผ ์ธ๋ถ ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํ๋ ๊ฒ์ด๋ค.
์๋ฒ๋ฅผ ์ธํฐ๋ท์ ๊ณต๊ฐํ๋ ์๊ฐ, ์ ์ธ๊ณ ๋๊ตฌ๋ ์ ๊ทผํ ์ ์์ด์. ๋น์ฐํ ํด์ปค, ๋ด, ์ค์บ๋๋ ํฌํจ์ด์์. ์ค์ ๋ก ์๋ฒ๋ฅผ ์ฌ๋ ค๋๋ฉด ์ ๋ถ ๋ด์ ์๋ํ๋ ๊ณต๊ฒฉ ์๋๊ฐ ๋ค์ด์ค๊ธฐ ์์ํด์!
๊ทธ๋์ ๋ณด์ ์ค์ ์ "๋์ค์ ํด๋ ๋๋ ๊ฒ"์ด ์๋๋ผ ์๋น์ค ์คํ ์ ์ ๋ฐ๋์ ํด์ผ ํ๋ ๊ฒ์ด์์. Nginx์์ ํ ์ ์๋ ๋ณด์ ์ค์ ๋ง ์ ํด๋ฌ๋ ๋๋ถ๋ถ์ ๊ธฐ๋ณธ์ ์ธ ๊ณต๊ฒฉ์ ๋ง์ ์ ์์ด์.
Nginx ๋ณด์ ๊ณ์ธต
graph TD
A["๐ ์ธํฐ๋ท<br/>(๊ณต๊ฒฉ์ ํฌํจ)"] --> B["๐ฅ ๋ฐฉํ๋ฒฝ<br/>UFW/iptables"]
B --> C["๐ก๏ธ Nginx ๋ณด์ ๊ณ์ธต"]
C --> D["๐ฅ๏ธ ์ ํ๋ฆฌ์ผ์ด์
<br/>Spring Boot ๋ฑ"]
C --> C1["์๋ฒ ์ ๋ณด ์จ๊ธฐ๊ธฐ"]
C --> C2["์์ฒญ ์ ํ (Rate Limit)"]
C --> C3["๋ณด์ ํค๋"]
C --> C4["์ ๊ทผ ์ ์ด (IP/Auth)"]
C --> C5["SSL/TLS ๊ฐํ"]
C --> C6["์์ฒญ ํฌ๊ธฐ ์ ํ"]
style C fill:#FFD700Mermaid
๋ณต์ฌ
1. ์๋ฒ ์ ๋ณด ์จ๊ธฐ๊ธฐ
ํด์ปค๊ฐ ๊ฐ์ฅ ๋จผ์ ํ๋ ๊ฑด ์๋ฒ ์ ๋ณด๋ฅผ ํ์
ํ๋ ๊ฑฐ์์. Nginx ๋ฒ์ ์ด ์๋ ค์ง๋ฉด ํด๋น ๋ฒ์ ์ ์๋ ค์ง ์ทจ์ฝ์ ์ ๊ณต๊ฒฉํ ์ ์๊ฑฐ๋ ์!
http {
# Nginx ๋ฒ์ ์ ๋ณด ์จ๊ธฐ๊ธฐ (์๋ต ํค๋์์ ์ ๊ฑฐ)
server_tokens off;
}
Plain Text
๋ณต์ฌ
์ค์ | ์ ์ฉ ์ | ์ ์ฉ ํ |
์๋ต ํค๋ | Server: nginx/1.24.0 | Server: nginx |
์๋ฌ ํ์ด์ง | nginx/1.24.0 ํ์ | nginx ๋ง ํ์ |
2. Rate Limiting (์์ฒญ ์ ํ)
DDoS ๊ณต๊ฒฉ์ด๋ ๋ธ๋ฃจํธํฌ์ค ๊ณต๊ฒฉ์ ๋ฐฉ์ดํ๋ ๊ฐ์ฅ ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ์ด์์!
graph LR
A["๐ค ์ ์ ์ฌ์ฉ์<br/>์ด๋น 5ํ ์์ฒญ"] -->|โ
ํ์ฉ| C["๐ฅ๏ธ Nginx"]
B["๐ค ๊ณต๊ฒฉ์<br/>์ด๋น 100ํ ์์ฒญ"] -->|โ 429 ์ฐจ๋จ| C
style A fill:#90EE90
style B fill:#FFB3B3Mermaid
๋ณต์ฌ
http {
# Rate Limit ์์ญ ์ ์
# $binary_remote_addr = ํด๋ผ์ด์ธํธ IP ๊ธฐ์ค
# zone=limit_req:10m = 10MB ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ
# rate=10r/s = ์ด๋น 10๊ฐ ์์ฒญ ํ์ฉ
limit_req_zone $binary_remote_addr zone=limit_req:10m rate=10r/s;
# ๋ก๊ทธ์ธ ์๋ ์ ํ (๋ ์๊ฒฉ)
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
server {
# ์ผ๋ฐ ์์ฒญ์ Rate Limit ์ ์ฉ
location / {
limit_req zone=limit_req burst=20 nodelay;
}
# ๋ก๊ทธ์ธ ๊ฒฝ๋ก๋ ๋ ์๊ฒฉํ๊ฒ
location /api/auth/login {
limit_req zone=login_limit burst=5 nodelay;
proxy_pass <http://localhost:8080>;
}
}
}
Plain Text
๋ณต์ฌ
์ค์ | ์๋ฏธ |
rate=10r/s | ์ด๋น 10๊ฐ ์์ฒญ ํ์ฉ |
burst=20 | ์๊ฐ์ ์ผ๋ก 20๊ฐ๊น์ง ์ด๊ณผ ํ์ฉ (ํ์ ๋๊ธฐ) |
nodelay | ํ ๋๊ธฐ ์์ด ์ฆ์ ์ฒ๋ฆฌํ๊ณ , ์ด๊ณผ ์ ์ฆ์ ๊ฑฐ๋ถ |
์ํฉ | ๊ฒฐ๊ณผ |
์ด๋น 10๊ฐ ์ดํ | |
์ด๋น 11~30๊ฐ | |
์ด๋น 31๊ฐ ์ด์ |
3. ๋ณด์ ํค๋ (Security Headers)
server {
# XSS ๊ณต๊ฒฉ ๋ฐฉ์ง
add_header X-Content-Type-Options "nosniff" always;
# ํด๋ฆญ์ฌํน ๋ฐฉ์ง (iframe ์ฝ์
์ฐจ๋จ)
add_header X-Frame-Options "SAMEORIGIN" always;
# XSS ํํฐ ํ์ฑํ
add_header X-XSS-Protection "1; mode=block" always;
# HTTPS ๊ฐ์ (HSTS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Referrer ์ ๋ณด ์ ํ
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Content Security Policy (๊ณ ๊ธ)
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
}
Plain Text
๋ณต์ฌ
ํค๋ | ๋ฐฉ์ด ๋์ | ์ค๋ช
|
X-Content-Type-Options | MIME ์ค๋ํ | ๋ธ๋ผ์ฐ์ ๊ฐ Content-Type์ ์์๋ก ๋ฐ๊พธ์ง ๋ชปํ๊ฒ |
X-Frame-Options | ํด๋ฆญ์ฌํน | ๋ค๋ฅธ ์ฌ์ดํธ๊ฐ iframe์ผ๋ก ๋ด ์ฌ์ดํธ๋ฅผ ์ฝ์
๋ชปํ๊ฒ |
X-XSS-Protection | XSS ๊ณต๊ฒฉ | ๋ธ๋ผ์ฐ์ ์ XSS ํํฐ ํ์ฑํ |
Strict-Transport-Security | ๋ค์ด๊ทธ๋ ์ด๋ ๊ณต๊ฒฉ | HTTPS ์ ์ ๊ฐ์ (1๋
๊ฐ ๊ธฐ์ต) |
Referrer-Policy | ์ ๋ณด ์ ์ถ | ์ธ๋ถ ์ด๋ ์ Referer ์ ๋ณด ์ ํ |
Content-Security-Policy | XSS, ๋ฐ์ดํฐ ์ฝ์
| ํ์ฉ๋ ์ถ์ฒ์ ๋ฆฌ์์ค๋ง ๋ก๋ |
4. ์ ๊ทผ ์ ์ด
IP ๊ธฐ๋ฐ ์ ๊ทผ ์ ์ด
# ๊ด๋ฆฌ์ ํ์ด์ง โ ํน์ IP๋ง ํ์ฉ
location /admin/ {
allow 203.0.113.0/24; # ํ์ฌ IP ๋์ญ
allow 10.0.0.0/8; # ๋ด๋ถ ๋คํธ์ํฌ
deny all; # ๋๋จธ์ง ์ ๋ถ ์ฐจ๋จ
proxy_pass <http://localhost:8080>;
}
# ํน์ IP ์ฐจ๋จ
location / {
deny 192.168.1.100; # ํน์ IP ์ฐจ๋จ
deny 10.0.0.0/8; # IP ๋์ญ ์ฐจ๋จ
allow all; # ๋๋จธ์ง ํ์ฉ
}
Plain Text
๋ณต์ฌ
Basic ์ธ์ฆ (ID/๋น๋ฐ๋ฒํธ)
# htpasswd ์ค์น
sudo apt install apache2-utils
# ๋น๋ฐ๋ฒํธ ํ์ผ ์์ฑ
sudo htpasswd -c /etc/nginx/.htpasswd admin
# ๋น๋ฐ๋ฒํธ ์
๋ ฅ ํ๋กฌํํธ
Bash
๋ณต์ฌ
# ์คํ
์ด์ง ์๋ฒ ๋ณดํธ
location / {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass <http://localhost:8080>;
}
Plain Text
๋ณต์ฌ
5. SSL/TLS ๊ฐํ
server {
listen 443 ssl http2;
# ์ต์ TLS๋ง ํ์ฉ (1.2, 1.3)
ssl_protocols TLSv1.2 TLSv1.3;
# ๊ฐ๋ ฅํ ์ํธํ ์ค์ํธ
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
# SSL ์ธ์
์บ์
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# DH ํ๋ผ๋ฏธํฐ (์ถ๊ฐ ๋ณด์)
ssl_dhparam /etc/nginx/dhparam.pem;
}
Plain Text
๋ณต์ฌ
# DH ํ๋ผ๋ฏธํฐ ์์ฑ (์๊ฐ์ด ์ข ๊ฑธ๋ฆผ)
sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
Bash
๋ณต์ฌ
6. ์์ฒญ ํฌ๊ธฐ ๋ฐ ๋ฒํผ ์ ํ
http {
# ์์ฒญ ๋ฐ๋ ํฌ๊ธฐ ์ ํ (ํ์ผ ์
๋ก๋ ๋ฑ)
client_max_body_size 10M;
# ๋ฒํผ ํฌ๊ธฐ ์ ํ (๋ฒํผ ์ค๋ฒํ๋ก์ฐ ๋ฐฉ์ง)
client_body_buffer_size 1K;
client_header_buffer_size 1K;
large_client_header_buffers 2 1K;
}
Plain Text
๋ณต์ฌ
7. ๋ด ๋ฐ ์ค์บ๋ ์ฐจ๋จ
# ์
์ฑ ๋ด User-Agent ์ฐจ๋จ
if ($http_user_agent ~* (SemrushBot|AhrefsBot|MJ12bot|DotBot|BLEXBot)) {
return 403;
}
# ๋น์ด์๋ User-Agent ์ฐจ๋จ
if ($http_user_agent = "") {
return 403;
}
# ํน์ HTTP ๋ฉ์๋๋ง ํ์ฉ
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|PATCH)$) {
return 405;
}
# ์จ๊ฒจ์ง ํ์ผ ์ ๊ทผ ์ฐจ๋จ (.env, .git ๋ฑ)
location ~ /\\. {
deny all;
access_log off;
log_not_found off;
}
Plain Text
๋ณต์ฌ
๋ณด์ ์ค์ ์ข
ํฉ ์ฒดํฌ๋ฆฌ์คํธ
์์ | ์ค์ | ์ค์๋ | ๋ช
๋ น์ด/์ค์ |
1 | ์๋ฒ ๋ฒ์ ์จ๊ธฐ๊ธฐ | server_tokens off | |
2 | HTTPS ์ ์ฉ | Let's Encrypt + HTTPโHTTPS ๋ฆฌ๋ค์ด๋ ํธ | |
3 | ๋ณด์ ํค๋ ์ถ๊ฐ | X-Frame-Options, HSTS ๋ฑ | |
4 | Rate Limiting | limit_req_zone | |
5 | ๋ฐฉํ๋ฒฝ ์ค์ | ufw allow 'Nginx Full' | |
6 | SSL/TLS ๊ฐํ | TLSv1.2/1.3๋ง, ๊ฐ๋ ฅํ cipher | |
7 | ์จ๊น ํ์ผ ์ฐจ๋จ | location ~ /\\. | |
8 | ๊ด๋ฆฌ์ ํ์ด์ง IP ์ ํ | allow/deny | |
9 | ํ์ผ ์
๋ก๋ ํฌ๊ธฐ ์ ํ | client_max_body_size | |
10 | ์
์ฑ ๋ด ์ฐจ๋จ | User-Agent ํํฐ๋ง |
๋ณด์ ์ ๊ฒ ๋๊ตฌ
๋๊ตฌ | ์ฉ๋ | URL/๋ช
๋ น์ด |
SSL Labs | SSL/TLS ์ค์ ์ ๊ฒ | ssllabs.com/ssltest/ |
Security Headers | ๋ณด์ ํค๋ ์ ๊ฒ | securityheaders.com |
Nmap | ํฌํธ ์ค์บ | nmap -sV ์๋ฒIP |
curl | ํค๋ ํ์ธ | curl -I <https://example.com> |
# ๋ณด์ ํค๋ ํ์ธ
curl -I <https://example.com>
# ์ด๋ฆฐ ํฌํธ ํ์ธ
sudo ss -tlnp
# ์ ์ ์๋ ๋ก๊ทธ ํ์ธ (๋ฌด์ฐจ๋ณ ๋์
๊ณต๊ฒฉ ๊ฐ์ง)
grep "error" /var/log/nginx/error.log | tail -20
Bash
๋ณต์ฌ
ํต์ฌ ์ ๋ฆฌ
server_tokens off: Nginx ๋ฒ์ ์ ๋ณด ์จ๊ธฐ๊ธฐ (๊ธฐ๋ณธ ์ค์ ๊ธฐ๋ณธ!)
Rate Limiting: limit_req_zone์ผ๋ก DDoS/๋ธ๋ฃจํธํฌ์ค ๋ฐฉ์ด
๋ณด์ ํค๋: X-Frame-Options, HSTS, CSP ๋ฑ์ผ๋ก ์น ๊ณต๊ฒฉ ๋ฐฉ์ด
์ ๊ทผ ์ ์ด: IP ์ ํ(allow/deny), Basic ์ธ์ฆ์ผ๋ก ๊ด๋ฆฌ์ ๋ณดํธ
SSL ๊ฐํ: TLS 1.2/1.3๋ง ํ์ฉ, ๊ฐ๋ ฅํ ์ํธํ ์ค์ํธ ์ฌ์ฉ
์จ๊น ํ์ผ(.env, .git) ์ ๊ทผ ์ฐจ๋จ ํ์!




