リフト&シフトした環境など、セキュリティグループとサーバー内で二重で許可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