
Naxsi와 Nginx를 연동해본다.
$ sudo apt -y install build-essential bzip2 unzip libpcre3-dev libssl-dev daemon libgeoip-dev wget zlib1g-dev
$ sudo adduser --system --no-create-home --disabled-login --disabled-password --group www-data
$ wget https://github.com/nbs-system/naxsi/archive/master.zip
$ unzip master.zip
$ wget http://nginx.org/download/nginx-1.18.0.tar.gz
$ tar xzf nginx-1.18.0.tar.gz
$ cd nginx-1.18.0
$ sudo mkdir -p /var/lib/nginx/body
$ ./configure --conf-path=/etc/nginx/nginx.conf --add-module=../naxsi-master/naxsi_src/ --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --user=www-data --group=www-data --with-http_ssl_module --with-http_geoip_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --without-http_uwsgi_module --without-http_scgi_module --prefix=/usr
$ make
$ sudo make install
$ cd ../
$ sudo cp naxsi-master/naxsi_config/naxsi_core.rules /etc/nginx/
naxsi.rules파일을 생성한 뒤 아래의 내용을 넣는다.
$ sudo vi /etc/nginx/naxsi.rules
SecRulesEnabled;
DeniedUrl "/error.html";
## check rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
/etc/nginx/nginx.conf에 naxsi 정책을 포함시킨다.
$ sudo vi /etc/nginx/nginx.conf
user www-data;
...
http {
...
include /etc/nginx/naxsi_core.rules;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
...
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
...
tcp_nodelay on;
gzip on;
gzip_disable "MSIE [1-6].(?!.*SV1)";
...
server {
...
location / {
include /etc/nginx/naxsi.rules;
...
}
...
}
...
}
/etc/init.d/nginx를 생성하고 다음을 작성한다.
#!/bin/bash
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
# Include nginx defaults if available
if [ -f /etc/nginx ] ; then
. /etc/nginx
fi
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /var/run/nginx.pid --exec $DAEMON --$DAEMON_OPTS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/nginx.pid --exec $DAEMON
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/nginx.pid --exec $DAEMON
sleep 1
start-stop-daemon --start --quiet --pidfile /var/run/nginx.pid --exec $DAEMON --$DAEMON_OPTS
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/nginx.pid --exec $DAEMON
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
서비스로 등록하고 싶다면 /lib/systemd/system/nginx.service 파일을 생성하고 다음의 내용을 넣는다.
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
테스트를 진행해본다.
성공적으로 테스트가 되었다면 서비스를 시작한다.
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo chmod +x /etc/init.d/nginx
$ sudo /etc/init.d/nginx start
적용 여부를 확인하기 위해
/usr/html/index.html에 다음과 같이 작성한다.
<body>
<form action="index.html" method="post">
<input type="text" name="userid">
<input type="password" name="userpw">
<input type="submit" value="ok">
</form>
</body>
/usr/html/error.html에는 다음과 같이 작성한다.
<html>
<head>
<title>Blocked By NAXSI</title>
</head>
<body>
<div style="text-align: center">
<h1>Malicious Request</h1>
<hr>
<p>This Request Has Been Blocked By NAXSI.</p>
</div>
</body>
</html>
로그를 모니터링하면서 input값에 SQL Injection(' or 1=1 #)을 넣은뒤 로그를 살펴본다.
차단한다면 error 로그가 쌓인다.
Nginx가 HTML을 POST로 받지 않으므로 405 코드가 반환될 것이다.
$ sudo tail -f /var/log/nginx/error.log
2022/11/16 07:54:22 [error] 15292#0: *5 NAXSI_FMT: ip=192.168.0.20&server=192.168.0.24&uri=/index.html&vers=1.3&total_processed=4&total_blocked=1&config=block&cscore0=$SQL&score0=6&cscore1=$XSS&score1=8&zone0=BODY&id0=1009&var_name0=userid&zone1=BODY&id1=1013&var_name1=userid, client: 192.168.0.20, server: localhost, request: "POST /index.html HTTP/1.1", host: "192.168.0.24", referrer: "http://192.168.0.24/"