Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Switchboard – A mDNS based reverse proxy for personal infrastructure (github.com)
92 points by whytheplatypus 10 days ago | hide | past | web | favorite | 37 comments

I’m in the process of building out a smallish home lab, with most things running in containers, and one of the things I wanted was dns for my internal things that Just Worked. It seems this is still harder than it needs to be. I started looking at Consul + Traefik, but the latest version of Traefik seems to have gotten significantly more complex for simple use cases. I’ve since started looking at Caddy, which seems far more straightforward. I will look at this, however, since it might be simpler still.

+1 for Caddy.

I have been using it for years now for my personal stuff (almost all containers) and it's a breeze (the https part especially). I recently [0] added SSO for all my local stuff so I just have to login once and have access to everything.

[0] https://joshstrange.com/securing-your-self-hosted-apps-with-...

It makes my morning that this might be useful to someone aside from myself. I went down a similar path trying to find something mindless to route traffic to small projects I tend to run on raspberry pi's around the house, which resulted in this being made.

You can have the best of both worlds; since this project is written in Go, it can easily be made into a Caddy module that takes care of the mDNS part, without having to overlap other functionality. Docs: https://caddyserver.com/docs/extending-caddy

The simplest: shared `/etc/hosts`. And container hint: you can bind mount individual files as volumes.

Also cool is that you can bind mount the same sqlite backing db file into multiple containers.

That seems dangerous? How can it be so? Surely multiple instances of SQLite shouldn't read the same backing file..

The whole job of sqlite is to handle the locking to keep such accesses safe.

Ok, I see. I did some reading and it looks like this to me:

* the DB is supported by a backing file

* this backing file supports multiple read threads simultaneously but writes are locked via filesystem locks

* write performance with multiple writers is therefore dangerous

* read performance is good if no one is writing and consistent even if someone is

I spent the past weekend setting up a VPS for a personal project, and Caddy worked wonderfully well. All I needed was HTTPS for a server, and a two line Caddyfile gave me that:


reverse_proxy localhost:8000

I'm using dnscrypt proxy with as filtering and some local DNS config, configured with dnscrypt server running on my VPS. It is running on pi-zero (old $5 one without wireless), a bit slow (50ms query), but works fine, especially with caching

+1 for Traefik. The problem was the documentation IMO. It works great including the integration with Docker.

BIND provides DNS that just works. :)

Agreed, but my point is that if I spin up a new container with something in it, I want to be able to have DNS registration occur automatically so that I’m not having to go update DNS entries somewhere.

A simple solution would be `dnsmasq` which provides DNS and DHCP, but it cannot be used on a public network. More complex setup would be ISC DHCP server that maintains a dynamic subdomain in BIND.

>ISC DHCP server that maintains a dynamic subdomain in BIND

This is what I do. I don't remember setting it up being particularly complex

PowerDNS lets you do that (if you run it against a SQL database), or CoreDNS/etcd for simple stuff.

Caddy user here... definitely interesting to me.

A little bit of docs would help. Not sure what a node is here, and what is mDNS doing.

Seems like the perfect thing for me (I run a stupid dual-traefik setup that does TLS SNI negotiation for me that I want to get rid of), but I can't figure out what is this.

very very fair.

mDNS is just the method of communicating what traffic should be sent where. The "switchboard" listens for mDNS broadcasts that tell it what services want traffic routed to them under what conditions. A "node" (which was a bad choice of words) is the other side of that, a program broadcasting one of those mDNS resources (e.g. send traffic that's been sent to the domain "example.test" to this machine on port 8080)

How does it work with LetsEncrypt? I always thought you need to be public in order to get valid SSL certs. How does LetsEncrypt work with mDNS?

mDNS would be used for the internal network to discover hosts. The proxy server would terminate SSL using a LetsEncrypt certificate before forwarding traffic to one of the internal nodes (discovered via mDNS).

I have about 70 devices and services at home (pure software services such as a web app, up to WiFi-connected IoT).

I manage everything via dnsmasq on my router, and I use a DNS wildcard to make sure that all unknown IPs map to my server.

This is because the server holds the docker engine on whihc all "software services" are located. I did a few bounces between Traefik and Caddy over the years and finally settled on Caddy.

Caddy is a truly fantastic web server. If you manually forced IPs on your containers there is not problem at all (2 lines per service). If you did not, there is unfortunately no built-in mechanism in Caddy to autodiscover them (such as the one in Traefik). I wrote my own using the new Caddy API (v2).

My router (runs Tomato, but I think DD-WRT is the same) automatically puts host names into its DNS server; I've never had to do anything.

Host names with spaces, etc (e.g., DNS non-compliant) don't work, but otherwise it Just Works.

Edit: language

I'm pretty sure this is more feature rich than dnsmasq, but the golang ipkg on the latest OpenWRT release is 99MB. My overlay filesystem started at less than 24MB. This software not for users like us. Perhaps someone will implement equivalent functionality using C or Python libraries for those of us that run by choice in a resource-constrained or embedded environment.

That's going to be the golang compiler - you can cross compile static binaries from your PC that will run on ARM. The final binary size should be a few mb.

I’ve got all UniFi gear but I believe it works the same. Where that doesn’t work is when using containers.

Thinking "aloud" here, but you might be able to get something like this with the macvlan network driver with docker. On FreeBSD I'm able to use a bridge interface that has a VLAN interface as a member (e.g. bridge10 with vlan10), and then have my jails create a vnet interface within that bridge. To the rest of the network it looks like yet another host (including showing up in Unifi).

if you run pi-hole you can do the same. Really useful for home networks

I’m actually looking for something that does the mDNS registration for multiple back-end services (I did https://github.com/piku/avahi-aliases for announcing mDNS hostnames, which will go along nicely with this, but wanted an all-in-one or a Traefik/Caddy plugin that would do the registration itself).

Would you be willing to make a Caddy plugin for it? Here's how: https://caddyserver.com/docs/extending-caddy

I'm trying to figure out whether or not I keep using DBus and leverage Avahi or not, but that's the general idea - either Caddy or Traefik.

Cloudflare Argo Tunnel is awesome, though it requires Argo which is $5 a month.


Run a simple command locally, and have a https server endpoint connected to anything on your machine.

My favorite is ngrok. Great developer and well documented product that I even rely on for production.

Hope this isn’t too off topic, but does anyone happen to know if there’s any way to VPN with mDNS so that iTunes syncing and/or media sharing work remotely?

You generally need an Ethernet based VPN which you can do with openvpn.

Otherwise Avahi has a mode to allow reflecting (mdns traffic between two interfaces) on point to point interfaces and if you run that on the VPN server it may let mdns work from your vpn client to the local lan of the server. Will depend if your mdns implementation tries to query on the VPN interface though. Which again for avahi you can enable point to point on the client side. Unsure if you can do that on windows/Mac.

You just have to make sure that multicast is setup right and it should work.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact