Self-host your own digital island
1{ pkgs, config, lib, ... }: 2 3let 4 cfg = config.eilean; 5 domain = config.networking.domain; 6in { 7 options.eilean.gitea = { 8 enable = lib.mkEnableOption "gitea"; 9 sshPort = lib.mkOption { 10 type = lib.types.int; 11 default = 3001; 12 }; 13 }; 14 15 config = lib.mkIf cfg.gitea.enable { 16 services.nginx = { 17 recommendedProxySettings = true; 18 virtualHosts."git.${domain}" = { 19 enableACME = true; 20 forceSSL = true; 21 locations."/" = { 22 proxyPass = "http://localhost:${builtins.toString config.services.gitea.settings.server.HTTP_PORT}/"; 23 }; 24 }; 25 }; 26 27 users.users.git = { 28 description = "Git Service"; 29 home = config.services.gitea.stateDir; 30 useDefaultShell = true; 31 group = "gitea"; 32 isSystemUser = true; 33 }; 34 35 services.gitea = { 36 enable = true; 37 user = "git"; 38 appName = "git | ${domain}"; 39 mailerPasswordFile = "${config.eilean.secretsDir}/email-pswd-unhashed"; 40 settings = { 41 server = { 42 ROOT_URL = "https://git.${domain}/"; 43 DOMAIN = "git.${domain}"; 44 }; 45 mailer = { 46 ENABLED = true; 47 FROM = "git@${domain}"; 48 MAILER_TYPE = "smtp"; 49 HOST = "mail.${domain}:465"; 50 USER = "misc@${domain}"; 51 IS_TLS_ENABLED = true; 52 }; 53 repository.DEFAULT_BRANCH = "main"; 54 service.DISABLE_REGISTRATION = true; 55 #server.HTTP_PORT = 3000; 56 }; 57 database = { 58 type = "postgres"; 59 passwordFile = "${config.eilean.secretsDir}/gitea-db"; 60 user = "git"; 61 name = "git"; 62 #createDatabase = true; 63 #socket = "/run/postgresql"; 64 }; 65 #stateDir = "/var/lib/gitea"; 66 }; 67 68 # https://github.com/NixOS/nixpkgs/issues/103446 69 systemd.services.gitea.serviceConfig = { 70 ReadWritePaths = [ "/var/lib/postfix/queue/maildrop" ]; 71 NoNewPrivileges = lib.mkForce false; 72 PrivateDevices = lib.mkForce false; 73 PrivateUsers = lib.mkForce false; 74 ProtectHostname = lib.mkForce false; 75 ProtectClock = lib.mkForce false; 76 ProtectKernelTunables = lib.mkForce false; 77 ProtectKernelModules = lib.mkForce false; 78 ProtectKernelLogs = lib.mkForce false; 79 RestrictAddressFamilies = lib.mkForce [ ]; 80 LockPersonality = lib.mkForce false; 81 MemoryDenyWriteExecute = lib.mkForce false; 82 RestrictRealtime = lib.mkForce false; 83 RestrictSUIDSGID = lib.mkForce false; 84 SystemCallArchitectures = lib.mkForce ""; 85 SystemCallFilter = lib.mkForce []; 86 }; 87 88 eilean.dns.enable = true; 89 eilean.services.dns.zones.${config.networking.domain}.records = [ 90 { 91 name = "git"; 92 type = "CNAME"; 93 data = "vps"; 94 } 95 ]; 96 97 # proxy port 22 on ethernet interface to internal gitea ssh server 98 # openssh server remains accessible on port 22 via vpn(s) 99 100 # allow forwarding 101 boot.kernel.sysctl = { 102 "net.ipv4.ip_forward" = 1; 103 "net.ipv6.conf.all.forwarding" = 1; 104 }; 105 106 networking.firewall = { 107 allowedTCPPorts = [ 108 22 109 cfg.gitea.sshPort 110 ]; 111 extraCommands = '' 112 # proxy all traffic on public interface to the gitea SSH server 113 iptables -A PREROUTING -t nat -i ${config.eilean.publicInterface} -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort} 114 ip6tables -A PREROUTING -t nat -i ${config.eilean.publicInterface} -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort} 115 116 # proxy locally originating outgoing packets 117 iptables -A OUTPUT -d ${config.eilean.serverIpv4} -t nat -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort} 118 ip6tables -A OUTPUT -d ${config.eilean.serverIpv6} -t nat -p tcp --dport 22 -j REDIRECT --to-port ${builtins.toString cfg.gitea.sshPort} 119 ''; 120 }; 121 122 services.gitea.settings.server = { 123 START_SSH_SERVER = true; 124 SSH_LISTEN_PORT = cfg.gitea.sshPort; 125 }; 126 }; 127}