what's the simple way to map services to subdomains instead of specifying the port number?
from laserjet@lemmy.dbzer0.com to selfhosted@lemmy.world on 12 Jul 00:17
https://lemmy.dbzer0.com/post/72123752

I have a bunch of services running on my LAN, mostly from a single Debian machine. I access them at URLs like devicename.lan:portnumber. I would like to change to servicename.devicename.lan.

How it works now: The router (openwrt) sets a static IP per device and the port number is selected by the application or system unit running it.

What is the absolute simplest way to accomplish this? I don’t mind if it is managed by the router or by the server machine itself. Hoping for something that can be configured with a text file or web interface or other basic mathod.

These sevices are private, just for me and I have no plans to ever access them externally. I have so far avoided any certificates or SSL or other stuff. I don’t use docker and would rather not get into it right now. I like my domain name setup how it is with fake local domains.

Hoping this could be possible without making a whole project out of it.

#selfhosted

threaded - newest

algernon@lemmy.ml on 12 Jul 00:22 next collapse

If all your services support binding to a unix socket, I’d bind them to /run/<servicename>.sock or similar, and set up a reverse proxy that hits /run/$servicename.sock when serving $servicename.devicename.lan. If the service can’t bind to a unix socket, you can probably socat it or similar, and keep using the generic reverse proxy. Then, all your router has to do is route port 80 to your Debian machine.

laserjet@lemmy.dbzer0.com on 12 Jul 03:27 collapse

If all your services support binding to a unix socket

how do I know?

algernon@lemmy.ml on 12 Jul 07:20 collapse

Check their docs, mostly.

moonpiedumplings@programming.dev on 12 Jul 00:23 next collapse

You want a reverse proxy. A reverse proxy reads requests to subdomains and then forwards them to ports and back.

The easiest GUI one is: nginxproxymanager.com

But there is also just straight nginx, or you can use Caddy or traefik or anything else.

BingBong@sh.itjust.works on 12 Jul 03:26 next collapse

This is what I do. There is actually an nginx proxy manager plugin for home assistant that I used and helped make it really trivial.

myrmidex@belgae.social on 12 Jul 06:42 collapse

One benefit of Caddy over NPM: local certificates.

The latest selfh.st newsletter linked to a relevant video:

www.youtube.com/watch?v=EVnwnFY7C1w&ref=selfh.st

moonpiedumplings@programming.dev on 12 Jul 16:20 collapse

You can use local certs with nginx proxy manager as well. You can upload certs via the web ui.

Rather than local certs though, I would recommend buying a domain and using it locally, with https. The problem with the local cert approach outlined in the video, is that importing a root cert opens up a big security hole to MITM attacks. If an attacker gets the root certificate, they can now MITM everything else your browser is accessing. You turn the browser from one of the most secure components of a modern OS, into only as secure as the server hosting the root certificates.

The approach I would prefer, is to buy a domain, and use it locally, using DNS-01 challenges to get letsencrypt signed certificates even from within an internal network. Both Caddy and NPM have support for DNS-01 challenges.

CameronDev@programming.dev on 12 Jul 00:23 next collapse

Nginx proxy manager is the easy way. Spin it up and the UI is fairly straight forward. You can also achieve the same thing with nginx or caddy, but you’ll have to set up the configs by hand.

nginxproxymanager.com

litchralee@sh.itjust.works on 12 Jul 00:51 next collapse

What is the absolute simplest way to accomplish this?

< gets on soap box>

The absolute simplest way is to use IPv6: on your Debian machine, assign multiple IPv6 addresses, one for each service you want to expose to your LAN. There’s no penalty with having a dozen v6 addresses.

Although you have those addresses, your machine generally uses just a single one for its own outbound and inbound traffic. For each service, you would edit their config so that they bind to a specific IPv6 address. Finally, you would configure an AAAA entry in DNS so that your chosen subdomain will point to the IPv6 address in question.

As an example, suppose you had three different web servers running Nginx, currently on port 80, 8081, and 42069. What you would change is the server config for each server instance, adidng the IPv6 address as part of the “listen” directive. Since each instance is now bound to a different IP address, nginx can now listen to the conventional port 80 and n’ary will the three collide. In other software, the configuration option you’re looking for is the “bind address”. By binding each app to its own IP, it will only respond if you send a request to that IP (or DNS name, which translates to an IP); this conveniently makes debugging really easy.

For a home network, you might have a single /64 IPv6 subnet. But that still means you literally have billions upon billions of addresses to use before you ever run out. And as you’ve recognized, using DNS names to identify services is a lot easier and intuitive than using port numbers. It also neatly avoids the need to memorize IPv6 addresses, because that’s never been necessary: we have DNS.

If your ISP won’t give you IPv6, you can still use locally-assigned private ranges, known as ULA, and this works because your services are contained to your LAN. Best practice is to randomly generate a subnet then use it.

< gets off soap box>

frongt@lemmy.zip on 12 Jul 01:13 next collapse

You don’t need ipv6 for that. You can assign as many ipv4 addresses to an interface as you want.

Edit: this is also certainly not the simplest way, especially since I have no idea how it would interact with docker. It’s a significantly larger management headache than a single rule-based reverse proxy.

laserjet@lemmy.dbzer0.com on 12 Jul 03:19 collapse

If your ISP won’t give you IPv6

how can my ISP influence this on my home network that has no external access?

possiblylinux127@lemmy.zip on 12 Jul 05:05 collapse

Do you not have internet access?

laserjet@lemmy.dbzer0.com on 12 Jul 05:16 collapse

Yes but all my services work in my LAN even if I am not connected to the outside world. Obviously not fully functional, but everything runs.

possiblylinux127@lemmy.zip on 12 Jul 05:47 collapse

You are getting confused by NAT

In IPv6 there is no NAT. NAT makes things more complicated and adds overhead that isn’t needed. In the old (pre Nat) internet IPs worked like it was suppose to and each device had its own routable address. IPv6 fixes this by both using a massive address space and allowing hosts to get infinite IPs. You can assign a IP address to each service since there is so much space.

In general NAT is the enemy of peer to peer networks which is what IP as a protocol is designed to do

talkingpumpkin@lemmy.world on 12 Jul 01:40 next collapse

The simplest (= most basic) solution would be to assign several IPs to the machine (you can add multiple on the same network interface) and have each service listen on a specific address.

un_ax@lemmy.today on 12 Jul 01:49 next collapse

If they’re just internal the simplest way is to add another IP on the same interface to whatever is serving your service, then bind the service to that IP and add the entry in DNS.

If for some reason you want to keep everything hosted on one IP, for a reverse proxy, caddy is pretty simple. An example caddyfile would be:

http://service1.devicename.lan/ { 
    reverse_proxy 1.2.3.4:9005
}

http://service2.devicename.lan/ { 
    reverse_proxy 127.0.0.1:1234
}

This would also allow you to set https in the future using ACME (dns method if internal only) or your own CA / custom cert.

laserjet@lemmy.dbzer0.com on 12 Jul 03:29 collapse

I don’t really like the idea of having a separate IP for every service. It would need to be configured in the service itself (assuming that is possible for all of them, I don’t know), on the router, and by whatever means you create IPs. Too complex.

A lot of people are recommending caddy.

All my web services use apache or lighttd. Do I use caddy just for this or do I have to figure out how to move each of them to use this web server?

Also does it work for non-web services, like ssh or samba? (Which wasn’t in my original question, I only thought of it now.)

possiblylinux127@lemmy.zip on 12 Jul 05:09 collapse

I would look into learning about the OSI model

For context, Caddy is a reverse proxy which is specific to the layer 7 protocol http. Layer 7 protocols are generally not compatible with one another since under the hood SSH, HTTP are all very different despite them all running on top of TCP.

stratself@lemdro.id on 12 Jul 02:39 next collapse

Use Caddy on each device, with tls turned off. Basically

http://service1.devicename.lan/ {
    tls off
    reverse_proxy localhost:8000
}
http://service2.devicename.lan/ {
    tls off
    reverse_proxy localhost:8096
}
laserjet@lemmy.dbzer0.com on 12 Jul 03:25 next collapse

A lot of people are recommending caddy.

When you say “on each device” you mean this configuration would refer to the services running on that device right? Not that every client device needs to have this set up?

All my web services use apache or lighttd. Do I use caddy just for this or do I have to figure out how to move each of them to use this web server?

Also does it work for non-web services, like ssh or samba? (Which wasn’t in my original question, I only thought of it now.)

stratself@lemdro.id on 12 Jul 04:28 next collapse

When you say “on each device” you mean this configuration would refer to the services running on that device right? Not that every client device needs to have this set up?

The device that runs multiple services will set that up, yes. Not the client.

All my web services use apache or lighttd. Do I use caddy just for this or do I have to figure out how to move each of them to use this web server?

Apache and lighttpd can both do the same thing that Caddy does (multiplex many services via subdomain names on port 80). Caddy is just simpler and hence recommended.

You can move all services to use Caddy, takes some learning but overall better. Alternatively, if you already set up apache/lighttpd for each of your services, you can put Caddy in front and do something like

