feat: use ACME and nginx instead of caddy

This commit is contained in:
Benjamin Bädorf 2023-11-14 18:44:46 +01:00
parent 5cf48868b0
commit 29e183b0c7
No known key found for this signature in database
GPG key ID: 1B7BF5B77A521346
26 changed files with 359 additions and 428 deletions

View file

@ -58,6 +58,7 @@
inputs.nixos-hardware.nixosModules.raspberry-pi-4
./pie
self.nixosModules.yule
self.nixosModules.acme
self.nixosModules.docker
self.nixosModules.invoiceplane
];
@ -69,6 +70,7 @@
self.nixosModules.base
./frikandel
self.nixosModules.yule
self.nixosModules.acme
self.nixosModules.docker
];
};

View file

@ -4,6 +4,7 @@
./configuration.nix
./networking.nix
./nginx.nix
./wireguard.nix
./email.nix
./website.nix

View file

@ -5,16 +5,16 @@
lib,
...
}: let
restartMaddyOnCertRenewal = pkgs.writeShellScriptBin "restart-maddy-on-cert-renewal" ''
if [ "$1" == "mail.b12f.io"]; then
${pkgs.systemd}/bin/systemctl restart maddy.service;
fi
dkimDNSb12fio = ''
default._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8WrnxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB" ) ;
'';
in {
age.secrets."b12f.io-dkim-private-rsa" = {
file = "${flake.self}/secrets/b12f.io-dkim-private-rsa.age";
path = "/var/lib/maddy/dkim_keys/b12f.io_default.key";
mode = "400";
owner = "rspamd";
owner = "maddy";
};
age.secrets."mail@b12f.io-password" = {
@ -23,23 +23,20 @@ in {
owner = "maddy";
};
services.caddy = {
globalConfig = ''
events {
on cert_obtained exec ${restartMaddyOnCertRenewal}/bin/restart-maddy-on-cert-renewal {event.data.name}
}
'';
security.acme.certs = {
"mail.b12f.io" = {
reloadServices = [ "maddy" ];
group = "maddy";
};
"mta-sts.b12f.io" = {};
};
virtualHosts = {
"mail.b12f.io".extraConfig = ''
respond "404 Not Found"
'';
"mta-sts.b12f.io".extraConfig = ''
encode gzip
file_server
root * ${
pkgs.runCommand "testdir" {} ''
services.nginx.virtualHosts = {
"mta-sts.b12f.io" = {
forceSSL = true;
useACMEHost = "mta-sts.b12f.io";
locations."/" = {
root = pkgs.runCommand "create-well-known-mta-sts" {} ''
mkdir -p "$out/.well-known"
echo "
version: STSv1
@ -47,53 +44,183 @@ in {
max_age: 604800
mx: mail.b12f.io
" > "$out/.well-known/mta-sts.txt"
''
}
'';
tryFiles = "$uri $uri/ =404";
};
};
};
systemd.tmpfiles.rules = [
"d '/run/maddy' 0750 maddy maddy - -"
];
system.activationScripts.makeMaddyDKIMDNS = lib.stringAfter [ "var" ] ''
mkdir -p /var/lib/maddy/dkim_keys
echo '${dkimDNSb12fio}' >> /var/lib/maddy/dkim_keys/b12f.io_default.dns
'';
services.maddy = {
enable = false;
enable = true;
openFirewall = true;
hostname = "mail.b12f.io";
primaryDomain = "b12f.io";
ensureAccounts = [
"mail@b12f.io"
];
ensureCredentials = {
# Do not use this in production. This will make passwords world-readable
# in the Nix store
"mail@b12f.io".passwordFile = config.age.secrets."mail@b12f.io-password".path;
};
tls = {
loader = "file";
certificates = [
{
keyPath = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.b12f.io/mail.b12f.io.key";
certPath = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.b12f.io/mail.b12f.io.crt";
keyPath = "${config.security.acme.certs."mail.b12f.io".directory}/key.pem";
certPath = "${config.security.acme.certs."mail.b12f.io".directory}/cert.pem";
}
];
};
config = ''
# Minimal configuration with TLS disabled, adapted from upstream example
# configuration here https://github.com/foxcpp/maddy/blob/master/maddy.conf
# Do not use this in production!
config = (builtins.replaceStrings ["msgpipeline local_routing {"] [''msgpipeline local_routing {
auth.pass_table local_authdb {
table sql_table {
driver sqlite3
dsn credentials.db
table_name passwords
}
}
storage.imapsql local_mailboxes {
driver sqlite3
dsn imapsql.db
}
table.chain local_rewrites {
optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
optional_step static {
entry postmaster postmaster@$(primary_domain)
}
optional_step file /etc/maddy/aliases
}
msgpipeline local_routing {
check {
rspamd {
api_path http://localhost:11334
}
}''] config.services.maddy.config.default) ++ ''
}
destination b12f.io {
modify {
domains b12f.io
selector default
key_path ${config.age.secrets."b12f.io-dkim-private-rsa".path}
replace_rcpt regexp ".*" "mail@b12f.io"
}
deliver_to &local_mailboxes
}
destination postmaster $(local_domains) {
modify {
replace_rcpt &local_rewrites
}
deliver_to &local_mailboxes
}
default_destination {
reject 550 5.1.1 "User doesn't exist"
}
}
smtp tcp://0.0.0.0:25 {
limits {
all rate 20 1s
all concurrency 10
}
dmarc yes
check {
require_mx_record
dkim
spf
}
source $(local_domains) {
reject 501 5.1.8 "Use Submission for outgoing SMTP"
}
default_source {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.1.1 "User doesn't exist"
}
}
}
submission tcp://0.0.0.0:587 {
limits {
all rate 50 1s
}
auth &local_authdb
source $(local_domains) {
check {
authorize_sender {
prepare_email &local_rewrites
user_to_email identity
}
}
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
modify {
dkim $(primary_domain) $(local_domains) default
}
deliver_to &remote_queue
}
}
default_source {
reject 501 5.1.8 "Non-local sender domain"
}
}
target.remote outbound_delivery {
limits {
destination rate 20 1s
destination concurrency 10
}
mx_auth {
dane
mtasts {
cache fs
fs_dir mtasts_cache/
}
local_policy {
min_tls_level encrypted
min_mx_level none
}
}
}
target.queue remote_queue {
target &outbound_delivery
autogenerated_msg_domain $(primary_domain)
bounce {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.0.0 "Refusing to send DSNs to non-local addresses"
}
}
}
imap tcp://0.0.0.0:143 {
auth &local_authdb
storage &local_mailboxes
}
'';
};
services.rspamd = {

View file

@ -32,15 +32,4 @@
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
# Caddy reverse proxy for local services like cups
services.caddy = {
enable = true;
globalConfig = ''
default_bind 128.140.109.213 2a01:4f8:c2c:b60::
# auto_https off
email acme@benjaminbaedorf.eu
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
'';
};
}

23
hosts/frikandel/nginx.nix Normal file
View file

@ -0,0 +1,23 @@
{
flake,
config,
pkgs,
lib,
...
}: {
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedTlsSettings = true;
recommendedProxySettings = true;
defaultListenAddresses = [
"128.140.109.213"
"[2a01:4f8:c2c:b60::]"
];
};
}

View file

@ -22,25 +22,27 @@
'';
};
in {
services.caddy.virtualHosts = {
security.acme.certs = {
"benjaminbaedorf.eu" = {};
"b12f.io" = {};
};
services.nginx.virtualHosts = {
"benjaminbaedorf.eu" = {
extraConfig = ''
redir https://b12f.io{uri} temporary
'';
forceSSL = true;
useACMEHost = "benjaminbaedorf.eu";
locations."/".return = "302 https://b12f.io$request_uri";
};
"b12f.io" = {
extraConfig = ''
handle {
root * ${bbeu}
try_files {path}.html {path}
file_server
}
forceSSL = true;
useACMEHost = "b12f.io";
handle_errors {
respond "{http.error.status_code} {http.error.status_text}"
}
'';
locations."/" = {
root = bbeu;
index = "index.html";
tryFiles = "$uri $uri/ =404";
};
};
};
}

View file

@ -1,44 +0,0 @@
{
flake,
config,
pkgs,
lib,
...
}:
with lib; let
psCfg = config.pub-solar;
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
getIP4 = with pkgs; writeShellScriptBin "getIP" ''
${curl}/bin/curl -4 https://ipcheck-ds.wieistmeineip.de/callback/ | ${coreutils}/bin/tail -c +2 | ${coreutils}/bin/head -c -1 | ${jq}/bin/jq '.ip' -r
'';
getIP6 = with pkgs; writeShellScriptBin "getIP" ''
echo "2a02:908:5b1:e3c0:2::"
'';
in {
imports = [
flake.self.nixosModules.ddclient
];
services.ddclient = {
enable = true;
protocol = "dyndns1";
domains = [
"pie.b12f.io"
"droppie.b12f.io"
];
server = "ddns.hosting.de";
username = "b12f";
usev4 = "cmdv4, cmdv4=${getIP4}/bin/getIP";
usev6 = "cmdv6, cmdv6=${getIP6}/bin/getIP";
verbose = true;
passwordFile = "/run/agenix/dyndns.key";
interval = "1min";
};
age.secrets."dyndns.key" = {
file = "${flake.self}/secrets/dyndns.key.age";
mode = "400";
owner = "root";
};
}

View file

@ -4,12 +4,12 @@
./configuration.nix
./networking.nix
./nginx.nix
./wireguard.nix
./backup.nix
./unbound.nix
./dhcpd.nix
./wake-droppie.nix
./ddclient.nix
./paperless.nix
./firefly.nix
./invoiceplane.nix

View file

@ -29,24 +29,22 @@ in {
mode = "400";
};
services.caddy = {
enable = true;
extraConfig = ''
firefly.b12f.io {
reverse_proxy 127.0.0.1:8080
security.acme.certs = {
"firefly.b12f.io" = {};
"firefly-importer.b12f.io" = {};
};
basicauth * {
b12f $2a$05$/xM7USOzLczswXmiacO6UOdg1YNPIw/KJMbMVerEkpsCtNUFwte4a
}
}
firefly-importer.b12f.io {
reverse_proxy 127.0.0.1:8081
basicauth * {
b12f $2a$05$/xM7USOzLczswXmiacO6UOdg1YNPIw/KJMbMVerEkpsCtNUFwte4a
}
}
'';
services.nginx.virtualHosts = {
"firefly.b12f.io" = {
forceSSL = true;
useACMEHost = "firefly.b12f.io";
locations."/".proxyPass = "http://127.0.0.1:8080";
};
"firefly-importer.b12f.io" = {
forceSSL = true;
useACMEHost = "firefly.b12f.io";
locations."/".proxyPass = "http://127.0.0.1:8081";
};
};
systemd.services."docker-network-firefly" = let

View file

@ -20,7 +20,20 @@ in {
mode = "400";
};
security.acme.certs = {
"invoicing.b12f.io" = {};
};
services.nginx.virtualHosts = {
"invoicing.b12f.io" = {
forceSSL = true;
useACMEHost = "invoicing.b12f.io";
};
};
services.invoiceplane.webserver = "nginx";
services.invoiceplane.sites."invoicing.b12f.io" = {
# nginx is not supported
enable = true;
database = {

View file

@ -24,17 +24,5 @@
];
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.openssh.openFirewall = true;
# Caddy reverse proxy for local services like cups
services.caddy = {
globalConfig = ''
default_bind 192.168.178.2 2a02:908:5b1:e3c0:2:: 10.0.1.2 fd00:b12f:acab:1312:acab:2::
# auto_https off
email acme@benjaminbaedorf.eu
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
'';
};
}

25
hosts/pie/nginx.nix Normal file
View file

@ -0,0 +1,25 @@
{
flake,
config,
pkgs,
lib,
...
}: {
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedTlsSettings = true;
recommendedProxySettings = true;
defaultListenAddresses = [
"192.168.178.2"
# "2a02:908:5b1:e3c0:2::"
"10.0.1.2"
"[fd00:b12f:acab:1312:acab:2::]"
];
};
}

View file

@ -47,18 +47,16 @@ in {
};
};
services.caddy = {
enable = true;
extraConfig = ''
paperless.b12f.io {
request_header Host localhost:${builtins.toString config.services.paperless.port}
reverse_proxy 127.0.0.1:${builtins.toString config.services.paperless.port}
security.acme.certs = {
"paperless.b12f.io" = {};
};
basicauth * {
b12f $2a$05$/xM7USOzLczswXmiacO6UOdg1YNPIw/KJMbMVerEkpsCtNUFwte4a
}
}
'';
services.nginx.virtualHosts = {
"paperless.b12f.io" = {
forceSSL = true;
useACMEHost = "paperless.b12f.io";
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString config.services.paperless.port}";
};
};
systemd.tmpfiles.rules = [

View file

@ -61,16 +61,13 @@
"fd00:b12f:acab:1312::/64 allow"
];
local-zone = [
"\"b12f.io\" static"
"\"b12f.io\" transparent"
"\"local\" static"
"\"box\" static"
];
local-data = [
"\"brwb8763f64a364.local. 10800 IN A 192.168.178.4\""
"\"droppie.local. 10800 IN A 192.168.178.3\""
"\"droppie.local. 10800 IN AAAA 2a02:908:5b1:e3c0:3::\""
"\"droppie.b12f.io. 10800 IN A 10.0.1.3\""
"\"droppie.b12f.io. 10800 IN AAAA fd00:b12f:acab:1312:acab:3::\""
"\"backup.b12f.io. 10800 IN A 10.0.1.3\""
@ -102,6 +99,7 @@
tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt";
};
forward-zone = [
{
name = ".";
@ -111,7 +109,7 @@
"185.253.5.0#dns0.eu"
"2a0f:fc81::#dns0.eu"
];
# forward-tls-upstream = "yes";
forward-tls-upstream = "yes";
}
];

