๐บ ๋ชฉ์ฐจ ๐บ(๋ณด์๋ ค๋ฉด ์๋ ๋๋ณด๊ธฐ ๋ฅผ ๋๋ฌ์ฃผ์ธ์.)
1. Nginx + ModSecurity + Fail2ban + Docker => 1. ์ทจ์ฝํ ์น์ฌ์ดํธ
2. Nginx + ModSecurity + Fail2ban + Docker => 2. ModSecurity + Fail2ban ์ค์น
3. Nginx + ModSecurity + Fail2ban + Docker => 3. Fail2ban ์ค์ ๋ฐฉ๋ฒ
4. Nginx + ModSecurity + Fail2ban + Docker => 4. Nginx Limit req ์ค์
5. Nginx + ModSecurity + Fail2ban + Docker => 5. Dockerhub ์ด๋ฏธ์ง ์ฌ์ฉ
1. Dockerfile ์์ฑ์ ์์์...
1) ์ ๊ธ์์ ์๋จ์ Nginx 1๊ฐ, ๋ท๋จ์ Nginx 2๊ฐ๋ฅผ ์ค์นํ์์ต๋๋ค. ์ด ๋ชจ๋ Nginx์ ModSecurity, Fail2ban๋ฅผ ์ค์นํ ํ์๋ ์์ต๋๋ค. ์๋จ์ Reverse Proxy๊ธฐ๋ฅ์ ํ๋ Nginx์๋ง ModSecurity, Fail2ban๋ฅผ ์ค์นํ ๊ฒ์ ๋๋ค.
2) docker hub์๋ ์ด๋ฏธ Nginx + ModSecurity + Fail2ban๊ฐ ์ค์น๋ ์ด๋ฏธ์ง๋ค์ด ์กด์ฌํ๋ฉฐ, ๊ทธ๊ฒ์ ๋ค์ด๋ฐ์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ํ์ง๋ง, docker hub์ ์ฌ๋ ค์ ธ ์๋ ์ด๋ฏธ์ง ์ค์ ์ ์ฑ์ฝ๋๊ฐ ๋ค์ด์๋ ๊ฒ๋ ๋ง๋ค๊ณ ํ๋ฉฐ, ์ฌ๊ธฐ์๋ ๊ณต๋ถ๋ฅผ ์ํ์ฌ Dockerfile์ ์ด์ฉํ์ฌ ์ง์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ์ฌ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
3) ์ฐธ๊ณ ๋ก Dockerfile์ ์ด์ฉํ์ฌ ์ค๋ผํด ํด๋ผ์ฐ๋ ๋ฌด๋ฃ ์๋ฒ์ ๊ตฌ๊ธ ํด๋ผ์ฐ๋ ๋ฌด๋ฃ ์๋ฒ์์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํด๋ณด์๋๋, ์ค๋ผํด์ 30๋ถ~1์๊ฐ ์ ๋ ๊ฑธ๋ฆฌ๊ณ , ๊ตฌ๊ธ์์๋ 10์๊ฐ ์ด์์ด ๊ฑธ๋ ธ์ต๋๋ค. ๋ฐ๋ผ์, ๋ก์ปฌ์์ ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์์ฑํ๊ณ , ๊ทธ ์ด๋ฏธ์ง๋ฅผ docker hub์ ์ฌ๋ฆฐ ํ, ์๋ฒ์์๋ docker hub์ ์ฌ๋ฆฐ ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ ์ผ ๋น ๋ฅด๋ค๋ ๊ฒ์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.(1~2๋ถ ์์)
2. Dockerfile ๋ฐ ๊ธฐํ ํด๋, ํ์ผ ์์ฑ
1) docker/front ํด๋ ์์ Dockerfile ํ์ผ ๋ฐ ๊ธฐํ 4๊ฐ์ ํ์ผ(์ด 5๊ฐ) ์ถ๊ฐ. (ModSecurity์ Fail2ban๊ฐ ํฌํจ๋ nginx ์ด๋ฏธ์ง ์์ฑ์ ์ํจ.)
2) docker ํด๋ ์์ fail2ban ์ค์ ํ์ผ์ด ๋ค์ด์๋ ํด๋ ์์ฑ
3) Dockerfile ์์ ๋ด์ฉ
https://github.com/b-04-e/nginxwaf
์ง๊ธ ์ค๋ช ํ๋ ์ค์ ํ์ผ๋ค์ ์ ๋งํฌ์์ ๊ฐ์ ธ์ ์๋์ ๊ฐ์ด ์์ ์ ํ ํ ์ฌ์ฉ์ ํ์์ผ๋ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
* ๋ฒ ์ด์ค ์ด๋ฏธ์ง๋ฅผ ํน์ ๋ฒ์ ์ผ๋ก ๊ณ ์
* Nginx ๋ฒ์ ๋ณ๊ฒฝ
* Nginx ๋ชจ๋ ์ถ๊ฐ : --with-http_stub_status_module (์ถํ ์๋ฒ ๋ชจ๋ํฐ๋ง์ ํ์ํ๊ธฐ ๋๋ฌธ์...)
* CMD ๋ช ๋ น ๋์ ENTRYPOINT ์ฌ์ฉ
4) docker-compose.yml ์์ ๋ด์ฉ
version: '3.9'
networks:
mung_net:
driver: bridge
services:
front_nginx:
container_name: front_nginx_cname
#image: nginx:1.23.2 #๐ดnginx ์ด๋ฏธ์ง๋ฅผ ์ง์ ์ฌ์ฉํ์ง ์๊ณ
build: ./docker/front/ #๐ดDockerfile์ ์ด์ฉํ์ฌ ์ง์ ๋ง๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉ
restart: always
privileged: true #๐ดfail2ban์ ์ํด ์ถ๊ฐํด์ฃผ์ด์ผ ํจ.
ports:
- "80:80"
- "81:81"
- "82:82"
volumes:
#- ./docker/front/default.conf:/etc/nginx/conf.d/default.conf
#- ./docker/front/nginx.conf:/etc/nginx/nginx.conf
#๐ดDockerfile์์ nginx๋ฅผ ์์ค๋ฅผ ๋ค์ด๋ฐ์ ์ค์น์ ํ์๊ธฐ์ ๊ธฐ๋ณธ ๊ฒฝ๋ก๊ฐ ๋ค๋ฆ. ๊ทธ๋์ ์๋์ฒ๋ผ ์์ ํจ.
- ./docker/front/default.conf:/usr/local/nginx/conf.d/default.conf #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/front/nginx.conf:/usr/local/nginx/conf/nginx.conf #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/front/modsecurity.conf:/usr/local/nginx/conf/modsecurity.conf #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/front/modsec_includes.conf:/usr/local/nginx/conf/modsec_includes.conf #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/front/crs-setup.conf:/usr/local/nginx/conf/rules/crs-setup.conf #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/fail2ban/jail.conf:/etc/fail2ban/jail.conf #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/fail2ban/jail.conf:/etc/fail2ban/jail.local #๐ด์ถ๊ฐ ๋ด์ฉ
- ./docker/fail2ban/filter.d/:/etc/fail2ban/filter.d/ #๐ด์ถ๊ฐ ๋ด์ฉ
- ./log/logs/:/usr/local/nginx/logs/ #๐ด์ด ๋ถ๋ถ์ modsecurity, fail2ban์ด ์ ๋๋ก ๋์ํ๋์ง
- ./log/log/:/var/log/ #๐ดํ
์คํธ ๋ชฉ์ ์ผ๋ก log๋ฅผ ์ฝ๊ฒ ๋ณด๊ธฐ ์ํจ. ๋์ค์๋ ์ง์ธ๊ฒ์.
depends_on:
- web
- web2
networks:
- mung_net
web:
########### ์ดํ ๋ด์ฉ์ ๋ณ๊ฒฝ๋ ๊ฒ ์์ ############
5) docker/front/nginx.conf ํ์ผ ์์
#user nginx; #๐ด์ฃผ์์ฒ๋ฆฌ(์ญ์ ํด๋ ๋จ.)
user nobody; #๐ดuser๋ฅผ nginx์์ nobody๋ก ์์
worker_processes auto;
#error_log /var/log/nginx/error.log notice; #๐ด์ฃผ์์ฒ๋ฆฌํด์ผ ํจ.
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
#include /etc/nginx/mime.types; #๐ด์ด ๋ถ๋ถ์
include mime.types; #๐ด์ด๋ ๊ฒ ์์ ์ ํด์ผ ์ค๋ฅ๊ฐ ๋์ง ์์.
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log /var/log/nginx/access.log main; #๐ด์ฃผ์์ฒ๋ฆฌํด์ผ ํจ.
sendfile on;
keepalive_timeout 65;
gzip on;
#include /etc/nginx/conf.d/*.conf; #๐ด๊ฒฝ๋ก๊ฐ ๋ฌ๋ผ์ก๊ธฐ์
include /usr/local/nginx/conf.d/*.conf; #๐ด์ด๋ ๊ฒ ์์ ์ ํด์ผ ํจ.
}
6) docker/front/default.conf ํ์ผ ์์
modsecurity๊ฐ ๊ฐ์ํ๊ธธ ์ํ๋ server ๋ธ๋ญ ์์๋ง ์๋ 2์ค์ ์ ๋ ฅํฉ๋๋ค. ์ ๋ ์์๋ก web ๋ธ๋ญ ํ๊ตฐ๋ฐ๋ง ์ ๋ ฅ์ ํ์์ต๋๋ค.
server {
listen 80;
modsecurity on; #๐ดmodsecurity ์๋์ ์ํด
modsecurity_rules_file /usr/local/nginx/conf/modsecurity.conf; #๐ด2์ค ์ถ๊ฐ
location / {
proxy_pass http://web;
proxy_redirect off;
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_buffering off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
########์ดํ ๋์ผ #################
7) ์ด์ ์์ฑ๋์์ต๋๋ค. docker-compose.yml ํ์ผ์ ์ด์ฉํ์ฌ ์ปจํ ์ด๋๋ฅผ ์์ฑํฉ๋๋ค.
8) ๊ทธ๋ฆฌ๊ณ , 80ํฌํธ์ 81ํฌํธ๋ก ๊ฐ๊ฐ ์ ์์ ํด๋ด ๋๋ค. ๊ทธ๋ฆฌ๊ณ , ์ด์ ๊ฒ์๊ธ์ฒ๋ผ ์์ด๋ ์ฐฝ์ 1' or 1=1 # ์ด๋ผ๋ sql ์ธ์ ์ ๊ณต๊ฒฉ์ ์๋ํด ๋ด ๋๋ค. ๊ทธ๋ผ ์ฒซ๋ฒ์งธ ์๋ฒ๋ 403 Forbidden ์ด ๋์ค๋ฉฐ ๊ณต๊ฒฉ์ ์๋์ผ๋ก ์ฐจ๋จํด ์ค๋๋ค. ํ์ง๋ง, ๋๋ฒ์งธ ์๋ฒ๋ docker/front/default.conf ํ์ผ์์ server ๋ธ๋ญ ์์ modsecurity on ์ด๋ผ๋ 2์ค์ ๋ฃ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฐจ๋จ์ด ๋์ง ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
9) ์ด๋ฒ์๋ Reflexed XSS ๊ณต๊ฒฉ์ผ๋ก ์๋์ ๊ฐ์ด ์ ๋ ฅํด๋ด ๋๋ค.
http://localhost/index.php?value=<script>alert("ํดํน์ค");</script>
๊ทธ๋ผ ์ด๋ฒ์๋ ์ฒซ๋ฒ์งธ ์๋ฒ๋ ์ ์ฐจ๋จ์ ํด์ฃผ์ง๋ง, ๋๋ฒ์งธ ์๋ฒ๋ ๊ทธ๋๋ก ๊ณต๊ฒฉ์ ๋ ธ์ถ๋์ด ์์ต๋๋ค.
10) log ํ์ธ
์ 4) docker-compose.yml ์์ ๋ถ๋ถ์์ ํ ์คํธ ๋ชฉ์ ์ผ๋ก ์ฐ๋ฆฌ๋ log ํ์ผ์ ์ฝ๊ฒ ๋ณผ ์ ์๋๋ก ์ค์ ์ ํ์์ต๋๋ค.
- ./log/logs/:/usr/local/nginx/logs/
- ./log/log/:/var/log/
๊ทธ๋์, ์์ ํด๋๋ฅผ ๋ณด๋ฉด log ํด๋๊ฐ ์๋์ผ๋ก ์์ฑ์ด ๋์์ผ๋ฉฐ, ๊ฐ๊ฐ์ log ํ์ผ์์ ์น์๋ฒ์ ์ ์ ๊ธฐ๋ก ๋ฐ ์ฐจ๋จ๋๋ ๊ธฐ๋ก๋ค์ ๋ชจ๋ ํ์ธํด ๋ณผ ์ ์์ต๋๋ค. (์์์ ์ค์นํ ๋ชจ๋ ์๋น์ค๋ค์ด ์ ์๋ํ๊ณ ์๋ค๋ ๋ป์ ๋๋ค.)
3. ์์ ์์ค
์์์ ์์ ํ ๋ชจ๋ ์์ค๋ ์๋ ๋งํฌ์์ ๋ค์ด๋ฐ์ผ์ค ์ ์์ต๋๋ค.
https://github.com/mmssem/ModSecurityFail2ban/releases/tag/์ต์ข ํ์ผ
๐ด๐ด github์ ์ฌ๋ฆฌ๊ณ ๋์ ๋ณด๋ [nginx-req-limit] ์ค์ ๋๋ฌธ์ fail2ban์ด ์คํ์ด ๋์ง ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค์. docker/fail2ban/jail.conf ํ์ผ ์์์ 292~299๋ฒ์งธ ์ค์ ์ฐ์ ๋ชจ๋ ์ฃผ์ ์ฒ๋ฆฌ๋ฅผ ํ์๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ , ๋ค์ ๊ฒ์๊ธ๋ ์ฐธ๊ณ ํด ๋ณด์๊ธธ ๋ฐ๋๋๋ค.