Commit Graph

180 Commits

Author SHA1 Message Date
roof 50f2200b45 fix: wireguard health_check error + logs page ALL service + rotate confirmation
- WireGuardManager.test_connectivity: make peer_ip optional so health_check
  can call it without args (was logging ERROR on every health poll)
- Logs page: add ALL option to service selector (uses search across all services)
- Logs page: show service tag on each log line when in ALL/search mode
- Logs page: require window.confirm before rotating logs to prevent accidental data loss

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:47:41 -04:00
roof 67ddc97795 feat: overhaul Logs page with search, container logs, statistics, and rotation
- Added 4-tab layout: Service Logs, Container Logs, Statistics & Rotation, Health History
- Service Logs: service/level/line-count selector, keyword search, auto-refresh (5s)
- Container Logs: container picker, tail lines selector, auto-refresh
- Statistics & Rotation: per-service file size, entry/error/warning counts, per-service and bulk rotate buttons
- Added logsAPI in api.js: getServiceLogs, searchLogs, exportLogs, getStatistics, rotateLogs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:38:08 -04:00
roof 1a5da3a207 docs(ui): clarify rule source separation on routing tabs
Added info banners on Firewall, Peer Routes, and Live iptables tabs
explaining that stored rules (NAT/Firewall/Peer Routes forms) and live
rules (pic-peer-* from Peers page, PostUp from wg0.conf) are separate
by design — Live iptables shows everything, each form tab shows only
what it manages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:32:24 -04:00
roof 4bf583c071 fix: diagnostics tab — run ping/traceroute in cell-wireguard, fix wrong method call
The connectivity endpoint was calling routing_manager.test_connectivity()
(no args, internal health check) instead of test_routing_connectivity(target_ip).
Also ping/traceroute aren't installed in the API container; run them via
docker exec cell-wireguard instead.

Updated test_api_endpoints to mock test_routing_connectivity and cover
the new DELETE /firewall/<id> and GET /live-iptables endpoints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:26:40 -04:00
roof 901094f60a feat: routing page — port forwarding tab, live iptables, diagnostics, firewall delete
Backend:
- routing_manager.remove_firewall_rule(): remove stored rule + iptables -D
- routing_manager.get_live_iptables(): dump filter/nat tables from cell-wireguard
- DELETE /api/routing/firewall/<rule_id> endpoint (was missing)
- GET /api/routing/live-iptables endpoint

Frontend Routing.jsx — 7 tabs:
- Overview: proper routing table with destination/gateway/interface columns
- Port Forwarding: clean DNAT form (protocol, ext port → internal IP:port)
- NAT Rules: MASQUERADE/SNAT only, cleaner layout
- Peer Routes: IP route entries through VPN peers
- Firewall: custom rules with working delete button
- Live iptables: read-only terminal view of actual running rules in cell-wireguard
- Diagnostics: ping + traceroute test from server with output display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:14:49 -04:00
roof 84d33aa88c fix: prevent _syncconf from touching live container when run from tests
Added a path guard: if the config file resolves to /tmp/ or a pytest
temp dir, _syncconf bails out immediately. Without this, tests calling
add_peer/remove_peer with a temp-dir WireGuardManager would connect to
the live cell-wireguard container and remove production peers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:05:56 -04:00
roof 53c7661812 feat: per-peer access enforcement, live peer status, auto IP assignment
Server-side access control:
- firewall_manager.py: per-peer iptables FORWARD rules in WireGuard container;
  virtual IPs on Caddy (172.20.0.21-24) for per-service DROP/ACCEPT targeting
- CoreDNS Corefile regenerated with ACL blocks for blocked services per peer
- POST /api/wireguard/apply-enforcement re-applies rules after WireGuard restart;
  wg0.conf PostUp calls it via curl so rules restore automatically on container start

WireGuard fixes:
- _syncconf uses `wg set peer` instead of `wg syncconf` to avoid resetting ListenPort
- add_peer validates AllowedIPs must be /32 — rejects full/split tunnel CIDRs that
  would route internet or LAN traffic to that peer
- _config_file() checks for linuxserver wg_confs/ subdirectory first

UI:
- Peers page fetches /api/wireguard/peers/statuses for live handshake data;
  status badge now shows real Online/Offline + seconds since last handshake
- IP field removed from Add Peer form (auto-assigned from 10.0.0.0/24)

Tests (246 pass):
- test_firewall_manager.py: 22 tests for ACL generation, iptables rule correctness,
  comment tagging, clear_peer_rules filter logic
