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