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