diff --git a/hosts/jorah.cx.ts.hillion.co.uk/default.nix b/hosts/jorah.cx.ts.hillion.co.uk/default.nix index 1e9149b..64ed13c 100644 --- a/hosts/jorah.cx.ts.hillion.co.uk/default.nix +++ b/hosts/jorah.cx.ts.hillion.co.uk/default.nix @@ -21,8 +21,14 @@ ## Custom Services custom = { locations.autoServe = true; - services.version_tracker.enable = true; www.global.enable = true; + services = { + version_tracker.enable = true; + gitea.actions = { + enable = true; + tokenSecret = ../../secrets/gitea/actions/jorah.age; + }; + }; }; ## Filesystems @@ -34,6 +40,11 @@ }; ## Networking + boot.kernel.sysctl = { + "net.ipv4.ip_forward" = true; + "net.ipv6.conf.all.forwarding" = true; + }; + networking = { useDHCP = false; interfaces = { diff --git a/modules/services/default.nix b/modules/services/default.nix index 9c6d199..64f6c4b 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -3,7 +3,7 @@ { imports = [ ./downloads.nix - ./gitea.nix + ./gitea/default.nix ./homeassistant.nix ./mastodon/default.nix ./matrix.nix diff --git a/modules/services/gitea/actions.nix b/modules/services/gitea/actions.nix new file mode 100644 index 0000000..14dd8a9 --- /dev/null +++ b/modules/services/gitea/actions.nix @@ -0,0 +1,98 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.custom.services.gitea.actions; +in +{ + options.custom.services.gitea.actions = { + enable = lib.mkEnableOption "gitea-actions"; + + labels = lib.mkOption { + type = with lib.types; listOf str; + default = [ + "ubuntu-latest:docker://node:16-bullseye" + "ubuntu-20.04:docker://node:16-bullseye" + ]; + }; + tokenSecret = lib.mkOption { + type = lib.types.path; + }; + }; + + config = lib.mkIf cfg.enable { + age.secrets."gitea/actions/token".file = cfg.tokenSecret; + + # Run gitea-actions in a container and firewall it such that it can only + # access the Internet (not private networks). + containers."gitea-actions" = { + autoStart = true; + ephemeral = true; + + privateNetwork = true; # all traffic goes through ve-gitea-actions on the host + hostAddress = "10.108.27.1"; + localAddress = "10.108.27.2"; + + extraFlags = [ + # Extra system calls required to nest Docker, taken from https://wiki.archlinux.org/title/systemd-nspawn + "--system-call-filter=add_key" + "--system-call-filter=keyctl" + "--system-call-filter=bpf" + ]; + + bindMounts = let tokenPath = config.age.secrets."gitea/actions/token".path; in { + "${tokenPath}".hostPath = tokenPath; + }; + + timeoutStartSec = "5min"; + + config = (hostConfig: ({ config, pkgs, ... }: { + config = let cfg = hostConfig.custom.services.gitea.actions; in { + system.stateVersion = "23.11"; + + virtualisation.docker.enable = true; + + services.gitea-actions-runner.instances.container = { + enable = true; + url = "https://gitea.hillion.co.uk"; + tokenFile = hostConfig.age.secrets."gitea/actions/token".path; + + name = "${hostConfig.networking.hostName}"; + labels = cfg.labels; + + settings = { + runner = { + capacity = 3; + }; + }; + }; + + # Drop any packets to private networks + networking = { + firewall.enable = lib.mkForce false; + nftables = { + enable = true; + ruleset = '' + table inet filter { + chain output { + type filter hook output priority 100; policy accept; + + ip daddr 10.0.0.0/8 drop + ip daddr 100.64.0.0/10 drop + ip daddr 172.16.0.0/12 drop + ip daddr 192.168.0.0/16 drop + } + } + ''; + }; + }; + }; + })) config; + }; + + networking.nat = { + enable = true; + externalInterface = "eth0"; + internalIPs = [ "10.108.27.2" ]; + }; + }; +} diff --git a/modules/services/gitea/default.nix b/modules/services/gitea/default.nix new file mode 100644 index 0000000..0b8e006 --- /dev/null +++ b/modules/services/gitea/default.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + imports = [ + ./actions.nix + ./gitea.nix + ]; +} diff --git a/modules/services/gitea.nix b/modules/services/gitea/gitea.nix similarity index 89% rename from modules/services/gitea.nix rename to modules/services/gitea/gitea.nix index a875861..eb7520f 100644 --- a/modules/services/gitea.nix +++ b/modules/services/gitea/gitea.nix @@ -20,30 +20,30 @@ in config = lib.mkIf cfg.enable { age.secrets = { "gitea/mailer_password" = { - file = ../../secrets/gitea/mailer_password.age; + file = ../../../secrets/gitea/mailer_password.age; owner = config.services.gitea.user; group = config.services.gitea.group; }; "gitea/oauth_jwt_secret" = { - file = ../../secrets/gitea/oauth_jwt_secret.age; + file = ../../../secrets/gitea/oauth_jwt_secret.age; owner = config.services.gitea.user; group = config.services.gitea.group; path = "${config.services.gitea.customDir}/conf/oauth2_jwt_secret"; }; "gitea/lfs_jwt_secret" = { - file = ../../secrets/gitea/lfs_jwt_secret.age; + file = ../../../secrets/gitea/lfs_jwt_secret.age; owner = config.services.gitea.user; group = config.services.gitea.group; path = "${config.services.gitea.customDir}/conf/lfs_jwt_secret"; }; "gitea/security_secret_key" = { - file = ../../secrets/gitea/security_secret_key.age; + file = ../../../secrets/gitea/security_secret_key.age; owner = config.services.gitea.user; group = config.services.gitea.group; path = "${config.services.gitea.customDir}/conf/secret_key"; }; "gitea/security_internal_token" = { - file = ../../secrets/gitea/security_internal_token.age; + file = ../../../secrets/gitea/security_internal_token.age; owner = config.services.gitea.user; group = config.services.gitea.group; path = "${config.services.gitea.customDir}/conf/internal_token"; @@ -97,10 +97,6 @@ in }; }; - boot.kernel.sysctl = { - "net.ipv4.ip_forward" = 1; - "net.ipv6.conf.all.forwarding" = 1; - }; networking.firewall.extraCommands = '' # proxy all traffic on public interface to the gitea SSH server iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.sshPort} diff --git a/secrets/gitea/actions/jorah.age b/secrets/gitea/actions/jorah.age new file mode 100644 index 0000000..2e5ff2d --- /dev/null +++ b/secrets/gitea/actions/jorah.age @@ -0,0 +1,19 @@ +age-encryption.org/v1 +-> ssh-rsa GxPFJQ +IULcxHpUsH6OI4cfixNPM89VJNcVkK+Z8IpgjzRspSyKc5N7jox6DYSbcuPsjGs7 +aS2JYOKOx4hYW9aL3B+tef2I24+NzMDTCT31g9gvuLA0wSMWBoFwVodPbfj1ekHy +wDUK5XrgyJtFrwTrvuklGYpb/qIEG//k7M/342C9QqfNesv9nULQ6P7+r7jJvxIW +sOo6qWHFqD/wIiwtLYiX3pOWC6m91L1QNGVh+9/t58YU8RLsgLm2+2vyg13mKya1 +UktTKZbhgRXyUJb7h+vVgDKjAnwqnIDL8asCSDuoSRDBcCxwgSpTDOxAEn9X2oJx +6S3JLQDhWLlIYrqmVT1aGg +-> ssh-rsa K9mW1w +hbVlu640hhzR9rJi4b+1c+/V+EilbmwWaNzV7/0+a9BQusTf413hffhk8QXvuze8 +04LuVctZW5L5B1eOCIeziHc6F5CyAjTsaEDM8SeKGmFjKccjdcSUdbsql87KR5Id +/drK41oNA6NlmWrLz3YaSz7A9F+B5lgsJDWgXhMFK3Hru8+gnBQPXkwT/IuQLWI1 +sXhJN/dHrBsQ5Cc+fRO7/r6u3jiQ1DOS85qQHStsYYXqea0pfiu5wpPdGZVuECwa +/R3+ov1JOTK4T3W8TIqOU9ODJxWT697Nv64c8dV3Hq5ymEKkvmZpp1C1/QoCW2EY +Nk7PF5zM95SM/IdECQjJGQ +-> ssh-ed25519 Qo6/7A 3gQq8TrBY/7Evlu+q6awqBFjG9m5b7ED+dolo8CJCE4 +JdbLYPo875DQyocjOaVmWQPdgWssuz/T6DJNqgFF020 +--- 0si8/IY1PiYgcmtTFDqu0cj7dW6DFqvgirY0tiSZfdA +A(]7qp05c$$W|%`/uXɈ\~!ledDg .i])l>E \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 742ad02..8e7b57e 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -106,6 +106,8 @@ in "gitea/security_secret_key.age".publicKeys = jake_users ++ [ ts.cx.jorah ]; "gitea/security_internal_token.age".publicKeys = jake_users ++ [ ts.cx.jorah ]; + "gitea/actions/jorah.age".publicKeys = jake_users ++ [ ts.cx.jorah ]; + # HomeAssistant Secrets "homeassistant/secrets.yaml.age".publicKeys = jake_users ++ [ ts.home.microserver ];