27
modules/acme/default.nix Normal file
View file

@ -0,0 +1,27 @@
{
flake,
config,
pkgs,
lib,
...
}: {
age.secrets."hosting-de-acme-secrets" = {
file = "${flake.self}/secrets/hosting-de-acme-secrets.age";
mode = "400";
owner = "acme";
};
security.acme = {
acceptTerms = true;
defaults = {
email = "acme@benjaminbaedorf.eu";
# server = "https://acme-staging-v02.api.letsencrypt.org/directory";
dnsProvider = "hostingde";
dnsPropagationCheck = true;
credentialsFile = config.age.secrets."hosting-de-acme-secrets".path;
group = "nginx";
webroot = null;
};
};
}

View file

@ -9,7 +9,7 @@
systemd.services.NetworkManager-wait-online.enable = lib.mkDefault false;
systemd.services.systemd-networkd-wait-online.enable = lib.mkDefault false;
networking.hosts = (flake.self.lib.addLocalHostname ["caddy.local"]) // {
networking.hosts = {
"128.140.109.213" = [ "vpn.b12f.io" ];
"2a01:4f8:c2c:b60::" = [ "vpn.b12f.io" ];
"2a02:908:5b1:e3c0:2::" = [ "pie-wg.b12f.io" ];

View file

@ -1,245 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.ddclient;
boolToStr = bool: if bool then "yes" else "no";
dataDir = "/var/lib/ddclient";
StateDirectory = builtins.baseNameOf dataDir;
RuntimeDirectory = StateDirectory;
usev4 = if cfg.usev4 != "" then "usev4=${cfg.usev4}" else "";
usev6 = if cfg.usev6 != "" then "usev6=${cfg.usev6}" else "";
configFile' = pkgs.writeText "ddclient.conf" ''
# This file can be used as a template for configFile or is automatically generated by Nix options.
use=no
${usev4}
${usev6}
cache=${dataDir}/ddclient.cache
foreground=yes
login=${cfg.username}
password=${if cfg.protocol == "nsupdate" then "/run/${RuntimeDirectory}/ddclient.key" else "@password_placeholder@"}
protocol=${cfg.protocol}
${lib.optionalString (cfg.script != "") "script=${cfg.script}"}
${lib.optionalString (cfg.server != "") "server=${cfg.server}"}
${lib.optionalString (cfg.zone != "") "zone=${cfg.zone}"}
ssl=${boolToStr cfg.ssl}
wildcard=yes
quiet=${boolToStr cfg.quiet}
verbose=${boolToStr cfg.verbose}
${cfg.extraConfig}
${lib.concatStringsSep "," cfg.domains}
'';
configFile = if (cfg.configFile != null) then cfg.configFile else configFile';
preStart = ''
install --mode=600 --owner=$USER ${configFile} /run/${RuntimeDirectory}/ddclient.conf
${lib.optionalString (cfg.configFile == null) (if (cfg.protocol == "nsupdate") then ''
install --mode=600 --owner=$USER ${cfg.passwordFile} /run/${RuntimeDirectory}/ddclient.key
'' else if (cfg.passwordFile != null) then ''
"${pkgs.replace-secret}/bin/replace-secret" "@password_placeholder@" "${cfg.passwordFile}" "/run/${RuntimeDirectory}/ddclient.conf"
'' else ''
sed -i '/^password=@password_placeholder@$/d' /run/${RuntimeDirectory}/ddclient.conf
'')}
'';
in with lib; {
disabledModules = [
"services/networking/ddclient.nix"
];
imports = [
(mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ]
(config:
let value = getAttrFromPath [ "services" "ddclient" "domain" ] config;
in if value != "" then [ value ] else []))
(mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "")
(mkRemovedOptionModule [ "services" "ddclient" "password" ] "Use services.ddclient.passwordFile instead.")
];
###### interface
options = {
services.ddclient = with lib.types; {
enable = mkOption {
default = false;
type = bool;
description = lib.mdDoc ''
Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org).
'';
};
package = mkOption {
type = package;
default = pkgs.ddclient;
defaultText = lib.literalExpression "pkgs.ddclient";
description = lib.mdDoc ''
The ddclient executable package run by the service.
'';
};
domains = mkOption {
default = [ "" ];
type = listOf str;
description = lib.mdDoc ''
Domain name(s) to synchronize.
'';
};
username = mkOption {
# For `nsupdate` username contains the path to the nsupdate executable
default = lib.optionalString (config.services.ddclient.protocol == "nsupdate") "${pkgs.bind.dnsutils}/bin/nsupdate";
defaultText = "";
type = str;
description = lib.mdDoc ''
User name.
'';
};
passwordFile = mkOption {
default = null;
type = nullOr str;
description = lib.mdDoc ''
A file containing the password or a TSIG key in named format when using the nsupdate protocol.
'';
};
interval = mkOption {
default = "10min";
type = str;
description = lib.mdDoc ''
The interval at which to run the check and update.
See {command}`man 7 systemd.time` for the format.
'';
};
configFile = mkOption {
default = null;
type = nullOr path;
description = lib.mdDoc ''
Path to configuration file.
When set this overrides the generated configuration from module options.
'';
example = "/root/nixos/secrets/ddclient.conf";
};
protocol = mkOption {
default = "dyndns2";
type = str;
description = lib.mdDoc ''
Protocol to use with dynamic DNS provider (see https://sourceforge.net/p/ddclient/wiki/protocols).
'';
};
server = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
Server address.
'';
};
ssl = mkOption {
default = true;
type = bool;
description = lib.mdDoc ''
Whether to use SSL/TLS to connect to dynamic DNS provider.
'';
};
quiet = mkOption {
default = false;
type = bool;
description = lib.mdDoc ''
Print no messages for unnecessary updates.
'';
};
script = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
script as required by some providers.
'';
};
usev4 = mkOption {
default = "webv4, webv4=checkip.dyndns.com/, webv4-skip='Current IP Address: '";
type = str;
description = lib.mdDoc ''
Method to determine the IP address to send to the dynamic DNS provider.
'';
};
usev6 = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
Method to determine the IP address to send to the dynamic DNS provider.
'';
};
verbose = mkOption {
default = false;
type = bool;
description = lib.mdDoc ''
Print verbose information.
'';
};
zone = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
zone as required by some providers.
'';
};
extraConfig = mkOption {
default = "";
type = lines;
description = lib.mdDoc ''
Extra configuration. Contents will be added verbatim to the configuration file.
::: {.note}
`daemon` should not be added here because it does not work great with the systemd-timer approach the service uses.
:::
'';
};
};
};
###### implementation
config = mkIf config.services.ddclient.enable {
systemd.services.ddclient = {
description = "Dynamic DNS Client";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
restartTriggers = optional (cfg.configFile != null) cfg.configFile;
serviceConfig = {
DynamicUser = true;
RuntimeDirectoryMode = "0700";
inherit RuntimeDirectory;
inherit StateDirectory;
Type = "oneshot";
ExecStartPre = "!${pkgs.writeShellScript "ddclient-prestart" preStart}";
ExecStart = "${lib.getBin cfg.package}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf";
};
};
systemd.timers.ddclient = {
description = "Run ddclient";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = cfg.interval;
OnUnitInactiveSec = cfg.interval;
};
};
};
}

