Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GeoIP module #46

Open
teodorch85 opened this issue Jan 8, 2019 · 106 comments
Open

Add GeoIP module #46

teodorch85 opened this issue Jan 8, 2019 · 106 comments

Comments

@teodorch85
Copy link

Hi! As I am noob with nginx is it possible to enable the GeoIP module so we can limit access also by location?
https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-by-geoip/

Thank you!

@jc21
Copy link
Member

jc21 commented Jan 8, 2019

Sounds doable. Makes sense to include with improvements in #38 as well.

@wuast94
Copy link

wuast94 commented Feb 21, 2019

the geoip module is active by default so no worry. its just a bit of path mapping and edit config files :P

the main problem of geoip module is using legacy geoip databases that are deprecated.
from https://dev.maxmind.com/geoip/legacy/downloadable/
to https://dev.maxmind.com/geoip/geoip2/geolite2/ wich is using
maxmind databases

but the geoip module from nginx is using teh legacy databases. so i dont know if its an issue from nginx itselfs or from npm. it sounds nice to block countries etc but i thing nginx need to fix it first before this feature can addet by devs to the container or am i wrong ?
i wrote more to -> #78

@jc21
Copy link
Member

jc21 commented Feb 25, 2019

Yep I've found the legacy databases are not longer supplied anymore so everyone has to convert to geo2.

Seems it's trivial to add the new module: https://docs.nginx.com/nginx/admin-guide/dynamic-modules/geoip2/

Also the geolite databases need to be baked in to the docker image.

@wuast94
Copy link

wuast94 commented Feb 25, 2019

I think it should be better to make this possible over mounting the nginx dir to host system. So everyone can edit this as wanted (use other modules or databases)

And I think the geo2 module should be addet by nginx docker Mainter. Many modules are installed by defoult: https://github.com/nginxinc/docker-nginx/blob/master/stable/alpine/Dockerfile

@jc21
Copy link
Member

jc21 commented Feb 25, 2019

You can already do that if you want to. In any docker image there is no restriction in what you're mounting and where. Even though I bake in config or files you're always able to override them.

@corvy

This comment has been minimized.

@ghallford
Copy link

This would be awesome because in order to use this

Currently nginx fails with this error when I add the custom log format:

2020/07/09 16:36:21 [emerg] 3022#3022: unknown "geoip2_data_city_name" variable

I need the geoIP information to send to InfluxDB custom format:

log_format custom '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" $host "$http_user_agent" "$request_time" "$upstream_connect_time" "$geoip2_data_city_name" "$geoip2_data_country_code"';

@joggs

This comment has been minimized.

@brokoler

This comment has been minimized.

@risiman

This comment has been minimized.

@andyshutak
Copy link

Likewise this will help massively in reducing attempted logons and bruteforcing on my network. Watching closely.

@Br3b
Copy link

Br3b commented Mar 2, 2021

Hi guys,
this would be great! I was trying to get the geoip module or to at least implement a kind of monitoring possibility for the ngxin proxy manager with telegraf and grafana. But my limited docker knowledge is just not enough.
I would appreciate if this feature would be available out of the box :)
Stay healthy!

@rh535

This comment has been minimized.

@danner26
Copy link

@jc21 any update? I would be happy to help develop on this if y'all need an extra hand in order to get it included.

@mgutt

This comment has been minimized.

@phrogg
Copy link

phrogg commented Apr 26, 2021

Is there any way, to do this without it implemented? If I can set it up manually I may be able to make an PR out of it.

@mouseron
Copy link

Checking in to see if how this is going. @jc21 is there any update please. It would be great to have this implemented please and thank you!

@jc21
Copy link
Member

jc21 commented Jul 20, 2021

See #1202

@mouseron
Copy link

See #1202

Thanks and it's great to see there will be a V3! I wasn't aware.

It's not clear not me whether GeoIP2 will be part of this new version though... The closest statement I could find was "UI Configurable IP ranges for real_ip determination"

Will GeoIP2 be incorporated?

Thanks again!

@Pacerino
Copy link

@mouseron
Take a look at https://github.com/sherpya/geolite2legacy
and
https://www.miyuru.lk/geoiplegacy

@Pacerino
Copy link

