blob: 376c7a4b2686c05072ca79aee297e423f1665a75 (
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
|
{ ... }:
{
imports = [
../../modules/common.nix
./hardware.nix
./devices.nix
../../services/pds.nix
../../services/akkoma
];
foundation = {
www = {
enable = true;
public = true;
tailnet = true;
};
monitoring = {
client.enable = true;
services = [
"base"
"akkoma"
"pds"
];
};
};
system.stateVersion = "23.05";
}
.highlight .mb { color: #F0F } /* Literal.Number.Bin */
.highlight .mf { color: #F0F } /* Literal.Number.Float */
.highlight .mh { color: #F0F } /* Literal.Number.Hex */
.highlight .mi { color: #F0F } /* Literal.Number.Integer */
.highlight .mo { color: #F0F } /* Literal.Number.Oct */
.highlight .sa { color: #87CEEB } /* Literal.String.Affix */
.highlight .sb { color: #87CEEB } /* Literal.String.Backtick */
.highlight .sc { color: #87CEEB } /* Literal.String.Char */
.highlight .dl { color: #87CEEB } /* Literal.String.Delimiter */
.highlight .sd { color: #87CEEB } /* Literal.String.Doc */
.highlight .s2 { color: #87CEEB } /* Literal.String.Double */
.highlight .se { color: #87CEEB } /* Literal.String.Escape */
.highlight .sh { color: #87CEEB } /* Literal.String.Heredoc */
.highlight .si { color: #87CEEB } /* Literal.String.Interpol */
.highlight .sx { color: #87CEEB } /* Literal.String.Other */
.highlight .sr { color: #87CEEB } /* Literal.String.Regex */
.highlight .s1 { color: #87CEEB } /* Literal.String.Single */
.highlight .ss { color: #87CEEB } /* Literal.String.Symbol */
.highlight .bp { color: #DDD } /* Name.Builtin.Pseudo */
.highlight .fm { color: #FF0 } /* Name.Function.Magic */
.highlight .vc { color: #EEDD82 } /* Name.Variable.Class */
.highlight .vg { color: #EEDD82 } /* Name.Variable.Global */
.highlight .vi { color: #EEDD82 } /* Name.Variable.Instance */
.highlight .vm { color: #EEDD82 } /* Name.Variable.Magic */
.highlight .il { color: #F0F } /* Literal.Number.Integer.Long */# NOTE: the tailnet virtual host and it's certificate management
# has been mostly superseded by the `rnrd.fyi` domain, allowing
# for both vastly simpler certificate requesting and subdomains,
# which tailscale does not support for their magicdns product.
{
me,
config,
lib,
pkgs,
...
}:
let
cfg = config.foundation.www;
rnrdInternalUrl = if me.is.renard then "rnrd.fyi" else "${me.name}.rnrd.fyi";
oneWeekInSeconds = 7 * 24 * 60 * 60;
tailscaleRenewScript = pkgs.writeShellScript "tailscale-cert-renew" ''
set -euxo pipefail
check_validity() {
pem=$1
${pkgs.openssl}/bin/openssl x509 \
-checkend ${toString oneWeekInSeconds} \
-noout <$pem &&
[ "$(${pkgs.openssl}/bin/openssl x509 -pubkey -noout <$pem)" \
= "$(${pkgs.openssl}/bin/openssl pkey -pubout <out/key.pem)" ]
}
try_renew() {
${pkgs.tailscale}/bin/tailscale cert \
--cert-file certificates/fullchain.pem \
--key-file certificates/key.pem \
${me.tailscale.domain}
}
cut_out_certificate_authority() {
fullchain=$1
buf=""
while read LINE; do
if [[ $LINE == *"BEGIN CERTIFICATE"* ]]; then
buf=""
fi
buf="$buf$LINE"$'\n'
done < $fullchain
echo "$buf"
}
install_certificates() {
touch out/renewed
cp -vp 'certificates/fullchain.pem' out/fullchain.pem
cp -vp 'certificates/key.pem' out/key.pem
ln -sf fullchain.pem out/cert.pem
cat out/key.pem out/fullchain.pem > out/full.pem
cut_out_certificate_authority out/fullchain.pem > out/chain.pem
chown 'acme:nginx' out/*
chmod 640 out/*
}
if [[ ! -e 'out/fullchain.pem' ]] || ! check_validity out/fullchain.pem; then
echo 1>&2 "attempting tailscale certificate renewal..."
if ! try_renew; then
echo 1>&2 "renewal failed :("
exit 1
fi
install_certificates
echo 1>&2 "successfully renewed certificate :)"
else
echo 1>&2 "renewal not yet necessary."
fi
'';
in
{
options.foundation.www = {
tailnet = lib.mkEnableOption "tailnet internal host";
};
config = lib.mkIf (cfg.enable && cfg.tailnet) {
security.acme.certs.${me.tailscale.domain} = {
# since we replace the renew script, the dns provider is not important,
# however, we can't have the configuration thinking that the acme
# renewal service depends on nginx, so instead it's a "dns certificate".
dnsProvider = "dummy";
webroot = null;
};
# overwrite default acme behaviour with tailscale
systemd.services."acme-order-renew-${me.tailscale.domain}" = {
serviceConfig.ExecStart = lib.mkForce "+${tailscaleRenewScript}";
};
# tailnet internal vhost
services.nginx.virtualHosts = {
# mostly superceded
tailnet = {
forceSSL = true;
enableACME = true;
serverName = me.tailscale.domain;
listenAddresses = [ me.tailscale.ip ];
# point to the default page, for now!
locations."/" = {
alias = "${cfg.defaultPage}/";
};
extraConfig = ''
access_log /var/log/nginx/tailnet.access.log json_combined;
'';
};
# default page for the `rnrd.fyi` internal domain
${rnrdInternalUrl} = {
useACMEHost = "rnrd.fyi";
forceSSL = true;
listenAddresses = [ me.tailscale.ip ];
locations."/" = {
alias = "${cfg.defaultPage}/";
};
extraConfig = ''
access_log /var/log/nginx/tailnet.access.log json_combined;
'';
};
};
foundation.tailnetServices = [
"nginx"
"acme-${me.tailscale.domain}"
];
};
}
|