this post was submitted on 20 Nov 2023
3 points (100.0% liked)

Self-Hosted Main

502 readers
1 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

For Example

We welcome posts that include suggestions for good self-hosted alternatives to popular online services, how they are better, or how they give back control of your data. Also include hints and tips for less technical readers.

Useful Lists

founded 1 year ago
MODERATORS
 

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).

you are viewing a single comment's thread
view the rest of the comments
[–] BillGoats@alien.top 1 points 10 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!