diff --git a/hosts/faunus-ater.nix b/hosts/faunus-ater.nix index c1fa411..c6d6627 100644 --- a/hosts/faunus-ater.nix +++ b/hosts/faunus-ater.nix @@ -53,14 +53,30 @@ in { }; # === Git.home, because everything else sucks === - services.gogsHome = { + services.gogs = { enable = true; - passwordFile = sopsPath "gogs-database-password"; - addr = { - v4 = vpnIPv4; - v6 = vpnIPv6; - }; stateDir = "/data/dirty/gogs"; + appName = "Malte's Secret Git Stash"; + cookieSecure = true; + database.passwordFile = sopsPath "gogs-database-password"; + httpPort = config.state.services.git.port; + rootUrl = "https://git.tammena.me/"; + domain = "git.tammena.me"; + # FIXME: Remove after upstream fix of database type + extraConfig = '' + [database] + TYPE = sqlite3 + + [auth] + DISABLE_REGISTRATION = true + SHOW_REGISTRATION_BUTTON = false + ''; + }; + services.nginx.virtualHosts."git.home" = mkVirtHost "git-home" { + locations."/" = { + proxyPass = "http://${config.services.gogs.httpAddress}:${builtins.toString config.services.gogs.httpPort}"; + proxyWebsockets = true; + }; }; virtualisation.oci-containers.backend = "podman"; @@ -387,6 +403,13 @@ in { }; }; + # All services that run here, that should be exposed need to be exposed on the VPN + networking.firewall.interfaces.${config.services.tailscale.interfaceName}.allowedTCPPorts = let + selectPort = name: config: config.port; + filterRunningHereAndExposed = lib.attrsets.filterAttrs (name: conf: conf.host == config.networking.hostName && conf ? external && conf.external); + in + lib.attrsets.mapAttrsToList selectPort (filterRunningHereAndExposed config.state.services); + # This value determines the NixOS release from which the default # settings for stateful data, like file locations and database versions # on your system were taken. It‘s perfectly fine and recommended to leave diff --git a/hosts/granodomus-lima.nix b/hosts/granodomus-lima.nix index e0d52fd..c3a3922 100644 --- a/hosts/granodomus-lima.nix +++ b/hosts/granodomus-lima.nix @@ -37,40 +37,63 @@ in { sops.defaultSopsFile = ../secrets/hosts/granodomus-lima/secrets.yaml; sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; + services.fail2ban = { + enable = true; + ignoreIP = let + vpn = (builtins.import ../state.nix).vpn; + extractIPs = host: config: [config.v4 config.v6]; + in + lib.flatten (lib.attrsets.mapAttrsToList extractIPs vpn); + }; + # Run radicale with infcloud interface for me and Marie services.radicaleWithInfcloud.enable = true; - sops.secrets = let - nginxSecret = { - owner = "nginx"; - mode = "0400"; + services.nginx.virtualHosts = let + services = (builtins.import ../state.nix).services; + removeUnexposed = lib.attrsets.filterAttrs (name: config: config ? "external" && config.external); + createVirtHost = name: config: { + name = "${name}.tammena.me"; + value = mkVirtHost "${name}-tammena-me" { + locations."/" = { + proxyPass = "http://${config.host}:${builtins.toString config.port}"; + proxyWebsockets = true; + }; + }; }; - in { - certificate-key-config-tammena-me = nginxSecret; - certificate-key-todo-tammena-me = nginxSecret; - certificate-key-time-tammena-me = nginxSecret; - }; + in + lib.mapAttrs' createVirtHost (removeUnexposed services); - services.nginx.virtualHosts = { - "config.tammena.me" = mkVirtHost "config-tammena-me" { - locations."/" = { - proxyPass = "https://config.home"; - proxyWebsockets = true; + sops.secrets = + lib.mapAttrs' (name: config: { + name = "certificate-key-${name}-tammena-me"; + value = { + owner = "nginx"; + mode = "0400"; }; - }; - "todo.tammena.me" = mkVirtHost "todo-tammena-me" { - locations."/" = { - proxyPass = "https://todo.home"; - proxyWebsockets = true; - }; - }; - "time.tammena.me" = mkVirtHost "time-tammena-me" { - locations."/" = { - proxyPass = "https://time.home"; - proxyWebsockets = true; - }; - }; - }; + }) + (builtins.import ../state.nix).services; + + # services.nginx.virtualHosts = { + # "config.tammena.me" = mkVirtHost "config-tammena-me" { + # locations."/" = { + # proxyPass = "https://config.home"; + # proxyWebsockets = true; + # }; + # }; + # "todo.tammena.me" = mkVirtHost "todo-tammena-me" { + # locations."/" = { + # proxyPass = "https://todo.home"; + # proxyWebsockets = true; + # }; + # }; + # "time.tammena.me" = mkVirtHost "time-tammena-me" { + # locations."/" = { + # proxyPass = "https://time.home"; + # proxyWebsockets = true; + # }; + # }; + # }; services.qemuGuest.enable = true; diff --git a/modules/base-system.nix b/modules/base-system.nix index 643dbcf..93c96b3 100644 --- a/modules/base-system.nix +++ b/modules/base-system.nix @@ -26,7 +26,6 @@ in { ./taskserver.nix ./wakeup.nix ./darkman.nix - ./gogs.nix ./state.nix ]; diff --git a/modules/gogs.nix b/modules/gogs.nix deleted file mode 100644 index 9ca2557..0000000 --- a/modules/gogs.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ - pkgs, - config, - lib, - ... -}: let - cfg = config.services.gogsHome; -in { - options.services.gogsHome = { - enable = lib.mkEnableOption "Pre-Configured gogs service"; - passwordFile = with lib; - mkOption { - type = types.str; - description = "Password file for the database"; - }; - addr.v4 = with lib; - mkOption { - type = types.str; - description = "v4-Address to listen on"; - }; - addr.v6 = with lib; - mkOption { - type = types.str; - description = "v6-Address to listen on"; - }; - stateDir = with lib; - mkOption { - type = types.str; - description = "Root path for all the data"; - }; - }; - - config = lib.mkIf cfg.enable { - services.gogs = { - inherit (cfg) stateDir; - enable = true; - appName = "Malte's Secret Git Stash"; - cookieSecure = true; - database.passwordFile = cfg.passwordFile; - httpPort = 10219; - rootUrl = "https://git.home/"; - domain = "git.home"; - # FIXME: Remove after upstream fix of database type - extraConfig = '' - [database] - TYPE = sqlite3 - ''; - }; - - services.nginx.virtualHosts.${config.services.gogs.domain} = { - addSSL = true; - listenAddresses = [cfg.addr.v4 "[${cfg.addr.v6}]"]; - sslTrustedCertificate = pkgs.writeText "ca.crt" (builtins.readFile ../secrets/ca.crt); - sslCertificateKey = config.sops.secrets."certificate-key-git-home".path; - sslCertificate = ../secrets/pub/git-home.crt; - locations."/" = { - proxyPass = "http://${config.services.gogs.httpAddress}:${toString config.services.gogs.httpPort}"; - proxyWebsockets = true; - }; - }; - }; -} diff --git a/modules/state.nix b/modules/state.nix index b738c38..4142347 100644 --- a/modules/state.nix +++ b/modules/state.nix @@ -41,6 +41,27 @@ in { description = "VPN internal DNS server address"; readOnly = true; }; + services = mkOption { + type = with types; + attrsOf (submodule { + options = { + host = mkOption { + type = str; + description = "Host where the service runs"; + }; + port = mkOption { + type = number; + description = "Port over which the service can be accessed"; + }; + external = mkOption { + type = nullOr bool; + description = "Whether this service should be exposed (outside of VPN)"; + }; + }; + }); + description = "Service settings"; + readOnly = true; + }; }; config.state = let @@ -63,5 +84,9 @@ in { }) state.vpn else builtins.throw "No VPN definitions"; + services = + if state ? services + then state.services + else {}; }; } diff --git a/secrets/hosts/granodomus-lima/secrets.yaml b/secrets/hosts/granodomus-lima/secrets.yaml index d4d3227..3bfbe83 100644 --- a/secrets/hosts/granodomus-lima/secrets.yaml +++ b/secrets/hosts/granodomus-lima/secrets.yaml @@ -3,6 +3,7 @@ certificate-key-config-tammena-me: ENC[AES256_GCM,data:Xi/ZOiUmDDTJSICxCrWCUKlXJ certificate-key-todo-tammena-me: ENC[AES256_GCM,data:rmuVdlxUxURygFB+JCijuPQkKOcr9mUmmkRJ7edxsIkyo3K/YSwGf8AF7jJF43f9Dhf2xzRSK2CveSDFOVI6NzNXkZvth1yySQT4QDpbWjlU4fkk9Jo64fYANUMPcakRyHHQiZN0pSCWvtP2WUEM66pr/94ihH6KyQ8SRsLlUbXdMXPzNI9Ydgk5Px3KMx2qy7MXRVsFgsSA2fI0C0+PFXVuNAflGXmDqokWIQdeSgHYmHXItIbVnPuCMr/GW0N8hQ4TkxKqWrijrgTA6FoQx2NEscQelV2eZKxzucE/0YbNl5O4a8jP5l5C245Ypsp4N0XP79RTVALMUA5ZoPBKQsR/dL2c5VRyqI8iVX1PtSBOt6HyrtrZ3UhC4vmXdlkiXb8AnMETRgn1zs36fMU=,iv:yQcLBF1tJ4+Gut6h8xVc0HJ4rIQk/x2Xw6e0QilNd2A=,tag:f01qLt8wqiWw9fauObPqvQ==,type:str] certificate-key-time-tammena-me: ENC[AES256_GCM,data:b5UCTT/QwuoU0ami+GAUWFSdWtZGmFpK03SbXMs1NDspIs2U88lKrUp+kZ0S6Em+IFBRgwTzwia3ljLuGPEDSIdwS+utLSuJhfUd8m95IH8XDVfpmY59tAcWzmWuMSDjCQDBAVUVowocnO+DZLGvofny6306uIXu0Kd4RVG0O515dHGh2ynkAhOZJClqt3TLYUVzdMG7KQWCDoHhcEQv6YhPTaHHp5+1wsICSxZkWz5OSNkadPrZgGBfDpGMUz2laJIfbI/EfDJ+KewW4m+N5LOiTtBWTJivO+fEdoGo5MQxBaaXP10zpu/vNfaxe+QMfNJrzXR3sfdmpe/YF0miUf5SIqebW34apopQ1n9MAI3qneh3NMoQwj48FrHUjM0fMSRISImEuKN28vCDbSM=,iv:ML+a2gCM5Iq2N27Zzt210DURqEnMyjAzn2EJ6VfCxsc=,tag:2bWZmsdoOGeEgBYCAhluhA==,type:str] certificate-key-cal-tammena-me: ENC[AES256_GCM,data:1vLOI1kayAfQKv83ZPLZdqeUZGE5M9uTCPVKL9jC45gqXL9FmNtWZIAucttY1pPZGLxD9f9FU/NDnVpUxOz7tJKMI33HMyhJ+io3zf+hRk5rQN6qIBt665IHH36wHMr9hxy/mD7sSeKsMKjLyLTL6Jn2DucJEupRJWvZ3y9uv/7BulhQfpOngMPj4kAX33eZOVrww1AbrZXeUeuEiFiV4aa74BuXNODHq4H2qq1L1EwHNuI0IdItWTniFAoKdpGJu6bLL4e2N1Jj3NTeEUOhsR1iM/lrM/qjfQNUcg92iAWUd5j6WNfRVR4YcWYlePizx0/LTcBHh4ouTFupye87rDANGsnFWs6YqiM/qWoFKbncrf9t/de5IZklmoFlLmb92k2oyXvt3OKpL598Od4=,iv:un+TMKF01AiTWXyNEWtF25ELXUmBzBf060gdtx7FdKc=,tag:AsTTJ7gTrb3+4AGD+tTTmA==,type:str] +certificate-key-git-tammena-me: ENC[AES256_GCM,data:PeKtIjTPRuTrA7mh2wybdejhj3ElUzA3mswftqP54JkD574nCuOR74Pl9OF/csIRoXikl9Rduqbf+L9CL99ibMU/c+kOYPoVQKSu0+kcnYYcGUKZ2KiEarcbYsa78WqYT7Kt5GrKeJ6awA4jLuxBkd0GGk8ZYBG3uxIews4nrqDbhqlCpZXzrSzoyDIn8MY0fHdPOmU5bif94TQNaoQLcAKE1zUKGQeTygMb+nSylIct8C1LTC/N0n0R+gA0KbIfxAnfgH9SfAqz+Upz95IAVXlM9MCBvOF7BZwj+oqNjCz80d0ofcSf9nvVfwzuYf3sT56huQPTonG0FcEL8LT9QANjSJcM29Wro0JYRdgAa+946OCFPHLl6Q7jcPAuDAz2xM+HnQaqCsgCOMqNDq4=,iv:WqfR4GQIZhIKfM95T71JflprIF1iet0mAQouAntQs54=,tag:DBmBP7JwOX9AHlAEH7wC0Q==,type:str] sops: kms: [] gcp_kms: [] @@ -18,8 +19,8 @@ sops: UW4vM0c5aUQyUDlGZEhERTdhdnVmQmcKA7UK+a+CbqPXsz24QZwo7fWbRlh0peKE qc90P8uofufse9XJ/6ReF2ypUPjYfXbPq1c5vIrZYk/8Y1wS/+Z9xg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2023-09-12T20:12:32Z" - mac: ENC[AES256_GCM,data:0G5L2koNhB0OMLYTNc+1AjG46TCVtwYqXtLhdW9ey7bEm8ZyJqyV3+Thtzd7fycl5HAHtFW3hu+/1FLs5IC/oOtr+7XZsGOvusMGhsBoHrJC5NSqRmRQUwm3ZFMDPWnAZ4n1Ua8+ai11tunNih1Bv4YA6F25GQe6UOMtdB6tgdQ=,iv:tzmKAj1DTRCUO/qQq1gvJ8GHgSAli6pEMvRUYbx4D2M=,tag:f/+ZLqG7gu1NDICVNb6i8Q==,type:str] + lastmodified: "2023-10-30T13:45:20Z" + mac: ENC[AES256_GCM,data:LBqoV4d2uJJksew18HgYjA3oQZp1LAtejhDMrVvuw0h69tJoZgHPL1tTs8VdzxtjLwtplWs31xa8L/HiZT7URBBywQVE5RfVBFAgDP/ukxoPBjcbN9CvAuu5Bx8vj8KY58cKlCzuqo3rZzvWDMNHwzmZvf8o7Vwm0jYNIdwwyEE=,iv:loUqYCTMarbrNF2GZVCFBNvuGGqFVG3EArHy/hoj3ko=,tag:RyppqE7E0iYR5TJVrN4N7Q==,type:str] pgp: - created_at: "2023-01-15T18:09:59Z" enc: | diff --git a/secrets/pub/git-tammena-me.crt b/secrets/pub/git-tammena-me.crt new file mode 100644 index 0000000..3f711a0 --- /dev/null +++ b/secrets/pub/git-tammena-me.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBpjCCAU2gAwIBAgIUYcxq5e6WbgaWqf6Y0jO7BttjxK8wCgYIKoZIzj0EAwIw +FTETMBEGA1UEAwwKTXkgSG9tZSBDQTAeFw0yMzEwMzAxMzQ1MTlaFw0yNDEwMjkx +MzQ1MTlaMBExDzANBgNVBAMMBiouaG9tZTBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABEvM9Ue0hNEp+v5LV8YQqgJf0rzwhx5yR7pAw5f3tLs579FWWGj29R/baYO3 +hBPykDoN61+nDj+imL+i+WRjh5ejfzB9MAsGA1UdDwQEAwIF4DATBgNVHSUEDDAK +BggrBgEFBQcDATAZBgNVHREEEjAQgg5naXQudGFtbWVuYS5tZTAdBgNVHQ4EFgQU +ax1ogN8AUZeBo+PCG2yL17hbNgUwHwYDVR0jBBgwFoAU3LHFhGwT3qMYGN9SmsFe +qDIHztMwCgYIKoZIzj0EAwIDRwAwRAIgBzxmAP/6VkRNWCCYDxeD572NUjkYtE8D +Ql3Dzy5WSbsCICD14Od/O8UEk3szZkBdBLKvgcTiXBG20lyffw+0tbUw +-----END CERTIFICATE----- diff --git a/state.nix b/state.nix index 4c77028..492fe40 100644 --- a/state.nix +++ b/state.nix @@ -33,6 +33,14 @@ v6 = "fd7a:115c:a1e0:ab12:4843:cd96:627c:6e2b"; }; }; + #### SERVICES #### + # Information about which services run where + # Type: attrsOf { host: str, port: number } + services = { + git = { + host = "faunus-ater"; + port = 10219; + external = true; }; }; }