リフト&シフトした環境など、セキュリティグループとサーバー内で二重で許可IPを制御している場合があります。
「セキュリティグループでもサーバー内設定でも許可しているIPからのアクセスが失敗する、、、」「アクセスログには許可したIPが書いてあるのに、、、」という場合は、mod_remoteip
を設定することで解決するかもしれません。
起きてる問題と背景
- セキュリティグループで許可してる
- Apache設定でも許可してる
- アクセスログには許可IPからのアクセスと記載されている
- しかし、許可IPからのアクセスが失敗する
原因と対処方法
- X-Forwarded-For ヘッダーをログファイルに記載する設定をしているため許可IPからのアクセスが失敗しているように見えるが、実際は前段のALBのIPを接続元IPとして評価しているためアクセスに失敗する。
- X-Forwarded-For ヘッダーをクライアントIPとして扱う設定が必要
mod_remoteipを有効化し、以下の設定をconfファイルに追加する必要があります。
RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 10.0.0.0/16 # VPCのCIDR
検証
まずは問題を再現します。
全てのIPからのhttpを許可するALBと背後のApacheサーバーを用意します。
アクセスをすると 200 で成功することが確認できます。
[ec2-user@ip-10-0-1-242 ~]$ curl ipecho.net/plain; echo 13.231.80.97 [ec2-user@ip-10-0-1-242 ~]$ curl -I http://y-ishikawa-terraform-alb-1243176883.ap-northeast-1.elb.amazonaws.com/ HTTP/1.1 200 OK Date: Sat, 23 Aug 2025 00:39:19 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 233 Connection: keep-alive Server: Apache/2.4.64 (Amazon Linux) Last-Modified: Sat, 23 Aug 2025 00:19:49 GMT ETag: "e9-63cfd47d80ed8" Accept-Ranges: bytes [ec2-user@ip-10-0-1-242 ~]$
アクセスログ
[root@ip-10-0-1-174 conf]# tail -f /var/log/httpd/access_log 13.231.80.97 - - [23/Aug/2025:00:39:19 +0000] "HEAD / HTTP/1.1" 200 - "-" "curl/8.11.1"
confファイルでもIP制限をかけます。
先ほど成功した接続元IPの13.231.80.97
は許可します。
# httpd.conf ### /var/www/html ディレクトリに対するアクセス制御 <Directory "/var/www/html"> # まず全てのアクセスを拒否する Require all denied # 先ほど成功した接続元IPからのアクセスのみを許可する Require ip 13.231.80.97 </Directory>
アクセスすると失敗します。
[ec2-user@ip-10-0-1-242 ~]$ curl -I http://y-ishikawa-terraform-alb-1243176883.ap-northeast-1.elb.amazonaws.com/ HTTP/1.1 403 Forbidden Date: Sat, 23 Aug 2025 01:19:32 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 45 Connection: keep-alive Server: Apache/2.4.64 (Amazon Linux) Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes [ec2-user@ip-10-0-1-242 ~]$
アクセスログには許可したはずのIPが記載されています。
[root@ip-10-0-1-174 conf]# tail -f /var/log/httpd/access_log 13.231.80.97 - - [23/Aug/2025:01:19:32 +0000] "HEAD / HTTP/1.1" 403 - "-" "curl/8.11.1"
失敗する原因はX-Forwarded-For ヘッダーをクライアントIPとして扱う設定がされていないからです。
以下設定を追加します。
# httpd.conf ### X-Forwarded-For ヘッダーをクライアントIPとして扱う RemoteIPHeader X-Forwarded-For ### 信頼するプロキシサーバーのIPアドレスを指定 ### ELBやCloudFrontなど、手前のプロキシのIPアドレス、もしくはVPCなどCIDR範囲を記述します。 RemoteIPTrustedProxy 10.0.0.0/16 # VPCのCIDR ### 必要に応じて追加
XFFヘッダーはクライアントが偽装できるため、mod_remoteip
を使用し、RemoteIPTrustedProxy
で信頼できるプロキシを正確に指定する必要があります。これにより、信頼できないプロキシからの偽装されたXFFヘッダーを無視できます。
設定後Apacheを再起動して、もう一度アクセスすると成功します。
[ec2-user@ip-10-0-1-242 ~]$ curl -I http://y-ishikawa-terraform-alb-1243176883.ap-northeast-1.elb.amazonaws.com/ HTTP/1.1 200 OK Date: Sat, 23 Aug 2025 01:25:24 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 233 Connection: keep-alive Server: Apache/2.4.64 (Amazon Linux) Last-Modified: Sat, 23 Aug 2025 00:19:49 GMT ETag: "e9-63cfd47d80ed8" Accept-Ranges: bytes [ec2-user@ip-10-0-1-242 ~]$
ログファイルにも成功が記載されていますが、IPが記載されていません。
[root@ip-10-0-1-174 conf.modules.d]# tail -f /var/log/httpd/access_log - - - [23/Aug/2025:01:24:34 +0000] "GET / HTTP/1.1" 403 45 "-" "ELB-HealthChecker/2.0"
これはログフォーマットを以下のように接続元IPとして X-Forwarded-For ヘッダーを直接指定 (%{X-Forwarded-For}i) しているためです。
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
mod_remoteip を使うと、Apacheが認識するクライアントIP (%a) 自体が X-Forwarded-For の値で上書きされます。そのため、ログには %a を使用するのが正しい方法となります。
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
修正後、再度アクセスすると正しくクライアントIPが記録されるようになります。
[root@ip-10-0-1-174 conf.modules.d]# tail -f /var/log/httpd/access_log 13.231.80.97 - - [23/Aug/2025:01:31:48 +0000] "HEAD / HTTP/1.1" 200 - "-" "curl/8.11.1"
参考になったら幸いです。
mod_remoteip
https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html