summaryrefslogtreecommitdiff
path: root/blog/2023-02-13-new-website-using-gnix.md
blob: 04cdc02780c02bac2693cce899a14207d80095da (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
103
# 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 an ACME challenge that requires changing a 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!