nginx-proxy-manager
nginx-proxy-manager copied to clipboard
FORBIDDEN: Despite Documentation! Creating "Local only" Access List, requires PUBLIC IPs ONLY
Checklist
- Have you pulled and found the error with
jc21/nginx-proxy-manager:latest
docker image?- Yes
- Are you sure you're not using someone else's docker image?
- Yes
- Have you searched for similar issues (both open and closed)?
- Yes
Describe the bug
Despite what the documentation say, adding local IPs, subnets, and local gateway is NOT working in my case!.
i used the following docker-compose.yaml
file to do the installation:
` npm-app:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-app
restart: always
ports:
- 80:80
- 81:81
- 443:443
environment:
- DB_MYSQL_HOST=npm-db
- DB_MYSQL_PORT=3306
- DB_MYSQL_USER=npm
- DB_MYSQL_PASSWORD=PASSWORD
- DB_MYSQL_NAME=npm
volumes:
- npm-data:/data
- npm-ssl:/etc/letsencrypt
networks:
- nginx
npm-db:
image: jc21/mariadb-aria:latest
container_name: nginx-db
restart: always
environment:
- MYSQL_ROOT_PASSWORD=PASSWORD
- MYSQL_DATABASE=npm
- MYSQL_USER=npm
- MYSQL_PASSWORD=PASSWORD
volumes:
- npm-db:/var/lib/mysql
networks:
- nginx`
The conf file:
`------------------------------------------------------------
example.domain.com
------------------------------------------------------------
server {
set $forward_scheme http;
set $server "myApp";
set $port 80;
listen 80; listen [::]:80;
server_name example.domain.com;
Block Exploits
include conf.d/include/block-exploits.conf;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_http_version 1.1;
access_log /data/logs/proxy-host-2_access.log proxy; error_log /data/logs/proxy-host-2_error.log warn;
location / {
# Access Rules
allow 0.0.0.0/8;
allow 192.168.0.0/24; # according to Wikipedia, this should be normally sufficient.
allow 192.168.0.0/16;# extra,
allow 127.0.0.0/8;
allow 172.16.0.0/12;# according to Wikipedia, this should be normally sufficient.
allow 172.19.0.0/16;#extra, the proxy subnet
deny all;
# Access checks must...
satisfy all;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
# Proxy!
include conf.d/include/proxy.conf;
}
Custom
include /data/nginx/custom/server_proxy[.]conf; }
Nginx Proxy Manager Version
I pulled the latest docker image: docker pull jc21/nginx-proxy-manager:latest
Expected behavior
its expected that the page would load without getting 403 ERROR forbidden!!!.
Screenshots
Operating System
Raspbian Os 64x, docker & Portainer.
Additional context
Possible duplicate https://github.com/jc21/nginx-proxy-manager/issues/1279
Possible duplicate #1279 This is kinda the same but differs in one aspect: people in that bug are getting an error message from the npm which tells that the client is in fact connected locally "172.16.20.102" and yet they are not able to access the page!.
In my situation, the NPM gives the following error message and doesn't recognize that the client is connected locally:
2021/09/07 17:03:09 [error] 3626#3626: *5038 access forbidden by rule, client: 95.x.x.x, server: subdomain.mydomain.com, request: "GET / HTTP/1.1", host: "subdomain.mydomain.com"
the 95.x.x.x being the public IP of the router!. So NPM is not recognizing that I'm in the local network!!!!.
I can't add the public IP of my router because it will be dynamically changed by the ISP.
That's how these both issues differ.
Did you find a solution for your "local access" problem? I have a similar problem, NPM is not able to access only the local nework without going through the "outside" internet. Their are some subdomains that would rather keep outside acces. How to solve this?
I struggled with this too, but after thinking about this for a while I'm fairly certain this issue has nothing to do with NPM itself but rather with the router/networking setup.
Basically, the typical setup (as far as I can tell) uses port forwarding configured in one's home router and a DNS entry some domain that uses the router's public IP (e.g. using some dynamic DNS service). As far as I understand in this setup NPM will never be able to receive the local IP address because every connection to NPM resolves to the router's IP which in turn creates a connection to NPM. So it absolutely makes sense to see the router's public IP address in the logs as it's where the connection is originating from NPM's point of view.
To be honest, I think there's nothing NPM can do to fix this. It does exactly what it's made for: configure a NGINX instance as a reverse proxy. But NPM can't configure your local network to route requests directly to itself without going through the router's public IP and port forwarding.
See also: https://github.com/jc21/nginx-proxy-manager/issues/1105#issuecomment-950384265
Unfortunately there is nothing we can do about that. If you look into the access logs of your proxy host found at /data/logs/proxy-host-
_access.log. You will see something like [Client 172.19.0.1] in each of the lines, which shows you what IP nginx has received that request from. If your NPM instance is in the public internet, and not in your local network, local ip adresses are NOT available, and nginx will only receive your routers public ip address from the requesting client.
So, I was trying to figure out the same. I wanted local access to some URLs only.
And indeed, with normal settings this will not work because NPM will always receive the Public IP as the traffic is routed through a DNS thats located outside your network.
However, I just found a way to make it work for me. I am using Adguard as my DNS. Within there, I can specify DNS Rewrites. So adding the URL I want to be only available locally and rewriting this to the IP of NPM makes NPM receive the local IPs asking for access.
This results in the Access List working as intended.
This should work with any locally hosted DNS service that allows you to do custom routes.
So, I was trying to figure out the same. I wanted local access to some URLs only.
And indeed, with normal settings this will not work because NPM will always receive the Public IP as the traffic is routed through a DNS thats located outside your network.
However, I just found a way to make it work for me. I am using Adguard as my DNS. Within there, I can specify DNS Rewrites. So adding the URL I want to be only available locally and rewriting this to the IP of NPM makes NPM receive the local IPs asking for access.
This results in the Access List working as intended.
This should work with any locally hosted DNS service that allows you to do custom routes.
Interesting find! I’m also using Adguard, so could you please explain it a little more in detail how to do it. Could you please give an example how to configure adguard.
Sure thing, its pretty simple.
Put your desired URL, or a wildcard and put it in a DNS rewrite in Adguard. i.e.: *.myddns.duckdns.org and simply rewrite it to the IP where NPM is running in your local network. That should be the same IP that you also forwarded port 80 and 443 in your router. You can find this in Adguard under Filter & DNS Rewrite
@almostserious thanks for sharing I will give it a try!
Unfortunately it isn’t working for me. I have configured exactly as you described, but it isn’t working. Could it be related to the fact that I have setup Adguard with macvlan? I have read that macvlan can’t communicate with the host due some security limitations of Docker.
To provide some feedback for anyone with ability to perform "Host Overrides"
You can assign an access list of just your local subnet as shown...
But you need to be able to adjust your router/firewall DNS settings (in my case using PFSense DNS Resolver, located at the bottom of that page) to override the IP of the DNS Request your trying to make
in this example i have Dynamic DNS setup and a Godaddy Domain name all being pointed back to my home webserver being hosted on Unraid. Some are exposed to the public, others just local subnet. In my example of local only, i just simply created a made up website name (myembyserver.network), and added that to the host override section of PFsense. The name resolves on my local network only, is routed through NPM perfectly.
Issue is now considered stale. If you want to keep it open, please comment :+1: