【トラブルメモ】Nginxで不正なドメインでのアクセスを防ぐ

こんにちは。

Django製CMSのWagtailでWebサイトを公開して、あー良かったと思ったのも束の間。Sentryというエラー監視サービスから、突然メールが来まして、「もう今月分オーバーしたよ!アップグレードしろよ!」というメール。。

mami
え?フリープランはエラー5000件までOKじゃないの?全然使ってないよ?

とSentryを確認するとエラー14Kでオーバーしてる。。
エラー内容は以下が大量に。。
Invalid HTTP_HOST header: ‘(不明ドメイン)’. You may need to add ‘(不明ドメイン)’ to ALLOWED_HOSTS.

mami
(不明ドメイン)どこのどいつだよ!!

異なるドメインでアクセスして、プログラムの脆弱性を見つけて侵入しようとする者がいるようです。Django(Wagtail)でALLOWED_HOSTSの設定をして、無視されたとしても、大量のリクエストを処理するのでサーバーがパンクしてしまいます。そしてSentryも使えなくなっちゃった。。というわけで、Nginxの設定を見直します。

Nginxの設定

nanoを使って設定ファイルを編集します。

sudo nano /etc/nginx/sites-available/(your project)

公式サイトの情報を頼りに以下を一番上に追加します。

server {
    listen      80 default_server;
    return      444;
}

default_serverは指定されたポート上の定義されていないすべての接続を取得します。return 444で何のレスポンスも返さずにコネクションを閉じます。

Nginxを再起動します。

sudo systemctl restart nginx

よし、これでOK!とSentryのエラーを解決済みにして、暫くするとSentryから「まだ同じ問題発生してるぞ!片付いてないじゃないか!」のメール。。えぇ。。

Nginxの設定2

不本意ですが、不正ドメインを使ってアクセスしてみます。すると、「Invalid HTTP_HOST header: ‘(不明ドメイン)’. You may need to add ‘(不明ドメイン)’ to ALLOWED_HOSTS.」が出力されます。どうやら、Httpsでのアクセスに対して対策が出来ていなかったようです。無料SSL証明書のLet’s Encryptを使っているので、以下を追加します。

server {
    listen      443 default_server;
    ssl_certificate /etc/letsencrypt/live/secondherb.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/secondherb.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    return      444;
}

Nginxを再起動します。

sudo systemctl restart nginx

もう一度不正ドメインを使ってアクセスしてみます。Djangoでのエラーは無くなりました。