元フリーエンジニアライフ

Ruby on Rails とか MovableType とかAWSやってるフリーランスウェブエンジニアの記録でした。現在は法人成りしてIT社長。

ELB + EC2 + nginx 環境でアクセス元IPアドレスによる制限をかける

ELB + EC2 (nginx + unicorn + Rails)環境で運用中のサービスに対して、あるIPアドレスからディレクトリトラバーサルなどの攻撃を受けたので、その対応メモ。

取り急ぎ該当IPアドレスからのアクセスを遮断しようと考えたが、EC2の為、セキュリティグループでの制限ではブラックリスト(拒否)は使えない。(VPCであればネットワークACLだけで対応可能・・・)

ELBを使用しているため、入ってくるパケットはフロントサーバからのものであり、iptablesでの対応は、できない。

やむなくnginxのHttpMapModuleを用いて、X-Forwarded-Forに入っている対象のIPアドレスでの振り分けで対応することにした。

参考

特定のIPアドレスのみ禁止

1conf.d/deny_ip_map.conf

# ERBによりクライアントのIPアドレスが X-Forwarded-For 末尾に追加されるので、それを正規表現でマッチさせる
# ex)
# X-Forwarded-For: zzz.zzz.zzz.zzz
# X-Forwarded-For: zzz.zzz.zzz.zzz, yyy.yyy.yyy.yyy
map $http_x_forwarded_for $denied {
    default allow;
    ~\s*XXX.XXX.XXX.XXX$ deny;
    ~\s*YYY.YYY.YYY.YYY$ deny;
}

読み込み側

include conf.d/deny_ip_map.conf;
server {
    listen 80 default_server;

    # 省略
    location / {
        # conf.d/deny_ip_map.conf により設定する $denied が "deny" なら403
        if ( $denied = "deny" ) {
            return 403;
        }

        # 省略
    }
}

特定のIPアドレスのみ許可

逆に特定のIPアドレスのみ許可する場合は、

conf.d/allow_ip_map.conf

map $http_x_forwarded_for $allowed {
    default deny;
    ~\s*XXX.XXX.XXX.XXX$ allow;
    ~\s*YYY.YYY.YYY.YYY$ allow;
}

という風にな感じになると思う。(未検証)

ただし・・・

できればフロント側で制限できた方が良いので、はじめからVPCでやっといた方がよいと思います。

人力は大変

攻撃を受けたのを確認してから人力で追加するのも大変なので、できれば fluentdなんかを使って自動検出・自動追加&通知とかやりたい。