Compare commits
2 commits
f3cecd422f
...
358f2296ce
| Author | SHA1 | Date | |
|---|---|---|---|
| 358f2296ce | |||
| 227fc49cb8 |
3 changed files with 97 additions and 8 deletions
|
|
@ -89,6 +89,47 @@ let
|
||||||
date +%s > "${lastSeenFile}"
|
date +%s > "${lastSeenFile}"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
fwIp = "${config.networkPrefix}.97.1";
|
||||||
|
|
||||||
|
nasWakeHtml = pkgs.writeText "nas-wake.html" ''
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="refresh" content="15">
|
||||||
|
<title>Waking up NAS...</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: #1a1a2e; color: #e0e0e0; }
|
||||||
|
.container { text-align: center; padding: 2rem; }
|
||||||
|
h1 { font-size: 1.8em; margin-bottom: 0.5em; }
|
||||||
|
p { font-size: 1.1em; color: #aaa; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>NAS is waking up…</h1>
|
||||||
|
<p>A wake-on-LAN packet has been sent.<br>This page will refresh automatically in 15 seconds.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'';
|
||||||
|
|
||||||
|
nasWakeHttpScript = pkgs.writeShellScript "nas-wake-http" ''
|
||||||
|
# Trigger WOL (reuses cooldown/holdoff from wakeScript)
|
||||||
|
${wakeScript} >&2 || true
|
||||||
|
|
||||||
|
BODY=$(cat ${nasWakeHtml})
|
||||||
|
LENGTH=''${#BODY}
|
||||||
|
|
||||||
|
printf "HTTP/1.1 503 Service Unavailable\r\n"
|
||||||
|
printf "Content-Type: text/html; charset=utf-8\r\n"
|
||||||
|
printf "Content-Length: %d\r\n" "$LENGTH"
|
||||||
|
printf "Retry-After: 15\r\n"
|
||||||
|
printf "Connection: close\r\n"
|
||||||
|
printf "\r\n"
|
||||||
|
printf "%s" "$BODY"
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
systemd.services.nas-wake-journal = {
|
systemd.services.nas-wake-journal = {
|
||||||
|
|
@ -130,4 +171,26 @@ in
|
||||||
AccuracySec = "1s";
|
AccuracySec = "1s";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Allow web-02 (bridged to server) to reach the wake HTTP endpoint
|
||||||
|
networking.firewall.interfaces."server".allowedTCPPorts = [ 9800 ];
|
||||||
|
|
||||||
|
# HTTP endpoint for nginx error_page → WOL trigger.
|
||||||
|
# When nginx on web-arm gets a 502/504 from a NAS-proxied vhost, it
|
||||||
|
# proxies the request here. We send WOL and return a "waking up" page.
|
||||||
|
systemd.services.nas-wake-http = {
|
||||||
|
description = "HTTP endpoint to wake NAS on reverse-proxy failure";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = with pkgs; [ coreutils ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.socat}/bin/socat TCP-LISTEN:9800,bind=${fwIp},reuseaddr,fork EXEC:${nasWakeHttpScript}";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "5s";
|
||||||
|
RuntimeDirectory = "nas-wake-on-access";
|
||||||
|
RuntimeDirectoryPreserve = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,16 @@
|
||||||
{ config, lib, ... }: {
|
{ config, lib, ... }: {
|
||||||
|
# Catch-all default server: drop connections from bots/scanners hitting
|
||||||
|
# by IP or unknown Host header. Without this, the alphabetically first
|
||||||
|
# vhost (audiobooks) becomes the implicit default — and its @nas_wake
|
||||||
|
# error handler wakes the NAS on every random internet probe.
|
||||||
|
services.nginx.virtualHosts."_" = {
|
||||||
|
default = true;
|
||||||
|
rejectSSL = true;
|
||||||
|
extraConfig = ''
|
||||||
|
return 444;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."git.cloonar.com" = {
|
services.nginx.virtualHosts."git.cloonar.com" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
@ -45,12 +57,17 @@
|
||||||
allow ${config.networkPrefix}.97.0/24;
|
allow ${config.networkPrefix}.97.0/24;
|
||||||
allow ${config.networkPrefix}.98.0/24;
|
allow ${config.networkPrefix}.98.0/24;
|
||||||
deny all;
|
deny all;
|
||||||
|
proxy_connect_timeout 3s;
|
||||||
|
error_page 502 504 = @nas_wake;
|
||||||
'';
|
'';
|
||||||
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://${config.networkPrefix}.97.11:8000";
|
proxyPass = "http://${config.networkPrefix}.97.11:8000";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
};
|
};
|
||||||
|
locations."@nas_wake" = {
|
||||||
|
proxyPass = "http://${config.networkPrefix}.97.1:9800";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."jellyfin.cloonar.com" = {
|
services.nginx.virtualHosts."jellyfin.cloonar.com" = {
|
||||||
|
|
@ -58,6 +75,11 @@
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_connect_timeout 3s;
|
||||||
|
error_page 502 504 = @nas_wake;
|
||||||
|
'';
|
||||||
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://${config.networkPrefix}.97.11:8096";
|
proxyPass = "http://${config.networkPrefix}.97.11:8096";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
|
|
@ -73,6 +95,9 @@
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
locations."@nas_wake" = {
|
||||||
|
proxyPass = "http://${config.networkPrefix}.97.1:9800";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."audiobooks.cloonar.com" = {
|
services.nginx.virtualHosts."audiobooks.cloonar.com" = {
|
||||||
|
|
@ -80,6 +105,11 @@
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_connect_timeout 3s;
|
||||||
|
error_page 502 504 = @nas_wake;
|
||||||
|
'';
|
||||||
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://${config.networkPrefix}.97.11:13378";
|
proxyPass = "http://${config.networkPrefix}.97.11:13378";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
|
|
@ -94,6 +124,9 @@
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
locations."@nas_wake" = {
|
||||||
|
proxyPass = "http://${config.networkPrefix}.97.1:9800";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."moltbot.cloonar.com" = {
|
services.nginx.virtualHosts."moltbot.cloonar.com" = {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
|
boot.loader.timeout = 1;
|
||||||
boot.loader.systemd-boot = {
|
boot.loader.systemd-boot = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configurationLimit = 5;
|
configurationLimit = 5;
|
||||||
|
|
@ -28,8 +29,6 @@
|
||||||
boot.swraid = {
|
boot.swraid = {
|
||||||
enable = true;
|
enable = true;
|
||||||
mdadmConf = ''
|
mdadmConf = ''
|
||||||
DEVICE /dev/disk/by-id/nvme-KIOXIA-EXCERIA_PLUS_G3_SSD_7FJKS1MAZ0E7-part1
|
|
||||||
DEVICE /dev/disk/by-id/nvme-KIOXIA-EXCERIA_PLUS_G3_SSD_7FJKS1M9Z0E7-part1
|
|
||||||
DEVICE /dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_8582A01SF4MJ-part1
|
DEVICE /dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_8582A01SF4MJ-part1
|
||||||
DEVICE /dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_75V2A0H3F4MJ-part1
|
DEVICE /dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_75V2A0H3F4MJ-part1
|
||||||
'';
|
'';
|
||||||
|
|
@ -84,12 +83,6 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# LVM volumes on RAID array
|
|
||||||
fileSystems."/var/lib/downloads" = {
|
|
||||||
device = "/dev/vg-data-fast/downloads";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/var/lib/multimedia" = {
|
fileSystems."/var/lib/multimedia" = {
|
||||||
device = "/dev/vg-data-slow/multimedia";
|
device = "/dev/vg-data-slow/multimedia";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue