feat: fix qemu onto hetzner and fix mailserver

This commit is contained in:
Jet Pham 2026-02-20 02:46:08 -08:00
parent d800c6a180
commit afd3360582
No known key found for this signature in database
5 changed files with 77 additions and 13 deletions

3
.gitignore vendored
View file

@ -4,8 +4,9 @@ result-*
# Secrets (Untracked) # Secrets (Untracked)
secrets/secrets.nix secrets/secrets.nix
dkim_private.pem
# Only track the example file # Only track the example file
!secrets/secrets.nix.example !secrets/secrets.nix.example
install.log install.log

View file

@ -19,7 +19,15 @@ This repository uses **untracked secrets**, so you must build the system locally
2. Fill in the values (generate random keys, etc). 2. Fill in the values (generate random keys, etc).
- `tailscaleKey` must be a **Reusable** key from the Tailscale admin console. - `tailscaleKey` must be a **Reusable** key from the Tailscale admin console.
### 2. Initial Install (Wite & Install) ### 2. Verify Configuration Locally
Because `secrets/secrets.nix` is untracked by git, standard `nix flake check` will fail.
To build the server configuration locally and ensure there are no syntax or evaluation errors before pushing to the server, run:
```bash
nix build path:.#nixosConfigurations.extremist-software.config.system.build.toplevel --impure --dry-run
```
### 3. Initial Install (Wipe & Install)
Run this command to build and deploy. **Warning: Wipes the server disk.** Run this command to build and deploy. **Warning: Wipes the server disk.**
```bash ```bash

View file

@ -2,12 +2,12 @@
{ {
imports = [ imports = [
(modulesPath + "/profiles/qemu-guest.nix")
./modules/caddy.nix ./modules/caddy.nix
./modules/forgejo.nix ./modules/forgejo.nix
./modules/mail.nix ./modules/mail.nix
./modules/searx.nix ./modules/searx.nix
./modules/matrix.nix ./modules/matrix.nix
./modules/matrix.nix
./modules/monitoring.nix ./modules/monitoring.nix
./secrets/secrets-scheme.nix ./secrets/secrets-scheme.nix
# Impure Secrets # Impure Secrets

View file

@ -3,10 +3,18 @@
{ {
services.caddy = { services.caddy = {
enable = true; enable = true;
email = "postmaster@extremist.software";
virtualHosts = { virtualHosts = {
"extremist.software" = { "extremist.software" = {
useACMEHost = "extremist.software";
extraConfig = '' extraConfig = ''
respond "Hi" handle /.well-known/acme-challenge/* {
root * /var/lib/acme/acme-challenge
file_server
}
handle {
respond "Hi"
}
''; '';
}; };
@ -17,10 +25,15 @@
}; };
"mail.extremist.software" = { "mail.extremist.software" = {
# Stalwart handles its own certs usually, or we can proxy UI here useACMEHost = "extremist.software";
# Stalwart UI is usually on 8080
extraConfig = '' extraConfig = ''
reverse_proxy localhost:8080 handle /.well-known/acme-challenge/* {
root * /var/lib/acme/acme-challenge
file_server
}
handle {
reverse_proxy localhost:8080
}
''; '';
}; };
@ -45,5 +58,20 @@
}; };
}; };
# Configure ACME to fetch Let's Encrypt certificates so they can be shared with other services like Stalwart
security.acme = {
acceptTerms = true;
defaults.email = "postmaster@extremist.software";
defaults.server = "https://acme-v02.api.letsencrypt.org/directory";
certs."extremist.software" = {
webroot = "/var/lib/acme/acme-challenge";
extraDomainNames = [ "mail.extremist.software" ];
group = "acme";
};
};
# Ensure Caddy can read the certs too now that they are in the acme group
users.users.caddy.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];
} }

View file

@ -3,29 +3,56 @@
{ {
services.stalwart = { services.stalwart = {
enable = true; enable = true;
# Let stalwart open its own ports if needed for the main services
openFirewall = true;
settings = { settings = {
server = { server = {
hostname = "mail.extremist.software"; hostname = "extremist.software";
tls = { tls = {
enable = true; enable = true;
implicit = false; # StartTLS usually on 587 implicit = false; # StartTLS usually on 587
}; };
listener = {
smtp = {
protocol = "smtp";
bind = "[::]:25";
};
submissions = {
bind = "[::]:465";
protocol = "smtp";
tls.implicit = true;
};
imaps = {
bind = "[::]:993";
protocol = "imap";
tls.implicit = true;
};
management = {
bind = [ "127.0.0.1:8080" ];
protocol = "http";
};
};
};
# Use the certificate procured by security.acme for Caddy
certificate."default" = {
cert = "%{file:/var/lib/acme/extremist.software/fullchain.pem}%";
private-key = "%{file:/var/lib/acme/extremist.software/key.pem}%";
}; };
authentication.fallback-admin = { authentication.fallback-admin = {
user = "admin"; user = "admin";
secret = config.mySecrets.stalwartAdmin; secret = config.mySecrets.stalwartAdmin;
}; };
# Stalwart configuration is quite extensive.
# By default it listens on standard ports (25, 465, 587, 993, 4190)
# and provides a web admin UI on 8080.
}; };
}; };
# Allow Stalwart to read the ACME certificate procured for Caddy
systemd.services.stalwart.serviceConfig.SupplementaryGroups = [ "acme" ];
# Open Firewalls for Mail # Open Firewalls for Mail
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [
25 465 587 # SMTP
993 # IMAP (Secure) 993 # IMAP (Secure)
4190 # Sieve 4190 # Sieve
8080 # Admin UI (Reverse proxied, but good to double check loopback) 8080 # Admin UI (Reverse proxied, but good to double check loopback)