BillGoats

joined 1 year ago
[–] BillGoats@alien.top 1 points 11 months ago

Thanks. For one-off regex patterns I tend to just google examples and pick one from StackOverflow, lol. But you're right, it's not the best option!

 

Background

I've made a lot of changes to my setup recently, and one that made something like this necessary. Specifically, I'm now self-hosting DNS (using Technitium). In it, I've created a zone for my domain (e.g. example.com) with an A record for subdomains (*.example.com) pointing to the local IP of my server. This does 2 pretty cool things. 1) When I'm at home, requests to my public subdomains goes directly to my server instead of via CloudFlare. 2) I can set up subdomains with SSL that are only available from my home network (using access lists in NPM).

Problem

In NPM, the access list for local access includes my local subnet. That works - but when I'm connected to my local network via WireGuard (FireZone), the IP that is seen by the services I connect to is my public IP. This changes quite a lot, and my ISP doesn't offer static IPs for private users.

Research

I started looking into how to make add dynamic IPs to NPM access lists. I came across a couple of GitHub issues (1, 2) on the topic. It looks like people have solved the problem, but not in a complete way without modifying the NPM docker image. I did not want to do that, so decided looking into writing a separate script.

Solution

What I ended up with is available in this gist. Usage:

update-public-ip-acl.sh -i 1 -p /home/BillGoats/docker/npm/data -d npm-app

The -p parameter points to NPMs database (database.sqlite). The -i is the ID of the database entry you want to change, and -d is the name of the NPM docker container. The script assumes that you have already added an entry that you want to maintain. I guess one could make the script smarter, but I found that easiest to implement.

So, to get started: Add your current public IP (or some random IP if you want to verify that this works) to an ACL. Then, to get the ID of this entry, execute:

sudo sqlite3 "/path/to/database.sqlite" "select id from access_list_client where address = '';"

This should output the ID you need to execute the script.

What the script actually does is the following:

  1. Check currently configured IP.
  2. Check current public IP.
  • If they are the same, exit with code 0.
  • If they are not the same, proceed.
  1. Replace the old IP with the new one in the NPM database.
  2. Replace the old IP wth the new one in /data/nginx/proxy_host/.conf.
  3. Execute nginx -s reload in the NPM container.

Conclusions

During testing, this seems to have worked fine. I did notice however that if I modified the access list manually, the ID of the underlying entry disappeared from the database and was replaced by a new row.

There's probably room for improvement in general. Suggestions are highly welcome. Hopefully this is enough to get others in the same boat a little further.

Edit: Forgot to mention that the idea is to run this on a cron schedule (say every 5 minutes).

 

Background

I recently made an effort to harden my network due to (technically) exposing more of it with FireZone (WireGuard). For the curious, I shared some details in a recent comment. I didn't mention it in the comment, but I also set up local DNS (Technitium) with block lists.

I'm approaching a point where I'm comfortable with my setup security-wise, but I'm missing a couple of things still: A solid firewall and proper backups. In this post, I'm interested in discussing the former.

NPM serves as the primary entrypoint into my server. For a while I considered looking into putting fail2ban in front of it, but then I came across CrowdSec which seems like a superior solution. And so I started looking into how to implement it alongside NPM.

There's an official guide, but it relies on a fork of a fork (Docker Hub) of NPM, which seems unsustainable. I also found this guide in a reddit post, which relies on a fork of the official image. However, it looks like the image is no longer hosted on Docker Hub.

Here is the (NPM) GitHub issue where the "fork of a fork" image came into existence (lepresidente/nginx-proxy-manager). It has some interesting discussions about the challenges of having NPM and CrowdSec coexist and cooperate.

tl;dr

I can't find any documentet, successful attempt at having CrowdSec function in front of Nginx Proxy Manager. The solutions that are publicly documentet, even officially by CrowdSec, rely on forks of NPM.


Conclusions

I feel like it should be possible to have the two services work together with the official images. Probably with a relatively complex setup. If anyone has made this work somehow, I'd be very happy to look at your docker-compose files.

Thanks for reading.