Nginx 反向代理到 Yesod 转发的 ip 地址不起作用
Nginx reverse proxy to Yesod forwarded ip address does not work
我将 nginx 设置为 Yesod 的反向代理。 /var/log/nginx/access.log
中的IP地址为客户端真实IP地址。
123.123.123.123 - - [09/Oct/2020:07:11:16 +0000] "GET / HTTP/1.1" 200 ...
但是Yesod在日志中显示的IP地址是127.0.0.1,来自nginx。
127.0.0.1 - - [09/Oct/2020:07:11:16 +0000] "GET / HTTP/1.0" 200 - "https://...
这是我的 nginx 配置:
...
server {
server_name example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:3000; # Reverse proxy to your Yesod app
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
...
我已经重新启动了 nginx 和 yesod 二进制文件。但是Yesod列出的IP还是127.0.0.1.
我犯了什么配置错误?
或者我需要编辑我的 Yesod 二进制文件的日志代码吗?
谢谢各位好心的读者
答案是 Yesod 有一个配置选项可以使用转发的 IP headers。
我通过阅读 src/Settings.hs
找到它,其中包含以下内容:
data AppSettings = AppSettings
{ appStaticDir :: String
-- ^ Directory from which to serve static files.
, appDatabaseConf :: PostgresConf
-- ^ Configuration settings for accessing the database.
, appRoot :: Maybe Text
-- ^ Base for all generated URLs. If @Nothing@, determined
-- from the request headers.
, appHost :: HostPreference
-- ^ Host/interface the server should bind to.
, appPort :: Int
-- ^ Port to listen on
, appIpFromHeader :: Bool
-- ^ Get the IP address from the header when logging. Useful when sitting
-- behind a reverse proxy.
...
因此您需要编辑 config/settings.yaml
其中包含以下行:
...
ip-from-header: "_env:YESOD_IP_FROM_HEADER:false"
...
或者,你也可以改变环境变量运行这个命令export YESOD_IP_FROM_HEADER=true
.
那就解决了。
我将 nginx 设置为 Yesod 的反向代理。 /var/log/nginx/access.log
中的IP地址为客户端真实IP地址。
123.123.123.123 - - [09/Oct/2020:07:11:16 +0000] "GET / HTTP/1.1" 200 ...
但是Yesod在日志中显示的IP地址是127.0.0.1,来自nginx。
127.0.0.1 - - [09/Oct/2020:07:11:16 +0000] "GET / HTTP/1.0" 200 - "https://...
这是我的 nginx 配置:
...
server {
server_name example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:3000; # Reverse proxy to your Yesod app
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
...
我已经重新启动了 nginx 和 yesod 二进制文件。但是Yesod列出的IP还是127.0.0.1.
我犯了什么配置错误?
或者我需要编辑我的 Yesod 二进制文件的日志代码吗?
谢谢各位好心的读者
答案是 Yesod 有一个配置选项可以使用转发的 IP headers。
我通过阅读 src/Settings.hs
找到它,其中包含以下内容:
data AppSettings = AppSettings
{ appStaticDir :: String
-- ^ Directory from which to serve static files.
, appDatabaseConf :: PostgresConf
-- ^ Configuration settings for accessing the database.
, appRoot :: Maybe Text
-- ^ Base for all generated URLs. If @Nothing@, determined
-- from the request headers.
, appHost :: HostPreference
-- ^ Host/interface the server should bind to.
, appPort :: Int
-- ^ Port to listen on
, appIpFromHeader :: Bool
-- ^ Get the IP address from the header when logging. Useful when sitting
-- behind a reverse proxy.
...
因此您需要编辑 config/settings.yaml
其中包含以下行:
...
ip-from-header: "_env:YESOD_IP_FROM_HEADER:false"
...
或者,你也可以改变环境变量运行这个命令export YESOD_IP_FROM_HEADER=true
.
那就解决了。