Skip to content

Releases: peterldowns/localias

2.1.0+commit.46b0a47

12 May 18:06
46b0a47
Compare
Choose a tag to compare
fix: install root certs correctly by changing how daemonization works…

… (#31)

## Bugfix

Fix #30 by changing how daemonization works. 

- Previously: `start`/`reload` would apply the latest config in the
foreground process, then fork(), then start Caddy.
- Now: `start`/`reload` apply the latest config, starts Caddy in the
foreground process, then fork()s.
- By starting Caddy in the foreground process, any activities requiring
sudo/root will happen while the program is still interactive.
- This fixes the problem (adding the root cert to the system store
requires sudo/root privileges, but because Caddy was running in a
background process, it couldn't request that permission.)
- The foreground process exits cleanly and the background process starts
Caddy again, this time without any need for sudo/root privileges because
any of the work it needed to do was already done in the foreground
process.

## Friendlier CLI

This change encouraged me to make the following improvements to the CLI
commands:

- `stop` just kills the daemon, if it's running. If the daemon wasn't
running, `stop` will now exit cleanly. Previously, it would throw an
error, but that's user-hostile because the goal of running `stop` is to
ensure no running daemon — if that goal is accomplished by stopping a
running daemon, or confirming no daemon was running, doesn't really
matter.
- `start` will start a new daemon. If one was already running, it will
be killed and replaced by a new one. The user's goal is to ensure a
daemon is running, with the latest config, and this is achieved
regardless of whether or not there was an existing daemon.
- `reload` becomes an alias for `start`, because they have the exact
same behavior — ensure that a daemon is running with the latest
configuiration.

## Get rid of `caddymodules`

A while ago, localias was built using `gomod2nix`, and there was an
incompatibility between that helper and the opentelemetry modules
included in Caddy. To work around this, I created a `caddymodules`
package that imported all of the Caddy modules _except_ opentelemetry,
which was fine because this project doesn't use the opentelemetry
modules in any way.

Because localias no longer uses `gomod2nix`, this PR gets rid of the
`caddymodules` hack entirely. This then allowed me to upgrade the
version of Caddy that is being installed, and it will make it easier to
stay up to date as Caddy receives further improvements.

## SSL renewal server

With an upgraded Caddy came a problem — for SSL issuance, Caddy now
requires you to implement an "automation policy" server that confirms
that it can issue a new certificate for a given domain. This is
primarily aimed at issuing certificates for real life domains accessible
to the public, not for internal development aliases, but the restriction
still stands. To do this, I used Caddy itself to respond to these
requests.

For more information, read:
- https://caddyserver.com/docs/automatic-https#on-demand-tls
-
https://caddy.community/t/serving-tens-of-thousands-of-domains-over-https-with-caddy/11179
- https://github.com/caddyserver/caddy/pull/6055

In the future, I could implement this by writing a custom policy module
instead of using the HTTP ask, but this works for now.

## Dependencies cleanup

- General updates of all imported golang packages.
- Update the `flake.nix` and `flake.lock` files, switch to
`buildGoModule` instead of `buildGo120Module` to make it easier to use
this flake with an override `nixpkgs` upstream.

2.1.0+commit.2eef727

12 May 19:55
2eef727
Compare
Choose a tag to compare
bump version in README

2.0.3+commit.fe5d709

04 Apr 18:25
fe5d709
Compare
Choose a tag to compare
ci: remove brew bottling scripts

I'm going to follow the goreleaser pattern of skipping bottles/casks
and just doing binary installs. This means I don't need to repackage
each binary into a separate artifact.

See
https://github.com/peterldowns/homebrew-tap/commit/e4756b9da030933f5e98812ddc2dcb04c1cf0f38
for an example of what the brew Formula looks like --- it just consumes
the built binaries. Simple.

2.0.3+commit.c3c6d97

03 Apr 20:15
c3c6d97
Compare
Choose a tag to compare
fix(certs): automatically refresh tls certificates with on_demand_tls…

… (#28)

This PR is intended to fix issue #27. The bug was that while "on demand"
TLS issuing (including automatic certificate renewal) was *enabled* for
the local CA, it wasn't actually turned on. The fix is to turn on the
automatic certificate renewal.

Once that was turned on, Caddy started showing a warning regarding a
missing `on_demand_tls` global configuration block, so I updated the
config to include that, too.

The warning looks like:

```bash
2024/04/03 19:25:08.859	WARN	tls	YOUR SERVER MAY BE VULNERABLE TO ABUSE: on-demand TLS is enabled, but no protections are in place	{"docs": "https://caddyserver.com/docs/automatic-https#on-demand-tls"}
```

I tested that this PR solves the problem by:

* Updating each entry to have `tls.issuer.lifetime = 10s`, so that the
certs generated for each site would expire after 10 seconds. (The
default period is `12h`.)
* Confirming that once the certificate expires, `localias` did not
automatically renew the certificate.
* Adding the `tls.on_demand` configuration statement to turn on
automatic certificate renewal.
* Confirming that with this new configuration option, `localias` would
automatically renew the certificate when the next request was made to
the website.

For Caddy docs that helped me figure this out, see:
* https://caddyserver.com/docs/automatic-https#on-demand-tls
* https://caddyserver.com/docs/caddyfile/directives/tls#internal

<details> 
<summary> <i>Click here to see example logs proving automatic
certificate renewal</i> </summary>

```bash
2024/04/03 19:25:08.861	INFO	tls	finished cleaning storage units
2024/04/03 19:26:05.217	INFO	tls.on_demand	attempting certificate renewal	{"server_name": "expiry.test", "subjects": ["expiry.test"], "expiration": "2024/04/03 19:24:58.000", "remaining": -67.217564, "revoked": false}
2024/04/03 19:26:05.223	INFO	tls.renew	acquiring lock	{"identifier": "expiry.test"}
2024/04/03 19:26:05.246	INFO	tls.renew	lock acquired	{"identifier": "expiry.test"}
2024/04/03 19:26:05.246	INFO	tls.renew	renewing certificate	{"identifier": "expiry.test", "remaining": -67.24655}
2024/04/03 19:26:05.249	INFO	tls.renew	certificate renewed successfully	{"identifier": "expiry.test"}
2024/04/03 19:26:05.249	INFO	tls.renew	releasing lock	{"identifier": "expiry.test"}
2024/04/03 19:26:05.250	INFO	tls.cache	replaced certificate in cache	{"subjects": ["expiry.test"], "new_expiration": "2024/04/03 19:26:16.000"}
2024/04/03 19:26:13.149	INFO	tls.on_demand	attempting certificate renewal	{"server_name": "expiry.test", "subjects": ["expiry.test"], "expiration": "2024/04/03 19:26:16.000", "remaining": 2.850843, "revoked": false}
2024/04/03 19:26:13.154	INFO	tls.renew	acquiring lock	{"identifier": "expiry.test"}
2024/04/03 19:26:13.179	INFO	tls.renew	lock acquired	{"identifier": "expiry.test"}
2024/04/03 19:26:13.180	INFO	tls.renew	renewing certificate	{"identifier": "expiry.test", "remaining": 2.819957}
2024/04/03 19:26:13.181	INFO	tls.renew	certificate renewed successfully	{"identifier": "expiry.test"}
2024/04/03 19:26:13.181	INFO	tls.renew	releasing lock	{"identifier": "expiry.test"}
2024/04/03 19:26:13.181	INFO	tls.cache	replaced certificate in cache	{"subjects": ["expiry.test"], "new_expiration": "2024/04/03 19:26:24.000"}
2024/04/03 19:26:45.121	INFO	tls.on_demand	attempting certificate renewal	{"server_name": "expiry.test", "subjects": ["expiry.test"], "expiration": "2024/04/03 19:26:24.000", "remaining": -21.12137, "revoked": false}
2024/04/03 19:26:45.122	INFO	tls.renew	acquiring lock	{"identifier": "expiry.test"}
2024/04/03 19:26:45.146	INFO	tls.renew	lock acquired	{"identifier": "expiry.test"}
2024/04/03 19:26:45.147	INFO	tls.renew	renewing certificate	{"identifier": "expiry.test", "remaining": -21.147127}
2024/04/03 19:26:45.154	INFO	tls.renew	certificate renewed successfully	{"identifier": "expiry.test"}
2024/04/03 19:26:45.154	INFO	tls.renew	releasing lock	{"identifier": "expiry.test"}
2024/04/03 19:26:45.155	INFO	tls.cache	replaced certificate in cache	{"subjects": ["expiry.test"], "new_expiration": "2024/04/03 19:26:56.000"}
2024/04/03 19:26:55.618	INFO	tls.on_demand	attempting certificate renewal	{"server_name": "expiry.test", "subjects": ["expiry.test"], "expiration": "2024/04/03 19:26:56.000", "remaining": 0.381874, "revoked": false}
2024/04/03 19:26:55.619	INFO	tls.renew	acquiring lock	{"identifier": "expiry.test"}
2024/04/03 19:26:55.641	INFO	tls.renew	lock acquired	{"identifier": "expiry.test"}
2024/04/03 19:26:55.641	INFO	tls.renew	renewing certificate	{"identifier": "expiry.test", "remaining": 0.358275}
2024/04/03 19:26:55.650	INFO	tls.renew	certificate renewed successfully	{"identifier": "expiry.test"}
2024/04/03 19:26:55.650	INFO	tls.renew	releasing lock	{"identifier": "expiry.test"}
2024/04/03 19:26:55.653	INFO	tls.cache	replaced certificate in cache	{"subjects": ["expiry.test"], "new_expiration": "2024/04/03 19:27:06.000"}
```
</details>

2.0.2+commit.56d660e

20 Mar 21:25
56d660e
Compare
Choose a tag to compare
fix(mDNS): fix mDNS serving from computers with hostnames ending in .…

…local

Fixes #20 and #21, both of which were caused by the mDNS server not
working when the host running localias has a hostname already ending in
.local. I tested this with hostnames `pld-mbp-22` and
`pld-mbp-22.local`, and in both cases mDNS serving worked correctly and
served responses to another computer on the local network.

2.0.1+commit.e3fade1

11 Jan 16:17
e3fade1
Compare
Choose a tag to compare
fix(docs) remove references to outdated daemon subcommand

2.0.1+commit.d9ec4e8

29 Dec 20:42
d9ec4e8
Compare
Choose a tag to compare
docs: update demo image

2.0.1+commit.c358250

29 Dec 20:07
c358250
Compare
Choose a tag to compare
fix(cli): fix broken mDNS resolving on macOS with go1.19

While testing, I noticed that localias installed via homebrew
was unable to serve .local aliases over mDNS:

```
❯ /opt/homebrew/bin/localias run
[ ... snip ... ]
error: failed to find local IP: lookup pld-mbp-22.local on 8.8.8.8:53: no such host
```

The problem is that the release binaries were being built with go1.19,
which does not use the macOS system DNS resolution algorithm. Locally, I
had been developing with go1.20, which does. See https://danp.net/posts/macos-dns-change-in-go-1-20/
for more information on the differences between go1.19 and go1.20.

To fix this issue, this commit:

- Updates the release binary workflow to use go1.20
- Updates the localias server code to warn but continue if the mDNS
  server cannot be started, so that mDNS errors do not prevent you
  from successfully using localias.
- Adds some log lines showing which aliases are being served over mDNS
  when they are successfully being served. This should make debugging
  easier in the future.

2.0.0+commit.ce353ff

29 Dec 19:30
ce353ff
Compare
Choose a tag to compare
fix(cli) better error messages on invalid commands

2.0.0+commit.6fd5535

29 Dec 19:13
6fd5535
Compare
Choose a tag to compare
release version 2.0.0 (#19)

* release version 2.0.0

- Implement mDNS for .local domains.
- removed `daemon` subcommand
- code cleanups
  - remove macOS app
  - better naming and organization
  - switch to `buildGoModule`, stop using `gomod2nix`
  - pin go1.20 in nix build because github.com/quic-go/quic-go cannot be
    built with go1.21
- Resolve some user-reported issues
  - Update secure/insecure domain docs (#17)
  - Explain "localias is already running" error message (#18)