feat: add unbound control

This commit is contained in:
Benjamin Bädorf 2023-11-13 15:48:05 +01:00
parent d2d9b6cd4c
commit 5cf48868b0
No known key found for this signature in database
GPG key ID: 1B7BF5B77A521346
17 changed files with 243 additions and 22 deletions

View file

@ -1,20 +1,55 @@
{ {
flake,
config,
pkgs, pkgs,
lib, lib,
flake,
... ...
}: { }: let
restartMaddyOnCertRenewal = pkgs.writeShellScriptBin "restart-maddy-on-cert-renewal" ''
if [ "$1" == "mail.b12f.io"]; then
${pkgs.systemd}/bin/systemctl restart maddy.service;
fi
'';
in {
age.secrets."b12f.io-dkim-private-rsa" = {
file = "${flake.self}/secrets/b12f.io-dkim-private-rsa.age";
mode = "400";
owner = "rspamd";
};
age.secrets."mail@b12f.io-password" = { age.secrets."mail@b12f.io-password" = {
file = "${flake.self}/secrets/mail@b12f.io-password.age"; file = "${flake.self}/secrets/mail@b12f.io-password.age";
mode = "400"; mode = "400";
# owner = "maddy"; owner = "maddy";
}; };
services.caddy.virtualHosts = { services.caddy = {
"mail.b12f.io" = { globalConfig = ''
extraConfig = '' events {
on cert_obtained exec ${restartMaddyOnCertRenewal}/bin/restart-maddy-on-cert-renewal {event.data.name}
}
'';
virtualHosts = {
"mail.b12f.io".extraConfig = ''
respond "404 Not Found" respond "404 Not Found"
''; '';
"mta-sts.b12f.io".extraConfig = ''
encode gzip
file_server
root * ${
pkgs.runCommand "testdir" {} ''
mkdir -p "$out/.well-known"
echo "
version: STSv1
mode: enforce
max_age: 604800
mx: mail.b12f.io
" > "$out/.well-known/mta-sts.txt"
''
}
'';
}; };
}; };
@ -23,6 +58,8 @@
openFirewall = true; openFirewall = true;
hostname = "mail.b12f.io";
primaryDomain = "b12f.io"; primaryDomain = "b12f.io";
ensureAccounts = [ ensureAccounts = [
@ -32,16 +69,39 @@
ensureCredentials = { ensureCredentials = {
# Do not use this in production. This will make passwords world-readable # Do not use this in production. This will make passwords world-readable
# in the Nix store # in the Nix store
"mail@b12f.io".passwordFile = "${pkgs.writeText "postmaster" "test"}"; "mail@b12f.io".passwordFile = config.age.secrets."mail@b12f.io-password".path;
}; };
tls = { tls = {
certificates = [ certificates = [
{ {
keyPath = ""; keyPath = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.b12f.io/mail.b12f.io.key";
certPath = ""; certPath = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.b12f.io/mail.b12f.io.crt";
} }
]; ];
}; };
};
config = (builtins.replaceStrings ["msgpipeline local_routing {"] [''msgpipeline local_routing {
check {
rspamd {
api_path http://localhost:11334
}
}''] config.services.maddy.config.default) ++ ''
modify {
domains b12f.io
selector default
key_path ${config.age.secrets."b12f.io-dkim-private-rsa".path}
}
'';
};
services.rspamd = {
enable = true;
locals."dkim_signing.conf".text = ''
enabled = false;
'';
};
systemd.services.rspamd.serviceConfig.SupplementaryGroups = [ "maddy" ];
} }

View file

@ -10,7 +10,7 @@
# #
# This variable can be set from a file if you append it with _FILE # This variable can be set from a file if you append it with _FILE
# #
FIREFLY_III_URL=https://firefly.b12f.io FIREFLY_III_URL=http://firefly:8080
# #
# Imagine Firefly III can be reached at "http://172.16.0.2:8082" (internal Docker network or something). # Imagine Firefly III can be reached at "http://172.16.0.2:8082" (internal Docker network or something).

View file

@ -2,7 +2,7 @@
{ {
networking.firewall.allowedUDPPorts = [ 67 547 ]; networking.firewall.allowedUDPPorts = [ 67 547 ];
networking.firewall.extraInputRules = '' networking.firewall.extraInputRules = ''
ip6 daddr ff02::1:2/128 udp dport 547 accept comment "DHCPv6 client" ip6 daddr ff02::1:2/128 udp dport 547 accept comment "DHCPv6 server"
''; '';
services.kea.dhcp4 = { services.kea.dhcp4 = {

View file

@ -34,9 +34,17 @@ in {
extraConfig = '' extraConfig = ''
firefly.b12f.io { firefly.b12f.io {
reverse_proxy 127.0.0.1:8080 reverse_proxy 127.0.0.1:8080
basicauth * {
b12f $2a$05$/xM7USOzLczswXmiacO6UOdg1YNPIw/KJMbMVerEkpsCtNUFwte4a
}
} }
firefly-importer.b12f.io { firefly-importer.b12f.io {
reverse_proxy 127.0.0.1:8081 reverse_proxy 127.0.0.1:8081
basicauth * {
b12f $2a$05$/xM7USOzLczswXmiacO6UOdg1YNPIw/KJMbMVerEkpsCtNUFwte4a
}
} }
''; '';
}; };

View file

@ -20,7 +20,7 @@
]; ];
ipv6.addresses = [ ipv6.addresses = [
{ address = "2a02:908:5b1:e3c0:2::"; prefixLength = 128; } { address = "2a02:908:5b1:e3c0:2::"; prefixLength = 128; }
{ address = "fe80::b12f:acab:1312:acab"; prefixLength = 128; } { address = "fe80:b12f:acab:1312:acab:2::"; prefixLength = 128; }
]; ];
}; };

