feat: expose git via tammena.me

This commit is contained in:
Malte Tammena 2023-10-30 15:35:55 +01:00
parent 1ee4ea8d47
commit 323f17815c
8 changed files with 127 additions and 99 deletions

View file

@ -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. Its perfectly fine and recommended to leave

View file

@ -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;

View file

@ -26,7 +26,6 @@ in {
./taskserver.nix
./wakeup.nix
./darkman.nix
./gogs.nix
./state.nix
];

View file

@ -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;
};
};
};
}

View file

@ -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 {};
};
}

View file

@ -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: |

View file

@ -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-----

View file

@ -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;
};
};
}