This repository has no description
10 kB
317 lines
1{ config, pkgs, ... }:
2{
3 users.groups.download.members = [ "transmission" ];
4 services.transmission = {
5 enable = true;
6 home = "/var/state/transmission";
7 group = "download";
8 downloadDirPermissions = "775";
9 settings = {
10 download-dir = "/var/download/transmission";
11 incomplete-dir-enabled = false;
12 rpc-bind-address = "::";
13 message-level = 1;
14 umask = 18;
15 rpc-whitelist-enabled = false;
16 rpc-host-whitelist-enabled = false;
17 };
18 };
19
20 security.acme.defaults.email = "spam@krebsco.de";
21 security.acme.acceptTerms = true;
22 security.acme.certs."yellow.r".server = config.krebs.ssl.acmeURL;
23 security.acme.certs."jelly.r".server = config.krebs.ssl.acmeURL;
24 security.acme.certs."radar.r".server = config.krebs.ssl.acmeURL;
25 security.acme.certs."sonar.r".server = config.krebs.ssl.acmeURL;
26 security.acme.certs."transmission.r".server = config.krebs.ssl.acmeURL;
27 services.nginx = {
28 enable = true;
29 package = pkgs.nginx.override {
30 modules = with pkgs.nginxModules; [
31 fancyindex
32 ];
33 };
34 virtualHosts."yellow.r" = {
35 serverAlias = [ "flix.r" ];
36 default = true;
37 enableACME = true;
38 addSSL = true;
39 locations."/" = {
40 root = "/var/download";
41 extraConfig = ''
42 fancyindex on;
43 fancyindex_footer "/fancy.html";
44 include ${pkgs.nginx}/conf/mime.types;
45 include ${pkgs.writeText "extrMime" ''
46 types {
47 video/webm mkv;
48 }
49 ''};
50 create_full_put_path on;
51 '';
52 };
53 locations."/chatty" = {
54 proxyPass = "http://localhost:3000";
55 extraConfig = ''
56 rewrite /chatty/(.*) /$1 break;
57 proxy_set_header Host $host;
58 '';
59 };
60 locations."= /fancy.html".extraConfig = ''
61 alias ${pkgs.writeText "nginx_footer" ''
62 <div id="mydiv">
63 <!-- Include a header DIV with the same name as the draggable DIV, followed by "header" -->
64 <div id="mydivheader">Click here to move</div>
65 <iframe src="/chatty/index.html"></iframe>
66 </div>
67 <style>
68 #mydiv {
69 position: absolute;
70 z-index: 9;
71 background-color: #f1f1f1;
72 border: 1px solid #d3d3d3;
73 text-align: center;
74 }
75
76 #mydivheader {
77 padding: 10px;
78 cursor: move;
79 z-index: 10;
80 background-color: #2196F3;
81 color: #fff;
82 }
83 </style>
84 <script>
85 // Make the DIV element draggable:
86 dragElement(document.getElementById("mydiv"));
87
88 function dragElement(elmnt) {
89 var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
90 if (document.getElementById(elmnt.id + "header")) {
91 // if present, the header is where you move the DIV from:
92 document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
93 } else {
94 // otherwise, move the DIV from anywhere inside the DIV:
95 elmnt.onmousedown = dragMouseDown;
96 }
97
98 function dragMouseDown(e) {
99 e = e || window.event;
100 e.preventDefault();
101 // get the mouse cursor position at startup:
102 pos3 = e.clientX;
103 pos4 = e.clientY;
104 document.onmouseup = closeDragElement;
105 // call a function whenever the cursor moves:
106 document.onmousemove = elementDrag;
107 }
108
109 function elementDrag(e) {
110 e = e || window.event;
111 e.preventDefault();
112 // calculate the new cursor position:
113 pos1 = pos3 - e.clientX;
114 pos2 = pos4 - e.clientY;
115 pos3 = e.clientX;
116 pos4 = e.clientY;
117 // set the element's new position:
118 elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
119 elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
120 }
121
122 function closeDragElement() {
123 // stop moving when mouse button is released:
124 document.onmouseup = null;
125 document.onmousemove = null;
126 }
127 }
128 </script>
129 ''};
130 '';
131 };
132 virtualHosts."jelly.r" = {
133 enableACME = true;
134 addSSL = true;
135 locations."/".extraConfig = ''
136 proxy_pass http://localhost:8096/;
137 proxy_set_header Accept-Encoding "";
138 '';
139 };
140 virtualHosts."transmission.r" = {
141 enableACME = true;
142 addSSL = true;
143 locations."/" = {
144 proxyWebsockets = true;
145 proxyPass = "http://128.0.0.1:9091";
146 };
147 };
148 virtualHosts."radar.r" = {
149 enableACME = true;
150 addSSL = true;
151 locations."/" = {
152 proxyWebsockets = true;
153 proxyPass = "http://localhost:7878";
154 };
155 };
156 virtualHosts."sonar.r" = {
157 enableACME = true;
158 addSSL = true;
159 locations."/" = {
160 proxyWebsockets = true;
161 proxyPass = "http://localhost:8989";
162 };
163 };
164 };
165
166 services.samba = {
167 enable = true;
168 enableNmbd = false;
169 extraConfig = ''
170 workgroup = WORKGROUP
171 server string = ${config.networking.hostName}
172 # only allow retiolum addresses
173 hosts allow = 42::/16 10.243.0.0/16 10.244.0.0/16
174
175 # Use sendfile() for performance gain
176 use sendfile = true
177
178 # No NetBIOS is needed
179 disable netbios = true
180
181 # Only mangle non-valid NTFS names, don't care about DOS support
182 mangled names = illegal
183
184 # Performance optimizations
185 socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
186
187 # Disable all printing
188 load printers = false
189 disable spoolss = true
190 printcap name = /dev/null
191
192 map to guest = Bad User
193 max log size = 50
194 dns proxy = no
195 security = user
196
197 [global]
198 syslog only = yes
199 '';
200 shares.public = {
201 comment = "Warez";
202 path = "/var/download";
203 public = "yes";
204 "only guest" = "yes";
205 "create mask" = "0644";
206 "directory mask" = "2777";
207 writable = "no";
208 printable = "no";
209 };
210 };
211
212 systemd.services.bruellwuerfel =
213 let
214 bruellwuerfelSrc = pkgs.fetchFromGitHub {
215 owner = "krebs";
216 repo = "bruellwuerfel";
217 rev = "dc73adf69249fb63a4b024f1f3fbc9e541b27015";
218 sha256 = "078jp1gbavdp8lnwa09xa5m6bbbd05fi4x5ldkkgin5z04hwlhmd";
219 };
220 in {
221 wantedBy = [ "multi-user.target" ];
222 environment = {
223 IRC_CHANNEL = "#flix";
224 IRC_NICK = "bruelli";
225 IRC_SERVER = "irc.r";
226 IRC_HISTORY_FILE = "/tmp/bruelli.history";
227 };
228 serviceConfig = {
229 ExecStart = "${pkgs.deno}/bin/deno run -A ${bruellwuerfelSrc}/src/index.ts";
230 };
231 };
232
233 krebs.iptables = {
234 enable = true;
235 tables.filter.INPUT.rules = [
236 { predicate = "-p tcp --dport 80"; target = "ACCEPT"; } # nginx web dir
237 { predicate = "-p tcp --dport 443"; target = "ACCEPT"; } # nginx web dir
238 { predicate = "-p tcp --dport 9091"; target = "ACCEPT"; } # transmission-web
239 { predicate = "-p tcp --dport 51413"; target = "ACCEPT"; } # transmission-traffic
240 { predicate = "-p udp --dport 51413"; target = "ACCEPT"; } # transmission-traffic
241 { predicate = "-p tcp --dport 8096"; target = "ACCEPT"; } # jellyfin
242 { predicate = "-p tcp --dport 8920"; target = "ACCEPT"; } # jellyfin
243 { predicate = "-p udp --dport 1900"; target = "ACCEPT"; } # jellyfin
244 { predicate = "-p udp --dport 7359"; target = "ACCEPT"; } # jellyfin
245 { predicate = "-p tcp --dport 9696"; target = "ACCEPT"; } # prowlarr
246 { predicate = "-p tcp --dport 8989"; target = "ACCEPT"; } # sonarr
247 { predicate = "-p tcp --dport 7878"; target = "ACCEPT"; } # radarr
248 { predicate = "-p tcp --dport 6767"; target = "ACCEPT"; } # bazarr
249
250 # smbd
251 { predicate = "-i retiolum -p tcp --dport 445"; target = "ACCEPT"; }
252 { predicate = "-i retiolum -p tcp --dport 111"; target = "ACCEPT"; }
253 { predicate = "-i retiolum -p udp --dport 111"; target = "ACCEPT"; }
254 { predicate = "-i retiolum -p tcp --dport 2049"; target = "ACCEPT"; }
255 { predicate = "-i retiolum -p udp --dport 2049"; target = "ACCEPT"; }
256 { predicate = "-i retiolum -p tcp --dport 4000:4002"; target = "ACCEPT"; }
257 { predicate = "-i retiolum -p udp --dport 4000:4002"; target = "ACCEPT"; }
258 { predicate = "-i wiregrill -p tcp --dport 445"; target = "ACCEPT"; }
259 { predicate = "-i wiregrill -p tcp --dport 111"; target = "ACCEPT"; }
260 { predicate = "-i wiregrill -p udp --dport 111"; target = "ACCEPT"; }
261 { predicate = "-i wiregrill -p tcp --dport 2049"; target = "ACCEPT"; }
262 { predicate = "-i wiregrill -p udp --dport 2049"; target = "ACCEPT"; }
263 { predicate = "-i wiregrill -p tcp --dport 4000:4002"; target = "ACCEPT"; }
264 { predicate = "-i wiregrill -p udp --dport 4000:4002"; target = "ACCEPT"; }
265 ];
266 };
267
268 systemd.services.flix-index = {
269 wantedBy = [ "multi-user.target" ];
270 path = [
271 pkgs.coreutils
272 pkgs.findutils
273 pkgs.inotify-tools
274 ];
275 serviceConfig = {
276 Restart = "always";
277 ExecStart = pkgs.writers.writeDash "flix-index" ''
278 set -efu
279
280 DIR=/var/download
281 cd "$DIR"
282 while inotifywait -rq -e create -e move -e delete "$DIR"; do
283 find . -type f > "$DIR"/index.tmp
284 mv "$DIR"/index.tmp "$DIR"/index
285 done
286 '';
287 };
288 };
289
290 services.jellyfin = {
291 enable = true;
292 group = "download";
293 };
294
295 # movies
296 services.radarr = {
297 enable = true;
298 group = "download";
299 };
300
301 # shows
302 services.sonarr = {
303 enable = true;
304 group = "download";
305 };
306
307 # indexers
308 services.prowlarr = {
309 enable = true;
310 };
311
312 # subtitles
313 services.bazarr = {
314 enable = true;
315 group = "download";
316 };
317}