タケユー・ウェブ日報

Ruby on Rails や Flutter といったWeb・モバイルアプリ技術を武器にお客様のビジネス立ち上げを支援する、タケユー・ウェブ株式会社の技術ブログです。

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なんかを使って自動検出・自動追加&通知とかやりたい。