Configuration for my NixOS based systems and Home Manager
0
fork

Configure Feed

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

at 61ba8a8c85365ac8effbb1690d9eddbce9d11d3b 535 lines 16 kB view raw
1{ config 2, lib 3, pkgs 4, unstable 5, ... 6}: 7{ 8 9 services.zfs = { 10 autoScrub.enable = true; 11 }; 12 services.nfs.server.enable = true; 13 # Some programs need SUID wrappers, can be configured further or are 14 # started in user sessions. 15 # programs.mtr.enable = true; 16 programs.gnupg.agent = { 17 enable = true; 18 enableSSHSupport = false; 19 }; 20 21 # Fish shell, the best 22 programs.fish.enable = true; 23 24 # MOSH, SSH over flakey connections 25 programs.mosh.enable = true; 26 27 # List services that you want to enable: 28 29 # Enable the OpenSSH daemon. 30 services.openssh = { 31 enable = true; 32 openFirewall = true; 33 settings.PasswordAuthentication = false; 34 }; 35 36 # This option is for enabling the bolt daemon for managing Thunderbolt/USB4 Devices. 37 services.hardware.bolt.enable = true; 38 39 # Tailscale 40 services.tailscale = { 41 enable = true; 42 useRoutingFeatures = "client"; 43 }; 44 45 # Containers and VMs 46 virtualisation = { 47 podman = { 48 enable = true; 49 dockerCompat = true; 50 defaultNetwork.settings.dns_enabled = true; 51 }; 52 }; 53 54 # Samba, for shares 55 # TODO 56 services.samba = { 57 enable = true; 58 openFirewall = true; 59 nmbd.enable = true; 60 winbindd.enable = true; 61 settings = { 62 global = { 63 workgroup = "WORKGROUP"; 64 "server string" = "misaki"; 65 security = "user"; 66 "use sendfile" = "yes"; 67 "hosts allow" = "192.168.1. 127.0.0.1 localhost"; 68 "hosts deny" = "0.0.0.0/0"; 69 "guest account" = "nobody"; 70 "map to guest" = "bad user"; 71 deadtime = 30; 72 }; 73 shokuhou = { 74 path = "/srv/shokuhou"; 75 browseable = "yes"; 76 "read only" = "no"; 77 "guest ok" = "no"; 78 "create mask" = "0644"; 79 "directory mask" = "0755"; 80 "force user" = "noah"; 81 "force group" = "nas"; 82 }; 83 mentalout = { 84 path = "/srv/mentalout"; 85 browseable = "yes"; 86 "read only" = "no"; 87 "guest ok" = "no"; 88 "create mask" = "0644"; 89 "directory mask" = "0755"; 90 "force user" = "noah"; 91 "force group" = "nas"; 92 }; 93 }; 94 }; 95 services.samba-wsdd = { 96 enable = true; 97 openFirewall = true; 98 }; 99 100 services.coredns = { 101 enable = true; 102 config = lib.readFile ./coredns/config; 103 }; 104 105 services.nats = { 106 enable = true; 107 jetstream = true; 108 user = "nats"; 109 group = "nats"; 110 serverName = "misaki"; 111 dataDir = "/srv/shokuhou/applications/nats"; 112 validateConfig = false; 113 settings = { 114 authorization = { 115 users = [ 116 { 117 user = "seedbox@packetlost.dev"; 118 permissions = { 119 publish = [ 120 "torrents" 121 "torrents.>" 122 "$JS.API.INFO" 123 #"$JS.API.STREAM.INFO.>" 124 "$KV.torrents.>" 125 #"$JS.API.STREAM.*.*.OBJ_torrents" 126 "$JS.API.*.*.OBJ_torrents" 127 "$JS.API.STREAM.MSG.GET.OBJ_torrents" 128 "$JS.API.*.*.OBJ_torrents.>" 129 "$O.torrents.>" 130 ]; 131 subscribe = [ 132 "torrents.>" 133 "_INBOX.>" 134 ]; 135 allow_responses = false; 136 }; 137 } 138 { user = "odin@packetlost.dev"; } 139 { user = "misaki@packetlost.dev"; } 140 { user = "noah@packetlost.dev"; } 141 { user = "touma-nixos@packetlost.dev"; } 142 ]; 143 }; 144 tls = { 145 cert_file = "/srv/nats/nats.packetlost.dev/cert.pem"; 146 key_file = "/srv/nats/nats.packetlost.dev/key.pem"; 147 ca_file = "/srv/nats/minica.pem"; 148 verify_and_map = true; 149 }; 150 jetstream = { 151 # 50GB 152 max_file_store = 53687091200; 153 max_mem = 8589934592; 154 }; 155 }; 156 }; 157 158 # Minio's object storage has been mostly replaced with NATS. If I specifically need a 159 # S3-like API, this will be revived. 160 services.minio = { 161 enable = false; 162 listenAddress = ":9003"; 163 consoleAddress = ":9004"; 164 dataDir = [ 165 /srv/shokuhou/applications/minio 166 ]; 167 }; 168 169 services.netatalk = { 170 enable = true; 171 settings = { 172 time-machine = { 173 path = "/srv/shokuhou/backup/timemachine"; 174 "valid users" = "noah"; 175 "time machine" = true; 176 }; 177 }; 178 }; 179 180 services.webdav.enable = false; 181 services.sftpgo = { 182 enable = false; 183 dataDir = /srv/shokuhou/documents/sftpgo; 184 group = "nas"; 185 }; 186 services.syncthing = { 187 enable = false; 188 openDefaultPorts = true; 189 # disable the sync folder creation 190 extraFlags = [ "--no-default-folder" ]; 191 settings = { 192 folders = { 193 "Sync" = { 194 path = "/srv/shokuhou/documents/sync"; 195 }; 196 }; 197 }; 198 }; 199 200 services.grafana = { 201 enable = false; 202 settings.server.http_port = 2342; 203 settings.server.domain = "grafana.packetlost.dev"; 204 settings.server.http_addr = "127.0.0.1"; 205 }; 206 207 services.prometheus = { 208 enable = false; 209 port = 9001; 210 exporters = { 211 node = { 212 enable = true; 213 enabledCollectors = [ "systemd" ]; 214 port = 9002; 215 }; 216 }; 217 218 scrapeConfigs = [ 219 { 220 job_name = "chrysalis"; 221 static_configs = [ 222 { targets = [ "127.0.0.1:${builtins.toString config.services.prometheus.exporters.node.port}" ]; } 223 ]; 224 } 225 ]; 226 }; 227 228 # TODO: figure out how to appropriately configure this 229 services.step-ca = { 230 enable = false; 231 openFirewall = true; 232 port = 8443; 233 address = "0.0.0.0"; 234 intermediatePasswordFile = /etc/nixos/step-ca-intermediate-ca-password; 235 settings = builtins.fromJSON (builtins.readFile /home/noah/.step/config/ca.json); 236 }; 237 238 age.secrets.acme = { 239 file = ./secrets/porkbun-api-key.age; 240 owner = "root"; 241 group = "acme"; 242 }; 243 244 # TODO: re-enable this once Agenix is set up 245 security.acme = { 246 acceptTerms = true; 247 defaults.email = "noah@packetlost.dev"; 248 certs."plex.packetlost.dev" = { 249 dnsProvider = "porkbun"; 250 group = "httpd"; 251 environmentFile = config.age.secrets.acme.path; 252 }; 253 certs."img.ngp.computer" = { 254 group = "httpd"; 255 dnsProvider = "porkbun"; 256 environmentFile = config.age.secrets.acme.path; 257 }; 258 certs."photos.ngp.computer" = { 259 group = "httpd"; 260 dnsProvider = "porkbun"; 261 environmentFile = config.age.secrets.acme.path; 262 }; 263 certs."jellyfin.packetlost.dev" = { 264 group = "httpd"; 265 dnsProvider = "porkbun"; 266 environmentFile = config.age.secrets.acme.path; 267 }; 268 }; 269 270 # A test email server that only works on LAN 271 services.maddy = { 272 enable = true; 273 openFirewall = true; 274 primaryDomain = "misaki.local"; 275 ensureAccounts = [ 276 "noah@misaki.local" 277 "postmaster@misaki.local" 278 "test@misaki.local" 279 ]; 280 ensureCredentials = { 281 "noah@misaki.local".passwordFile = "${pkgs.writeText "noah" "Password123"}"; 282 "postmaster@misaki.local".passwordFile = "${pkgs.writeText "noah" "Password123"}"; 283 "test@misaki.local".passwordFile = "${pkgs.writeText "test" "Password123"}"; 284 }; 285 }; 286 287 services.nix-serve = { 288 enable = true; 289 secretKeyFile = "/srv/cache/cache-priv-key.pem"; 290 #openFirewall = true; 291 }; 292 293 services.plex = { 294 enable = true; 295 openFirewall = false; # we proxy this with nginx 296 group = "nas"; 297 user = "noah"; 298 package = unstable.plex; 299 }; 300 301 services.jellyfin = { 302 enable = true; 303 openFirewall = true; 304 user = "noah"; 305 group = "nas"; 306 logDir = "/srv/shokuhou/applications/jellyfin/log"; 307 cacheDir = "/srv/shokuhou/applications/jellyfin/cache"; 308 dataDir = "/srv/shokuhou/applications/jellyfin/data"; 309 configDir = "/srv/shokuhou/applications/jellyfin/config"; 310 }; 311 312 # services.gitea = { 313 # enable = true; 314 # user = "git"; 315 # domain = "git.packetlost.dev"; 316 # }; 317 318 # Litterbox, collect my IRC logs 319 systemd = { 320 services = { 321 "litterbox@" = { 322 path = [ pkgs.litterbox ]; 323 serviceConfig = { 324 StartLimitIntervalSec = 5; 325 StartLimitBurst = 10; 326 Restart = "on-failure"; 327 RestartSec = "10s"; 328 Type = "simple"; 329 ExecStart = "${pkgs.litterbox}/bin/litterbox /srv/litterbox/%i.conf"; 330 ExecReload = "kill -USR1 $MAINPID"; 331 User = "noah"; 332 Group = "litterbox"; 333 }; 334 }; 335 336 #"litterbox@libera.irc.packetlost.dev" = { 337 # overrideStrategy = "asDropin"; 338 # wantedBy = [ "multi-user.target" ]; 339 #}; 340 "update-downstream-src" = { 341 path = with pkgs; [ 342 rc 343 coreutils 344 git 345 openssh 346 ]; 347 script = "exec ${./scripts/update-src}"; 348 serviceConfig = { 349 Type = "oneshot"; 350 User = "noah"; 351 WorkingDirectory = "/srv/src"; 352 }; 353 }; 354 }; 355 timers = { 356 "update-downstream-src" = { 357 wantedBy = [ "timers.target" ]; 358 timerConfig = { 359 OnCalendar = "daily"; 360 Persistent = true; 361 }; 362 }; 363 }; 364 }; 365 366 services.teamspeak3 = { 367 enable = true; 368 openFirewall = true; 369 }; 370 371 services.immich = { 372 enable = true; 373 package = unstable.immich; 374 accelerationDevices = [ "/dev/dri/renderD128" ]; 375 mediaLocation = "/srv/shokuhou/pictures/immich"; 376 }; 377 users.users.immich.extraGroups = [ 378 "video" 379 "render" 380 "nas" 381 ]; 382 383 # Nginx Reverse SSL Proxy 384 services.nginx = { 385 enable = true; 386 group = "nas"; 387 user = "noah"; 388 389 # This is disabled for now 390 #virtualHosts."${config.services.grafana.settings.server.domain}" = { 391 # locations."/" = { 392 # proxyPass = "http://127.0.0.1:${builtins.toString config.services.grafana.settings.server.http_port}"; 393 # proxyWebsockets = true; 394 # }; 395 #}; 396 397 virtualHosts."cache.packetlost.dev" = { 398 locations."/".proxyPass = 399 "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; 400 }; 401 virtualHosts."photos.ngp.computer" = { 402 enableACME = false; 403 useACMEHost = "photos.ngp.computer"; 404 acmeRoot = null; 405 forceSSL = true; 406 locations."/" = { 407 proxyPass = "http://[::1]:${toString config.services.immich.port}"; 408 proxyWebsockets = true; 409 recommendedProxySettings = true; 410 extraConfig = '' 411 client_max_body_size 50000M; 412 proxy_read_timeout 600s; 413 proxy_send_timeout 600s; 414 send_timeout 600s; 415 ''; 416 }; 417 }; 418 virtualHosts."img.ngp.computer" = { 419 forceSSL = true; 420 enableACME = false; 421 useACMEHost = "img.ngp.computer"; 422 acmeRoot = null; 423 root = "/srv/shokuhou/pictures/public"; 424 extraConfig = '' 425 sendfile on; 426 autoindex_exact_size on; 427 tcp_nopush on; 428 ''; 429 locations."/" = { 430 extraConfig = '' 431 autoindex on; 432 autoindex_exact_size on; 433 alias /srv/shokuhou/pictures/public/$1; 434 ''; 435 }; 436 # Don't use this unless you want the contents of this folder to be in the Nix 437 # Store and only updated when switching 438 #root = "/srv/shokuhou/pictures/public"; 439 #extraConfig = '' 440 # sendfile on; 441 # sendfile_max_chunk 1m; 442 # tcp_nopush on; 443 # root /srv/shokuhou/pictures/public; 444 # location ~ /.* { 445 # } 446 #''; 447 }; 448 virtualHosts."jellyfin.packetlost.dev" = { 449 forceSSL = true; 450 enableACME = false; 451 useACMEHost = "jellyfin.packetlost.dev"; 452 acmeRoot = null; 453 http2 = true; 454 locations."/" = { 455 proxyPass = "http://localhost:8096/"; 456 }; 457 }; 458 459 # give a name to the virtual host. It also becomes the server name. 460 virtualHosts."plex.packetlost.dev" = { 461 # Since we want a secure connection, we force SSL 462 forceSSL = true; 463 enableACME = false; 464 useACMEHost = "plex.packetlost.dev"; 465 acmeRoot = null; 466 467 # http2 can more performant for streaming: https://blog.cloudflare.com/introducing-http2/ 468 http2 = true; 469 470 # Provide the ssl cert and key for the vhost 471 # These are filled in automatically with ACME 472 extraConfig = '' 473 474 #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause 475 send_timeout 100m; 476 477 # Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/ 478 ssl_stapling on; 479 ssl_stapling_verify on; 480 481 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 482 ssl_prefer_server_ciphers on; 483 #Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384. 484 ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; 485 486 # Forward real ip and host to Plex 487 proxy_set_header X-Real-IP $remote_addr; 488 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 489 proxy_set_header X-Forwarded-Proto $scheme; 490 proxy_set_header Host $server_addr; 491 proxy_set_header Referer $server_addr; 492 proxy_set_header Origin $server_addr; 493 494 # Plex has A LOT of javascript, xml and html. This helps a lot, but if it causes playback issues with devices turn it off. 495 gzip on; 496 gzip_vary on; 497 gzip_min_length 1000; 498 gzip_proxied any; 499 gzip_types text/plain text/css text/xml application/xml text/javascript application/x-javascript image/svg+xml; 500 gzip_disable "MSIE [1-6]\."; 501 502 # Nginx default client_max_body_size is 1MB, which breaks Camera Upload feature from the phones. 503 # Increasing the limit fixes the issue. Anyhow, if 4K videos are expected to be uploaded, the size might need to be increased even more 504 client_max_body_size 100M; 505 506 # Plex headers 507 proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; 508 proxy_set_header X-Plex-Device $http_x_plex_device; 509 proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; 510 proxy_set_header X-Plex-Platform $http_x_plex_platform; 511 proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; 512 proxy_set_header X-Plex-Product $http_x_plex_product; 513 proxy_set_header X-Plex-Token $http_x_plex_token; 514 proxy_set_header X-Plex-Version $http_x_plex_version; 515 proxy_set_header X-Plex-Nocache $http_x_plex_nocache; 516 proxy_set_header X-Plex-Provides $http_x_plex_provides; 517 proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; 518 proxy_set_header X-Plex-Model $http_x_plex_model; 519 520 # Websockets 521 proxy_http_version 1.1; 522 proxy_set_header Upgrade $http_upgrade; 523 proxy_set_header Connection "upgrade"; 524 525 # Buffering off send to the client as soon as the data is received from Plex. 526 proxy_redirect off; 527 proxy_buffering off; 528 ''; 529 530 locations."/" = { 531 proxyPass = "http://localhost:32400/"; 532 }; 533 }; 534 }; 535}