LoginSignup
19
14

More than 5 years have passed since last update.

NginxのWAFモジュールのNaxsi(naxsi-0.54)をインストールしてみた

Posted at

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の設定

/usr/local/nginx/nxapi/nxapi.json
{
# 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(学習モード)

/usr/local/nginx/conf/nginx.conf
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は正常に動いています。
bash:ログファイル
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に読み込みます。
bash:ルールの生成
./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

 本番設定

/usr/local/nginx/conf/nginx.conf
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とかに切り替えて、セミリアルタイムの取り込みに帰れると素敵だなと妄想してます。

若干ポエミーで尻すぼみな内容になってしまいました、ごめんなさい。

19
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
14