View file

@ -53,6 +53,10 @@ in {
paperless.b12f.io { paperless.b12f.io {
request_header Host localhost:${builtins.toString config.services.paperless.port} request_header Host localhost:${builtins.toString config.services.paperless.port}
reverse_proxy 127.0.0.1:${builtins.toString config.services.paperless.port} reverse_proxy 127.0.0.1:${builtins.toString config.services.paperless.port}
basicauth * {
b12f $2a$05$/xM7USOzLczswXmiacO6UOdg1YNPIw/KJMbMVerEkpsCtNUFwte4a
}
} }
''; '';
}; };

View file

@ -1,4 +1,34 @@
{ pkgs, lib, ... }: { {
flake,
config,
pkgs,
lib,
...
}: {
age.secrets."unbound_control.key" = {
file = "${flake.self}/secrets/unbound_control.key.age";
mode = "400";
owner = "unbound";
};
age.secrets."unbound_control.pem" = {
file = "${flake.self}/secrets/unbound_control.pem.age";
mode = "400";
owner = "unbound";
};
age.secrets."unbound_server.key" = {
file = "${flake.self}/secrets/unbound_server.key.age";
mode = "400";
owner = "unbound";
};
age.secrets."unbound_server.pem" = {
file = "${flake.self}/secrets/unbound_server.pem.age";
mode = "400";
owner = "unbound";
};
networking.firewall.allowedUDPPorts = [ 53 ]; networking.firewall.allowedUDPPorts = [ 53 ];
networking.firewall.allowedTCPPorts = [ 53 ]; networking.firewall.allowedTCPPorts = [ 53 ];
@ -10,16 +40,25 @@
"\"${pkgs.adlist.unbound-adblockStevenBlack}\"" "\"${pkgs.adlist.unbound-adblockStevenBlack}\""
]; ];
interface = [ interface = [
"0.0.0.0" "127.0.0.1"
"::0" "::1"
"192.168.178.2"
"2a02:908:5b1:e3c0:2::"
"10.0.1.2"
"fd00:b12f:acab:1312:acab:2::"
]; ];
access-control = [ access-control = [
"127.0.0.1/32 allow"
# Allow from local network # Allow from local network
"192.168.178.0/24 allow" "192.168.178.0/24 allow"
"2a02:908:5b1:e3c0::/64 allow"
# Allow from wireguard # Allow from wireguard
"10.0.1.0/24 allow" "10.0.1.0/24 allow"
"fd00:b12f:acab:1312:acab::/48 allow" "fd00:b12f:acab:1312::/64 allow"
]; ];
local-zone = [ local-zone = [
"\"b12f.io\" static" "\"b12f.io\" static"
@ -60,21 +99,29 @@
"\"fritz.box. 10800 IN A 192.168.178.1\"" "\"fritz.box. 10800 IN A 192.168.178.1\""
"\"fritz.box. 10800 IN AAAA fd00::3ea6:2fff:fe57:30b0\"" "\"fritz.box. 10800 IN AAAA fd00::3ea6:2fff:fe57:30b0\""
]; ];
tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt";
}; };
forward-zone = [ forward-zone = [
{ {
name = "."; name = ".";
forward-addr = [ forward-addr = [
"193.110.81.0" #dns0.eu "193.110.81.0#dns0.eu"
"2a0f:fc80::" #dns0.eu "2a0f:fc80::#dns0.eu"
"185.253.5.0" #dns0.eu "185.253.5.0#dns0.eu"
"2a0f:fc81::" #dns0.eu "2a0f:fc81::#dns0.eu"
]; ];
forward-tls-upstream = "yes"; # forward-tls-upstream = "yes";
} }
]; ];
remote-control.control-enable = true; remote-control = {
control-enable = true;
control-key-file = config.age.secrets."unbound_control.key".path;
server-cert-file = config.age.secrets."unbound_server.pem".path;
server-key-file = config.age.secrets."unbound_server.key".path;
control-cert-file = config.age.secrets."unbound_control.pem".path;
};
}; };
}; };

67
pkgs/caddy/default.nix Normal file
View file

