This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

configs.services.git: knot owner, git ssh on port 22

Sets the knot's owner DID (lass.pds.lassul.us), which turns the knot on.
knot-rs binds one SSH address, so it stays on [::]:2222 and port 22 on
neoprism's two public addresses is redirected to it (configs/ssh-redirect.nix
only rejects 22 that still reaches sshd). Admin SSH is unchanged.

+137 -125
+137 -125
configs/services/git/knot.nix
··· 7 7 }: 8 8 let 9 9 domain = "knot.lassul.us"; 10 - # DID of the owner's account on pds.lassul.us; the knot stays off while null 11 - ownerDid = null; 10 + # DID of the owner's account on pds.lassul.us 11 + ownerDid = "did:plc:6nk6tk76up7254wawocoekjr"; # lass.pds.lassul.us 12 12 user = "tangled-knot"; 13 13 stateDir = "/var/lib/tangled-knot"; 14 14 listenAddr = "127.0.0.1:5555"; ··· 62 62 # in a fetched source, importing them would be IFD): plain HTTP behind 63 63 # nginx, unprivileged ports, keys in stateDir. The Go knot's unit and user 64 64 # are both named knot, which the DNS server already uses. 65 - # Knot 2 serves ssh itself, on port 2222 since sshd keeps 22, so clone URLs 66 - # need ssh://git@knot.lassul.us:2222/... or a Port line in ~/.ssh/config. 65 + # Knot 2 serves ssh itself on [::]:2222 (it binds a single address, and 66 + # sshd keeps 22). Port 22 on the public addresses is redirected to it, so 67 + # git@knot.lassul.us:<owner>/<repo> works as the appview shows it. Admin 68 + # ssh stays on 22 via retiolum/wiregrill and on public 45621 69 + # (ssh-redirect.nix). 67 70 68 - config = lib.mkIf (ownerDid != null) { 69 - clan.core.vars.generators.tangled-knot = { 70 - files."knot.env" = { }; 71 - runtimeInputs = [ pkgs.openssl ]; 72 - script = '' 73 - echo "KNOT_MASTER_KEY=$(openssl rand -base64 32)" > "$out/knot.env" 74 - ''; 75 - }; 71 + clan.core.vars.generators.tangled-knot = { 72 + files."knot.env" = { }; 73 + runtimeInputs = [ pkgs.openssl ]; 74 + script = '' 75 + echo "KNOT_MASTER_KEY=$(openssl rand -base64 32)" > "$out/knot.env" 76 + ''; 77 + }; 76 78 77 - environment.systemPackages = [ package ]; 78 - environment.etc."knot/config.toml".source = configFile; 79 + environment.systemPackages = [ package ]; 80 + environment.etc."knot/config.toml".source = configFile; 79 81 80 - users.users.${user} = { 81 - isSystemUser = true; 82 - home = stateDir; 82 + users.users.${user} = { 83 + isSystemUser = true; 84 + home = stateDir; 85 + group = user; 86 + }; 87 + users.groups.${user} = { }; 88 + 89 + systemd.tmpfiles.settings."10-knot-rs" = { 90 + ${stateDir}.d = { 91 + mode = "0750"; 92 + inherit user; 83 93 group = user; 84 94 }; 85 - users.groups.${user} = { }; 86 - 87 - systemd.tmpfiles.settings."10-knot-rs" = { 88 - ${stateDir}.d = { 89 - mode = "0750"; 90 - inherit user; 91 - group = user; 92 - }; 93 - "${stateDir}/repos".d = { 94 - mode = "0750"; 95 - inherit user; 96 - group = user; 97 - }; 95 + "${stateDir}/repos".d = { 96 + mode = "0750"; 97 + inherit user; 98 + group = user; 98 99 }; 100 + }; 99 101 100 - systemd.services.knot-rs = { 101 - description = "knot git server"; 102 - after = [ "network-online.target" ]; 103 - wants = [ "network-online.target" ]; 104 - wantedBy = [ "multi-user.target" ]; 105 - restartTriggers = [ configFile ]; 106 - startLimitIntervalSec = 60; 107 - startLimitBurst = 5; 108 - serviceConfig = { 109 - User = user; 110 - Group = user; 111 - UMask = "0077"; 112 - WorkingDirectory = stateDir; 113 - EnvironmentFile = config.clan.core.vars.generators.tangled-knot.files."knot.env".path; 114 - ExecStart = "${lib.getExe package} /etc/knot/config.toml"; 115 - Restart = "on-failure"; 116 - RestartSec = 5; 117 - TimeoutStopSec = 120; 118 - LimitNOFILE = 65536; 119 - CapabilityBoundingSet = [ ]; 120 - ReadWritePaths = [ 121 - stateDir 122 - "${stateDir}/repos" 123 - ]; 124 - NoNewPrivileges = true; 125 - ProtectProc = "invisible"; 126 - ProtectSystem = "strict"; 127 - ProtectHome = true; 128 - PrivateTmp = true; 129 - PrivateDevices = true; 130 - PrivateUsers = true; 131 - ProtectHostname = true; 132 - ProtectClock = true; 133 - ProtectKernelTunables = true; 134 - ProtectKernelModules = true; 135 - ProtectKernelLogs = true; 136 - ProtectControlGroups = true; 137 - RestrictAddressFamilies = [ 138 - "AF_INET" 139 - "AF_INET6" 140 - "AF_NETLINK" 141 - "AF_UNIX" 142 - ]; 143 - RestrictNamespaces = true; 144 - LockPersonality = true; 145 - MemoryDenyWriteExecute = true; 146 - RestrictRealtime = true; 147 - RestrictSUIDSGID = true; 148 - RemoveIPC = true; 149 - PrivateMounts = true; 150 - SystemCallFilter = [ 151 - "@system-service" 152 - "~@privileged @resources" 153 - ]; 154 - SystemCallArchitectures = "native"; 155 - }; 102 + systemd.services.knot-rs = { 103 + description = "knot git server"; 104 + after = [ "network-online.target" ]; 105 + wants = [ "network-online.target" ]; 106 + wantedBy = [ "multi-user.target" ]; 107 + restartTriggers = [ configFile ]; 108 + startLimitIntervalSec = 60; 109 + startLimitBurst = 5; 110 + serviceConfig = { 111 + User = user; 112 + Group = user; 113 + UMask = "0077"; 114 + WorkingDirectory = stateDir; 115 + EnvironmentFile = config.clan.core.vars.generators.tangled-knot.files."knot.env".path; 116 + ExecStart = "${lib.getExe package} /etc/knot/config.toml"; 117 + Restart = "on-failure"; 118 + RestartSec = 5; 119 + TimeoutStopSec = 120; 120 + LimitNOFILE = 65536; 121 + CapabilityBoundingSet = [ ]; 122 + ReadWritePaths = [ 123 + stateDir 124 + "${stateDir}/repos" 125 + ]; 126 + NoNewPrivileges = true; 127 + ProtectProc = "invisible"; 128 + ProtectSystem = "strict"; 129 + ProtectHome = true; 130 + PrivateTmp = true; 131 + PrivateDevices = true; 132 + PrivateUsers = true; 133 + ProtectHostname = true; 134 + ProtectClock = true; 135 + ProtectKernelTunables = true; 136 + ProtectKernelModules = true; 137 + ProtectKernelLogs = true; 138 + ProtectControlGroups = true; 139 + RestrictAddressFamilies = [ 140 + "AF_INET" 141 + "AF_INET6" 142 + "AF_NETLINK" 143 + "AF_UNIX" 144 + ]; 145 + RestrictNamespaces = true; 146 + LockPersonality = true; 147 + MemoryDenyWriteExecute = true; 148 + RestrictRealtime = true; 149 + RestrictSUIDSGID = true; 150 + RemoveIPC = true; 151 + PrivateMounts = true; 152 + SystemCallFilter = [ 153 + "@system-service" 154 + "~@privileged @resources" 155 + ]; 156 + SystemCallArchitectures = "native"; 156 157 }; 158 + }; 157 159 158 - networking.firewall.allowedTCPPorts = [ sshPort ]; 160 + networking.firewall.allowedTCPPorts = [ sshPort ]; 159 161 160 - # knot 2 doesn't request crawls (no KNOT_MIRRORS), so subscribe our 161 - # mirror (knotmirror.nix) to the knot's event stream whenever either 162 - # starts; the mirror marks a knot offline after it was unreachable for a 163 - # while 164 - systemd.services.knotmirror-request-crawl = { 165 - wantedBy = [ 166 - "knot-rs.service" 167 - "knotmirror.service" 168 - ]; 169 - after = [ 170 - "knot-rs.service" 171 - "knotmirror.service" 172 - ]; 173 - serviceConfig.Type = "oneshot"; 174 - script = '' 175 - ${pkgs.curl}/bin/curl -fsS --retry 10 --retry-connrefused \ 176 - -H 'Content-Type: application/json' -d '{"hostname":"${domain}"}' \ 177 - http://127.0.0.1:7000/xrpc/sh.tangled.sync.requestCrawl 162 + # knot 2 doesn't request crawls (no KNOT_MIRRORS), so subscribe our 163 + # mirror (knotmirror.nix) to the knot's event stream whenever either 164 + # starts; the mirror marks a knot offline after it was unreachable for a 165 + # while 166 + systemd.services.knotmirror-request-crawl = { 167 + wantedBy = [ 168 + "knot-rs.service" 169 + "knotmirror.service" 170 + ]; 171 + after = [ 172 + "knot-rs.service" 173 + "knotmirror.service" 174 + ]; 175 + serviceConfig.Type = "oneshot"; 176 + script = '' 177 + ${pkgs.curl}/bin/curl -fsS --retry 10 --retry-connrefused \ 178 + -H 'Content-Type: application/json' -d '{"hostname":"${domain}"}' \ 179 + http://127.0.0.1:7000/xrpc/sh.tangled.sync.requestCrawl 180 + ''; 181 + }; 182 + 183 + networking.nftables.tables.knot-ssh = { 184 + family = "inet"; 185 + content = '' 186 + chain prerouting { 187 + type nat hook prerouting priority dstnat; policy accept; 188 + ip daddr 95.217.192.59 tcp dport 22 redirect to :${toString sshPort} 189 + ip6 daddr 2a01:4f9:4a:4f1a::2 tcp dport 22 redirect to :${toString sshPort} 190 + } 191 + ''; 192 + }; 193 + 194 + # repos (with the ACL data), sealed keys and ssh host key; the master key 195 + # is in vars 196 + lass.backup.state.tangled-knot.folders = [ stateDir ]; 197 + 198 + services.nginx.virtualHosts.${domain} = { 199 + enableACME = true; 200 + forceSSL = true; 201 + locations."/" = { 202 + proxyPass = "http://${listenAddr}"; 203 + recommendedProxySettings = true; 204 + # /events 205 + proxyWebsockets = true; 206 + extraConfig = '' 207 + proxy_read_timeout 1d; 208 + client_max_body_size 0; 209 + proxy_request_buffering off; 178 210 ''; 179 - }; 180 - 181 - # repos (with the ACL data), sealed keys and ssh host key; the master key 182 - # is in vars 183 - lass.backup.state.tangled-knot.folders = [ stateDir ]; 184 - 185 - services.nginx.virtualHosts.${domain} = { 186 - enableACME = true; 187 - forceSSL = true; 188 - locations."/" = { 189 - proxyPass = "http://${listenAddr}"; 190 - recommendedProxySettings = true; 191 - # /events 192 - proxyWebsockets = true; 193 - extraConfig = '' 194 - proxy_read_timeout 1d; 195 - client_max_body_size 0; 196 - proxy_request_buffering off; 197 - ''; 198 - }; 199 211 }; 200 212 }; 201 213 }