NginxProxyManager / nginx-proxy-manager

Docker container for managing Nginx proxy hosts with a simple, powerful interface
https://nginxproxymanager.com
MIT License
23.35k stars 2.7k forks source link

X-forwared-for shows Cloudflare IP instead of real IP #1358

Open bernikr opened 3 years ago

bernikr commented 3 years ago

Checklist

Describe the bug When using Cloudflare infront of NPM, NPM populates the X-forwarded-for header with the cloudflare IP instead of the real IP that cloudflare provices in its X-forwarded-for header. I would expect NPM to check if the source IP is one of cloudflare's and trust the X-forwarded-for header in that case. This seemd to be a feature in 2.6.0 but broken in all verisons afterwards.

Nginx Proxy Manager Version 2.9.8

To Reproduce Set up a cloudflare domain and let it point to NPM. If you now navigate to the site the server behind NPM will get one of cloudflare's IPs as the X-forwarded-for header instead of the client IP

Expected behavior Show the real client IP that cloudflare reports in the X-forwarded-for header.

Operating System Synology NAS

Additional context The closed issues #112 and #811 both suggest using the following settings as a workaround:

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

This is however a major security risk as it doesnt check if the request is actually coming from cloudflare. It allows anyone with knowledge of your IP to send requests pretending to be from cloudflare with an CF-Connecting-IP header set to any IP they want, (including lan ips such as 10.0.0.1) possibly circumventing any IP based security measures.

schevenin commented 3 years ago

Use v2.6.0 is what I found in my #811

TritonB7 commented 2 years ago

Found the following:

set_real_ip_from defines trusted addresses that are known to send correct replacement addresses. Source: https://nginx.org/en/docs/http/ngx_http_realip_module.html

nginx configuration file snippet (IPv4 only):

set_real_ip_from    03.21.244.0/22;
set_real_ip_from    103.22.200.0/22;
set_real_ip_from    103.31.4.0/22;
set_real_ip_from    104.16.0.0/13;
set_real_ip_from    104.24.0.0/14;
set_real_ip_from    108.162.192.0/18;
set_real_ip_from    131.0.72.0/22;
set_real_ip_from    141.101.64.0/18;
set_real_ip_from    162.158.0.0/15;
set_real_ip_from    172.64.0.0/13;
set_real_ip_from    173.245.48.0/20;
set_real_ip_from    188.114.96.0/20;
set_real_ip_from    190.93.240.0/20;
set_real_ip_from    197.234.240.0/22;
set_real_ip_from    198.41.128.0/17;

#use any of the following two

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

Cloudflare Documentation: https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs

Cloudflare IPs: https://www.cloudflare.com/ips

gmcinalli commented 2 years ago

Awesome @TritonB7, I've tried it and it seems to work!

ctrlbrk42 commented 2 years ago

Is this still not automatic/internal to NPM v2.9.16?

I am migrating to NPM. Previously, I was using this on my own config:

#!/bin/bash echo "#Cloudflare" > /var/www/nginx/cloudflare.conf; for i in $(curl https://www.cloudflare.com/ips-v4); do echo "set_real_ip_from $i;" >> /var/www/nginx/cloudflare.conf; done echo "real_ip_header CF-Connecting-IP;" >> /var/www/nginx/cloudflare.conf;

Not ideal but hacky enough to get the job done.

I landed on this thread because am experiencing this issue with my upstream behind NPM, it's not logging the correct IP where it was pre-NPM.

punksinatra commented 2 years ago

Is this still not automatic/internal to NPM v2.9.16?

I am migrating to NPM. Previously, I was using this on my own config:

#!/bin/bash echo "#Cloudflare" > /var/www/nginx/cloudflare.conf; for i in $(curl https://www.cloudflare.com/ips-v4); do echo "set_real_ip_from $i;" >> /var/www/nginx/cloudflare.conf; done echo "real_ip_header CF-Connecting-IP;" >> /var/www/nginx/cloudflare.conf;

Not ideal but hacky enough to get the job done.

I landed on this thread because am experiencing this issue with my upstream behind NPM, it's not logging the correct IP where it was pre-NPM.

Not sure if you have fixed this but I saw something here 811 check the post by techc0de maybe you can try it.

ctrlbrk42 commented 2 years ago

Is this still not automatic/internal to NPM v2.9.16?

I am migrating to NPM. Previously, I was using this on my own config:

#!/bin/bash echo "#Cloudflare" > /var/www/nginx/cloudflare.conf; for i in $(curl https://www.cloudflare.com/ips-v4); do echo "set_real_ip_from $i;" >> /var/www/nginx/cloudflare.conf; done echo "real_ip_header CF-Connecting-IP;" >> /var/www/nginx/cloudflare.conf;

Not ideal but hacky enough to get the job done.

I landed on this thread because am experiencing this issue with my upstream behind NPM, it's not logging the correct IP where it was pre-NPM.

Not sure if you have fixed this but I saw something here 811 check the post by techc0de maybe you can try it.

I switched to Caddy for this particular project.

bioszombie commented 1 year ago

Awesome @TritonB7, I've tried it and it seems to work!

Where did you update this? In the GUI or in the compose file?

gmcinalli commented 1 year ago

@bioszombie “Custom Nginx Configuration” field in the “Advanced” tab of the proxy host editing modal on the GUI.

bioszombie commented 1 year ago

@bioszombie “Custom Nginx Configuration” field in the “Advanced” tab of the proxy host editing modal on the GUI.

Thank you. That worked!

wdolan commented 1 year ago

I am currently trying to get this working with Guacamole and can't seem to figure it out as that isn't working. I am trying with the below and it doesn't seem to be picking up the remote ip but the ip address of Cloudflare that it is routing through. Does this look correct? I also tried adding a copy of the real_ip_header line under the location section which made no difference. set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/12; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; real_ip_header CF-Connecting-IP; location / { proxy_pass http://10.1.11.3:9998/guacamole/; proxy_cookie_path /guacamole/ /; }

gmcinalli commented 1 year ago

@wdolan I don't think you need the location block, that will be handled by the NPM UI.

wdolan commented 1 year ago

