Commit graph

960 commits

Author SHA1 Message Date
a93996444d Force overwrite existing ghostty config via Home Manager
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:23:34 +01:00
09d00909cb Switch to fish shell, ghostty terminal, and simplified prompt
- Replace bash with fish as default shell (all hosts)
- Replace kgx with ghostty (desktop hosts), update Super+T keybinding
- Custom two-line fish prompt: NixOS icon, username, path, hostname, ❯
- Nix-shell awareness, red ❯ on error
- Simplify fastfetch: user@host, OS, kernel, shell, terminal, uptime, memory
- Ghostty config: FiraCode Nerd Font, catppuccin-mocha, no titlebar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:22:21 +01:00
a14cc55921 Revert nixpkgs.stdenv.hostPlatform back to nixpkgs.hostPlatform
nixpkgs.stdenv.hostPlatform is not a valid NixOS option. The
deprecation warning comes from nixpkgs internals and is harmless.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 09:27:34 +01:00
f1f2afaace Fix deprecated nixpkgs.hostPlatform -> nixpkgs.stdenv.hostPlatform
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 09:26:26 +01:00
ediblerope
32464aa1fc flake: update inputs 2026-04-08 05:42:44 +00:00
8b62397037 Remove Docker, add server migration checklist to readme
- Remove virtualisation.docker.enable (no longer used after native
  migration of Authelia, go2rtc, and nginx)
- Add migration checklist documenting which state directories and
  secrets to back up when moving to new hardware

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 22:54:33 +01:00
aa38a7e065 Document Authelia users_database.yml structure and password hash generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 21:00:03 +01:00
6a2563f058 Fix go2rtc: use RuntimeDirectory instead of mkdir /run/go2rtc
DynamicUser can't write to /run directly. RuntimeDirectory lets systemd
create and manage the directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 20:51:22 +01:00
595efbb25a Move go2rtc RTSP credentials out of nix store, document all secrets
- go2rtc.nix: template config at runtime from /var/secrets/go2rtc-rtsp-url
  instead of embedding credentials in the nix store
- readme.md: add Mediaserver secrets section documenting all secrets
  needed for a fresh deploy (Cloudflare, go2rtc, Authelia)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 20:49:04 +01:00
08669d7eb5 Update docs: add new services to readme, remove obsolete go2rtc-readme
- readme.md: add authelia, fail2ban, homepage, arr-interconnect, nginx
  description updated to mention ACME. Remove omnisearch, add cachyos
  kernel to flake inputs table.
- cloudflare-ddns.md: document shared token usage with ACME, note
  Zone:Zone:Read permission requirement.