- test_peer_wg_integration.py: 10 tests for /32 enforcement, IP auto-assignment,
  syncconf called on add/remove
- test_wireguard_manager.py: updated to reflect correct IPs and /32 requirement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:01:07 -04:00
roof 8e41568964 feat: peer access config, DNS fix, real routing table, reinstall notifications
Peer creation/edit form now configures:
- Tunnel mode: full (0.0.0.0/0) or split (PIC only)
- Per-service access toggles (calendar, files, mail, webdav)
- Peer-to-peer communication toggle
- Optional calendar account creation
- Access capability badges in peer list

Bug fixes:
- DNS in client configs was 8.8.8.8 / 172.20.0.2 — now 172.20.0.3 (CoreDNS)
  This was why .cell domains didn't resolve on connected VPN peers
- get_peer_config API uses stored internet_access to set AllowedIPs
- New PUT /api/peers/<name> endpoint with config_changed detection
- POST /api/peers/<name>/clear-reinstall clears reinstall flag after download
- Routing page reads real host routes via /proc/1/net/route (pid: host)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 15:40:19 -04:00
roof 9d7d74f3f4 fix: full-tunnel default, real host routing table, peer config tunnel mode
- WireGuard default changed to full tunnel (0.0.0.0/0) — all peer traffic
  routes through PIC server so internet latency matches server's clean 41ms
- UI tunnel toggle now defaults to Full tunnel
- API /peers/config accepts allowed_ips param so UI toggle wires through
- Routing page reads real host routes via /proc/1/net/route (pid: host)
  instead of mock data; shows ens18/192.168.31.1 correctly
- Add iproute2 + util-linux to API Dockerfile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 15:20:55 -04:00
roof e7decf6f06 fix: port check, add missing service domains to Caddy and DNS zone
wg show outputs "listening port" not "listen port" — substring mismatch
caused port status to always show Blocked. Add webdav.cell, webmail.cell,
api.cell to Caddyfile and cell.zone so VPN peers can reach all services.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 14:50:29 -04:00
roof 03d100b776 fix: cell-ntp restart loop — add SYS_TIME cap, clear stale PID, remove log perms
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 14:37:56 -04:00
roof cbdefbd110 fix: static IPs for all containers, radicale config, DNS zone, cleanup
- Assign static IPs to all 13 containers (172.20.0.2–13) so DNS zone
  records match actual container IPs regardless of start order.
- Update cell.zone: all .cell domains now point to cell-caddy (172.20.0.2)
  which is the correct single entry point via Caddy reverse proxy.
- Create config/radicale/config so the calendar container actually starts.
- Fix webdav: replace empty users.passwd with USERNAME/PASSWORD env vars.
- Fix DNS fallback IP in wireguard_manager: 172.20.0.2→172.20.0.3 (cell-dns).
- Remove duplicate http://ui.cell from Caddyfile.
- Add persistent data volumes for rainloop and filegator.
- Fix mail domainname placeholder (yourdomain.com→cell.local).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 14:31:38 -04:00
roof 0b5a5b23e8 fix: split-tunnel default for peers, port check via wg interface, tunnel mode toggle in UI
- check_port_open now checks if wg0 interface is actually listening (via
  'wg show wg0') instead of requiring a live peer handshake. This means
  the port shows 'Open' whenever WireGuard is running, not only when a
  peer has connected recently.

- get_peer_config defaults to split-tunnel AllowedIPs (10.0.0.0/24,
  172.20.0.0/16) so VPN clients only route cell service traffic through
  the tunnel. Local LAN traffic (192.168.x.x etc.) stays direct, fixing
  the 60-120ms penalty when pinging local hosts while on VPN.

- Peer config modal now uses cell DNS (172.20.0.2) so .cell domains
  resolve correctly with both split and full tunnel.

- Added split/full tunnel toggle in the peer config modal so users can
  download either config variant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 14:18:43 -04:00
roof d3294552f0 fix: hairpin DNAT rule to eliminate VPN ping jitter to server public IP
When a full-tunnel VPN client pings the server's own public IP, traffic
loops out through Docker's external interface and back, causing 60-120ms
jitter. The DNAT PostUp rule intercepts packets from wg0 destined for the
public IP and redirects them to 10.0.0.1 (the VPN interface), keeping
traffic entirely inside the tunnel.

