From 1cd6750f8339cfb494871fdf6e5c211812b17a69 Mon Sep 17 00:00:00 2001 From: "Simon R. - fantomitechno" Date: Tue, 13 Oct 2026 16:36:29 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20a=20lot=20of=20things?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fant0mib0t/celestenet/docker-compose.yml | 4 +- .../continuwuity/docker-compose.yml | 2 +- flake.lock | 30 ++-- hosts/fant0mib0t/default.nix | 4 +- modules/caddy/conseil | 14 +- modules/caddy/default.nix | 5 +- modules/caddy/fant0mib0t | 75 +++++++--- modules/cli-apps/ssh_config | 2 +- modules/ipmi-fan-control.nix | 137 ++++++++++++++++++ modules/radius/config/.gitignore | 1 - modules/radius/config/clients.conf | 4 - modules/radius/default.nix | 7 - 12 files changed, 224 insertions(+), 61 deletions(-) create mode 100644 modules/ipmi-fan-control.nix delete mode 100644 modules/radius/config/.gitignore delete mode 100644 modules/radius/config/clients.conf delete mode 100644 modules/radius/default.nix diff --git a/docker/fant0mib0t/celestenet/docker-compose.yml b/docker/fant0mib0t/celestenet/docker-compose.yml index a5c5e51..ee32c9f 100644 --- a/docker/fant0mib0t/celestenet/docker-compose.yml +++ b/docker/fant0mib0t/celestenet/docker-compose.yml @@ -5,8 +5,8 @@ services: image: ghcr.io/fantomitechno/celestenet:latest container_name: celestenet ports: - - "127.0.0.1:17230:17230/tcp" - - "127.0.0.1:17230:17230/udp" + - "17230:17230/tcp" + - "17230:17230/udp" - "127.0.0.1:1099:17232/tcp" - "127.0.0.1:1099:17232/udp" volumes: diff --git a/docker/fant0mib0t/continuwuity/docker-compose.yml b/docker/fant0mib0t/continuwuity/docker-compose.yml index 05f0abb..1927942 100644 --- a/docker/fant0mib0t/continuwuity/docker-compose.yml +++ b/docker/fant0mib0t/continuwuity/docker-compose.yml @@ -16,7 +16,7 @@ services: CONTINUWUITY_DATABASE_PATH: /var/lib/continuwuity CONTINUWUITY_ADDRESS: 0.0.0.0 CONTINUWUITY_PORT: 8008 - CONTINUWUITY_MATRIX_RTC__foci: '[{ type = "livekit", livekit_service_url = "https://livekit.fantomitechno.dev" }]'' + CONTINUWUITY_MATRIX_RTC__foci: '[{ type = "livekit", livekit_service_url = "https://livekit.fantomitechno.dev" }]' lk-jwt-service: image: ghcr.io/element-hq/lk-jwt-service:0.5.0 diff --git a/flake.lock b/flake.lock index 7c68b80..c54b8c3 100644 --- a/flake.lock +++ b/flake.lock @@ -29,11 +29,11 @@ ] }, "locked": { - "lastModified": 1789760829, - "narHash": "sha256-O3zDyR9k2Dw2BTyKVaL3xLgU1xlKEJuDosYP9al536U=", + "lastModified": 1791247494, + "narHash": "sha256-2WLkEy/+OJvNJW1c5VV7BMDQdQmn0i0wlJVFFwxuB0E=", "owner": "9001", "repo": "copyparty", - "rev": "097b83056ecf74546e4d19c88dce38e1e3220bda", + "rev": "1a87dc32187557e2ddacfb1ee424425a601b8588", "type": "github" }, "original": { @@ -222,11 +222,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1789754912, - "narHash": "sha256-E0j/V87ueEkwEzBpm5b+zogCWSdb7PQ+Q2Rzj5Dh268=", + "lastModified": 1791111688, + "narHash": "sha256-915Ghhr9ggrJoNY2Td5zEz3ZLQJageAhWG5yxgsj4xQ=", "owner": "AlvaroParker", "repo": "helium-nix", - "rev": "9c4439b869e24994d680ed30b8ad7c4ce9b8a24b", + "rev": "9f8cab4e5aece0eb59e72ed1299186cad1b36614", "type": "github" }, "original": { @@ -242,11 +242,11 @@ ] }, "locked": { - "lastModified": 1789267039, - "narHash": "sha256-LWiBv9yAYFi2LPbUhDGHPGKYskJQjj2fw12OlyO1uQo=", + "lastModified": 1790996401, + "narHash": "sha256-f+kOxEmOUnQazVAmGg0i8hzwgd1kX/geY+k/Dpheye8=", "owner": "nix-community", "repo": "home-manager", - "rev": "ec172013fa62135f58fb58dd17ae9651e8f39727", + "rev": "db7d5e2332710f5abb088f6b5de927d7f9511b35", "type": "github" }, "original": { @@ -316,11 +316,11 @@ "systems": "systems_3" }, "locked": { - "lastModified": 1789791540, - "narHash": "sha256-esGNbob+ZtT9X+TEOQaEVFa1JM21DbHQIUTs4sgZbJA=", + "lastModified": 1791438199, + "narHash": "sha256-06m9ntnmlW8pRWNb7n08vOG0aRq5FYB7nM7lgEqTdqc=", "owner": "nix-community", "repo": "nix4vscode", - "rev": "79eb3e7e13d248f98eb10e8fa506529ad1312f35", + "rev": "c1eb4cc805f4a34fe3e089c4e8eab073e252a5d6", "type": "github" }, "original": { @@ -347,11 +347,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1789749394, - "narHash": "sha256-cFTsMQz8Hzn8MT49oaeLSHg62tE86NykugCWkeM2ypk=", + "lastModified": 1791353474, + "narHash": "sha256-v72qr4LsSz61tQki/41nHKZKPY6NSeZavtGlAInOCng=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cf9d2fb3e50fa1cd5114c47505ea9177f7ff5f49", + "rev": "2efa67fd26b6df417c33e4603185c701f260dd83", "type": "github" }, "original": { diff --git a/hosts/fant0mib0t/default.nix b/hosts/fant0mib0t/default.nix index de4973b..4d83db2 100644 --- a/hosts/fant0mib0t/default.nix +++ b/hosts/fant0mib0t/default.nix @@ -11,14 +11,14 @@ ../server.nix ] ++ builtins.map (i: ../../modules/${i}) ([ - # "caddy" + "caddy" # "forgejo" # "metrix/grafana.nix" # "metrix/prometheus.nix" - "radius" # "tangled" # "copyparty.nix" "docker.nix" + "ipmi-fan-control.nix" ]); # Bootloader diff --git a/modules/caddy/conseil b/modules/caddy/conseil index 62ecb74..22ea0ab 100644 --- a/modules/caddy/conseil +++ b/modules/caddy/conseil @@ -14,22 +14,22 @@ } } -@local_net client_ip 172.16.0.0/12 -@admin_net client_ip 172.16.10.0/24 -@server_net client_ip 172.16.20.0/24 -@admin_vpn_net client_ip 172.16.30.0/24 -@guest_net client_ip 172.16.100.0/24 - # Storage http://s3.fantom.internal { import logging garage + + @not_server_net not client_ip 172.16.20.0/24 abort not @server_net + reverse_proxy 127.0.0.1:4010 } s3.fantom.home { import logging garage - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4011 tls internal } \ No newline at end of file diff --git a/modules/caddy/default.nix b/modules/caddy/default.nix index 18646cc..0bb2253 100644 --- a/modules/caddy/default.nix +++ b/modules/caddy/default.nix @@ -1,8 +1,7 @@ -{ hostname, dotfileFolder, ... }: { +{ hostname, ... }: { services.caddy = { enable = true; - enableReload = true; - configFile = "${dotfileFolder}/modules/caddy/${hostname}"; + configFile = ./${hostname}; openFirewall = true; httpPort = 80; diff --git a/modules/caddy/fant0mib0t b/modules/caddy/fant0mib0t index a243aa8..1c810bc 100644 --- a/modules/caddy/fant0mib0t +++ b/modules/caddy/fant0mib0t @@ -14,16 +14,19 @@ } } -@local_net client_ip 172.16.0.0/12 -@admin_net client_ip 172.16.10.0/24 -@server_net client_ip 172.16.20.0/24 -@admin_vpn_net client_ip 172.16.30.0/24 -@guest_net client_ip 172.16.100.0/24 - rack.renoux.dev { respond "yup, this is a rack!" } +celestenet.fantomitechno.dev { + import logging cnet + + @not_local_net not client_ip 172.16.0.0/12 + + abort @not_local_net + reverse_proxy 127.0.0.1:1099 +} + # Communication matrix.fantomitechno.dev { import logging matrix @@ -60,7 +63,10 @@ spindle.fantomitechno.dev { git.fantomitechno.dev { import logging gitea - reverse_proxy not @local_net 127.0.0.1:4006 { + + @local_net client_ip 172.16.0.0/12 + @not_local_net not client_ip 172.16.0.0/12 + reverse_proxy @not_local_net 127.0.0.1:4006 { header_up X-Real-Ip {remote_host} } @@ -112,7 +118,10 @@ vault.renoux.dev { pdf.fantom.home { import logging paperless - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4060 tls internal } @@ -124,7 +133,10 @@ notes.fantomitechno.dev { graph.fantom.home { import logging grafana - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:3000 tls internal } @@ -153,63 +165,90 @@ fedi.m.fantomitechno.dev { jellyfin.fantom.home { import logging jellyfin - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4080 tls internal } music.fantom.home { import logging jellyfin - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4085 tls internal } torrent.fantom.home { import logging qbittorrent - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4090 tls internal } flaresolver.fantom.home { import logging flaresolver - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4091 tls internal } prowlarr.fantom.home { import logging prowlarr - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4092 tls internal } jackett.fantom.home { import logging jackett - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4093 tls internal } sonarr.fantom.home { import logging sonarr - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4094 tls internal } radarr.fantom.home { import logging radarr - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4095 tls internal } bazarr.fantom.home { import logging bazarr - abort not @local_net + + @not_local_net not client_ip 172.16.0.0/12 + abort @not_local_net + reverse_proxy 127.0.0.1:4096 tls internal } \ No newline at end of file diff --git a/modules/cli-apps/ssh_config b/modules/cli-apps/ssh_config index d140614..19268ed 100644 --- a/modules/cli-apps/ssh_config +++ b/modules/cli-apps/ssh_config @@ -1,6 +1,6 @@ Host knot.fantomitechno.dev User git - Hostname 100.116.20.78 + Hostname 172.16.15.4 Port 2222 Host git.fantomitechno.dev diff --git a/modules/ipmi-fan-control.nix b/modules/ipmi-fan-control.nix new file mode 100644 index 0000000..8c6b84c --- /dev/null +++ b/modules/ipmi-fan-control.nix @@ -0,0 +1,137 @@ +{ lib, pkgs, ... }: + +let + fanControl = pkgs.writeShellApplication { + name = "ipmi-fan-control"; + + runtimeInputs = with pkgs; [ + ipmitool + gawk + gnused + gnugrep + coreutils + ]; + + text = '' + INTERVAL=30 # seconds between adjustments + RETRY_DELAY=10 # seconds between retries after a failed read + MAX_FAILS=3 # consecutive failures before forcing 100% fans + + fails=0 + last1="" + last2="" + + # Percentage -> hex value for the Lenovo raw command + set_fan_speed() { + local bank=$1 pct=$2 hex + case $pct in + 0) hex=0x01 ;; + 25) hex=0x07 ;; + 30) hex=0x30 ;; + 35) hex=0x3A ;; + 40) hex=0x40 ;; + 50) hex=0x50 ;; + 60) hex=0x60 ;; + 70) hex=0x70 ;; + 80) hex=0x80 ;; + 90) hex=0x90 ;; + 95) hex=0xA0 ;; + 100) hex=0xFF ;; + *) echo "Unknown fan speed: $pct" >&2; return 1 ;; + esac + ipmitool raw 0x3a 0x07 "$bank" "$hex" 0x01 > /dev/null + } + + set_all_fans() { + set_fan_speed 0x01 "$1" + set_fan_speed 0x02 "$1" + } + + # Extract an integer temperature for a sensor label from the SDR dump + get_temp() { + local label=$1 data=$2 raw + raw=$(grep -w "$label" <<< "$data" | awk -F'|' '{print $5}' | sed 's/[^0-9.]//g') || true + echo "''${raw%%.*}" + } + + calc_speed() { + local t=$1 + if (( t < 40 )); then echo 0 + elif (( t < 45 )); then echo 25 + elif (( t < 50 )); then echo 30 + elif (( t < 55 )); then echo 35 + elif (( t < 60 )); then echo 40 + elif (( t < 65 )); then echo 50 + elif (( t < 70 )); then echo 60 + elif (( t < 75 )); then echo 70 + elif (( t < 80 )); then echo 80 + elif (( t < 85 )); then echo 90 + elif (( t < 90 )); then echo 95 + else echo 100 + fi + } + + echo "ipmi-fan-control started" + + while true; do + cpu1="" + cpu2="" + if data=$(ipmitool sdr type temperature); then + cpu1=$(get_temp "CPU 1 Temp" "$data") + cpu2=$(get_temp "CPU 2 Temp" "$data") + fi + + if [[ -z $cpu1 || -z $cpu2 ]]; then + fails=$((fails + 1)) + echo "Failed to read CPU temperatures ($fails/$MAX_FAILS)" >&2 + if (( fails >= MAX_FAILS )); then + echo "Too many failures, forcing fans to 100%" >&2 + set_all_fans 100 || true + fi + sleep "$RETRY_DELAY" + continue + fi + fails=0 + + s1=$(calc_speed "$cpu1") + s2=$(calc_speed "$cpu2") + set_fan_speed 0x01 "$s1" + set_fan_speed 0x02 "$s2" + + # Only log when something changes, to keep the journal quiet + if [[ $s1 != "$last1" || $s2 != "$last2" ]]; then + echo "CPU1 ''${cpu1}C -> fan bank 1 at $s1% | CPU2 ''${cpu2}C -> fan bank 2 at $s2%" + last1=$s1 + last2=$s2 + fi + + sleep "$INTERVAL" + done + ''; + }; +in +{ + # Make sure the local IPMI device (/dev/ipmi0) exists + boot.kernelModules = [ + "ipmi_devintf" + "ipmi_si" + ]; + + systemd.services.ipmi-fan-control = { + description = "Lenovo x3650 M5 IPMI fan control"; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-modules-load.service" ]; + + serviceConfig = { + ExecStart = lib.getExe fanControl; + Restart = "always"; + RestartSec = 10; + + # Failsafe: whenever the service stops or crashes, push both banks to 100% + ExecStopPost = [ + "${pkgs.ipmitool}/bin/ipmitool raw 0x3a 0x07 0x01 0x40 0x01" + "${pkgs.ipmitool}/bin/ipmitool raw 0x3a 0x07 0x02 0x40 0x01" + ]; + }; + }; +} diff --git a/modules/radius/config/.gitignore b/modules/radius/config/.gitignore deleted file mode 100644 index 5347237..0000000 --- a/modules/radius/config/.gitignore +++ /dev/null @@ -1 +0,0 @@ -users \ No newline at end of file diff --git a/modules/radius/config/clients.conf b/modules/radius/config/clients.conf deleted file mode 100644 index be31af6..0000000 --- a/modules/radius/config/clients.conf +++ /dev/null @@ -1,4 +0,0 @@ -client sg250-argo3 { - ipaddr = 172.16.20.3 - secret = fantom-lab -} \ No newline at end of file diff --git a/modules/radius/default.nix b/modules/radius/default.nix deleted file mode 100644 index 66ad719..0000000 --- a/modules/radius/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ dotfileFolder, ... }: -{ - services.freeradius = { - enable = true; - configDir = "${dotfileFolder}/modules/freeradius/config"; - }; -} -- 2.51.2