the geoip module is active by default so no worry. its just a bit of path mapping and edit config files :P

the main problem of geoip module is using legacy geoip databases that are deprecated.
from https://dev.maxmind.com/geoip/legacy/downloadable/
to https://dev.maxmind.com/geoip/geoip2/geolite2/ wich is using
maxmind databases

but the geoip module from nginx is using teh legacy databases. so i dont know if its an issue from nginx itselfs or from npm. it sounds nice to block countries etc but i thing nginx need to fix it first before this feature can addet by devs to the container or am i wrong ?
i wrote more to -> #78

Hey @wuast94 i was wondering how the geoip module is active by default when the openresty doesnt get compiled with the flag to enable the geoip module? It would be nice if you could explain in detail how you managed it. The anweres you've made arent detailed.

@jc21
Copy link
Member

jc21 commented Sep 13, 2021

@ghost
Copy link

ghost commented Oct 28, 2021

Here some useful material to compile geoip2 in openresty
https://www.electrosoftcloud.com/en/compile-geoip2-in-openresty-and-how-to-use-it/

@OuticNZ
Copy link

OuticNZ commented Oct 31, 2021

Did this get progressed any? Or is it waiting for someone to pick it up?

@chaptergy
Copy link
Collaborator

No, I don't think there is any progress, and I don't think there will come an official integration in v2 of npm, unless someone wants to get working on it and creates a PR.

@Pacerino
Copy link

I've actually made my own custom version of it with geoIP in order to use it with loki and grafana.
https://github.com/Pacerino/docker-nginx-full
https://github.com/Pacerino/nginx-proxy-manager

The only think is that i've ported the CI to Drone. There is an error appearing if creating the container about missing deps. I've temporary fixed it by installing libgeoip1_1.6 manually with DPKG

wget http://ftp.de.debian.org/debian/pool/main/g/geoip/libgeoip1_1.6.12-7_amd64.deb
dpkg -i libgeoip1_1.6.12-7_amd64.deb

After a reboot of the container everything works.

This is a quick and dirty implementation of it and not the latest release the main repo. The Frontend is missing the Logo but everything works. I should merge into the latest release and trying to get rid of the missing dep and the logo.

@firebowl
Copy link

firebowl commented Jan 1, 2022

Does anyone care about a geoip2 implementation? It would be a real pity if you have to give up the security of geoip2 for the really great and convenient variant of NPM.

@maboxx
Copy link

maboxx commented Jun 7, 2024

Thank you for the link but
But I just don't think I understand it completely, I'm so sorry. The link only concerns me from the point "nginx-Konfiguration für GeoIP2" Because the geoip module is already integrated in NPM, isn't it?

@nbently
Copy link

nbently commented Jun 7, 2024

@maboxx you might want to check to make sure your log_format configuration only includes variables present in the file you downloaded. I haven't tested this on the Country db, but theoretically it should still work, and it does seem like others have gotten it to work. FWIW the City db includes everything in the Country db but not the other way around. https://dev.maxmind.com/geoip/docs/databases/city-and-country#locations-files

Make sure your bind mounts are correct as well (e.g. the file on the host system is where you say it is).

I would suggest trying with my exact configuration first to see if that works and then tweaking it from there.

@maboxx
Copy link

maboxx commented Jun 8, 2024

@nbently
I do it now exactly like you:

[root@docker-a256c6b611ca:/app]# ls -ltr /data/
total 516
-rw-r--r-- 1 root root   2190 Feb  9 20:30 keys.json
drwxr-xr-x 1 root root     22 Feb 15 10:04 letsencrypt-acme-challenge
drwxr-xr-x 1 root root    136 Feb 15 10:04 nginx
drwxr-xr-x 1 root root      0 Feb 18 22:31 access
drwxr-xr-x 1 root root    120 Feb 24 15:23 custom_ssl
-rw-r--r-- 1 root root 524288 Jun  2 07:19 database.sqlite
drwxr-xr-x 1 root root  12584 Jun  2 07:19 logs
drwxr-x--- 1 root root     60 Jun  8 07:28 custom
drwxr-x--- 1 root root     78 Jun  8 07:33 geoip2db

