forked from
lass.pds.lassul.us/superconfig
This repository has no description
11 kB
417 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 extraConfig = ''
193 workgroup = WORKGROUP
194 server string = ${config.networking.hostName}
195 # only allow retiolum addresses
196 hosts allow = 42::/16 10.243.0.0/16 10.244.0.0/16 fdcc:c5da:5295:c853:d499::/80
197
198 # Use sendfile() for performance gain
199 use sendfile = true
200
201 # No NetBIOS is needed
202 disable netbios = true
203
204 # Only mangle non-valid NTFS names, don't care about DOS support
205 mangled names = illegal
206
207 # Performance optimizations
208 socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
209
210 # Disable all printing
211 load printers = false
212 disable spoolss = true
213 printcap name = /dev/null
214
215 map to guest = Bad User
216 max log size = 50
217 dns proxy = no
218 security = user
219
220 [global]
221 syslog only = yes
222 '';
223 shares.public = {
224 comment = "Warez";
225 path = "/var/download";
226 public = "yes";
227 "only guest" = "yes";
228 "create mask" = "0644";
229 "directory mask" = "2777";
230 writable = "no";
231 printable = "no";
232 };
233 };
234
235 systemd.services.bruellwuerfel =
236 let
237 bruellwuerfelSrc = pkgs.fetchFromGitHub {
238 owner = "krebs";
239 repo = "bruellwuerfel";
240 rev = "dc73adf69249fb63a4b024f1f3fbc9e541b27015";
241 sha256 = "078jp1gbavdp8lnwa09xa5m6bbbd05fi4x5ldkkgin5z04hwlhmd";
242 };
243 in
244 {
245 wantedBy = [ "multi-user.target" ];
246 after = [ "network-online.target" ];
247 environment = {
248 IRC_CHANNEL = "#flix";
249 IRC_NICK = "bruelli";
250 IRC_SERVER = "irc.r";
251 IRC_HISTORY_FILE = "/tmp/bruelli.history";
252 };
253 serviceConfig = {
254 ExecStart = "${pkgs.deno}/bin/deno run -A ${bruellwuerfelSrc}/src/index.ts";
255 };
256 };
257
258 krebs.iptables = {
259 enable = true;
260 tables.filter.INPUT.rules = [
261 {
262 predicate = "-p tcp --dport 80";
263 target = "ACCEPT";
264 } # nginx web dir
265 {
266 predicate = "-p tcp --dport 443";
267 target = "ACCEPT";
268 } # nginx web dir
269 {
270 predicate = "-p tcp --dport 9091";
271 target = "ACCEPT";
272 } # transmission-web
273 {
274 predicate = "-p tcp --dport 51413";
275 target = "ACCEPT";
276 } # transmission-traffic
277 {
278 predicate = "-p udp --dport 51413";
279 target = "ACCEPT";
280 } # transmission-traffic
281 {
282 predicate = "-p tcp --dport 8096";
283 target = "ACCEPT";
284 } # jellyfin
285 {
286 predicate = "-p tcp --dport 8920";
287 target = "ACCEPT";
288 } # jellyfin
289 {
290 predicate = "-p udp --dport 1900";
291 target = "ACCEPT";
292 } # jellyfin
293 {
294 predicate = "-p udp --dport 7359";
295 target = "ACCEPT";
296 } # jellyfin
297 {
298 predicate = "-p tcp --dport 5055";
299 target = "ACCEPT";
300 } # jellyseerr
301 {
302 predicate = "-p tcp --dport 9696";
303 target = "ACCEPT";
304 } # prowlarr
305 {
306 predicate = "-p tcp --dport 8989";
307 target = "ACCEPT";
308 } # sonarr
309 {
310 predicate = "-p tcp --dport 7878";
311 target = "ACCEPT";
312 } # radarr
313 {
314 predicate = "-p tcp --dport 6767";
315 target = "ACCEPT";
316 } # bazarr
317
318 # smbd
319 {
320 predicate = "-p tcp --dport 445";
321 target = "ACCEPT";
322 }
323 {
324 predicate = "-p tcp --dport 111";
325 target = "ACCEPT";
326 }
327 {
328 predicate = "-p udp --dport 111";
329 target = "ACCEPT";
330 }
331 {
332 predicate = "-p tcp --dport 2049";
333 target = "ACCEPT";
334 }
335 {
336 predicate = "-p udp --dport 2049";
337 target = "ACCEPT";
338 }
339 {
340 predicate = "-p tcp --dport 4000:4002";
341 target = "ACCEPT";
342 }
343 {
344 predicate = "-p udp --dport 4000:4002";
345 target = "ACCEPT";
346 }
347 ];
348
349 tables.nat.PREROUTING.rules = [
350 # transmission rpc port
351 {
352 predicate = "-i retiolum -p tcp --dport 9091";
353 target = "DNAT --to-destination fdb4:3310:947::2";
354 v4 = false;
355 }
356 ];
357 tables.filter.FORWARD.policy = "ACCEPT"; # we need this so we can forward into the the transmission network namespace
358 };
359
360 systemd.services.flix-index = {
361 wantedBy = [ "multi-user.target" ];
362 path = [
363 pkgs.coreutils
364 pkgs.findutils
365 pkgs.inotify-tools
366 ];
367 serviceConfig = {
368 Restart = "always";
369 ExecStart = pkgs.writers.writeDash "flix-index" ''
370 set -efu
371
372 DIR=/var/download
373 cd "$DIR"
374 while inotifywait -rq -e create -e move -e delete "$DIR"; do
375 find . -type f > "$DIR"/index.tmp
376 mv "$DIR"/index.tmp "$DIR"/index
377 done
378 '';
379 };
380 };
381
382 services.jellyfin = {
383 enable = true;
384 group = "download";
385 };
386
387 # request managment
388 services.jellyseerr = {
389 enable = true;
390 };
391
392 # movies
393 services.radarr = {
394 enable = true;
395 user = "download";
396 group = "download";
397 };
398
399 # shows
400 services.sonarr = {
401 enable = true;
402 user = "download";
403 group = "download";
404 };
405
406 # indexers
407 services.prowlarr = {
408 enable = true;
409 };
410
411 # subtitles
412 services.bazarr = {
413 enable = true;
414 user = "download";
415 group = "download";
416 };
417}