Commit graph

92 commits

Author SHA1 Message Date
ashie
db959e9fd4 feat: Replace SearXNG with Websurfx
- Add new Websurfx module (Rust-based meta search engine)
- Websurfx is faster and lighter than SearXNG
- Uses Redis for caching via Podman containers
- Configurable themes and color schemes (defaults to catppuccin-mocha)
- Disable SearXNG, enable Websurfx on search.ashisgreat.xyz
2026-03-19 23:37:32 +00:00
aa670604b5 fix(openclaw): recursively fix permissions on data directory
- Use 'chown -R 1000:1000' and 'chmod -R u+rwX' in the preStart script.

- This ensures all files in /var/lib/openclaw are accessible by the container's node user.
2026-03-19 23:13:41 +01:00
49ffe471a3 fix(openclaw): remove invalid self-improvement hook
- The 'hooks' section with 'self-improvement' was causing a validation error and a crash loop on startup.
2026-03-19 23:10:31 +01:00
b505d2a327 fix(openclaw): fix ebusy on config file write
- Replace read-only bind mount for openclaw.json with a full directory bind mount.

- Use systemd preStart to copy the Nix declarative config file before startup.

- This prevents the EBUSY crash loop when OpenClaw attempts to modify its own config file on launch.
2026-03-19 23:04:50 +01:00
43bc670bf4 feat(openclaw): enable self-improvement hook
- Declaratively enable the `self-improvement` hook in the OpenClaw configuration file since it is mounted read-only into the Podman container.
2026-03-19 23:02:28 +01:00
adb8ddb611 feat(security): expose internal services and DoH to public
- Remove `internalOnly = true` flag from Vaultwarden, Forgejo, and AdGuard Home to make them publicly accessible again.

- This also re-exposes the DNS-over-HTTPS (DoH) endpoint on the AdGuard Home domain.
2026-03-19 22:48:14 +01:00
5d177a0d5c feat(network): rewrite internal dns and expose adguard ui
- Add DNS rewrites in AdGuard Home for `*.ashisgreat.xyz` to route to the Tailscale IP (`100.64.0.3`).

- Securely expose the AdGuard Home Web UI to the Tailscale network instead of blocking it completely.
2026-03-19 22:43:45 +01:00
f31ec2ce65 feat(security): restrict internal services to tailscale
- Add `internalOnly` option to nginx module to block public access.

- Apply `internalOnly` flag to Forgejo and Vaultwarden to ensure they are only accessible over the VPN or localhost.
2026-03-19 22:35:33 +01:00
b0b0989d36 fix(openclaw): revert invalid github tools/mcp config 2026-03-19 22:26:07 +01:00
6155b36279 . 2026-03-19 22:17:54 +01:00
1c76661538 feat(network): route tailscale dns through adguard
- Configure Headscale to use the VPS Tailscale IP (100.64.0.3) as the global DNS server instead of external providers.

- Add firewall rules to allow DNS requests over the `tailscale0` interface.

- Add iptables PREROUTING rules to redirect standard DNS (port 53) from Tailscale clients to AdGuard Home (port 5353) to resolve port conflicts with `aardvark-dns`.
2026-03-19 22:14:18 +01:00
4925420fdc feat(openclaw): enable github tool in config 2026-03-19 22:11:47 +01:00
b7ccb0a07e Merge branch 'main' into fix/openclaw-network-isolation 2026-03-19 20:19:05 +00:00
9803eebb1d Merge branch 'main' into feat/headscale 2026-03-19 20:18:10 +00:00
96a86db323 Merge branch 'main' into fix/openclaw-network-isolation 2026-03-19 20:17:50 +00:00
1c28db5f8e feat(headscale): add self-hosted Tailscale control server
New module: modules/headscale.nix
- Headscale service listening on localhost with Nginx reverse proxy
- SQLite database (appropriate for personal use)
- Tailscale public DERP relays for NAT traversal fallback
- MagicDNS enabled with Mullvad/Quad9 upstream resolvers
- Optional OIDC authentication (Google, GitHub, etc.)
- Default auth: pre-shared API keys (headscale apikeys create)
- Added to backup paths (SQLite DB)
- headscale CLI tool added to system packages

Configuration:
- Domain: vpn.ashisgreat.xyz
- OIDC disabled by default (documented how to enable in configuration.nix)

To register a device after deploying:
  sudo headscale apikeys create
  tailscale up --login-server=https://vpn.ashisgreat.xyz --authkey=<key>

DNS record needed: vpn.ashisgreat.xyz → VPS IP
2026-03-19 15:39:56 +00:00
9092d6ec58 fix(openclaw): remove --network=host, use bridge network
- Drops --network=host from OpenClaw container
- Container now runs on Podman's default bridge network
- Gateway port already mapped via ports config (127.0.0.1:18789:8080)
- Container retains outbound internet access for Discord API, model providers, etc.
- Cannot reach other host services (Forgejo, Vaultwarden, etc.) — principle of least privilege