[root@docker-a256c6b611ca:/app]# ls -ltr /data/custom/
total 8
-rw-r----- 1 root root  39 May 29 07:26 server_proxy.conf
-rw-r----- 1 root root 437 Jun  8 07:23 http_top.conf

[root@docker-a256c6b611ca:/app]# ls -ltr /data/geoip2db/
total 55284
-rw-r----- 1 root root 50097859 Jun  7 15:49 GeoLite2-City.mmdb

[root@docker-a256c6b611ca:/app]# cat /data/custom/server_proxy.conf 
access_log /data/logs/geoip.log geoip;

[root@docker-a256c6b611ca:/app]# cat /data/custom/http_top.conf    
geoip2 /data/geoip2db/GeoLite2-City.mmdb {
auto_reload 5m;
$geoip2_data_country_iso_code country iso_code;
$geoip2_data_city_name city names en;
}

log_format geoip '$remote_addr - $remote_user [$time_local]'
           '"$request" $status $body_bytes_sent'
           '"$http_referer" $host "$http_user_agent"'
           '"$request_time" "$upstream_connect_time"'
           '"$geoip2_data_city_name" "$geoip2_data_country_iso_code"';

[root@docker-a256c6b611ca:/app]# ls -ltr /data/geoip2db/           
total 55284
-rw-r----- 1 root root 50097859 Jun  7 15:49 GeoLite2-City.mmdb

[root@docker-a256c6b611ca:/app]# cat /etc/nginx/modules/enable_ngx_http_geoip2_module.conf 
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;

I have now started Docker. How can I now check whether the module is loaded or working?

@nbently
Copy link

nbently commented Jun 8, 2024

@maboxx if you're in the container you should now see a new log in /data/logs called geoip.log. That file will contain all of the new log data with the location data in each line. Make sure you have at least one proxy host set up and configured as well (otherwise there won't be any logs).

@maboxx
Copy link

maboxx commented Jun 8, 2024

@nbently

