Nginx Proxy Manager real ip

zinsas

New Member
Sep 9, 2023
1
0
1
Hello, I am using the following combination. Proxmox VE, fail2ban is installed on it and the nextcloud container is deployed. The problem is that through the domain name and NPM certificate, fail2ban bans the ip of the container and not the ip from the user who connects through NPM. I assume that the problem is in the Proxmox or NPM network settings. Because if I open a port from a router, then f2b bans the real ip of the user
 

Attachments

  • 12.jpg
    12.jpg
    28.6 KB · Views: 19
Exact same issue here. I tried adding
Code:
proxy_set_header X-Forwarded-For $remote_addr;
to my NPM configs in various ways, but it still doesn't work. When I look at the logs using
Code:
fail2ban-regex /var/log/daemon.log /etc/fail2ban/filter.d/proxmox.conf --print-all-matched
, I get something like this:
Code:
pve pvedaemon[271358]: authentication failure; rhost=::ffff:192.168.1.2
, where I can see the IP address under
Code:
rhost
is the local IP of nginx, and not the public IP of the client as it should be for fail2ban to work correctly.

Any advice on how to fix this would be appreciated.
 
Last edited:
TL;DR: fail2ban blocks IPs using iptable rules, which isn't strightforward to do on proxied requests

So I went down the rabbit hole trying to solve this issue and
here's what I found.

Disclaimer: I did not manage to solve the issue, and the code and tweaks I've included below should be used with caution. I've never used Perl before and I relied on ChatGPT for sections of it. I would recommend against copying anything below in verbatim.

I found this proxmox forums thread where the author detailed how they solved the issue of getting client public IP by editing this (/usr/share/perl5/PVE/HTTPServer.pm) file. Their solution didn't work for me since my pve is behind cloudflare and also nginx running on the LAN, so my X-Forwarded-For header contains two IPs instead of just one.

So my solution involved adding the following to line after /usr/share/perl5/PVE/APIServer/AnyEvent.pm:1484 (ProxmoxVE Version 7.4-17):

Perl:
if ($request->header('X-Forwarded-For')) {
            my $x_forwarded_for = $request->header('X-Forwarded-For');

            # Number of proxies to count from the right
            my $proxy_count = 2;        # my value is 2 because I use cloudflare, then nginx locally

            # Split the input string into an array of IP addresses
            my @ip_list = split /\s*,\s*/, $x_forwarded_for;

            # Calculate the maximum iteration count
            my $max_iterations = $proxy_count + 1;

            # Iterate through the IP addresses from the right
            for my $i (reverse 0 .. $#ip_list) {
                $max_iterations--;
                if ($max_iterations == 0) {
                    last;
                }

                my $ip = $ip_list[$i];

                my $ip_parsed = Net::IP->new($ip);

                $proxy_count--;

                # Validate the IP address format
                if ($ip_parsed) {
                    if ($proxy_count == 0) {
                        if($ip_parsed->version() == 4){
                            my $ipv6_mapped_address = "::ffff:$ip";
                            $reqstate->{peer_host} = $ipv6_mapped_address;
                        }
                        else{
                            $reqstate->{peer_host} = $ip;
                        }
                        last;
                    }
                } else {
                    warn "Malformed IP found in X-Forwarded-For header. One of your proxies are appending the wrong IP, or \$proxy_count is incorrect.\n";
                    next;
                }
            }

            if($max_iterations == 0){
                warn "Error: Not enough valid IPs in X-Forwarded-For header. One of your proxies are appending the wrong IP, or \$proxy_count is incorrect.\n";
            }
        }

After editing the file, I did `systemctl restart pvedaemon` and `systemctl restart pveproxy`.

(Note: if you attempt anything similar and there are Perl compilation errors, the two commands above will fail. You can see the errors using `journalctl -xe`)

After this, the IP addresses in /var/log/daemon.log was correct, and I was able to confirm that fail2ban was banning the correct IP addresses, as `fail2ban-client banned` was correctly showing the public IP of my clients.

However, my clients were still able to access the Web UI while on the ban list.

I only found out after I had done all the above, but fail2ban bans users using iptables. So the actual ban cannot be done based on X-Forwarded-For (at least, not using the fail2ban default configuration). So in this configuration fail2ban will ban a specific bad acting client's public IP, and add this IP to the iptables blocklist, but this rule will never be met, because all public traffic is coming to the system from the reverse proxy LAN IP.

Since I'm using cloudflare, some googling shows that there are ways to use fail2ban to execute a script contacts the cloudflare API to block clients. Might pursue this in the future, but for now my understanding is that blocking proxied requests directly on the proxmox system isn't possible.
 
  • Like
Reactions: UdoB

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!