View file

@ -5,13 +5,13 @@
}: {
flake = {
nixosModules = rec {
acme = import ./acme;
adb = import ./adb;
arduino = import ./arduino;
audio = import ./audio;
bluetooth = import ./bluetooth;
core = import ./core;
crypto = import ./crypto;
ddclient = import ./ddclient;
desktop-extended = import ./desktop-extended;
docker = import ./docker;
gaming = import ./gaming;

View file

@ -226,7 +226,7 @@ in
};
options.webserver = mkOption {
type = types.enum [ "caddy" ];
type = types.enum [ "caddy" "nginx" ];
default = "caddy";
description = lib.mdDoc ''
Which webserver to use for virtual host management. Currently only
@ -358,5 +358,25 @@ in
};
})
(mkIf (cfg.webserver == "nginx") {
services.nginx = {
enable = true;
virtualHosts = mapAttrs' (hostName: cfg: (
nameValuePair "${hostName}" {
locations."/" = {
root = "${pkg hostName cfg}";
extraConfig = ''
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:${config.services.phpfpm.pools."invoiceplane-${hostName}".socket};
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
'';
};
}
)) eachSite;
};
})
]);
}

View file

@ -21,16 +21,4 @@
] ++ (if (pkgs.system == "x86_64-linux")
then [ pkgs.cups-brother-hl3140cw ]
else []);
networking.hosts = flake.self.lib.addLocalHostname ["cups.local"];
services.caddy = {
enable = true;
extraConfig = ''
cups.local {
request_header Host localhost:631
reverse_proxy unix//run/cups/cups.sock
}
'';
};
}