I am sad, there is no log :-(

[root@docker-a256c6b611ca:/data/logs]# ls -ltr geoip.log
ls: cannot access 'geoip.log': No such file or directory
[root@docker-a256c6b611ca:/data/logs]# 

I don't understand it. I do exactly what you do.

@cruunnerr
Copy link

cruunnerr commented Jun 10, 2024

@maboxx

I don't have much time at the moment. Will try to make you a noob-friendly HowTo till the weekend.

Just notice: I have my NPM docker folder in my home directory.

Basically I installed GeoIP like here: https://dev.maxmind.com/geoip/updating-databases

sudo add-apt-repository ppa:maxmind/ppa
sudo apt update
sudo apt install geoipupdate

I changed the DatabaseDirectory in /etc/GeoIP.conf:
DatabaseDirectory /home/USER/NPM_DOCKER_FOLDER/GeoIP
Also you need to insert your account-details here.

First try to download database:
sudo geoipupdate
should create you the database files in the /home/USER/NPM_DOCKER_FOLDER/GeoIP

Then created a crontab for updating database.

sudo crontab -e
content:

# m h  dom mon dow   command
14 21 * * * geoipupdate

Then I created the files

NPM_DOCKER_FOLDER/modules/enable_ngx_http_geoip2_module.conf
NPM_DOCKER_FOLDER/data/nginx/custom/http_top.conf
NPM_DOCKER_FOLDER/data/nginx/custom/server_proxy.conf

My files look like this:

enable_ngx_http_geoip2_module.conf:
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;

http_top.conf:

geoip2 /data/geoip2db/GeoLite2-Country.mmdb {
auto_reload 5m;
$geoip2_data_country_iso_code country iso_code;
}

map $geoip2_data_country_iso_code $allowed_country {
    default no;
    10.0.0.0/8 yes;
    192.168.0.0/16 yes;
    DE yes;

}

log_format geoip '$remote_addr - $remote_user [$time_local]'
           '"$request" $status $body_bytes_sent'
           '"$http_referer" $host "$http_user_agent"'
           '"$request_time" "$upstream_connect_time"'
           '"$geoip2_data_country_iso_code" "$allowed_country"';
           #'"$geoip2_data_city_name" "$geoip2_data_country_iso_code"';

server_proxy.conf:

if ($allowed_country = no) {
        return 444;
}
access_log /data/logs/geoip.log geoip;

Then I added the volume mounts to the docker-compose.yml:

version: "3"
services:
  app:
    image: jc21/nginx-proxy-manager:latest
    restart: always
    ports:
      - 80:80
      - 81:81
      - 443:443
    volumes:
      - ./config.json:/app/config/production.json
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - ./modules:/etc/nginx/modules
      - ./GeoIP:/data/geoip2db
    depends_on:
      - db
    environment:
    # if you want pretty colors in your docker logs:
    - FORCE_COLOR=1
  db:
    image: mariadb:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "_PRIVATE_"
      MYSQL_DATABASE: "_PRIVATE_"
      MYSQL_USER: "_PRIVATE_"
      MYSQL_PASSWORD: "_PRIVATE_"
    volumes:
      - ./data/mysql:/var/lib/mysql

start the container:

sudo docker-compose up -d

Notice that I added the

if ($allowed_country = no) {
        return 444;
}

part inside the server_proxy.conf, since I couldn't get it worked with adding these lines in the webUI. But it worked pretty well. I tested accessing my proxy hosts via VPN from different countries, and only Germany got a response. :)

@maboxx
Copy link

maboxx commented Jun 11, 2024

Thank you very much @cruunnerr @nbently @phyte22 for your patience and effort, I will check again point by point as soon as I have time.

@cruunnerr
Copy link

Thank you very much @cruunnerr @nbently @phyte22 for your patience and effort, I will check again point by point as soon as I have time.

You're very welcome. Please keep in mind, that GeoIP-Blocking is a nice thing to have, but doesn't free your server from getting attacked.
It is good for blocking bots and crawlers and surely prevents your proxy hosts from being inspected from several countries. But attackers often use bot nets and have several bots in different countries. So it kind of protects you from getting attacked from "everywhere".
But I would definitely recommend you to also install crowdsec (or at least fail2ban) on your bare NPM-Server. Since crowdsec detects basically even before the packets reaches your NPM-Docker instance and can effectively protect against many kinds of attacks on vulnerabilities or exploits. Just imagine NPM or your OS has a vulnerability which can be attacked even before packets reach your Hosts or your NPM Docker instance.
For example my crowdsec instance detected around 25 scenarios and blocked the IP's, just for today! For the hole June I have actually 473 blocked scenarios (85 of them from Germany, which even wouldn't have been blocked via GeoIP).

Just think about it ;)

@nbently
Copy link

nbently commented Jun 11, 2024

@maboxx can you show us where you have the bind mounts configured?

@maboxx
Copy link

maboxx commented Jun 12, 2024

I probably won't have time to go through the whole thing again until the weekend.
@cruunnerr
Thank you very much for the tips.
My constellation is such that my NPM runs on a virtual machine with hardened archlinux. Docker runs rootless there. NPM is my entrance to the network and then forwards to another virtual machine with my Nextcloud. This VM is also hardened and fail2ban is also running there. I may still have to take care of fail2ban on my NPM VM.

@nbently
I don't quite understand what you mean because my mounts work otherwise I couldn't access them from inside the container? Here is my stack that I deploy via Portainer.

version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy
    restart: always
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
      - '993:993'
      #- '587:587'
    volumes:
      - nginx-proxy-data:/data
      - nginx-proxy-letsencrypt:/etc/letsencrypt
      - nginx-proxy-modules:/etc/nginx/modules

volumes:
  nginx-proxy-data:
    name: nginx-proxy-data
  nginx-proxy-letsencrypt:
    name: nginx-proxy-letsencrpyt
  nginx-proxy-modules:
    name: nginx-proxy-modules

@nbently
Copy link

nbently commented Jun 14, 2024

@maboxx that's what I was wondering, I see you're using volumes and not bind mounts. Theoretically that should work no problem but I bet that's where the issue is. Probably something permission related if I had to guess.

What happens if you create the geoip.log file manually (just an empty file)? I'd also check to make sure all the files you created have the same permissions as everything else & that the user running nginx has access to them.

@maboxx
Copy link

maboxx commented Jun 15, 2024

