feat(homelab): fixing cf tunnels, authentik and tailscale!
This commit is contained in:
@@ -214,6 +214,9 @@
|
||||
scheduler = "scx_lavd";
|
||||
flags = "--performance";
|
||||
};
|
||||
tailscale = {
|
||||
enable = true
|
||||
};
|
||||
udisks = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
boot = {
|
||||
kernel = {
|
||||
variant = "latest";
|
||||
hardware = [ "amd" ];
|
||||
extraKernelParams = [ ];
|
||||
hardware = ["amd"];
|
||||
extraKernelParams = [];
|
||||
};
|
||||
loader = {
|
||||
default = {
|
||||
@@ -213,6 +213,9 @@
|
||||
scheduler = "scx_lavd";
|
||||
flags = "--performance";
|
||||
};
|
||||
tailscale = {
|
||||
enable = true;
|
||||
};
|
||||
udisks = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
@@ -8,16 +8,9 @@
|
||||
uid = 994;
|
||||
gid = 993;
|
||||
|
||||
authentik = {
|
||||
enable = true;
|
||||
};
|
||||
traefik = {
|
||||
enable = true;
|
||||
};
|
||||
www = {
|
||||
enable = true;
|
||||
url = "cnst.dev";
|
||||
};
|
||||
gitea = {
|
||||
enable = true;
|
||||
};
|
||||
@@ -62,6 +55,22 @@
|
||||
credentialsFile = config.age.secrets.vaultwardenCloudflared.path;
|
||||
};
|
||||
};
|
||||
www = {
|
||||
enable = true;
|
||||
url = "cnst.dev";
|
||||
cloudflared = {
|
||||
tunnelId = "e5076186-efb7-405a-998c-6155af7fb221";
|
||||
credentialsFile = config.age.secrets.wwwCloudflared.path;
|
||||
};
|
||||
};
|
||||
authentik = {
|
||||
enable = true;
|
||||
url = "auth.cnst.dev";
|
||||
cloudflared = {
|
||||
tunnelId = "b66f9368-db9e-4302-8b48-527cda34a635";
|
||||
credentialsFile = config.age.secrets.authentikCloudflared.path;
|
||||
};
|
||||
};
|
||||
nextcloud = {
|
||||
enable = true;
|
||||
adminpassFile = config.age.secrets.nextcloudAdminPass.path;
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
./nixos/services/udisks
|
||||
./nixos/services/xserver
|
||||
./nixos/services/zram
|
||||
./nixos/services/tailscale
|
||||
|
||||
./nixos/system/fonts
|
||||
./nixos/system/locale
|
||||
|
||||
16
modules/nixos/services/tailscale/default.nix
Normal file
16
modules/nixos/services/tailscale/default.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.nixos.services.tailscale;
|
||||
in {
|
||||
options.nixos.services.tailscale = {
|
||||
enable = mkEnableOption "Enable tailscale";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.tailscale.enable = true;
|
||||
};
|
||||
}
|
||||
@@ -15,7 +15,21 @@ in {
|
||||
};
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "auth.${srv.domain}";
|
||||
default = "auth.${srv.www.domain}";
|
||||
};
|
||||
cloudflared = {
|
||||
credentialsFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = lib.literalExpression ''
|
||||
pkgs.writeText "cloudflare-credentials.json" '''
|
||||
{"AccountTag":"secret"."TunnelSecret":"secret","TunnelID":"secret"}
|
||||
'''
|
||||
'';
|
||||
};
|
||||
tunnelId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "00000000-0000-0000-0000-000000000000";
|
||||
};
|
||||
};
|
||||
homepage.name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
@@ -36,10 +50,28 @@ in {
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
age.secrets.authentikEnv = {
|
||||
file = "${self}/secrets/authentikEnv.age";
|
||||
owner = "authentik";
|
||||
age.secrets = {
|
||||
authentikEnv = {
|
||||
file = "${self}/secrets/authentikEnv.age";
|
||||
owner = "authentik";
|
||||
};
|
||||
authentikCloudflared = {
|
||||
file = "${self}/secrets/authentikCloudflared.age";
|
||||
owner = "authentik";
|
||||
};
|
||||
};
|
||||
|
||||
server = {
|
||||
fail2ban = lib.mkIf cfg.enable {
|
||||
jails = {
|
||||
authentik = {
|
||||
serviceName = "${cfg.url}";
|
||||
failRegex = "^.*Username or password is incorrect. Try again. IP: <HOST>. Username: <F-USER>.*</F-USER>.$";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
authentik = {
|
||||
enable = true;
|
||||
@@ -52,6 +84,15 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
cloudflared = {
|
||||
enable = true;
|
||||
tunnels.${cfg.cloudflared.tunnelId} = {
|
||||
credentialsFile = cfg.cloudflared.credentialsFile;
|
||||
default = "http_status:404";
|
||||
ingress."${cfg.url}".service = "http://127.0.0.1:9000";
|
||||
};
|
||||
};
|
||||
|
||||
traefik = {
|
||||
dynamicConfigOptions = {
|
||||
http = {
|
||||
@@ -89,7 +130,7 @@ in {
|
||||
routers = {
|
||||
auth = {
|
||||
entryPoints = ["websecure"];
|
||||
rule = "Host(`${cfg.url}`) || HostRegexp(`{subdomain:[a-z0-9]+}.${srv.domain}`) && PathPrefix(`/outpost.goauthentik.io/`)";
|
||||
rule = "Host(`${cfg.url}`) || HostRegexp(`{subdomain:[a-z0-9]+}.${srv.www.url}`) && PathPrefix(`/outpost.goauthentik.io/`)";
|
||||
service = "auth";
|
||||
tls.certResolver = "letsencrypt";
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
self,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkOption mkEnableOption mkIf types;
|
||||
@@ -16,29 +17,97 @@ in {
|
||||
default = "";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Public domain name to be used to access the server services via Caddy reverse proxy
|
||||
Public domain name to be used to access the server services via Traefik reverse proxy
|
||||
'';
|
||||
};
|
||||
cloudflared = {
|
||||
credentialsFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = lib.literalExpression ''
|
||||
pkgs.writeText "cloudflare-credentials.json" '''
|
||||
{"AccountTag":"secret"."TunnelSecret":"secret","TunnelID":"secret"}
|
||||
'''
|
||||
'';
|
||||
};
|
||||
tunnelId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "00000000-0000-0000-0000-000000000000";
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
useACMEHost = cfg.url;
|
||||
extraConfig = ''
|
||||
handle_path /.well-known/webfinger {
|
||||
header Content-Type application/jrd+json
|
||||
respond `{
|
||||
"subject": "acct:adam@${cfg.url}",
|
||||
"links": [
|
||||
{
|
||||
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||
"href": "https://login.${cfg.url}/realms/cnix"
|
||||
}
|
||||
]
|
||||
}`
|
||||
}
|
||||
|
||||
reverse_proxy http://127.0.0.1:8283
|
||||
'';
|
||||
config = mkIf cfg.enable {
|
||||
age.secrets = {
|
||||
wwwCloudflared.file = "${self}/secrets/wwwCloudflared.age";
|
||||
};
|
||||
|
||||
server = {
|
||||
fail2ban = lib.mkIf config.server.www.enable {
|
||||
jails = {
|
||||
www = {
|
||||
serviceName = "cnst.dev";
|
||||
failRegex = "^.*Username or password is incorrect. Try again. IP: <HOST>. Username: <F-USER>.*</F-USER>.$";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
defaultListen = [
|
||||
{
|
||||
addr = "127.0.0.1";
|
||||
port = 8283;
|
||||
}
|
||||
];
|
||||
virtualHosts."webfinger" = {
|
||||
forceSSL = false;
|
||||
serverName = cfg.url;
|
||||
root = "/etc/webfinger";
|
||||
locations."= /.well-known/webfinger" = {
|
||||
root = "/etc/webfinger";
|
||||
extraConfig = ''
|
||||
default_type application/jrd+json;
|
||||
try_files /.well-known/webfinger =404;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cloudflared = {
|
||||
enable = true;
|
||||
tunnels.${cfg.cloudflared.tunnelId} = {
|
||||
credentialsFile = cfg.cloudflared.credentialsFile;
|
||||
default = "http_status:404";
|
||||
ingress."${cfg.url}".service = "http://127.0.0.1:8283";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."webfinger/.well-known/webfinger".text = ''
|
||||
{
|
||||
"subject": "acct:adam@${cfg.url}",
|
||||
"links": [
|
||||
{
|
||||
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||
"href": "https://auth.${cfg.url}/application/o/tailscale/"
|
||||
}
|
||||
]
|
||||
}
|
||||
'';
|
||||
|
||||
services.traefik.dynamicConfigOptions.http = {
|
||||
routers.webfinger = {
|
||||
entryPoints = ["websecure"];
|
||||
rule = "Host(`${cfg.url}`) && Path(`/.well-known/webfinger`)";
|
||||
service = "webfinger";
|
||||
tls.certResolver = "letsencrypt";
|
||||
};
|
||||
|
||||
services.webfinger.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:8283";}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
14
secrets/authentikCloudflared.age
Normal file
14
secrets/authentikCloudflared.age
Normal file
@@ -0,0 +1,14 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 t9iOEg 2oTh42u4hxJGAypwwLJwDCPMngauHB8BhKA83xAXr1M
|
||||
Sr6Hbfnd52F0dUk5RO3wxxJ7RGi3+NUCBq/MzDbKR7s
|
||||
-> ssh-ed25519 KUYMFA O2j6gYY1QR1ZlFiWw+7y6nKUeE658Wp3PdV6dsMqwTU
|
||||
NYwnTkZX5PHnNtL1vqJqIsYzIFUY43AVso8ecMAHvWs
|
||||
-> ssh-ed25519 76RhUQ VTzoQh0fHrG41Gr0YnPY7Jz7yFFugigm/DpUUE/Ny18
|
||||
SITvKJf5+ql4DhpJoPVvEXdLGIBeKnlLlm8u4QPr0RY
|
||||
-> ssh-ed25519 Jf8sqw oVI2y3zqpswvyZoNwklrKI1ZbxMJ5a1kzc43RErkbD8
|
||||
aHNuHMH2XNQ7+9sfsA8LMhBSgTDmvmI1wY26V2j+lsE
|
||||
--- 0UL0vxM2f5IeVhDO1Cg7SUmhuvpFh+GsEEW4g5JEORU
|
||||
<EFBFBD>)q<>$*<2A><><EFBFBD>b<10>X<EFBFBD><58><EFBFBD>`<60> %f
|
||||
_<EFBFBD>%%1ݗ<><DD97><EFBFBD>)<29><>fT<66>٧&<26>`+<2B>K<EFBFBD><4B>q<EFBFBD><71>I<><EEADBE><EFBFBD><EFBFBD><EFBFBD><19><><03>\=<3D>M<EFBFBD><4D><18>
|
||||
!<21><>7<EFBFBD>b<EFBFBD>]<5D>X<>_lri<72>_<EFBFBD><03><>;<3B>R
|
||||
<EFBFBD>)<29><>c<EFBFBD>H<><48>5.p<>:m<>_<EFBFBD>&Vj/<2F><01><>Ra|MU<4D><55>b<EFBFBD><62><02>y<EFBFBD><79><EFBFBD><EFBFBD>El<45>nS<6E>9"<11><>گ+<<3C>
|
||||
@@ -33,8 +33,7 @@ let
|
||||
rziggy
|
||||
];
|
||||
all = kima ++ bunk ++ sobotka ++ ziggy;
|
||||
in
|
||||
{
|
||||
in {
|
||||
# Generic
|
||||
"cnstssh.age".publicKeys = kima;
|
||||
"cnixssh.age".publicKeys = kima;
|
||||
@@ -60,6 +59,8 @@ in
|
||||
"slskd.age".publicKeys = kima ++ sobotka;
|
||||
"authentikEnv.age".publicKeys = kima ++ sobotka;
|
||||
"traefikEnv.age".publicKeys = kima ++ sobotka;
|
||||
"wwwCloudflared.age".publicKeys = kima ++ sobotka;
|
||||
"authentikCloudflared.age".publicKeys = kima ++ sobotka;
|
||||
|
||||
# Ziggy-specific
|
||||
"cloudflareDnsCredentialsZiggy.age".publicKeys = kima ++ ziggy;
|
||||
|
||||
11
secrets/wwwCloudflared.age
Normal file
11
secrets/wwwCloudflared.age
Normal file
@@ -0,0 +1,11 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 t9iOEg CWarcJM8RPjJW+e3BQ99KEUnOZQUDEIIeygeh/8MZUw
|
||||
xux60KMmyOVvgiuEqyEPXM1Wr2ne8AyHT6CAWKMOcKo
|
||||
-> ssh-ed25519 KUYMFA AThOlxHT41vsczkSGzJmT+VmWC2dAnLiIcTJP+YySkc
|
||||
Jy8HyRuzIFtGYMimxsQNm2NnbluVwS6ZuXhq4uRfabY
|
||||
-> ssh-ed25519 76RhUQ dKyDJ4DCNtYWQ2+cC7gwa+14aw99S+mU38tpQrlOmFc
|
||||
0mD5Qcv8b8Bh1e4mbqdH26UtCJaUe7C7dDDSXJd1iRY
|
||||
-> ssh-ed25519 Jf8sqw To2I/347gMqYx0PxMgYqbGekUpfqWOQwtgJ+0AFilTw
|
||||
nIo4dH9JnOuWo48a17Kjyee5sQV8HN+PNXCWDT4fjIg
|
||||
--- SuE6Z9ipbuWhxoaULMf6OGtG3BNkQ1BpWXkgfAI7Y6Y
|
||||
<EFBFBD>R<EFBFBD>u1<12><><16><><EFBFBD>d<EFBFBD>ژdʋ(s<0B>)<29>M0v<30>ѹ<EFBFBD><D1B9><EFBFBD>Z<EFBFBD>V<EFBFBD><56><10>q<05>i<EFBFBD>i<EFBFBD><69>Ec* <09>{<7B>~teP<65><50><EFBFBD>{<1C>D<>mA~Ŭ<><1B>c.<2E>TbƝ<62>}<<3C><><EFBFBD><EFBFBD><EFBFBD>e0<65>Vq<0C><><EFBFBD>k<EFBFBD><6B><EFBFBD>b<>T<1F><>*Y<><59>$<24><>t<EFBFBD><74>:<3A><>^<1C><>+<2B><1D><>;<3B>1<EFBFBD><31><EFBFBD>ۤ<EFBFBD><DBA4>Ӎ<12>X<EFBFBD>H<EFBFBD><03><>u<EFBFBD><75><EFBFBD>g<EFBFBD>߄<EFBFBD>o<EFBFBD>/<2F>G<EFBFBD><0E><><16>Kl<4B>I<EFBFBD>C<EFBFBD><43>==A<><11><>Y<EFBFBD><59><EFBFBD>U<EFBFBD><55><EFBFBD><EFBFBD>
|
||||
Reference in New Issue
Block a user