- Delete go2rtc-readme.md (documented Docker setup, now native NixOS).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 20:42:19 +01:00
372275da5e Fix Authelia forward-auth to match proven working NPM config
- Use /api/verify endpoint instead of /api/authz/forward-auth
- Add proxy_pass_request_body off to auth location
- Put redirect URL inline in error_page instead of using a variable
- Use X-Forwarded-Uri (matching old config) instead of X-Forwarded-URI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 20:35:59 +01:00
09d24eecf3 Fix Authelia forward-auth: use set instead of auth_request_set for redirect URL
auth_request_set reads variables from the auth subrequest context where
$scheme/$http_host/$request_uri are empty, causing a 500 instead of a
302 redirect. Using set captures from the main request context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 20:31:03 +01:00
64bd0b8f0b Fix nginx proxy_headers_hash warning from Authelia forward-auth headers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 17:27:23 +01:00
9ce1e00ea5 Remove broken --dns.propagation-wait flag, rely on default propagation check
The CNAME interference is resolved so the default lego propagation check
(querying Cloudflare authoritative NS) should work correctly now.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 17:20:19 +01:00
476379f4e4 Fix ACME: add 30s propagation wait and re-enable full DNS check
The previous dnsPropagationCheck=false caused lego to ask LE to validate
before the TXT record was globally visible. Adding --dns.propagation-wait
gives Cloudflare time to serve the record from all edge locations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 17:16:07 +01:00
b27d2913e8 Disable ACME DNS propagation check for Cloudflare
Cloudflare is the authoritative NS so API-created TXT records are
immediately visible — the propagation poll was timing out unnecessarily.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 16:53:00 +01:00
9838154b25 Fix authelia-setup: create state directory before migrating user database
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:58:51 +01:00
eadbc92126 Replace Docker containers with native NixOS modules for nginx, Authelia, and go2rtc
- Native nginx with ACME wildcard cert (*.nordhammer.it) via Cloudflare DNS-01
- Native Authelia SSO with forward auth protecting homepage + camera
- Native go2rtc camera streaming (no more Docker)
- Auto-migration script for Authelia secrets and user database from Docker
- Homepage hrefs updated to use HTTPS domain names
- Fail2ban updated for native nginx log paths + new Authelia jail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:47:56 +01:00
cb8ecc1409 Add FredOS-Macbook SSH key for passwordless login
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:51:11 +01:00
f59fce5087 Add auto-interconnect service for *arr stack
Systemd oneshot that runs after all services start and configures:
- Prowlarr → Sonarr (TV indexers, full sync)
- Prowlarr → Radarr (movie indexers, full sync)
- Sonarr → qBittorrent (download client, category: tv-sonarr)
- Radarr → qBittorrent (download client, category: radarr)
- Bazarr → Sonarr (subtitle management for TV)
- Bazarr → Radarr (subtitle management for movies)

Fully idempotent — checks for existing connections before creating.
API keys extracted from each app's config files at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:45:53 +01:00
d878d3b20c Auto-extract API keys for Homepage dashboard
Adds a systemd oneshot that runs before homepage-dashboard and:
- Reads *arr API keys from their config.xml files
- Reads Bazarr key from config.ini
- Creates a Jellyfin API key in the DB if one named "Homepage" doesn't exist
- Uses localhost for qBittorrent (LocalHostAuth=false, no creds needed)
- Writes everything to /etc/homepage-secrets

Zero manual setup — all keys are extracted or generated automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:13:17 +01:00
570ddf38f6 Allow passwordless sudo for fred
40-char password from a manager is impractical for frequent sudo use.
SSH is already key-only, so local privilege escalation is the only
remaining threat — acceptable on a single-user home server.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 13:07:24 +01:00
29dae0c5ea Add Homepage dashboard for FredOS-Mediaserver
Covers all running services: Jellyfin, Sonarr, Radarr, Bazarr, Prowlarr,
qBittorrent, Nginx Proxy Manager, Authelia, go2rtc. Live widgets for
*arr apps, Jellyfin now-playing, and qBittorrent speed use API keys
loaded from /etc/homepage-secrets (outside the Nix store).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:55:42 +01:00
ediblerope
549277ca0f flake: update inputs 2026-04-07 05:42:39 +00:00
39450ca786 Remove Suricata/ELK; add SSH key auth and disable password login
Adds authorised keys for FredOS-Gaming and phone. Disables SSH password
authentication on FredOS-Mediaserver — key auth only going forward.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:48:08 +01:00
ddb208b95d Fix ELK: explicitly disable ES 8.x security on both containers
ES 8.x enables security and enrollment by default. Adding
xpack.security.enrollment.enabled=false to Elasticsearch and
xpack.security.enabled=false to Kibana suppresses the enrollment
token screen and lets Kibana connect directly over HTTP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:31:02 +01:00
699bbd9f9a Add ELK stack for Suricata log visualisation
Elasticsearch + Kibana + Filebeat in Docker, bridged via an elk network.
Filebeat uses the Suricata module to parse eve.json and auto-installs
Kibana dashboards on first run. ES heap capped at 1g; Kibana Node heap
at 512m — total stack ~2-2.5 GB RAM.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:25:29 +01:00
43ce6b046f Fix Suricata: disable all DNP3/Modbus rules via regex pattern
Individual SID exclusions weren't enough — there are many more rules for
these industrial SCADA protocols than initially identified. Switch to
regex-based disable patterns (re:modbus, re:dnp3) so suricata-update
strips all of them from the generated rules file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 20:55:44 +01:00
d1ac7c6965 Disable Modbus Suricata rules that fail to parse
Modbus protocol detection is disabled in the NixOS build; the 5 Modbus
SIDs (2250005-2250009) cause the config test to fail and crash-loop the
service. Disable them alongside the existing DNP3 exclusions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 20:51:22 +01:00
b91b0ef234 Add Suricata IDS to FredOS-Mediaserver
Passive network monitoring via af-packet on eno1. Rulesets auto-updated
from ET/Open, abuse.ch, and other community sources via suricata-update.
Runs alongside fail2ban; IPS/blocking mode can be enabled later.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 20:36:45 +01:00
2104de314e
Merge pull request #2 from ediblerope/claude/create-claude-md-Je6Ea
fail2ban: fix bantime-increment option name (multipliers not multiplier)
2026-04-06 09:36:21 +01:00
Claude
78bb64d9f2
fail2ban: fix bantime-increment option name (multipliers not multiplier)
https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 08:35:15 +00:00
fbf817fff0
Merge pull request #1 from ediblerope/claude/create-claude-md-Je6Ea
Claude/create claude md je6 ea
2026-04-06 09:33:49 +01:00
Claude
6b432f3bc2
Remove CrowdSec — replaced by fail2ban
https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 08:28:08 +00:00
Claude
4935d42e48
fail2ban: add jails for Sonarr, Radarr, Prowlarr, Bazarr, qBittorrent
All services with openFirewall = true are now covered. The *arr suite
shares a single filter since they use the same logging codebase.