Ok but when I compare the permissions from my files with the permissions of your file which seen above in your thread they are the same. What can be different between using bind mounts or volumes? What is exactly the difference and how can I set bind mounts?
I think another difference to your configuration is that my docker runs "rootless" but this should normally also not a problem....
I created the geoip.log manually. After restart and one day after now the .log have 0 bytes.
Maybe I just clone my VM and install NPM exactly like you did without rootless to see if it works? It remains strange. I don't think anything is configured wrong. Rootless and no bind mount should not be a problem.

@cruunnerr
Little digression about crowdsec. I would like to install crowdsec to secure NPM (docker). How exactly did you install and configure it? Do you have any links? Did you also install crowdsec as a docker or directly on the machine? How do I connect Crowdsec to the NPM Docker so that it secures NPM? Ideally, I would also like to completely back up the local machine at the same time, not just NPM?

@XDark187
Copy link

Have a look at bunkerweb. Has geoblock included and other waf rules.

Great Alternative.

@maboxx
Copy link

maboxx commented Aug 23, 2024

@XDark187 Thanks for the tip. I still have no idea what exactly Bunkerweb is. I have heard of it but despite research I don't understand it exactly. Bunkweb is probably much more than "just" a proxy manager.

@XDark187
Copy link

@XDark187 Thanks for the tip. I still have no idea what exactly Bunkerweb is. I have heard of it but despite research I don't understand it exactly. Bunkweb is probably much more than "just" a proxy manager.

Bunkerweb is a reverse proxy but with a lot of security features to protect your services by default, one of these security features is geoIP blocking and stopping brute force attacks and stopping bots, all security features are just toggles that you can enable or disable if you don't need them.

NPM requires so much work just to enable geoip blocking.

NPM is easier but less secure and bunkerweb is more secure but requires a bit of time to get it fully setup. IMO it's 100% worth it.

If you don't want to bother with NPM or Bunkerweb the easiest way is to use geoIP blocking with Cloudflare.

@webysther
Copy link

webysther commented Oct 9, 2024

I think this issue is fixed on #3766: https://nginxproxymanager.com/advanced-config/#enabling-the-geoip2-module:

To enable the geoip2 module, you can create the custom configuration file /data/nginx/custom/root_top.conf and include the following snippet:

load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;

I have tested and is working rock solid.

@maboxx
Copy link

maboxx commented Oct 9, 2024

Many thanks for the tip. Does this need to be configured in addition to the things above or instead?

@webysther
Copy link

Many thanks for the tip. Does this need to be configured in addition to the things above or instead?

Add also the database of geoip /data/GeoLite2-Country.mmdb on http_top.conf:

geoip2 /data/GeoLite2-Country.mmdb {
    $geoip2_data_country_iso_code country iso_code;
}

After you can create map on server block:

map $geoip2_data_country_iso_code $allowed_countries {
  default 0;
  BE 1;
  CA 1;
  AR 1;
  FI 1;
  NL 1;
  PT 1;
  US 1;
  DE 1;
}

map $geoip2_data_country_iso_code $allowed_brazil {
  default 0;
  BR 1;
}

map $geoip2_data_country_iso_code $allowed_italy {
  default 0;
  IT 1;
}

@webysther
Copy link

webysther commented Oct 11, 2024

Thank you very much @cruunnerr @nbently @phyte22 for your patience and effort, I will check again point by point as soon as I have time.

You're very welcome. Please keep in mind, that GeoIP-Blocking is a nice thing to have, but doesn't free your server from getting attacked. It is good for blocking bots and crawlers and surely prevents your proxy hosts from being inspected from several countries. But attackers often use bot nets and have several bots in different countries. So it kind of protects you from getting attacked from "everywhere". But I would definitely recommend you to also install crowdsec (or at least fail2ban) on your bare NPM-Server. Since crowdsec detects basically even before the packets reaches your NPM-Docker instance and can effectively protect against many kinds of attacks on vulnerabilities or exploits. Just imagine NPM or your OS has a vulnerability which can be attacked even before packets reach your Hosts or your NPM Docker instance. For example my crowdsec instance detected around 25 scenarios and blocked the IP's, just for today! For the hole June I have actually 473 blocked scenarios (85 of them from Germany, which even wouldn't have been blocked via GeoIP).

