default.nix (9489B)
1 { 2 config, 3 lib, 4 pkgs, 5 inputs, 6 ... 7 }: 8 9 { 10 imports = [ 11 ./hardware.nix 12 ]; 13 14 # decrypt agenix secrets 15 age.secrets = { 16 email_vinbiz.file = ../../secrets/email_vinbiz.age; 17 email_vineetk.file = ../../secrets/email_vineetk.age; 18 email_13f0.file = ../../secrets/email_13f0.age; 19 20 hetzner_dns = { 21 file = ../../secrets/hetzner_dns.age; 22 owner = "root"; 23 group = "root"; 24 }; 25 26 radicale_users = { 27 file = ../../secrets/radicale_users.age; 28 owner = "radicale"; 29 }; 30 31 tailscale_saklas = { 32 file = ../../secrets/tailscale_saklas.age; 33 owner = "root"; 34 group = "root"; 35 }; 36 }; 37 38 # disable wifi and open some ports 39 networking = { 40 hostName = "saklas"; 41 hostId = "b0bababe"; 42 useDHCP = false; 43 44 wireless.enable = false; 45 46 firewall = { 47 allowedTCPPorts = [ 48 22 49 80 50 443 51 5222 52 5269 53 ]; 54 allowedUDPPorts = [ 55 3478 56 51820 57 ]; 58 }; 59 }; 60 61 systemd.network = { 62 enable = true; 63 networks."10-wan" = { 64 matchConfig.Name = "enp1s0"; 65 networkConfig.DHCP = "no"; 66 address = [ 67 "95.217.18.52/32" 68 "2a01:4f9:c010:a653::1/64" 69 ]; 70 dns = [ 71 "185.12.64.1" 72 "185.12.64.2" 73 ]; 74 routes = [ 75 { Destination = "172.31.1.1"; } 76 { 77 Gateway = "172.31.1.1"; 78 GatewayOnLink = true; 79 } 80 ]; 81 }; 82 }; 83 84 # Set your time zone. 85 time.timeZone = "America/Toronto"; 86 87 # Select internationalisation properties. 88 i18n.defaultLocale = "en_US.UTF-8"; 89 console = { 90 font = "Lat2-Terminus16"; 91 }; 92 93 # enable flakes and nix cli 94 nix.settings.experimental-features = [ 95 "nix-command" 96 "flakes" 97 ]; 98 99 # user accounts 100 users.users.root.openssh.authorizedKeys.keys = [ 101 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH kou@demiurge" 102 ]; 103 104 users.users.vin = { 105 isNormalUser = true; 106 107 extraGroups = [ 108 "nginx" 109 "wheel" 110 ]; 111 112 shell = pkgs.zsh; 113 114 openssh.authorizedKeys.keys = [ 115 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH kou@demiurge" 116 ]; 117 }; 118 119 # default packages for both me and root 120 environment = { 121 systemPackages = with pkgs; [ 122 doas-sudo-shim 123 gitMinimal 124 htop 125 ncdu 126 wget 127 ]; 128 129 pathsToLink = [ "/share/zsh" ]; 130 }; 131 132 programs = { 133 # disable nano. I don't like nano. 134 nano.enable = false; 135 136 # configuration in home-manager 137 zsh.enable = true; 138 zsh.promptInit = "PS1='$ '"; 139 }; 140 141 security = { 142 # TLS 143 acme = { 144 acceptTerms = true; 145 146 defaults = { 147 credentialFiles."HETZNER_API_KEY_FILE" = config.age.secrets.hetzner_dns.path; 148 dnsProvider = "hetzner"; 149 email = "acme@vineetk.net"; 150 server = "https://acme-v02.api.letsencrypt.org/directory"; 151 }; 152 153 certs = { 154 "vinbiz.ca".extraDomainNames = [ "*.vinbiz.ca" ]; 155 "vineetk.net".extraDomainNames = [ "*.vineetk.net" ]; 156 "13f0.net".extraDomainNames = [ "*.13f0.net" ]; 157 158 "xmpp.vineetk.net" = { 159 group = config.services.prosody.group; 160 extraDomainNames = [ 161 "vineetk.net" 162 "muc.vineetk.net" 163 "u.vineetk.net" 164 ]; 165 reloadServices = [ "prosody" ]; 166 }; 167 }; 168 }; 169 170 # I prefer doas over sudo for simplicity 171 doas = { 172 enable = true; 173 extraRules = [ 174 { 175 users = [ "vin" ]; 176 keepEnv = true; 177 persist = true; 178 } 179 ]; 180 }; 181 182 sudo.enable = false; 183 }; 184 185 services = { 186 # git 187 cgit."git.vineetk.net" = { 188 enable = true; 189 scanPath = "/var/lib/git"; 190 }; 191 192 # VPN 193 headscale = { 194 enable = true; 195 address = "127.0.0.1"; 196 port = 8080; 197 settings = { 198 server_url = "https://headscale.13f0.net"; 199 dns = { 200 base_domain = "epistemia"; 201 extra_records = [ 202 { 203 name = "invidious.demiurge.epistemia"; 204 type = "A"; 205 value = "100.64.0.2"; 206 } 207 { 208 name = "llm.demiurge.epistemia"; 209 type = "A"; 210 value = "100.64.0.2"; 211 } 212 { 213 name = "navidrome.demiurge.epistemia"; 214 type = "A"; 215 value = "100.64.0.2"; 216 } 217 { 218 name = "redlib.demiurge.epistemia"; 219 type = "A"; 220 value = "100.64.0.2"; 221 } 222 { 223 name = "sdui.demiurge.epistemia"; 224 type = "A"; 225 value = "100.64.0.2"; 226 } 227 { 228 name = "searx.demiurge.epistemia"; 229 type = "A"; 230 value = "100.64.0.2"; 231 } 232 ]; 233 }; 234 logtail.enabled = false; 235 }; 236 }; 237 238 tailscale = { 239 enable = true; 240 authKeyFile = config.age.secrets.tailscale_saklas.path; 241 extraDaemonFlags = [ "--no-logs-no-support" ]; 242 extraUpFlags = [ "--login-server=https://headscale.13f0.net" ]; 243 openFirewall = true; 244 }; 245 246 # XMPP 247 prosody = { 248 enable = true; 249 250 admins = [ "vin@vineetk.net" ]; 251 httpFileShare.domain = "u.vineetk.net"; 252 253 ssl.cert = config.security.acme.certs."xmpp.vineetk.net".directory + "/full.pem"; 254 ssl.key = config.security.acme.certs."xmpp.vineetk.net".directory + "/key.pem"; 255 256 muc = [ { domain = "muc.vineetk.net"; } ]; 257 virtualHosts.vineetk = { 258 domain = "vineetk.net"; 259 enabled = true; 260 }; 261 }; 262 263 # web server and reverse proxy 264 nginx = { 265 enable = true; 266 267 recommendedGzipSettings = true; 268 recommendedOptimisation = true; 269 recommendedProxySettings = true; 270 recommendedTlsSettings = true; 271 recommendedZstdSettings = true; 272 273 virtualHosts = { 274 "vineetk.net" = { 275 enableACME = true; 276 forceSSL = true; 277 default = true; 278 locations."/" = { 279 index = "index.html"; 280 root = "/var/www/vineetk_html"; 281 }; 282 }; 283 284 "radicale.vineetk.net" = { 285 useACMEHost = "vineetk.net"; 286 forceSSL = true; 287 locations."/" = { 288 proxyPass = "http://127.0.0.1:5232/"; 289 extraConfig = '' 290 proxy_pass_header Authorization; 291 ''; 292 }; 293 }; 294 295 "git.vineetk.net" = { 296 useACMEHost = "vineetk.net"; 297 forceSSL = true; 298 locations."/".proxyPass = "http://127.0.0.1:3000/"; 299 }; 300 301 "13f0.net" = { 302 enableACME = true; 303 forceSSL = true; 304 locations."/" = { 305 index = "index.html"; 306 root = "/var/www/13f0_html"; 307 }; 308 }; 309 310 "headscale.13f0.net" = { 311 useACMEHost = "13f0.net"; 312 forceSSL = true; 313 locations."/" = { 314 proxyPass = "http://127.0.0.1:8080"; 315 proxyWebsockets = true; 316 }; 317 }; 318 319 "vinbiz.ca" = { 320 enableACME = true; 321 forceSSL = true; 322 locations."/" = { 323 index = "index.html"; 324 root = "/var/www/vinbiz_html"; 325 }; 326 }; 327 }; 328 }; 329 330 # CalDAV and CardDAV 331 radicale = { 332 enable = true; 333 settings = { 334 server.hosts = [ "127.0.0.1:5232" ]; 335 auth = { 336 type = "htpasswd"; 337 htpasswd_filename = config.age.secrets.radicale_users.path; 338 htpasswd_encryption = "bcrypt"; 339 }; 340 }; 341 }; 342 343 # SSH 344 # first use tarpit 345 endlessh = { 346 enable = true; 347 port = 22; 348 openFirewall = true; 349 }; 350 351 # fail2ban if skiddie uses different port 352 fail2ban = { 353 enable = true; 354 ignoreIP = [ 355 "35.142.66.239/20" 356 "45.134.142.0/24" 357 ]; 358 }; 359 360 # normal openssh 361 openssh = { 362 enable = true; 363 ports = [ 2222 ]; 364 365 settings = { 366 KbdInteractiveAuthentication = false; 367 PasswordAuthentication = false; 368 PermitRootLogin = "prohibit-password"; 369 X11Forwarding = true; 370 }; 371 }; 372 }; 373 374 # email via simple-nixos-mailserver 375 mailserver = { 376 enable = true; 377 fqdn = "mail.vineetk.net"; 378 domains = [ 379 "vineetk.net" 380 "vinbiz.ca" 381 "13f0.net" 382 ]; 383 384 # A list of all login accounts. To create the password hashes, use 385 # nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt' 386 loginAccounts = { 387 "vineet@vineetk.net" = { 388 hashedPasswordFile = config.age.secrets.email_vineetk.path; 389 aliases = [ "@vineetk.net" ]; 390 }; 391 392 "kar@13f0.net" = { 393 hashedPasswordFile = config.age.secrets.email_13f0.path; 394 aliases = [ "@13f0.net" ]; 395 }; 396 397 "vineet@vinbiz.ca" = { 398 hashedPasswordFile = config.age.secrets.email_vinbiz.path; 399 aliases = [ "postmaster@vinbiz.ca" ]; 400 }; 401 "suresh@vinbiz.ca".hashedPasswordFile = config.age.secrets.email_vinbiz.path; 402 "revathy@vinbiz.ca".hashedPasswordFile = config.age.secrets.email_vinbiz.path; 403 "suren@vinbiz.ca".hashedPasswordFile = config.age.secrets.email_vinbiz.path; 404 }; 405 406 acmeCertificateName = "vineetk.net"; 407 certificateScheme = "acme"; 408 }; 409 410 # create caches and use mandoc 411 documentation.man = { 412 enable = true; 413 generateCaches = true; 414 man-db.enable = false; 415 mandoc.enable = true; 416 }; 417 418 system.stateVersion = "24.11"; 419 }