View file

@ -36,7 +36,6 @@ in buildGoModule rec {
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=";
};

View file

@ -0,0 +1,22 @@
age-encryption.org/v1
-> ssh-ed25519 8bHz7g 0fwjxxgvY3S/2oKgc+RxTWA9AuA7oS1MnMAqG0AZ2x4
LReuCNO8r5UMlipXheXT1SLQKlwGMC8Gpu8VtAUI3/4
-> ssh-ed25519 n71/yQ fiv1s9XA/ATrK/s8OkenXCCp3mUhn8gzp3I3S8h7BG4
XhzPW7aFm41nzr7ZaBSzS2qfQoVttgODXUqPaF+FvPY
-> ssh-rsa kFDS0A
gLhS2ce3jBP1UbJJt9dJ/4SmkNiL7LBuUik8Zq1WflxHlMqrRslb56Uuc4BJHTlp
KGt2zrzRRNEdSJgzJfK+AT1AHCza++C96ZZsxfhDexL/Gx7Lm6Bwp+D/XR9KYxEn
UF511OWWjoCbDWldUQr17y5cbiG4z+VlMMOuKox8RWHymG0ABe+kZEOg1GBZ/bLj
tUwgxdK/uGGI2/AJIs4tiiemiNo2cMup7fe+wBPqq1b/TcxxTGHfWuJopp3ISl5G
Ov7o7/HVCyemFSlBQTF1K3t68rw4a0ZkMcX86RpEtbiRFrEhS2IuGXnwteEnypER
OiafhbdIh56TnTvCKuxnTJdG1JobM1c15l9FhownRjKMwVjeQb39LKvQlJAkzGOr
eBtkGu42p8UGNpltTawKgWNOTsZNy5BYHvHvS73SXDcuwGVhhP5fbeImUgeBRUyT
2DWoK+vethjGL+tX+NNqeKM/Xr+k8QUGq+qehB6UoiTLL4NiwujeO230b9Afsh2/
xtzDTMueqTUVTzxA0GbIRSXCKCfDNifdJh6+ebnvizx5NarANvMNlP6sfBQ5gANf
N20IhtgnOxQ5l5URWqK/A5vk+cpP2GGkAGoW40m31gyug9AtuguNpEVRpLHJVtRn
DpHh5k0EMzWz7iQhYIVavLTh3AtxofLg4wp/cQEkcQg
-> OC`4fNF7-grease
YhGHL0+BVF6h6InKVlS3
--- NXJPtlRt28CuwumxjLQI8qY6i5GSbBPbBANxLpHmsHE
×€aqê802.æ–´"R=SÙÚ È³ ËŽlhª@ÄK¢¨Fö=;ž @ìåúiÕ°+àÚr¸£àð;4wI}ÕiËÑèõ1o —™
„¼¬ƒN¼ÂÜòG>Tõ3Œ7

Binary file not shown.

Binary file not shown.

View file

@ -42,7 +42,7 @@ let
];
in {
"dyndns.key.age".publicKeys = pieKeys ++ baseKeys;
"hosting.de-api.key.age".publicKeys = baseKeys;
"hosting-de-acme-secrets.age".publicKeys = pieKeys ++ frikandelKeys ++ baseKeys;
"droppie-ssh-root.key.age".publicKeys = droppieKeys ++ baseKeys;

View file

@ -112,7 +112,7 @@ 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\""
content = "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyla9hW3TvoXvZQxwzaJ4SZ9ict1HU3E6+FWlwNIgE6tIpTCyRJtiSIUDqB8TLTIBoxIs+QQBXZi+QUi3Agu6OSY2RiV0EwO8+oOOqOD9pERftc/aqe51cXuv4kPqwvpXEBwrXFWVM+VxivEubUJ7eKkFyXJpelv0LslXv/MmYbUyed6dF+reOGZCsvnbiRv74qdxbAL/25j62E8WrnxzJwhUtx/JhdBOjsHBvuw9hy6rZsVJL9eXayWyGRV6qmsLRzsRSBs+mDrgmKk4dugADd11+A03ics3i8hplRoWDkqnNKz1qy4f5TsV6v9283IANrAzRfHwX8EvNiFsBz+ZCQIDAQAB"
ttl = 300
}