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}