This repository has no description
0

Configure Feed

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

superconfig / 2configs / services / flix / default.nix
11 kB 396 lines
1{ config, pkgs, ... }: 2{ 3 users.users.download = { 4 isSystemUser = true; 5 uid = 1001; 6 group = "download"; 7 }; 8 users.groups.download.members = [ "transmission" ]; 9 services.transmission = { 10 enable = true; 11 home = "/var/state/transmission"; 12 group = "download"; 13 downloadDirPermissions = "775"; 14 settings = { 15 download-dir = "/var/download/transmission"; 16 incomplete-dir-enabled = false; 17 rpc-bind-address = "::"; 18 message-level = 1; 19 umask = 18; 20 rpc-whitelist-enabled = false; 21 rpc-host-whitelist-enabled = false; 22 }; 23 }; 24 systemd.services.transmission-watcher = { 25 wantedBy = [ "multi-user.target" ]; 26 startAt = "*:0/5"; 27 path = [ 28 pkgs.curl 29 pkgs.systemdMinimal 30 ]; 31 script = '' 32 set -efu -o pipefail 33 if ! curl -SsfL http://transmission.r; then 34 systemctl restart transmission* 35 fi 36 ''; 37 }; 38 39 security.acme.defaults.email = "spam@krebsco.de"; 40 security.acme.acceptTerms = true; 41 security.acme.certs."yellow.r".server = config.krebs.ssl.acmeURL; 42 security.acme.certs."jelly.r".server = config.krebs.ssl.acmeURL; 43 security.acme.certs."radar.r".server = config.krebs.ssl.acmeURL; 44 security.acme.certs."sonar.r".server = config.krebs.ssl.acmeURL; 45 security.acme.certs."transmission.r".server = config.krebs.ssl.acmeURL; 46 services.nginx = { 47 enable = true; 48 package = pkgs.nginx.override { 49 modules = with pkgs.nginxModules; [ 50 fancyindex 51 ]; 52 }; 53 virtualHosts."yellow.r" = { 54 serverAliases = [ "flix.r" ]; 55 default = true; 56 enableACME = true; 57 addSSL = true; 58 locations."/" = { 59 root = "/var/download"; 60 extraConfig = '' 61 fancyindex on; 62 fancyindex_footer "/fancy.html"; 63 include ${pkgs.nginx}/conf/mime.types; 64 include ${pkgs.writeText "extrMime" '' 65 types { 66 video/webm mkv; 67 } 68 ''}; 69 create_full_put_path on; 70 ''; 71 }; 72 locations."/chatty" = { 73 proxyPass = "http://localhost:3000"; 74 extraConfig = '' 75 rewrite /chatty/(.*) /$1 break; 76 proxy_set_header Host $host; 77 ''; 78 }; 79 locations."= /fancy.html".extraConfig = '' 80 alias ${pkgs.writeText "nginx_footer" '' 81 <div id="mydiv"> 82 <!-- Include a header DIV with the same name as the draggable DIV, followed by "header" --> 83 <div id="mydivheader">Click here to move</div> 84 <iframe src="/chatty/index.html"></iframe> 85 </div> 86 <style> 87 #mydiv { 88 position: absolute; 89 z-index: 9; 90 background-color: #f1f1f1; 91 border: 1px solid #d3d3d3; 92 text-align: center; 93 } 94 95 #mydivheader { 96 padding: 10px; 97 cursor: move; 98 z-index: 10; 99 background-color: #2196F3; 100 color: #fff; 101 } 102 </style> 103 <script> 104 // Make the DIV element draggable: 105 dragElement(document.getElementById("mydiv")); 106 107 function dragElement(elmnt) { 108 var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; 109 if (document.getElementById(elmnt.id + "header")) { 110 // if present, the header is where you move the DIV from: 111 document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown; 112 } else { 113 // otherwise, move the DIV from anywhere inside the DIV: 114 elmnt.onmousedown = dragMouseDown; 115 } 116 117 function dragMouseDown(e) { 118 e = e || window.event; 119 e.preventDefault(); 120 // get the mouse cursor position at startup: 121 pos3 = e.clientX; 122 pos4 = e.clientY; 123 document.onmouseup = closeDragElement; 124 // call a function whenever the cursor moves: 125 document.onmousemove = elementDrag; 126 } 127 128 function elementDrag(e) { 129 e = e || window.event; 130 e.preventDefault(); 131 // calculate the new cursor position: 132 pos1 = pos3 - e.clientX; 133 pos2 = pos4 - e.clientY; 134 pos3 = e.clientX; 135 pos4 = e.clientY; 136 // set the element's new position: 137 elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; 138 elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; 139 } 140 141 function closeDragElement() { 142 // stop moving when mouse button is released: 143 document.onmouseup = null; 144 document.onmousemove = null; 145 } 146 } 147 </script> 148 ''}; 149 ''; 150 }; 151 virtualHosts."jelly.r" = { 152 enableACME = true; 153 addSSL = true; 154 locations."/".extraConfig = '' 155 proxy_pass http://localhost:8096/; 156 proxy_set_header Accept-Encoding ""; 157 ''; 158 }; 159 virtualHosts."transmission.r" = { 160 enableACME = true; 161 addSSL = true; 162 locations."/" = { 163 proxyWebsockets = true; 164 proxyPass = "http://128.0.0.1:9091"; 165 }; 166 }; 167 virtualHosts."radar.r" = { 168 enableACME = true; 169 addSSL = true; 170 locations."/" = { 171 proxyWebsockets = true; 172 proxyPass = "http://localhost:7878"; 173 }; 174 }; 175 virtualHosts."sonar.r" = { 176 enableACME = true; 177 addSSL = true; 178 locations."/" = { 179 proxyWebsockets = true; 180 proxyPass = "http://localhost:8989"; 181 # sonar.r now has forced authentication 182 extraConfig = '' 183 proxy_set_header Authorization "Basic a3JlYnM6YWlkc2JhbGxz"; 184 ''; 185 }; 186 }; 187 }; 188 189 services.samba = { 190 enable = true; 191 enableNmbd = false; 192 settings.global = { 193 "hosts allow" = "42::/16 10.243.0.0/16 10.244.0.0/16 fdcc:c5da:5295:c853:d499::/80"; 194 "use sendfile" = "true"; 195 "disable netbios" = "true"; 196 "mangled names" = "illegal"; 197 "socket options" = "TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536"; 198 "load printers" = "false"; 199 "disable spoolss" = "true"; 200 "printcap name" = "/dev/null"; 201 "map to guest" = "Bad User"; 202 "max log size" = "50"; 203 "dns proxy" = "no"; 204 "security" = "user"; 205 "syslog only" = "yes"; 206 }; 207 shares.public = { 208 comment = "Warez"; 209 path = "/var/download"; 210 public = "yes"; 211 "only guest" = "yes"; 212 "create mask" = "0644"; 213 "directory mask" = "2777"; 214 writable = "no"; 215 printable = "no"; 216 }; 217 }; 218 219 systemd.services.bruellwuerfel = 220 let 221 bruellwuerfelSrc = pkgs.fetchFromGitHub { 222 owner = "krebs"; 223 repo = "bruellwuerfel"; 224 rev = "dc73adf69249fb63a4b024f1f3fbc9e541b27015"; 225 sha256 = "078jp1gbavdp8lnwa09xa5m6bbbd05fi4x5ldkkgin5z04hwlhmd"; 226 }; 227 in 228 { 229 wantedBy = [ "multi-user.target" ]; 230 after = [ "network-online.target" ]; 231 environment = { 232 IRC_CHANNEL = "#flix"; 233 IRC_NICK = "bruelli"; 234 IRC_SERVER = "irc.r"; 235 IRC_HISTORY_FILE = "/tmp/bruelli.history"; 236 }; 237 serviceConfig = { 238 ExecStart = "${pkgs.deno}/bin/deno run -A ${bruellwuerfelSrc}/src/index.ts"; 239 }; 240 }; 241 242 krebs.iptables = { 243 enable = true; 244 tables.filter.INPUT.rules = [ 245 { 246 predicate = "-p tcp --dport 80"; 247 target = "ACCEPT"; 248 } # nginx web dir 249 { 250 predicate = "-p tcp --dport 443"; 251 target = "ACCEPT"; 252 } # nginx web dir 253 { 254 predicate = "-p tcp --dport 9091"; 255 target = "ACCEPT"; 256 } # transmission-web 257 { 258 predicate = "-p tcp --dport 51413"; 259 target = "ACCEPT"; 260 } # transmission-traffic 261 { 262 predicate = "-p udp --dport 51413"; 263 target = "ACCEPT"; 264 } # transmission-traffic 265 { 266 predicate = "-p tcp --dport 8096"; 267 target = "ACCEPT"; 268 } # jellyfin 269 { 270 predicate = "-p tcp --dport 8920"; 271 target = "ACCEPT"; 272 } # jellyfin 273 { 274 predicate = "-p udp --dport 1900"; 275 target = "ACCEPT"; 276 } # jellyfin 277 { 278 predicate = "-p udp --dport 7359"; 279 target = "ACCEPT"; 280 } # jellyfin 281 282 # smbd 283 { 284 predicate = "-p tcp --dport 445"; 285 target = "ACCEPT"; 286 } 287 { 288 predicate = "-p tcp --dport 111"; 289 target = "ACCEPT"; 290 } 291 { 292 predicate = "-p udp --dport 111"; 293 target = "ACCEPT"; 294 } 295 { 296 predicate = "-p tcp --dport 2049"; 297 target = "ACCEPT"; 298 } 299 { 300 predicate = "-p udp --dport 2049"; 301 target = "ACCEPT"; 302 } 303 { 304 predicate = "-p tcp --dport 4000:4002"; 305 target = "ACCEPT"; 306 } 307 { 308 predicate = "-p udp --dport 4000:4002"; 309 target = "ACCEPT"; 310 } 311 ]; 312 313 tables.nat.PREROUTING.rules = [ 314 # transmission rpc port 315 { 316 predicate = "-i retiolum -p tcp --dport 9091"; 317 target = "DNAT --to-destination fdb4:3310:947::2"; 318 v4 = false; 319 } 320 ]; 321 tables.filter.FORWARD.policy = "ACCEPT"; # we need this so we can forward into the the transmission network namespace 322 }; 323 324 systemd.services.flix-index = { 325 wantedBy = [ "multi-user.target" ]; 326 path = [ 327 pkgs.coreutils 328 pkgs.findutils 329 pkgs.inotify-tools 330 ]; 331 serviceConfig = { 332 Restart = "always"; 333 ExecStart = pkgs.writers.writeDash "flix-index" '' 334 set -efu 335 336 DIR=/var/download 337 cd "$DIR" 338 while inotifywait -rq -e create -e move -e delete "$DIR"; do 339 find . -type f > "$DIR"/index.tmp 340 mv "$DIR"/index.tmp "$DIR"/index 341 done 342 ''; 343 }; 344 }; 345 346 services.jellyfin = { 347 enable = true; 348 group = "download"; 349 }; 350 351 # request managment 352 services.jellyseerr = { 353 enable = true; 354 openFirewall = true; 355 package = pkgs.jellyseerr.overrideAttrs (_: { 356 dontCheckForBrokenSymlinks = true; 357 }); 358 }; 359 360 # movies 361 services.radarr = { 362 enable = true; 363 openFirewall = true; 364 user = "download"; 365 group = "download"; 366 }; 367 368 # shows 369 services.sonarr = { 370 enable = true; 371 openFirewall = true; 372 user = "download"; 373 group = "download"; 374 }; 375 # sonarr needs unsecure packages 376 nixpkgs.config.permittedInsecurePackages = [ 377 "aspnetcore-runtime-wrapped-6.0.36" 378 "aspnetcore-runtime-6.0.36" 379 "dotnet-sdk-wrapped-6.0.428" 380 "dotnet-sdk-6.0.428" 381 ]; 382 383 # indexers 384 services.prowlarr = { 385 enable = true; 386 openFirewall = true; 387 }; 388 389 # subtitles 390 services.bazarr = { 391 enable = true; 392 openFirewall = true; 393 user = "download"; 394 group = "download"; 395 }; 396}