v0.16.3 — catch-all routing, and a command to serve a name
The release where catch-all DNS routing actually engages, plus a command that installs the web-server config for a name.
Catch-all routing works now
It has never engaged on a systemd-resolved machine, which is the platform it was built for.
discoverUpstreams read /etc/resolv.conf. On systemd-resolved that file is a stub:
/etc/resolv.conf nameserver 127.0.0.53 ← the stub
/run/systemd/resolve/resolv.conf nameserver 67.207.67.3 ← the real uplinks
nameserver 67.207.67.2
The loopback filter dropped 127.0.0.53 — correctly, since forwarding to the thing that is asking us is a loop. So discovery came back empty and the conditional did exactly what it was designed to do: fall back to routing every claimed ending by name, which systemd-resolved then truncates at around 1,090 entries without an error a caller can see.
The safety property worked. The feature was unreachable.
systemd's own uplink file is now consulted first, so dns enable writes Domains=~. — one line that never grows — and the bridge forwards everything that is not a claimed ending upstream.
Unchanged: loopback everywhere still means no upstreams, which still keeps per-ending routing rather than pointing every lookup at a bridge with nowhere to forward.
moshcode site <name>
Serving a name is four lines of web-server config, and every one of them is a line people get wrong the same way. This writes them.
moshcode site blue.eggs # show what would be installed
moshcode site blue.eggs --install # write the config
moshcode site blue.eggs --install --reload # and make it live
moshcode site blue.eggs --proxy 3000 # reverse-proxy a local port
What it gets right, in each case because getting it wrong is silent:
- No redirect to HTTPS. A box's default vhost usually sends everything there, and for an ending outside the DNS root that is a redirect to a page no certificate can exist for. Through the gateway it is worse, because the status is forwarded without the Location header — a 301 pointing nowhere at all.
- An exact
server_name, which is what beats the default vhost. - Both address families. Resolver users arrive over IPv6, because that is what the name points at; everyone else arrives via
pit.moshcode.sh, which fetches server-side. - Port 80 only, because a DNS record has nowhere to put a port.
The server is detected by asking who holds port 80, not by looking for a config directory. A box can carry /etc/nginx from a package installed years ago while Caddy is the thing answering, and writing nginx config there succeeds at every step and serves nothing — the worst outcome available, since everything reports success.
A new site is seeded with a starter page rather than left empty, because an empty root serves 404 and a 404 is indistinguishable from a broken install at exactly the moment someone is trying to tell those apart. Never over an existing site.
moshcode serves nothing itself. This writes a config file; nginx or Caddy does the serving.
Upgrading
moshcode update # as root
moshcode dns enable # as root
moshcode site <name> --install --reload # as root
If a bridge from an older build is already listening on port 5354, dns enable will report "bridge already running" and leave it there. An older bridge does not forward, so stop it first.