at master 11 kB view raw
1{ 2 nixpkgs-unstable, 3 config, 4 pkgs, 5 lib, 6 nixpkgs-chromedriver, 7 ... 8}: 9 10{ 11 custom.nix-cache.enable = true; 12 13 age.secrets."eon-freumh.org.cap" = { 14 file = ../../secrets/eon-freumh.org.cap.age; 15 mode = "770"; 16 owner = "acme-eon"; 17 group = "acme-eon"; 18 }; 19 security.acme-eon = { 20 acceptTerms = true; 21 defaults.email = "${config.custom.username}@${config.networking.domain}"; 22 defaults.capFile = config.age.secrets."eon-freumh.org.cap".path; 23 nginxCerts = [ 24 "nix-cache.vpn.freumh.org" 25 "jellyfin.vpn.freumh.org" 26 "jellyfin.freumh.org" 27 "jellyseerr.freumh.org" 28 "transmission.vpn.freumh.org" 29 "nextcloud.vpn.freumh.org" 30 "owntracks.vpn.freumh.org" 31 "immich.vpn.freumh.org" 32 "calibre.freumh.org" 33 "audiobookshelf.vpn.freumh.org" 34 ]; 35 }; 36 37 services.nginx = { 38 #requires = [ "tailscaled.service" ]; 39 clientMaxBodySize = "1g"; 40 virtualHosts = { 41 "nix-cache.vpn.freumh.org" = { 42 listenAddresses = [ "100.64.0.9" ]; 43 }; 44 "jellyfin.vpn.freumh.org" = { 45 onlySSL = true; 46 listenAddresses = [ "100.64.0.9" ]; 47 locations."/" = { 48 proxyPass = '' 49 http://localhost:8096 50 ''; 51 proxyWebsockets = true; 52 }; 53 }; 54 "jellyfin.freumh.org" = { 55 onlySSL = true; 56 locations."/" = { 57 recommendedProxySettings = true; 58 proxyPass = '' 59 http://localhost:8096 60 ''; 61 proxyWebsockets = true; 62 }; 63 }; 64 "jellyseerr.freumh.org" = { 65 onlySSL = true; 66 locations."/" = { 67 recommendedProxySettings = true; 68 proxyPass = '' 69 http://localhost:${builtins.toString config.services.jellyseerr.port} 70 ''; 71 proxyWebsockets = true; 72 }; 73 }; 74 "transmission.vpn.freumh.org" = { 75 onlySSL = true; 76 listenAddresses = [ "100.64.0.9" ]; 77 locations."/" = { 78 proxyPass = with config.services.transmission.settings; '' 79 http://localhost:${builtins.toString rpc-port} 80 ''; 81 }; 82 }; 83 "nextcloud.vpn.freumh.org" = { 84 onlySSL = true; 85 listenAddresses = [ "100.64.0.9" ]; 86 }; 87 "owntracks.vpn.freumh.org" = { 88 onlySSL = true; 89 listenAddresses = [ "100.64.0.9" ]; 90 }; 91 "immich.vpn.freumh.org" = { 92 onlySSL = true; 93 listenAddresses = [ "100.64.0.9" ]; 94 locations."/" = { 95 proxyPass = with config.services.immich; '' 96 http://${host}:${builtins.toString port} 97 ''; 98 }; 99 }; 100 "calibre.freumh.org" = { 101 addSSL = true; 102 locations."/" = { 103 recommendedProxySettings = true; 104 proxyPass = '' 105 http://127.0.0.1:${builtins.toString config.services.calibre-web.listen.port} 106 ''; 107 proxyWebsockets = true; 108 extraConfig = '' 109 proxy_buffer_size 128k; 110 proxy_buffers 4 256k; 111 proxy_busy_buffers_size 256k; 112 ''; 113 }; 114 }; 115 "audiobookshelf.vpn.freumh.org" = { 116 onlySSL = true; 117 listenAddresses = [ "100.64.0.9" ]; 118 locations."/" = { 119 proxyPass = '' 120 http://localhost:${builtins.toString config.services.audiobookshelf.port} 121 ''; 122 proxyWebsockets = true; 123 }; 124 }; 125 }; 126 }; 127 128 services.avahi = { 129 enable = true; 130 nssmdns4 = true; 131 publish = { 132 enable = true; 133 addresses = true; 134 workstation = true; 135 }; 136 }; 137 138 services.minidlna = { 139 enable = true; 140 openFirewall = true; 141 settings = { 142 media_dir = [ "/tank/" ]; 143 notify_interval = 60; 144 inofity = true; 145 }; 146 }; 147 148 services.jellyfin = { 149 enable = true; 150 openFirewall = true; 151 }; 152 users.users.${config.services.jellyfin.user}.extraGroups = [ 153 config.services.transmission.user 154 config.services.sonarr.user 155 config.services.radarr.user 156 config.services.bazarr.user 157 config.services.lidarr.user 158 config.services.readarr.user 159 ]; 160 161 services.samba = { 162 enable = true; 163 openFirewall = true; 164 settings = { 165 global = { 166 workgroup = "WORKGROUP"; 167 "server string" = "${config.networking.hostName}"; 168 "netbios name" = "${config.networking.hostName}"; 169 "security" = "user"; 170 #"use sendfile" = "yes"; 171 #"max protocol" = "smb2"; 172 # note: localhost is the ipv6 localhost ::1 173 "hosts allow" = "192.168.1. 192.168.0. 127.0.0.1 localhost 100.64.0.0/10"; 174 "hosts deny" = "0.0.0.0/0"; 175 "guest account" = "nobody"; 176 "map to guest" = "bad user"; 177 }; 178 tank = { 179 path = "/tank/"; 180 browseable = "yes"; 181 "read only" = "no"; 182 "guest ok" = "no"; 183 "create mask" = "0644"; 184 "directory mask" = "0755"; 185 }; 186 }; 187 }; 188 users.mutableUsers = lib.mkForce true; 189 190 age.secrets.nextcloud = { 191 file = ../../secrets/nextcloud.age; 192 mode = "770"; 193 owner = "nextcloud"; 194 group = "nextcloud"; 195 }; 196 services.nextcloud = { 197 enable = true; 198 package = pkgs.nextcloud29; 199 hostName = "nextcloud.vpn.freumh.org"; 200 config.adminpassFile = config.age.secrets.nextcloud.path; 201 }; 202 203 services.transmission = { 204 enable = true; 205 openRPCPort = true; 206 package = pkgs.transmission_3; 207 settings = { 208 download-dir = "/tank/transmission"; 209 incomplete-dir-enabled = false; 210 rpc-whitelist = "127.0.0.1,100.64.*.*,192.168.1.*"; 211 rpc-bind-address = "0.0.0.0"; 212 rpc-host-whitelist-enabled = false; 213 ratio-limit-enabled = true; 214 download-queue-size = 20; 215 }; 216 }; 217 218 services.prowlarr.enable = true; 219 services.flaresolverr.enable = true; 220 services.sonarr.enable = true; 221 services.radarr.enable = true; 222 services.bazarr.enable = true; 223 services.lidarr.enable = true; 224 services.readarr.enable = true; 225 services.nzbget.enable = true; 226 services.jellyseerr.enable = true; 227 users.users.${config.services.sonarr.user}.extraGroups = [ 228 config.services.transmission.user 229 config.services.nzbget.user 230 ]; 231 users.users.${config.services.radarr.user}.extraGroups = [ 232 config.services.transmission.user 233 config.services.nzbget.user 234 ]; 235 users.users.${config.services.bazarr.user}.extraGroups = [ 236 config.services.sonarr.user 237 config.services.radarr.user 238 ]; 239 users.users.${config.services.lidarr.user}.extraGroups = [ 240 config.services.transmission.user 241 config.services.nzbget.user 242 ]; 243 users.users.${config.services.readarr.user}.extraGroups = [ 244 config.services.transmission.user 245 config.services.nzbget.user 246 ]; 247 248 services.calibre-web = { 249 enable = true; 250 listen = { 251 port = 8084; 252 ip = "127.0.0.1"; 253 }; 254 options = { 255 enableBookConversion = true; 256 enableBookUploading = true; 257 enableKepubify = true; 258 }; 259 }; 260 users.users.${config.services.calibre-web.user}.extraGroups = [ 261 config.services.readarr.user 262 ]; 263 264 age.secrets.restic-owl.file = ../../secrets/restic-owl.age; 265 age.secrets.restic-gecko.file = ../../secrets/restic-gecko.age; 266 age.secrets.restic-shrew.file = ../../secrets/restic-shrew.age; 267 services.restic = { 268 #backups.owl = { 269 # repository = "${config.services.restic.server.dataDir}/owl"; 270 # passwordFile = "${config.custom.secretsDir}/restic-password-owl"; 271 # timerConfig = { 272 # OnCalendar = "02:00"; 273 # }; 274 # pruneOpts = [ 275 # "--keep-daily 7" 276 # "--keep-weekly 5" 277 # "--keep-monthly 12" 278 # "--keep-yearly 5" 279 # ]; 280 #}; 281 #backups.gecko = { 282 # repository = "${config.services.restic.server.dataDir}/gecko"; 283 # passwordFile = "${config.custom.secretsDir}/restic-password-gecko"; 284 # timerConfig = { 285 # OnCalendar = "02:00"; 286 # }; 287 # pruneOpts = [ 288 # "--keep-daily 7" 289 # "--keep-weekly 5" 290 # "--keep-monthly 12" 291 # "--keep-yearly 5" 292 # ]; 293 #}; 294 server = { 295 enable = true; 296 listenAddress = "100.64.0.9:8000"; 297 dataDir = "/tank/backups/restic"; 298 appendOnly = true; 299 extraFlags = [ "--no-auth" ]; 300 }; 301 }; 302 systemd.services.restic-rest-server = { 303 after = [ "tailscaled.service" ]; 304 requires = [ "tailscaled.service" ]; 305 }; 306 307 services.owntracks-recorder = { 308 enable = true; 309 host = "100.64.0.9"; 310 domain = "owntracks.vpn.freumh.org"; 311 }; 312 313 services.immich = { 314 enable = true; 315 openFirewall = true; 316 host = "100.64.0.9"; 317 mediaLocation = "/tank/immich"; 318 }; 319 320 services.audiobookshelf = { 321 enable = true; 322 port = 8001; 323 }; 324 users.users.${config.services.audiobookshelf.user}.extraGroups = [ 325 config.services.readarr.user 326 ]; 327 328 services.fail2ban = { 329 enable = true; 330 bantime = "24h"; 331 bantime-increment = { 332 enable = true; 333 multipliers = "1 2 4 8 16 32 64"; 334 maxtime = "168h"; 335 overalljails = true; 336 }; 337 jails."jellyfin".settings = { 338 backend = "auto"; 339 port = "80,443"; 340 protocol = "tcp"; 341 filter = "jellyfin"; 342 maxRetry = 3; 343 bantime = "86400"; 344 findTime = "43200"; 345 logPath = "/var/lib/jellyfin/log/*.log"; 346 }; 347 # requires 'Enable Proxy Support' for jellyseerr 348 jails."jellyseerr".settings = { 349 backend = "auto"; 350 port = "80,443"; 351 protocol = "tcp"; 352 filter = "jellyseerr"; 353 maxRetry = 3; 354 bantime = "86400"; 355 findTime = "43200"; 356 logPath = "/var/lib/jellyseerr/logs/overseerr.log"; 357 }; 358 # requires 'Enable Proxy Support' for jellyseerr 359 jails."calibre-web".settings = { 360 backend = "auto"; 361 port = "80,443"; 362 protocol = "tcp"; 363 filter = "calibre-web"; 364 maxRetry = 3; 365 bantime = "86400"; 366 findTime = "43200"; 367 logPath = "/var/lib/calibre-web/log"; 368 }; 369 }; 370 environment.etc = { 371 "fail2ban/filter.d/jellyfin.local".text = '' 372 [Definition] 373 failregex = ^.*Authentication request for .* has been denied \(IP: "<ADDR>"\)\. 374 ''; 375 "fail2ban/filter.d/jellyseerr.local".text = '' 376 [Definition] 377 failregex = ^.*\[warn\]\[Auth\]: Failed login attempt from user with incorrect Jellyfin credentials {"account":{"ip":"<HOST>","email": 378 ''; 379 "fail2ban/filter.d/calibre-web.local".text = '' 380 [Definition] 381 failregex = ^(?:\[\])?\s*WARN \{[^\}]*\} Login failed for user "<F-USER>[^"]*</F-USER>" IP-address: <ADDR> 382 ''; 383 }; 384 385 systemd.services.ddns = { 386 description = "Dynamic DNS"; 387 wantedBy = [ "multi-user.target" ]; 388 after = [ "network-online.target" ]; 389 wants = [ "network-online.target" ]; 390 serviceConfig = { 391 ExecStart = pkgs.writeShellScript "update-dns" '' 392 while true; do 393 IP="$(${pkgs.curl}/bin/curl https://ipinfo.io/ip 2> /dev/null)" 394 echo $IP 395 ${config.services.eon.package}/bin/capc update /run/agenix/eon-freumh.org.cap \ 396 -u "remove|jellyfin.freumh.org|A" \ 397 -u "remove|jellyseerr.freumh.org|A" \ 398 -u "remove|calibre.freumh.org|A" \ 399 -u "add|jellyfin.freumh.org|A|$IP|60" \ 400 -u "add|jellyseerr.freumh.org|A|$IP|60" \ 401 -u "add|calibre.freumh.org|A|$IP|60" \ 402 ; 403 sleep 3600 404 done 405 ''; 406 Restart = "always"; 407 RestartSec = 5; 408 User = "root"; 409 }; 410 }; 411}