Note: If OpenClaw needs to reach local services in the future, add explicit
extraOptions like --network=bridge or create a shared Podman network.
2026-03-19 15:09:05 +00:00
790501d290 feat(nginx): add rate limiting with per-domain overrides
- Global rate limit: 10 req/s with burst of 20
- Connection limit: 30 concurrent per IP
- Per-domain override support (requests, burst, enable/disable)
- SearXNG gets higher limits (20/40) to tolerate bot traffic
- Returns 429 when rate limited
2026-03-19 15:08:34 +00:00
fbea02867e feat(nginx): add security headers with per-domain CSP
- Add HSTS (6 months, includeSubDomains, preload-ready)
- Add X-Content-Type-Options: nosniff
- Add Permissions-Policy (disable camera/mic/geolocation)
- Add Cross-Origin-Resource-Policy: same-origin
- Add Cross-Origin-Opener-Policy: same-origin
- Add configurable Content-Security-Policy per domain

Per-service CSP tuning:
- SearXNG: null (handles its own CSP in settings.yml)
- Forgejo: relaxed (unsafe-inline/eval for code highlighting)
- Vaultwarden: relaxed (unsafe-eval for WebCrypto vault)

Fixes: missing CSP, HSTS, X-Content-Type-Options headers
2026-03-19 13:42:41 +00:00
837e71b69d Add Forgejo Actions Runner with sops secrets 2026-03-19 14:05:51 +01:00
f646c091cc Harden SSH and enable post-quantum key exchange (sntrup761x25519-sha512) for system and Forgejo 2026-03-19 00:05:12 +01:00
abf2080f91 Add auto-update and maintenance options to system module 2026-03-19 00:03:58 +01:00
748ccc6fc8 Enable Forgejo built-in SSH server on port 2222 2026-03-18 23:49:02 +01:00
6e9de4c189 Add Forgejo self-hosted Git service with Nginx, PostgreSQL, and Restic backups 2026-03-18 23:32:01 +01:00
c51c7183c1 Allow AdGuard Home to read ACME certificates via ReadOnlyPaths 2026-03-18 22:12:28 +01:00
deedd00762 Automate certificate path injection in AdGuard Home config 2026-03-18 22:11:08 +01:00
223f716b85 Remove explicit filter IDs from AdGuard config to avoid unmarshalling errors 2026-03-18 22:06:47 +01:00
8a9c513fde Fix AdGuard filter ID type (string to integer) 2026-03-18 22:02:44 +01:00
7ea9246d74 Manage AdGuard Home blocklists via NixOS using yq-go injection 2026-03-18 22:01:38 +01:00
4790078ff9 Fix CrowdSec GeoIP filter syntax 2026-03-18 21:54:34 +01:00
c3adfa7e25 Restrict incoming connections to DE via CrowdSec GeoIP 2026-03-18 21:53:05 +01:00
8f44273faf Cleanup 2026-03-18 21:33:42 +01:00
01b19c9fa0 Cleanup 2026-03-18 21:31:19 +01:00
ecf4fe59af Cleanup 2026-03-18 21:29:58 +01:00
e9652aaaa6 Cleanup 2026-03-18 21:27:41 +01:00
ac36befbd7 Cleanup 2026-03-18 21:26:19 +01:00
e82bbec626 Cleanup 2026-03-18 21:23:53 +01:00
1c56d477fa Cleanup 2026-03-18 21:23:37 +01:00
e1d18c18be Cleanup 2026-03-18 21:22:19 +01:00
1792180144 Cleanup 2026-03-18 21:20:42 +01:00
1942425605 feat(adguard): enable DoT and fix ClientID injection
- Enable DNS-over-TLS (DoT) on port 853 using Nginx's ACME certificates
- Fix an issue where the native NixOS module dropped SOPS client IDs
- Use sops.templates and yq to inject ClientIDs dynamically before start
- Enable allow_unencrypted_doh to fix Nginx proxying DoH correctly
2026-03-18 21:12:31 +01:00
5dd91f74b1 fix(adguard): resolve port 53 conflict
Change AdGuard Home DNS listener to bind to 127.0.0.1:5353 to avoid conflicting with existing services on port 53, since we only expose DoH via Nginx.
2026-03-18 20:58:07 +01:00
219391bc85 refactor(adguard): migrate to native nixos service
Replace the Podman container and manual YAML templating with the native  NixOS module for better system integration and simpler declarative configuration.
2026-03-18 20:56:30 +01:00
7a505055f8 fix(adguard): fix string interpolation syntax error
Fix a broken string concatenation that was causing a syntax error during NixOS evaluation.

Co-Authored-By: Gemini CLI <noreply@google.com>
2026-03-18 20:49:31 +01:00
93bef3b301 fix(adguard): rewrite with correct lib.length syntax
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:51:53 +01:00
7bdbe767b6 fix(adguard): use lib.length instead of == for empty check
Nix doesn't support == operator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:27:47 +01:00
51e937c02f fix(adguard): add empty clients list when no clients configured
AdGuard Home fails with empty persistent list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:27:21 +01:00
7b9b1e1909 fix(adguard): add newline before filtering section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:26:40 +01:00
a5d1f3e136 fix(adguard): fix YAML structure - clients at correct level
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:24:37 +01:00
ce152ba2b3 fix(adguard): fix template string concatenation
Properly concatenate optionalString with content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:23:51 +01:00