Hello, Maybe I have something wrong then. Even then trying to make a few variants on it, I am seeing connections as being from 127.0.0.1 despite having the below setup. When I connect through the host from the same network using the machine name instead of the external FQDN it reports correctly. Did I miss something? server { server_name remote.redacted.net; location / { set_real_ip_from 03.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; real_ip_header CF-Connecting-IP; proxy_pass http://localhost:8080/guacamole/;

proxy_pass http://localhost:8081;

proxy_read_timeout  90;
proxy_http_version  1.1;
proxy_cache_bypass  $http_upgrade;

proxy_buffering off;
proxy_set_header Upgrade           $http_upgrade;
proxy_set_header Connection        $http_connection;
proxy_set_header Host              $host;
proxy_set_header X-Real-IP         CF-Connecting-IP;
proxy_set_header X-Forwarded-For   CF-Connecting-IP;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host  $host;
proxy_set_header X-Forwarded-Port  $server_port;
proxy_intercept_errors on;

}

listen 443 http2 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/remote.redacted.net/fullchain.pem;

managed by Certbot

ssl_certificate_key /etc/letsencrypt/live/

remote.redacted.net/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 error_page 404 500 502 503 504 https://letmegooglethat.com/?q=why+does+my+server+have+an+error; }

Any help would be greatly appreciated.

On Thu, May 18, 2023 at 12:39 PM glassman81 @.***> wrote:

Found the following:

set_real_ip_from defines trusted addresses that are known to send correct replacement addresses. Source: https://nginx.org/en/docs/http/ngx_http_realip_module.html

nginx configuration file snippet (IPv4 only):

set_real_ip_from 03.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17;

use any of the following two

real_ip_header CF-Connecting-IP;

real_ip_header X-Forwarded-For;

Cloudflare Documentation: https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs

Cloudflare IPs: https://www.cloudflare.com/ips

Sorry, I know this post is a little older, but what would happen if you included the “real_ip_header X-Forwarded-For;” line but didn’t add any actual cloudflare addresses using “set_real_ip_from”?

— Reply to this email directly, view it on GitHub https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1358#issuecomment-1553324231, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABA3PV6GNDF3NWHJFS5ZXP3XGZGE3ANCNFSM5C7EPWOQ . You are receiving this because you were mentioned.Message ID: @.***>

LuXc-NL commented 9 months ago

Found the following:

set_real_ip_from defines trusted addresses that are known to send correct replacement addresses. Source: https://nginx.org/en/docs/http/ngx_http_realip_module.html

nginx configuration file snippet (IPv4 only):

set_real_ip_from    03.21.244.0/22;
set_real_ip_from    103.22.200.0/22;
set_real_ip_from    103.31.4.0/22;
set_real_ip_from    104.16.0.0/13;
set_real_ip_from    104.24.0.0/14;
set_real_ip_from    108.162.192.0/18;
set_real_ip_from    131.0.72.0/22;
set_real_ip_from    141.101.64.0/18;
set_real_ip_from    162.158.0.0/15;
set_real_ip_from    172.64.0.0/13;
set_real_ip_from    173.245.48.0/20;
set_real_ip_from    188.114.96.0/20;
set_real_ip_from    190.93.240.0/20;
set_real_ip_from    197.234.240.0/22;
set_real_ip_from    198.41.128.0/17;

#use any of the following two

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

Cloudflare Documentation: https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs

Cloudflare IPs: https://www.cloudflare.com/ips

You just saved my day!

reply2future commented 8 months ago

@bioszombie “Custom Nginx Configuration” field in the “Advanced” tab of the proxy host editing modal on the GUI.

If you want to take effect to all your websites, you could add the content to a file /data/nginx/custom/server_proxy.conf which is included at the end of every proxy server block. You could find more information from official document

Bluscream commented 7 months ago

this is a godsend :pray:

here's the latest ips

/portainer/Files/AppData/Config/nginx-proxy-manager $ cat data/nginx/custom/server_proxy.conf

set_real_ip_from    103.21.244.0/22;
set_real_ip_from    103.22.200.0/22;
set_real_ip_from    103.31.4.0/22;
set_real_ip_from    104.16.0.0/13;
set_real_ip_from    104.24.0.0/14;
set_real_ip_from    108.162.192.0/18;
set_real_ip_from    131.0.72.0/22;
set_real_ip_from    141.101.64.0/18;
set_real_ip_from    162.158.0.0/15;
set_real_ip_from    172.64.0.0/13;
set_real_ip_from    173.245.48.0/20;
set_real_ip_from    188.114.96.0/20;
set_real_ip_from    190.93.240.0/20;
set_real_ip_from    197.234.240.0/22;
set_real_ip_from    198.41.128.0/17;
set_real_ip_from    2400:cb00::/32;
set_real_ip_from    2405:8100::/32;
set_real_ip_from    2405:b500::/32;
set_real_ip_from    2606:4700::/32;
set_real_ip_from    2803:f800::/32;
set_real_ip_from    2a06:98c0::/29;
set_real_ip_from    2c0f:f248::/32;

#use any of the following two

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

EDIT: Seems like npm is already fetching these ips, isn't this a reason to implement a simple checkbox to enable cloudflare visitor ips? @jc21

2024-04-07T15:07:13.850501792Z [4/7/2024] [3:07:13 PM] [IP Ranges] › ℹ  info      Fetching https://www.cloudflare.com/ips-v4
2024-04-07T15:07:13.977207458Z [4/7/2024] [3:07:13 PM] [IP Ranges] › ℹ  info      Fetching https://www.cloudflare.com/ips-v6
MrrZed0 commented 7 months ago

Found the following:

set_real_ip_from defines trusted addresses that are known to send correct replacement addresses. Source: https://nginx.org/en/docs/http/ngx_http_realip_module.html

nginx configuration file snippet (IPv4 only):

set_real_ip_from    03.21.244.0/22;
set_real_ip_from    103.22.200.0/22;
set_real_ip_from    103.31.4.0/22;
set_real_ip_from    104.16.0.0/13;
set_real_ip_from    104.24.0.0/14;
set_real_ip_from    108.162.192.0/18;
set_real_ip_from    131.0.72.0/22;
set_real_ip_from    141.101.64.0/18;
set_real_ip_from    162.158.0.0/15;
set_real_ip_from    172.64.0.0/13;
set_real_ip_from    173.245.48.0/20;
set_real_ip_from    188.114.96.0/20;
set_real_ip_from    190.93.240.0/20;
set_real_ip_from    197.234.240.0/22;
set_real_ip_from    198.41.128.0/17;

#use any of the following two

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

Cloudflare Documentation: https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs

Cloudflare IPs: https://www.cloudflare.com/ips

man this worked for me using CasaOS with home assistant and Nginx Proxy Manager and Cloudflare with proxy enabled and now i can access it thanks to this information thanks so much, spend so many hours trying to get it to work

aerickt commented 14 hours ago

For anyone in the same situation as me: if you're using a Cloudflare zero trust tunnel, I only needed a single set_real_ip_from specifying the local Cloudflare network IP. This is the IP your server will report when visiting through the tunnel