@ -0,0 +1,67 @@
{
lib,
buildGoModule,
fetchFromGitHub,
vendorSha256 ? ""
}:
with lib;
let
plugins = [
"github.com/mholt/caddy-events-exec"
];
imports = flip concatMapStrings plugins (pkg: "\t\t\t_ \"${pkg}\"\n");
main = ''
package main
import (
caddycmd "github.com/caddyserver/caddy/v2/cmd"
_ "github.com/caddyserver/caddy/v2/modules/standard"
${imports}
)
func main() {
caddycmd.Main()
}
'';
in buildGoModule rec {
pname = "caddy";
version = "2.6.4";
subPackages = [ "cmd/caddy" ];
src = fetchFromGitHub {
owner = "caddyserver";
repo = pname;
# https://github.com/NixOS/nixpkgs/blob/nixos-21.11/pkgs/servers/caddy/default.nix
rev = "v${version}";
sha256 = "sha256-xNCxzoNpXkj8WF9+kYJfO18ux8/OhxygkGjA49+Q4vY=";
};
inherit vendorSha256;
overrideModAttrs = (_: {
preBuild = "echo '${main}' > cmd/caddy/main.go";
postInstall = "cp go.sum go.mod $out/ && ls $out/";
});
postPatch = ''
echo '${main}' > cmd/caddy/main.go
cat cmd/caddy/main.go
'';
postConfigure = ''
cp vendor/go.sum ./
cp vendor/go.mod ./
'';
meta = with lib; {
homepage = https://caddyserver.com;
description = "Fast, cross-platform HTTP/2 web server with automatic HTTPS";
license = licenses.asl20;
maintainers = with maintainers; [ rushmorem fpletz zimbatm ];
};
}

View file

@ -3,6 +3,7 @@ with prev; {
# keep sources this first # keep sources this first
sources = callPackage (import ./_sources/generated.nix) {}; sources = callPackage (import ./_sources/generated.nix) {};
# then, call packages with `final.callPackage` # then, call packages with `final.callPackage`
# caddy = callPackage (import ./caddy) {};
concourse = import ./concourse.nix final; concourse = import ./concourse.nix final;
import-gtk-settings = writeShellScriptBin "import-gtk-settings" (import ./import-gtk-settings.nix final); import-gtk-settings = writeShellScriptBin "import-gtk-settings" (import ./import-gtk-settings.nix final);
lgcl = writeShellScriptBin "lgcl" (import ./lgcl.nix final); lgcl = writeShellScriptBin "lgcl" (import ./lgcl.nix final);

Binary file not shown.

View file

@ -70,4 +70,11 @@ in {
"invoiceplane-db-secrets.env.age".publicKeys = pieKeys ++ baseKeys; "invoiceplane-db-secrets.env.age".publicKeys = pieKeys ++ baseKeys;
"mail@b12f.io-password.age".publicKeys = frikandelKeys ++ baseKeys; "mail@b12f.io-password.age".publicKeys = frikandelKeys ++ baseKeys;
"b12f.io-dkim-private-rsa.age".publicKeys = frikandelKeys ++ baseKeys;
"unbound_control.key.age".publicKeys = pieKeys ++ baseKeys;
"unbound_control.pem.age".publicKeys = pieKeys ++ baseKeys;
"unbound_server.key.age".publicKeys = pieKeys ++ baseKeys;
"unbound_server.pem.age".publicKeys = pieKeys ++ baseKeys;
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,3 +1,14 @@
# Usage
```
terraform-backend-git -l git terraform plan
```
```
terraform-backend-git -l git terraform apply
```
# FAQ
Problem: Problem:

View file

@ -92,6 +92,14 @@ resource "hostingde_record" "b12f-autodiscover" {
# ttl = 300 # ttl = 300
# } # }
resource "hostingde_record" "b12f-mta-sts" {
zone_id = hostingde_zone.b12f.id
name = "mta-sts.b12f.io"
type = "CNAME"
content = "frikandel.b12f.io"
ttl = 300
}
resource "hostingde_record" "b12f-spf" { resource "hostingde_record" "b12f-spf" {
zone_id = hostingde_zone.b12f.id zone_id = hostingde_zone.b12f.id
name = "b12f.io" name = "b12f.io"
@ -100,6 +108,14 @@ resource "hostingde_record" "b12f-spf" {
ttl = 300 ttl = 300
} }
resource "hostingde_record" "b12f-dkim" {
zone_id = hostingde_zone.b12f.id
name = "default._domainkey.b12f.io"
type = "TXT"
content = "\"v=DKIM1; k=rsa;\" \"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8Wr\" \"nxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB\""
ttl = 300
}
resource "hostingde_record" "b12f-droppie-AAAA" { resource "hostingde_record" "b12f-droppie-AAAA" {
zone_id = hostingde_zone.b12f.id zone_id = hostingde_zone.b12f.id
name = "droppie.b12f.io" name = "droppie.b12f.io"