Also updates SERVER_ADDRESS from 172.20.0.1/16 to 10.0.0.1/24 to avoid
routing conflict with the Docker bridge network on eth0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 14:02:36 -04:00
roof e79ee08c63 fix: WireGuard routing, DNS, service access, and UI improvements
- Fix CoreDNS not loading .cell zones (wrong Corefile path, now uses -conf flag)
- Fix WireGuard server address conflict (172.20.0.1/16 overlapped with Docker
  network; changed to 10.0.0.1/24 to eliminate duplicate routes)
- Add SERVERMODE=true and sysctls to WireGuard docker-compose for server mode
- Fix DNS zone file parser to handle 4-field records (name IN type value)
- Add get_dns_records() to NetworkManager; mount data/dns into API container
- Fix peer config endpoint: look up IP/key from registry, use real endpoint
- Add bulk peer statuses endpoint keyed by public_key
- Normalize snake_case API fields to camelCase in WireGuard UI
- Add port check endpoint (checks via live handshake, not unreliable TCP probe)
- Add Caddy virtual hosts for ui/calendar/files/mail .cell domains (HTTP only)
- Fix cell config domain default from cell.local to cell
- Fix Routing Network Config tab (was calling hardcoded localhost:3000)
- Fix DNS records display (record.value not record.ip)
- Move service access guide to top of Dashboard with login hints
- Add /api/routing/setup endpoint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 12:43:23 -04:00
roof bd67764bf4 feat: external IP detection, port status, fix peer config generation
- WireGuardManager: get_external_ip() (cached 1h), check_port_open(),
  get_server_config() returning public_key + detected endpoint
- API: /api/wireguard/server-config returns real external IP;
  /api/wireguard/refresh-ip forces re-detection;
  /api/wireguard/peers/config now looks up peer IP + private key from
  registry and uses real server endpoint automatically
- Fix doubled port in Endpoint (178.x:51820:51820 → 178.x:51820)
- Fix Address=/32 when peer_ip already has mask
- WebUI nginx: proxy /api/ and /health to cell-api (fixes localhost:3000
  hardcode — UI now works from any machine)
- api.js: baseURL='' so all calls go through nginx proxy
- WireGuard page: show Server Endpoint card with external IP, endpoint,
  public key, and Refresh IP button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 02:41:50 -04:00
roof 5239751a71 fix: all 214 tests passing (from 36 failures)
Key fixes:
- safe_makedirs() in all managers so tests run outside Docker (/app paths)
- WireGuardManager: rewrote with X25519 key gen, corrected method names
- VaultManager: init ca_cert=None, guard generate_certificate when CA missing
- ConfigManager: _save_all_configs wraps mkdir+write in try/except
- app.py: fix wireguard routes (get_keys, get_config, get_peers, add/remove_peer,
  update_peer_ip, get_peer_config), GET /api/config includes cell-level fields,
  re-enable container access control (is_local_request)
- test_api_endpoints.py: patch paths api.app.X -> app.X
- test_app_misc.py: patch paths api.app.X -> app.X, relax status assertions
- test_vault_api.py: replace patch('api.vault_manager') with patch.object(app, ...)
  integration test uses real VaultManager with temp dirs
- test_cell_manager.py: pass config_path to both managers in persistence test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 16:43:07 -04:00
Cloud bb6ccfe023 wip: wireguard 2025-09-14 03:31:14 -05:00
Cloud 5bd7443681 wip: peer make work with qr code 2025-09-13 12:08:28 -05:00
Constantin 4f65f95ac9 wip: peers 2025-09-13 18:56:00 +03:00
Constantin 3e8a1bd530 exclude platform: linux/amd64 2025-09-13 16:14:51 +03:00
Constantin 4052e95e2e docker compose version: '3.3' 2025-09-13 16:12:24 +03:00
Constantin 534206a236 switch python3 2025-09-13 16:10:51 +03:00
Constantin 36776353b9 wip: Fix ContainerDashboard 2025-09-13 15:49:32 +03:00
Constantin b40e4f277e fix uptime on dashboard 2025-09-13 14:42:44 +03:00
Constantin 47c2beaf96 fix for bus 2025-09-13 14:42:32 +03:00
Constantin de1e1154ce Merge branch 'master' 2025-09-13 14:25:41 +03:00
Constantin f0b6d1cff1 wip: make work Services Status 2025-09-13 14:23:31 +03:00
Administrator da0b935d19 Initial commit 2025-09-13 11:16:20 +00:00
Constantin 2277b11563 init 2025-09-12 23:04:52 +03:00