Elastic Load Balancerを使用したEC2にIPでHTTPアクセス拒否する方法について

Elastic Load Balancerを使用したEC2にIPでHTTPアクセス拒否する方法について

先日、ある案件でawsのElastic Load Balancer(以下ELB)を使用した構成で、IPや存在しないドメインでのアクセスは拒否したいという依頼がありました。
Default Virtual Host(※以下DVH)を設定すれば、OKと思っていたのですが、実際に設定してみると、Elastic Load Balancerが”OutOfService”になってしまいました。
色々と試行錯誤し、以下の対応で解決できました。

設定内容

はじめに以下のような設定を行ってみました。(NG設定例)

〆Name Base VirtualHostを使用
〆VirtualHostで複数のドメインを設定
〆以下、DVHを設定

        :
<VirtualHost *:80>
    ServerName dummy
    ServerSignature Off
    <Location />;
        Order deny,allow
        Deny from All
    </Location>
</VirtualHost>
        :

 

〆Health Check設定(AWSマネージメントコンソールにて。)
Ping Protocol:HTTP
Ping Port:80
Ping Path:/index.html
http://example.com/index.html

動作不具合内容

ELBのHealthCheckでhttp://example.com/index.html の監視を行うと、
“OutofService”となってしまう。

原因

ELBからEC2にはIPでアクセスされるので、DVHにアクセスが向いてしまう為、拒否(403 Forbidden)されてしまう。

対処方法

その① ELB healthcheckをTCP 80の監視設定に変更する

Ping Protocol:TCP
Ping Port:80

デメリット:

本設定だと、Apacheがダウンやゾンビ状態になった時でも、”InService”と認識したままになる為、
ELBが障害サーバの方へ転送した場合、サービスに影響が出るため、その②orその③の対処方法が良いと思います。

その② デフォルトバーチャルホストに、除外設定を組み込む(mod_rewriteで対応)

アクセスログを確認。
ELBからのアクセスログは以下のように出力される。

172.31.28.233 - - [06/Jun/2014:21:12:47 +0900] "GET /index.html HTTP/1.1" 200 496 "-" "ELB-HealthChecker/1.0"

UserAgentが”ELB-HealthChecker/1.0”となっているので、UserAgentで指定し、ELBからのアクセス拒否を除外することが可能!

		:
<VirtualHost *:80>
    ServerName dummy
    ServerSignature Off
    RewriteEngine On                                   # 追記
    RewriteCond %{HTTP_USER_AGENT} ELB-HealthChecker [NC]           # 追記
    RewriteRule (.*) http://example.com/index.html [R=200,L]              # 追記
    <Location />
        Order deny,allow
        Deny from All
    </Location>
</VirtualHost>
        :

 

その③デフォルトバーチャルホストに、除外設定を組み込む(mod_accessで対応)

mod_extract_forwardedのインストール

Global IPを引き継いで、EC2にアクセスさせるため、インストールする。
(IPでアクセスされた場合、ELBのHealthCheckのみ200を返させるため必要。)

▼インストール

# yum --enablerepo=epel install mod_extract_forwarded

▼設定

# vim /etc/httpd/conf.d/mod_extract_forwarded.conf

設定内容

LoadModule extract_forwarded_module modules/mod_extract_forwarded.so
MEForder refuse,accept
MEFrefuse all
MEFaccept all

▼DVH用のDocumentRoot、アクセスファイル作成

# mkdir -p /var/www/vhosts/dvh touch /var/www/vhosts/dvh/index.html
        :
<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/dvh/  # 追記
    ServerName dummy
    ServerSignature Off
    <Location />
        Order deny,allow
        Deny from All
        Allow from 172           # 追記
    </Location>
</VirtualHost>
        :

備考

※ ちなみにSSLをELBに設定している場合については、ELB⇒EC2には、443ではなく、80で通信される為、443用のDefault Virtual Hostは不要!

設定反映は忘れずに・・・

# service httpd graceful

本記事は、Qiitaで過去投稿しています。
http://qiita.com/arai/items/f179faccd2ad6d045396