NginxのWAFモジュールのNaxsiがバージョンアップしていたので、そのインストールと設定手順をまとめました。
大きく変わった箇所として、ホワイトリストの自動生成を行う[nx_tool]が[nxapi]と名前を変え、ホワイトリスト生成のための統計データの保存先がSQLiteからElasticSeaechへと変更されています。
では、さっそく。
準備
Nginxとnaxsiのダウンロード
cd /usr/local/src/
wget https://github.com/nbs-system/naxsi/archive/0.54.tar.gz
tar zxvf naxsi-0.54.tgz
https://nginx.org/download/nginx-1.10.1.tar.gz
tar zxvf nginx-1.10.1.tar.gz
NginxにNaxsiモジュールを追加してインストール
Nginxのconfigureオプションはお好みで
cd /uer/local/src/nginx-1.10.1/
./configure --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --add-module=../naxsi-0.54/naxsi_src/
make && maike install
ElasticSearchの用意
naxsi-0.54では、ElasticSearchのVersion1系を利用します。
Elasticのダウンロードページからは、1系最新のダウンロードページにたどり着けないので
下記のURLからダウンロードします。
https://www.elastic.co/guide/en/elasticsearch/reference/1.7/_installation.html
ElasticSearchのインストールと起動
cd /usr/local/src/
wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.5.tar.gz
tar -xvf elasticsearch-1.7.5.tar.gz
cd elasticsearch-1.7.5/bin
./elasticsearch
ElasticSearchの動作確認とNxapi用のIndexの作成
curl -XGET http://localhost:9200/
curl -XPUT 'http://localhost:9200/nxapi/'
Naxsiのセットアップ
Naxsiに付属しているディフォルトルールの配置
cp -rp /usr/local/src/naxsi-0.54/naxsi_config/naxsi_core.rules /usr/local/nginx/conf/
nxapiをコピー
cp -rp /usr/local/src/naxsi-0.54/nxapi/ /usr/local/nginx/
nxapiの設定
{
# ElasticSearchの設定
"elastic" : {
"host" : "127.0.0.1:9200",
"index" : "nxapi",
…
}
# ルールのパスを指定
"naxsi" : {
"rules_path" : "/usr/local/nginx/conf/naxsi_core.rules",
"template_path" : [ "tpl/"],
"geoipdb_path" : "nx_datas/country2coords.txt"
},
…
}
Nginxの設定
80番ポートで接続を受け付け、安全な接続を8080番へとProxyしています。
閾値以上の接続は、リターンコード[481]を返します。
## Sample(学習モード)
http {
# Naxsiのディフォルトルールの読み込み
include /usr/local/nginx/conf/naxsi_core.rules;
server {
listen 80;
server_name hogehoge.com;
access_log /var/log/nginx/hogehoge.com_access80.log main;
error_log /var/log/nginx/hogehoge.com_error80.log debug;
# エラー出力を”debug”にしないと、ルールの生成が行われないので注意
# error_log /var/log/nginx/hogehoge.com_error80.log warn;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host hogehoge.com;
#学習モードを有効にする
LearningMode;
# 自動学習ルールを一旦読み込ませない(現時点でファイルは存在しない)
# include /usr/local/nginx/conf/my.rules;
SecRulesEnabled;
#SecRulesDisabled;
DeniedUrl "/RequestDenied";
# しきい値の設定
## check rules ##
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
############
}
#リジェクトされた際のページ
location /RequestDenied {
return 481;
}
}
Nginxの再起動
# 設定ファイルの検証
/etc/init.d/nginx configtest
# 再起動
/etc/init.d/nginx restart
動作確認
サーバー内で動作検証を行います。
ラーニングモードなので、ブロックはされません。
curl "http://127.0.0.1/?a=<"
下記のようなログが出ていればNxasiは正常に動いています。
2016/06/23 22:18:47 [error] 13987#0: *1028 NAXSI_FMT: ip=127.0.0.1&server=127.0.0.1&uri=/&learning=1&vers=0.54&total_processed=358&total_blocked=27&block=1&cscore0=$XSS&score0=8&zone0=ARGS&id0=1302&var_name0=a, client: 127.0.0.1, server: , request: "GET /?a=< HTTP/1.1", host: "127.0.0.1"
ホワイトリストの生成
想定される挙動をブラウザで行いログに貯めます。
ある程度ログがたまれば、ログよりホワイトリストの生成をします。
ログファイルの読み込み
NginxのログをElasticSearchに読み込みます。
./nxtool.py -c nxapi.json --files=/var/log/nginx/hogehoge.com_error.log
ElasticSearch内のデータを確認します。
curl -XPOST "http://localhost:9200/nxapi/events/_search?pretty" -d '{}'
登録されたログの統計データを見ます(簡易)
./nxtool.py -c nxapi.json -x
# size :1000
# Whitelist(ing) ratio :
# false 100.0 % (total:750/750)
# Top servers :
# 123.123.123.123 97.87 % (total:734/750)
# 127.0.0.1 2.13 % (total:16/750)
# Top URI(s) :
# /index.php/ccm/system/dialogs/block/edit/submit 49.33 % (total:370/750)
# /index.php/ccm/system/dialogs/page/add_block/submit 22.0 % (total:165/750)
# / 20.93 % (total:157/750)
# /index.php/ccm/system/dialogs/file/upload_complete 3.73 % (total:28/750)
# /index.php/dashboard/system/seo/urls/save_urls 2.13 % (total:16/750)
# /index.php/ccm/system/file/upload 1.87 % (total:14/750)
# Top Zone(s) :
# BODY 64.0 % (total:480/750)
# ARGS 20.93 % (total:157/750)
# BODY|NAME 11.33 % (total:85/750)
# ARGS|NAME 3.73 % (total:28/750)
# Top Peer(s) :
# 121.121.121.121 76.53 % (total:574/750)
# 122.122.122.122 21.33 % (total:160/750)
# 127.0.0.1 2.13 % (total:16/750)
ホワイトリストの生成
※実はここから手順がかなり怪しいです・・・
ReadMeには[Generate whitelists]項目があるのですが、ホワイトリストの設置について明記されてなく。
一応これで、リストが生成されているはずです。
./nxtool.py -c nxapi.json -f --slack --colors | grep BasicRule > /usr/local/nginx/conf/my.rules
## 本番設定
http {
server {
#error_log /var/log/nginx/hogehoge.com_error80.log debug;
error_log /var/log/nginx/hogehoge_error80.log warn;
location / {
#LearningMode; #Enables learning mode
#自動学習モードをOFF
include /usr/local/nginx/conf/my.rules;
#自動学習したルールを反映
}
}
Nginxの再起動
#設定ファイルの検証
/etc/init.d/nginx configtest
#再起動
/etc/init.d/nginx restart
その他
Nginxからのログの取り込みがプログラム経由なので、FluentとかLogstashとかに切り替えて、セミリアルタイムの取り込みに帰れると素敵だなと妄想してます。
若干ポエミーで尻すぼみな内容になってしまいました、ごめんなさい。