http://service1.devicename.lan/ {
    tls off
    reverse_proxy localhost:<port-that-apache-listens-on>
}

Also does it work for non-web services, like ssh or samba? (Which wasn’t in my original question, I only thought of it now.)

No. Also, those should be running on their dedicated ports anyways

kossa@feddit.org on 12 Jul 05:32 collapse

Do I use caddy just for this or do I have to figure out how to move each of them to use this web server?

No, your services stay basically untouched. They still need to deliver their content via a webserver. But instead of delivering it straight to your browser, they now pass it to your reverse proxy (caddy), which delivers it to you.

possiblylinux127@lemmy.zip on 12 Jul 05:02 collapse

I personallly would just use a DNS challenge to get certificates

valar@lemmy.ca on 12 Jul 02:59 next collapse

Caddy makes it dead simple to do exactly what you described.

StrawberryPigtails@discuss.tchncs.de on 12 Jul 04:15 next collapse

Not sure if it’s the simplest way, but this is how I did it. I set up a reverse proxy service in a vm using caddy and then used pihole (also in a vm) to set up a local DNS record pointing to the reverse proxy. The systems need to be set up to use the pihole server as their DNS resolver.

How it works is you type audiobookshelf.local.lan in the address bar and it queries pihole which says it at 192.168.1.100 or whatever. The Caddy web server at that address then passes the request on to the service at 192.168.1.60:8080.

Setup is a bit tedious but it has worked for me.

nbsp@programming.dev on 12 Jul 04:32 next collapse

doc.traefik.io/traefik/ if you dockering

i use with openwrt DNS Forwarding to create a wilcard domain (eg service1.nbsp.lan, service2.nbsp.lan etc), then when i vpn in all my services just work ™️… kinda

Reannlegge@lemmy.ca on 12 Jul 04:42 next collapse

I wanted to say I know this one, but a lot of people beat me to it use caddy.

possiblylinux127@lemmy.zip on 12 Jul 05:02 next collapse

You just need a reverse proxy

Nomad@infosec.pub on 12 Jul 05:04 next collapse

Read up on the host header, any http server can parse that. Set up DNS resolver and the http server does the rest. If you already serve from a reverse proxy, just change the port setup to a host header based setup. The term to search for is vhost config.

Danitos@reddthat.com on 12 Jul 05:48 next collapse

I have that exact setup. Let’s suppose you want to use layzer.lan as your domain. The way I did it:

  1. Make a DNS record that maps *.layzer.lan to your private IP (let’s say it’s is 192.168.0.10). You can do this by either manually editing your local DNS resolver config file, or hosting a DNS server and adding a a new entry. I did the later, and chose AdGuard for that. Either option will make your PC underestand that going to any subdomain *.layzer.lan means going to 192.168.0.10.

  2. Use a reverse proxy. I use nginx-proxy-manager, and added a proxy host for each service you want to access with the link. For example, for my Immich server that is running in port 30041, I added a proxy host such that immich.layzer.lan takes you to 192.168.0.10:30041. Ports 80 and 443 have to be free for nginx to take. You can also add https support from here, and it’s very easy to do if you have bough a real domain.

Offtopic; I just noticed that on my Lemmy Android client you appear as laserjet, but on web you appear as layzerjeyt lol. Any idea why?

laserjet@lemmy.dbzer0.com on 12 Jul 09:53 next collapse

Offtopic

on dbz there is a setting to change your display name. not every instance enabled that option. but it’s how you see people with emojis, punctuation and stuff in their display names. not every client displays it. like some of the android clients don’t show avatars either. My handle is @laserjet@lemmy.dbzer0.com

HolidayGreed@sh.itjust.works on 12 Jul 10:30 collapse

A video showing this setup youtu.be/qlcVx-k-02E?is=lrO69gayyHk3m7Vc

Decronym@lemmy.decronym.xyz on 12 Jul 06:30 next collapse

Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:

Fewer Letters More Letters
CA (SSL) Certificate Authority
DNS Domain Name Service/System
ISP Internet Service Provider
NAT Network Address Translation
ULA Unique Local Address (non-routable local address, IPv6)
nginx Popular HTTP server

6 acronyms in this thread; the most compressed thread commented on today has 8 acronyms.

[Thread #52 for this comm, first seen 12th Jul 2026, 06:30] [FAQ] [Full list] [Contact] [Source code]

kokesh@lemmy.world on 12 Jul 07:29 collapse

Nginx manager. Surprisingly simple. You change your letsencrypt to contain yourdomain.com and *.yourdomain.com and voila.