【NGINX】解决WordPress无法获取访客真实IP的问题——proxy protocol

2020年7月31日 1582点热度 1人点赞 4条评论

背景

未部署SSL证书时,通过http访问,WP可以通过HTTP_X_FORWARDED_FOR这个header正确获取访客IP

部署SSL证书后,通过https访问,WP不能准确获取访客IP,只能获取本机的127.0.0.1的IP

WP运行环境:armbian+nginx 1.10.3+php7.4+樱花frp

FRP客户端的配置

frp的作者已经加入了对proxy protocol的支持,同时支持v1和v2版本(具体请参考这里),这个功能默认是关闭的,需要在frpc.ini中加入如下代码:

proxy_protocol_version = v2
或
proxy_protocol_version = v1

这段代码要加在你想开启proxy protocol的https的隧道后面,注意是https类型的隧道,如果你同时建立了http隧道用于向https跳转,那么也不必管http隧道。具体例子如下:

# frpc.ini
[web]
type = https
local_port = 443
custom_domains = test.yourdomain.com

# 目前支持 v1 和 v2 两个版本的 proxy protocol 协议。
proxy_protocol_version = v2

至于开启v1还是v2,取决于你的接收端(即nginx)支持v1还是v2协议,如果你的接收端只支持v1,但你在frp中配置了v2,也是不能用的。nginx支持何种协议,可以参考这里,下面是我摘录过来的:

Prerequisites

  • To accept the PROXY protocol v2, NGINX Plus R16 and later or NGINX Open Source 1.13.11 and later
  • To accept the PROXY protocol for HTTP, NGINX Plus R3 and later or NGINX Open Source 1.5.12 and later
  • For TCP client‑side PROXY protocol support, NGINX Plus R7 and later or NGINX Open Source 1.9.3 and later
  • To accept the PROXY protocol for TCP, NGINX Plus R11 and later or NGINX Open Source 1.11.4 and later
  • The Real‑IP modules for HTTP and Stream (TCP) are not included in NGINX Open Source by default; see Installing NGINX Open Source for details. No extra steps are required for NGINX Plus.

很明显,要想接收v2,你的nginx版本必须是1.13.11及以后的。所以1.10.3只能接收v1.

frp的配置只需要这一段代码,要注意的地方是,这段代码加在哪里,以及选择v1还是v2

nginx的配置

如果你的nginx.conf

/etc/nginx/nginx.conf

已经包含了sites-enabled

/etc/nginx/sites-enabled/

下的配置文件了,即在nginx.conf的http{}里有这么一段代码:

http {
······
include /etc/nginx/sites-enabled/*;
······
}

只需要对sites-enabled下的每个网站的配置文件修改即可。

假设我的配置文件是sites-enabled下的xyz文件,且该配置文件是有效的,配置好了ssl,配置好了http强制跳转https(这不重要,完全不需要修改强制http跳转https所监听的80端口)即下面的代码不需要修改:

#http强制跳https设置
server {
        listen 80;
        server_name blog.sherry.gq; #此处改为你自己的域名
        return 301 https://$host$request_uri;
}
这个代码完全不需要修改

首先要开启proxy protocol的解析(假如ssl监听的是443端口),然后要将header替换。所以需要修改的是另一个server下的内容如下:

server {
            listen 443 ssl proxy_protocol;#在443后面添加ssl proxy_protocol
            ······
            #Proxy Protocol设置(新增整行代码)
            set_real_ip_from 127.0.0.1;#(新增整行代码)
            real_ip_header proxy_protocol;#(新增整行代码)
            ······
            location / {
                   ······
                   #下面都是新增
                   proxy_set_header X-Forwarded-For $proxy_protocol_addr;
                   proxy_set_header X-Real-IP       $proxy_protocol_addr;
                   proxy_set_header Host            $host;
                   #新增结束
                   ······
            }
}
以上只展示了需要修改或者新增的设定以及代码所处位置,其他的设定保持原样即可

通过以上设定,重启sakurafrp和nginx服务,这时候WP就可以通过REMOTE_ADDR这个header正确获取访客的IP了

麦克斯和雪莉

非常规文科生

文章评论

  • 皇家元林

    很详细的文章,但是免费的nginx貌似不支持这个proxy protocol啊

    2023年9月3日
  • 皇家元林

    博主 我好像在你这问过你这个问题的。
    还是老问题listen 443 ssl proxy_protocol; 这个proxy_protocol加上 网站就打不开了,不加是正常的。这是咋回事?

    2023年10月3日