https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 08:24:18 +00:00
Claude
16363dc887
fail2ban: add jails for SSH, nginx proxy manager, and Jellyfin
Replaces bare enable flag with a dedicated service module covering:
- SSH brute force via journald
- Nginx Proxy Manager auth failures via Docker log files
- Jellyfin auth failures via journald
Includes incremental ban times (up to 1 week) and LAN ignore rules.

https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 08:21:23 +00:00
Claude
f5bb08d7dd
crowdsec: switch to Docker container with native firewall bouncer
Replaces the incomplete nixpkgs NixOS module with the official
CrowdSec Docker image for the LAPI, while keeping the firewall
bouncer as a native systemd service. API key is read from
/var/lib/secrets/crowdsec-bouncer-key at start time so it
never enters the Nix store.

https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 07:05:59 +00:00
Claude
f493d09c50
Add CrowdSec setup readme for Docker-based deployment
Documents API key generation, storage, bouncer registration,
and useful cscli commands.

https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 07:00:50 +00:00
Claude
82d92d7c8f
Add CLAUDE.md with project context and nix eval guidance
https://claude.ai/code/session_01PwAXuaoJx7qD5FhVLsn7Sn
2026-04-06 06:53:19 +00:00
ediblerope
739c7ebc78 flake: update inputs 2026-04-06 05:54:30 +00:00
8b85956f7c Fix CrowdSec race: order crowdsec after tmpfiles-resetup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 23:17:35 +01:00
9958198209 Fix CrowdSec: enable LAPI server and expose config.yaml for bouncer registration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 23:12:45 +01:00
2b090f1a35 Fix CrowdSec bouncer api_url to resolve null coercion error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 23:05:57 +01:00
509c4cc47d Add CrowdSec IPS with firewall bouncer on FredOS-Mediaserver
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 22:59:37 +01:00
3f8addd5bf Remove easyeffects from FredOS-Gaming packages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 22:15:14 +01:00
488016aaed Add easyeffects to FredOS-Gaming packages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 21:59:16 +01:00
742770300f
Update flake.lock 2026-04-05 11:25:55 +01:00
4b41511e39
Update common.nix 2026-04-05 11:21:25 +01:00
7085465350
Delete services/omnisearch.nix 2026-04-05 11:21:08 +01:00
8473d70c52
Update flake.nix 2026-04-05 11:20:36 +01:00