AWS ELB Apache 获取客户端 IP,避免 X-Forwarded-For 欺骗
AWS ELB Apache Get Client IP, Avoid X-Forwarded-For Spoofing
根据 apache 文档 (https://httpd.apace.org/docs/2.4/mod/mod_remoteip.html),我们在我们的服务器上实现了以下分配:
RemoteIPHeader X-Forwarded-For
获取客户端的 IP 而不是 ELB 的 IP。但是,我们没有注意到 ELB 还将所有其他 X-Forwarded-For
值附加到该字符串的左侧。所以这不是获取客户端 IP 的安全方法。
我们使用 LogFormat
和 \"%{X-Forwarded-For}i\"
来验证传入的值是否如文档所述。
192.168.0.0, 10.0.0.0
如果 192.168.0.0
是正在传递的 header 并且 10.0.0.0
是客户端的请求机器,那么 将会发生什么。没有 header 的标准请求是:
10.0.0.0
有没有办法提取最右边的IP?我在想,
RemoteIPHeader ('(?:\d{1,3}[.]){3}\d{1,3}$', X-Forwarded-For,)[0]
但无法在 apache 中找到配置此功能的函数。我可以在 PHP 中执行此操作,但随后我的日志将记录所有错误的 IP。
我试过:
SetEnvIf X-Forwarded-For '((?:\d{1,3}[.]){3}\d{1,3})$' ip_is=
RemoteIPHeader %{ip_is}
但这并没有影响。
更新:
Apache 配置运行:
LogFormat "%{%Y-%m-%d %H:%M:%S}t %a %u %A %p %m %U %q %>s \"%{User-agent}i\" %T/%D \"%{X-Forwarded-For}i\"" w3c_extended
CustomLog /var/log/httpd/example.com/access.log w3c_extended
我目前收到:
2021-02-27 14:29:06 10.0.21.150 - 10.0.20.222 443 GET /IPtest.php ?v=1 200 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 0/2822 "73.149.97.219"
或
2021-02-27 14:29:06 10.0.21.150 - 10.0.20.222 443 GET /IPtest.php ?v=1 200 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 0/2822 "10.0.21.150, 73.149.97.219"
我需要在这两种情况下捕获 73.149.97.219
。
我正在使用 apache 2.4 和 remoteIP 进行测试
RemoteIPHeader x-forwarded-for
您还需要告诉您的 Apache 负载平衡器(反向代理)的内部 IP 地址是什么。没有可靠的简单方法来确定内部 IP,它可以通过 'any' RFC1918(私有)IP 地址
所以您需要添加这 3 个子网。
RemoteIPTrustedProxy 10.0.0.0/8
RemoteIPTrustedProxy 172.16.0.0/12
RemoteIPTrustedProxy 192.168.0.0/16
然后使用 %a 作为日志格式
LogFromat %a
我用
测试过
RemoteIPTrustedProxy 127.0.0.1
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
使用 curl 测试
curl 127.0.0.1/so
127.0.0.1 - - [27/Feb/2021:15:02:38 +0100] "GET /so/ HTTP/1.1" 200 167 "-" "curl/7.52.1"
curl 127.0.0.1/so/ -H "x-forwarded-for: 1.2.3.4"
1.2.3.4 - - [27/Feb/2021:15:04:06 +0100] "GET /so/ HTTP/1.1" 200 167 "-" "curl/7.52.1"
curl 127.0.0.1/so/ -H "x-forwarded-for: 8.5.4.1, 1.2.3.4"
1.2.3.4 - - [27/Feb/2021:15:04:31 +0100] "GET /so/ HTTP/1.1" 200 167 "-" "curl/7.52.1"
我在不同的上下文中遇到了这个问题——apache 正在从被操纵的 X-Forwarded-For
header 中解析主机名。例如。 X-Forwarded-For: mumblemuble.burpcollaborator.com, 1.1.1.1, anotherdomainapachewillresolve.com
我的解决方案是修改X-Forwarded-For
header只包含ELB添加的IP地址,并丢弃ELB附加到header的IP地址。
ELB 不是其他反向代理,而是在 客户端 IP 之前附加现有 X-Forwarded-For
地址和主机名 。对于其他反向代理,您应该修改正则表达式以丢弃第一个逗号后的所有内容。
# because of "early", headers can only be set in a main server or virtual host context.
RequestHeader edit "X-Forwarded-For" "^(.+),(.+)$" "" early
根据 apache 文档 (https://httpd.apace.org/docs/2.4/mod/mod_remoteip.html),我们在我们的服务器上实现了以下分配:
RemoteIPHeader X-Forwarded-For
获取客户端的 IP 而不是 ELB 的 IP。但是,我们没有注意到 ELB 还将所有其他 X-Forwarded-For
值附加到该字符串的左侧。所以这不是获取客户端 IP 的安全方法。
我们使用 LogFormat
和 \"%{X-Forwarded-For}i\"
来验证传入的值是否如文档所述。
192.168.0.0, 10.0.0.0
如果 192.168.0.0
是正在传递的 header 并且 10.0.0.0
是客户端的请求机器,那么 将会发生什么。没有 header 的标准请求是:
10.0.0.0
有没有办法提取最右边的IP?我在想,
RemoteIPHeader ('(?:\d{1,3}[.]){3}\d{1,3}$', X-Forwarded-For,)[0]
但无法在 apache 中找到配置此功能的函数。我可以在 PHP 中执行此操作,但随后我的日志将记录所有错误的 IP。
我试过:
SetEnvIf X-Forwarded-For '((?:\d{1,3}[.]){3}\d{1,3})$' ip_is=
RemoteIPHeader %{ip_is}
但这并没有影响。
更新:
Apache 配置运行:
LogFormat "%{%Y-%m-%d %H:%M:%S}t %a %u %A %p %m %U %q %>s \"%{User-agent}i\" %T/%D \"%{X-Forwarded-For}i\"" w3c_extended
CustomLog /var/log/httpd/example.com/access.log w3c_extended
我目前收到:
2021-02-27 14:29:06 10.0.21.150 - 10.0.20.222 443 GET /IPtest.php ?v=1 200 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 0/2822 "73.149.97.219"
或
2021-02-27 14:29:06 10.0.21.150 - 10.0.20.222 443 GET /IPtest.php ?v=1 200 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 0/2822 "10.0.21.150, 73.149.97.219"
我需要在这两种情况下捕获 73.149.97.219
。
我正在使用 apache 2.4 和 remoteIP 进行测试
RemoteIPHeader x-forwarded-for
您还需要告诉您的 Apache 负载平衡器(反向代理)的内部 IP 地址是什么。没有可靠的简单方法来确定内部 IP,它可以通过 'any' RFC1918(私有)IP 地址 所以您需要添加这 3 个子网。
RemoteIPTrustedProxy 10.0.0.0/8
RemoteIPTrustedProxy 172.16.0.0/12
RemoteIPTrustedProxy 192.168.0.0/16
然后使用 %a 作为日志格式
LogFromat %a
我用
测试过RemoteIPTrustedProxy 127.0.0.1
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
使用 curl 测试
curl 127.0.0.1/so
127.0.0.1 - - [27/Feb/2021:15:02:38 +0100] "GET /so/ HTTP/1.1" 200 167 "-" "curl/7.52.1"
curl 127.0.0.1/so/ -H "x-forwarded-for: 1.2.3.4"
1.2.3.4 - - [27/Feb/2021:15:04:06 +0100] "GET /so/ HTTP/1.1" 200 167 "-" "curl/7.52.1"
curl 127.0.0.1/so/ -H "x-forwarded-for: 8.5.4.1, 1.2.3.4"
1.2.3.4 - - [27/Feb/2021:15:04:31 +0100] "GET /so/ HTTP/1.1" 200 167 "-" "curl/7.52.1"
我在不同的上下文中遇到了这个问题——apache 正在从被操纵的 X-Forwarded-For
header 中解析主机名。例如。 X-Forwarded-For: mumblemuble.burpcollaborator.com, 1.1.1.1, anotherdomainapachewillresolve.com
我的解决方案是修改X-Forwarded-For
header只包含ELB添加的IP地址,并丢弃ELB附加到header的IP地址。
ELB 不是其他反向代理,而是在 客户端 IP 之前附加现有 X-Forwarded-For
地址和主机名 。对于其他反向代理,您应该修改正则表达式以丢弃第一个逗号后的所有内容。
# because of "early", headers can only be set in a main server or virtual host context.
RequestHeader edit "X-Forwarded-For" "^(.+),(.+)$" "" early