aboutsummaryrefslogtreecommitdiff
path: root/articles/2023-02-13-new-website-using-gnix.md
blob: c919ad74d6b09548b4c0adbe92f792e7d96df2e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# New Website and gnix

_fixme: probably contains a lot of errors, shouldn't have written this late_

Last weekend I started a new attempt writing a reverse proxy: This time, with
success! I have been able to finally replace nginx for all services.
Additionally I now have a wildcard TLS certificate for all of
`*.metamuffin.org`.

The cgit instance is no longer available since it used CGI, which gnix does not
support nor I like.

## The reverse-proxy

Nginx was not optimal because I found it was hard to configure, required certbot
automatically chaning the config and was also just _too much_ for my use case.
(Who needs a http server that can also serve SMTP?!)

My new solution ([gnix](https://codeberg.org/metamuffin/gnix)) has very limited
configuration abilities for now but just enough to work. I simplified about 540
lines of `/etc/nginx/nginx.conf` to only 20 lines of `/etc/gnix.toml` (yesss.
TOML. of course it is.). The Proxy now only acts as a "Hostname Demultiplexer".
A configuration could look like this:

```toml
[http]
bind = "0.0.0.0:80"

[https]
bind = "0.0.0.0:443"
tls_cert = "/path/to/cert.pem"
tls_key = "/path/to/key.pem"

[hosts]
"domain.tld" = { backend = "127.0.0.1:18000" }
"www.domain.tld" = { backend = "127.0.0.1:18000" }
"keksmeet.domain.tld" = { backend = "127.0.0.1:18001" }
"otherdomain.tld" = { backend = "example.org:80" }
```

I am running two gnix instances now, one for `:80`+`:443` and another for matrix
federation on `:8448`. Additionally this required me to move my matrix
homeserver from `https://metamuffin.org/_matrix` to
`https://matrix.metamuffin.org/_matrix` via the `.well-known/matrix/server`
file. And that intern required me to host a file there, which was nginx' job
previously. At this point I started rewriting my main website.

## Wildcard Certificates

Another inconvinience was that I would need `certbot` to aquire one certificate
for each subdomain. Letsencrypt offers wildcard certificates; These can be
obtained by solving a ACME challenge that requires changing DNS record (to prove
you own the domain). My current registrar (Namecheap) does not offer me an API
for automatically applying these though. They do however (through a very very
confusing, badly designed user interface) allow me to set a custom nameserver.
By setting the nameserver to `144.91.114.82` (IP address of my VPS) the server
can run its own nameserver that has authority over resolving `metamuffin.org`. I
used BIND9's `named` to do that and also dynamically update records.

```conf
# /etc/named.conf (-rw-------; owned by named)
zone "metamuffin.org" IN {
	type master;
    # the zone file is trivial to configure, look it up somewhere else. :)
	file "metamuffin.org.zone";
    update-policy {
        # only allow certbot to change TXT records of _acme-challenge.metamuffin.org
        grant certbot. name _acme-challenge.metamuffin.org. TXT;
    };
};

# generated with `tsig-keygen -a HMAC-SHA512 -n HOST certbot`
key "certbot" {
	algorithm hmac-sha512;
	secret "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

Then certbot can be configured to use these credentials for solving challenges:

```ini
# /etc/certbot/rfc2136.ini (-rw-------; owned by root)
dns_rfc2136_server = 127.0.0.1
dns_rfc2136_port = 53
dns_rfc2136_name = certbot
dns_rfc2136_secret = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
dns_rfc2136_algorithm = HMAC-SHA512
```

Now you can automatically request new wildcard certificates by running
`doas certbot certonly --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -d '*.domain.tld' -d 'domain.tld' --server https://acme-v02.api.letsencrypt.org/directory`

## Rewrite of my website

As mentioned above, I replace my former Deno + pug.js + static file server setup
with a custom rust application (using Rocket and Markup and 253 other
dependencies). I rewrote my blog rendering system too, that why you don't see
syntax highlighting right now.

## End

In case of questions, ask me. Have fun suffering with the modern web!