Just think about it ;)

Good point, just to add some on this. The main point of using geoip is about reduce the attack surface. The big takes about security is more about this:

  • Keep a SYN-flood (DoS) protection on router
  • Block on firewall of router or before any reverse proxy the bogons and firehol level 1
  • If there no host with worldwide need, keep the geoip in firewall and not in reverse proxy
  • Any exposed host keep exploit protection and SSO like authelia
  • Never use DMZ, block all and enable by need in firewall

Never keep just one layer of security.

@maboxx
Copy link

maboxx commented Oct 12, 2024

Thank you very much for all the information. I haven't had time yet, but I'm going to try the topic again soon and hopefully I'll get it right and working.

@tanmaychimurkar
Copy link

Hi there, i also tried the comment as per @phyte22 here #46 (comment) , and setup everything according to the same volume mounts.

The geoip.log file appears, and it shows the correct iso country code and whether or not it is allowed. The only issue i have is when I put the following in the advanced configuration of the proxy_host:

if ($allowed_countries = 0) {
        return 444; 
}

My proxy host goes offline. Moreover, the logs from the npm container show the following:

[10/15/2024] [3:52:59 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:52:59 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:52:59 PM] [Nginx    ] › ℹ  info      Reloading Nginx
[10/15/2024] [3:52:59 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -s reload
[10/15/2024] [3:53:56 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Deleting file: /data/nginx/proxy_host/8.conf
[10/15/2024] [3:53:57 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Deleting file: /data/nginx/proxy_host/8.conf
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Deleting file: /data/nginx/proxy_host/8.conf.err
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Could not delete file: {
  "errno": -2,
  "code": "ENOENT",
  "syscall": "unlink",
  "path": "/data/nginx/proxy_host/8.conf.err"
}
[10/15/2024] [3:53:57 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:53:57 PM] [Nginx    ] › ℹ  info      Reloading Nginx
[10/15/2024] [3:53:57 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -s reload

(the last logs, where 8.conf.err is being deleted is after updating the server block in the Advanced tab of proxy_host)

When I then go to /data/nginx/proxy_host on my local machine, the 8.conf proxy_host file itself is gone. When I revert the changes in the Advanced block, the 8.conf proxy_host file comes back.

The fallback_error.log shows the followign:

2024/10/15 15:56:17 [error] 234#234: *1055 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 127.0.0.1, server: localhost-nginx-proxy-manager, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:80/favicon.ico", host: "xxx.xxx.xxx.xxx"

The proxy-host-8_error.log shows nothing to point me in the right direction. Anyone know how to resolve this?

@webysther
Copy link

webysther commented Oct 15, 2024

Hi there, i also tried the comment as per @phyte22 here #46 (comment) , and setup everything according to the same volume mounts.

The geoip.log file appears, and it shows the correct iso country code and whether or not it is allowed. The only issue i have is when I put the following in the advanced configuration of the proxy_host:

if ($allowed_countries = 0) {
        return 444; 
}

My proxy host goes offline. Moreover, the logs from the npm container show the following:

[10/15/2024] [3:52:59 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:52:59 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:52:59 PM] [Nginx    ] › ℹ  info      Reloading Nginx
[10/15/2024] [3:52:59 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -s reload
[10/15/2024] [3:53:56 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Deleting file: /data/nginx/proxy_host/8.conf
[10/15/2024] [3:53:57 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Deleting file: /data/nginx/proxy_host/8.conf
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Deleting file: /data/nginx/proxy_host/8.conf.err
[10/15/2024] [3:53:57 PM] [Nginx    ] › ⬤  debug     Could not delete file: {
  "errno": -2,
  "code": "ENOENT",
  "syscall": "unlink",
  "path": "/data/nginx/proxy_host/8.conf.err"
}
[10/15/2024] [3:53:57 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -t -g "error_log off;"
[10/15/2024] [3:53:57 PM] [Nginx    ] › ℹ  info      Reloading Nginx
[10/15/2024] [3:53:57 PM] [Global   ] › ⬤  debug     CMD: /usr/sbin/nginx -s reload

(the last logs, where 8.conf.err is being deleted is after updating the server block in the Advanced tab of proxy_host)

When I then go to /data/nginx/proxy_host on my local machine, the 8.conf proxy_host file itself is gone. When I revert the changes in the Advanced block, the 8.conf proxy_host file comes back.

The fallback_error.log shows the followign:

2024/10/15 15:56:17 [error] 234#234: *1055 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 127.0.0.1, server: localhost-nginx-proxy-manager, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:80/favicon.ico", host: "xxx.xxx.xxx.xxx"

The proxy-host-8_error.log shows nothing to point me in the right direction. Anyone know how to resolve this?

You have created in some how a loop condition that make you network going in a block state and reset. Check if you error page have a location that check again against the geoip or if there a loopback in somewhere. To help fix this, isolate and enable one host at time.

@gioman
Copy link

gioman commented Nov 26, 2024

load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;

After some trial and error I have been able to make geoip working for proxy hosts. Anyway the fact that docs say that there is also this module

load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so

seems to suggest that this approach can also be used for streams (am I wrong?). Anyway I'm struggling because in streams conf files generated by NPM, if something like

if ($allowed_countries = 0) {
        return 444; 
}

is added then an error like

nginx: [emerg] "if" directive is not allowed here in /data/nginx/stream/14.conf:11

is returned. If conditionals/if cannot be used there, how the same as proxy hosts can be achieved?

Thanks in advance

@gioman
Copy link

gioman commented Nov 30, 2024

Thanks in advance

I did not find a solution within NPM, but I possibly found one that seems to work and that must be applied on the host. I'm not by any mean an expert of NPM and UFW/IPTABLE, so please be kind if the following has something that is wrong. Suggestions and corrections are welcome.

First I installed the geoip module on the host, I used this guide https://www.seenlyst.com/blog/geo-blocking-ufw-iptables/ which I followed with success in other cases not involving NPM.

Then I also installed ufw-docker https://github.com/chaifeng/ufw-docker so to be able to define firewall rules on the host that also apply to the NPM container.

Then:

start UFW on the host, be careful to add a rule beforehand that will not cut you off from SSH, something like

ufw allow 22
ufw enable

Then

ufw-docker allow npm-app-1 443

this allows httpS traffic for the proxy hosts. Then:

sudo iptables -A ufw-user-forward -p tcp -m geoip --src-cc IT --dport 1234 -j ACCEPT

to allow (or deny, if you use "DROP" instead of "ACCEPT") IPs from a whatever country code to reach your stream port.

This rule is not persistent to reboots (and probably also UFW restarts/reloads(, I'm not sure what is the best way to make it persistent but for now I'm happy applying it with a script after the host reboot.

I have also added NPM as a proxy host in itself, so to be able reach it with its domain I had to add this rules too:

ufw-docker allow npm-app-1 81
sudo ufw allow from 172.18.0.0/16 to 65.21.179.35 port 81
sudo ufw allow from 172.18.0.0/16 to 65.21.179.35 port 443

The first one is necessary also to allow reach the NPM GUI with the host IP on port 81.

@Vaalus
Copy link

Vaalus commented Jan 8, 2025

@cruunnerr's comment.

I just logged in to say thank you! I tried your config and it immediately worked. Really appreciate it :)

EDIT: Just wanted to mention something, I couldn't access my site because I'm in the same Lan network. Had to modify the config files this way to get it to work:

http_top.conf

geoip2 /data/geoip2db/GeoLite2-Country.mmdb {
auto_reload 5m;
$geoip2_data_country_iso_code country iso_code;
}

map $geoip2_data_country_iso_code $allowed_country {
    default no;
    DE yes;
#^ Germany example.

}

# Define private IP ranges (LAN IPs)
geo $lan-ip {
    default no;
    10.0.0.0/8 yes;
    172.16.0.0/12 yes;
    192.168.0.0/16 yes;
    127.0.0.1 yes;
}

log_format geoip '$remote_addr - $remote_user [$time_local]'
           '"$request" $status $body_bytes_sent'
           '"$http_referer" $host "$http_user_agent"'
           '"$request_time" "$upstream_connect_time"'
           '"$geoip2_data_country_iso_code" "$allowed_country"';
           #'"$geoip2_data_city_name" "$geoip2_data_country_iso_code"';

server_proxy.conf

if ($lan-ip = yes) { set $allowed_country yes; }
if ($allowed_country = no) { return 444; }

access_log /data/logs/geoip.log geoip;

@webysther
Copy link

webysther commented Jan 8, 2025

@jc21 this is not fixed with https://nginxproxymanager.com/advanced-config/#enabling-the-geoip2-module ? @teodorch85 i think you can close I change to use the geoip and works perfect

@mauroreggio
Copy link

mauroreggio commented Jan 17, 2025

@jc21 this is not fixed with https://nginxproxymanager.com/advanced-config/#enabling-the-geoip2-module ? @teodorch85 i think you can close I change to use the geoip and works perfect

I webysther. Sorry for my question.
I follow the link and i simply read to add 2 line in a new config file. I start NPM and no error appears.
But ... how i can use geoip2 module?
Nothing in webconfig interface.
Nothing new in log.
Where i can work for put geoip2 module usage config? (i'm intrested in deny some location access and log IP access location).
Search many for example but not find nothing.
Thanks.

@webysther
Copy link

@jc21 this is not fixed with https://nginxproxymanager.com/advanced-config/#enabling-the-geoip2-module ? @teodorch85 i think you can close I change to use the geoip and works perfect

I webysther. Sorry for my question. I follow the link and i simply read to add 2 line in a new config file. I start NPM and no error appears. But ... how i can use geoip2 module? Nothing in webconfig interface. Nothing new in log. Where i can work for put geoip2 module usage config? (i'm intrested in deny some location access and log IP access location). Search many for example but not find nothing. Thanks.

Please read the comments here, there few examples like @Vaalus next my last comment.

@mauroreggio
Copy link

mauroreggio commented Jan 17, 2025

@jc21 this is not fixed with https://nginxproxymanager.com/advanced-config/#enabling-the-geoip2-module ? @teodorch85 i think you can close I change to use the geoip and works perfect

I webysther. Sorry for my question. I follow the link and i simply read to add 2 line in a new config file. I start NPM and no error appears. But ... how i can use geoip2 module? Nothing in webconfig interface. Nothing new in log. Where i can work for put geoip2 module usage config? (i'm intrested in deny some location access and log IP access location). Search many for example but not find nothing. Thanks.

Please read the comments here, there few examples like @Vaalus next my last comment.

I just work now on it ... and sorry because i not watch good before.
I try but in the "start container log" seems that NGPM not find the database

nginxpm-1 | ❯ Starting nginx ... nginxpm-1 | nginx: [emerg] MMDB_open("/data/geoip2db/GeoLite2-Country.mmdb") failed - Error opening the specified MaxMind DB file in /data/nginx/custom/http_top.conf:1

I think is because the first line of http_top.conf

geoip2 /data/geoip2db/GeoLite2-Country.mmdb {

but where is the database of geoip2 with this config?

@mauroreggio
Copy link

mauroreggio commented Jan 17, 2025

I think i understand something (let me know if is true).

  • GeoIP database must be download, update, maintained "out of NGPM container"
  • For this is necessary register an account in Maxmind and use all the tools that Maxmind makes available for this purpose.
    This is first step.
    Once i've obtained my database fresh copy (GeoLite2-Country.mmdb) i can succesfully run NGPM container with no errors and with http_top.conf added Custom Config File

geoip2 /data/GeoLite2-Country.mmdb {
    $geoip2_data_country_iso_code country iso_code;
}

Now i'm stuck in the next step that i read more up in #46 (comment)

After you can create map on server block:

map $geoip2_data_country_iso_code $allowed_italy {
  default 0;
  IT 1;
}

... where i must put this?
I try add in "Advanced" tab of my "Edit - Proxy Host" page of the webconfig page ... but this put the Proxy Host in error.

Image

EDIT: i add the block in http_top.conf
This works good and log all access in /data/logs/geoip.log
But in this way is for ALL "Proxy Hosts" that NGPM serve.
Is possible via web interface have the same result but maybe different settings for any "Proxy Host"? (maybe using the "Advanced" tab that i show in the image before?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests