1. 01 Aug, 2026 3 commits
    • Vitaly Lipatov's avatar
      memory: route-health fix + vici-socket lesson, igw changelog · 0d5c64d9
      Vitaly Lipatov authored
      Mark lesson_route_health_flush_hang resolved (bulk flush + 3m window shipped,
      deployed, timer re-enabled). Add lesson_vici_socket_acl_for_telegraf: the ikev2
      churn root cause (check-vpn-status.sh as telegraf can't read the vici socket ->
      false vpn_status=0), why the sudoers approach is blocked on ALT (sudo is
      4710 root:wheel), and the vici-socket ACL fix. Add objects/igw.md changelog.
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      0d5c64d9
    • Vitaly Lipatov's avatar
      add strongswan vici drop-in for telegraf vpn_status · 8144abe5
      Vitaly Lipatov authored
      check-vpn-status.sh (run as the telegraf user) calls swanctl --list-sas, which
      needs the root-only vici socket /run/charon.vici (770 root:root). Without
      access, swanctl fails and the script falls back to a flappy rx_bytes check,
      emitting false vpn_status connected=0 that churns ikev2.* gateways in
      route-health.
      
      This drop-in grants telegraf read access to the vici socket via ExecStartPost
      setfacl. On ALT, /bin/sudo is 4710 root:wheel (telegraf can't even exec it), so
      a sudoers approach is blocked; the vici ACL is the minimal contained fix and
      needs no script or sudoers change. Type=notify guarantees the socket exists at
      ExecStartPost; "|| true" so an ACL hiccup can never take the tunnel down.
      
      Deployed to ikev2.vdska (.131), ikev2.hetzner (.120), ikev2.gr (.139),
      ikev2.fr (.140).
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      8144abe5
    • Vitaly Lipatov's avatar
      fix route-health: bulk route flush + wider health window · 5f8a5bc3
      Vitaly Lipatov authored
      flush_gw_routes() deleted routes one-by-one in a loop (ip route del x127k),
      which hung the oneshot service for 20+ minutes under netlink contention and
      froze ALL gateway health monitoring. Replace with a single kernel-level
      "ip route flush table T via GW" -- the same idiom route-update.sh already uses
      for stale-gateway cleanup -- guarded by timeout 60.
      
      Also widen the ping and vpn_status InfluxDB query windows from 1m to 3m. The
      queries use last(), so a wider window does not delay reaction to a real outage;
      it only stops an empty result (=> false "dead") when telegraf momentarily
      starves under load. Together both changes break the flush->load->stale->flush
      feedback loop.
      
      Verified on igw: cycle time ~18s (was 20+ min), table 202 v6 routes via the
      ikev2.vdska peer restored to 127259.
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      5f8a5bc3
  2. 28 Jul, 2026 7 commits
  3. 05 Jul, 2026 4 commits
    • Vitaly Lipatov's avatar
      route-health: check ikev2.fr/ikev2.gr by ping (no iperf3 server on peer) · 08365b47
      Vitaly Lipatov authored
      These tunnel gateways had no iperf3 server / VPN-status feed on the remote
      peer (rpi), so route-health judged them by iperf3 -> success=0 -> permanently
      'down', masking real tunnel outages (a 7-day SA-down went unnoticed).
      
      Add is_pingonly_gw() (ikev2.fr, ikev2.gr) and judge them by ping loss alone
      (loss>=50 or no data = dead). Suppress the iperf/vpn marks in group display
      and health.json output for ping-only gateways so a healthy gw no longer shows
      'iperf=FAIL'.
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      08365b47
    • Vitaly Lipatov's avatar
      route-update: support explicit per-group pref override via options · 592e5f2d
      Vitaly Lipatov authored
      ip rule pref is otherwise derived from alphabetical group order, so a group
      cannot be consulted before a lexicographically-earlier one (e.g. fr vs egw)
      without renaming it — and digits sort after letters in ru_RU.UTF-8, so even
      a '0-fr' rename goes the wrong way.
      
      Allow an options line "pref N" to set the group's pref base directly,
      independent of name or locale. Used on fr (pref 900) so claude.ai via fr
      wins over the egw/ai table (pref 1210).
      
      Also call _fixup_rule_pref on the "resolved unchanged" skip path, so an
      options-only change actually migrates the ip rule to the new pref (previously
      the rule kept its old pref because load was skipped).
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      592e5f2d
    • Vitaly Lipatov's avatar
      route-update: support route-type keywords (blackhole/unreachable/...) in gateway · a7a51ff4
      Vitaly Lipatov authored
      Allow a group's gateway file to contain a kernel route-type keyword
      (blackhole/unreachable/prohibit/throw) instead of a next-hop. The script
      then installs routes of that type (ip route replace <kw> <dst> table N),
      so packets are rejected/dropped by the kernel instead of forwarded.
      
      unreachable/prohibit return ICMP to the client, giving instant failure
      (curl drops in ~2ms) vs hanging on a dead tunnel.
      
      Used on routes6.d/fr where the France egress (ikev2.fr) is IPv4-only and
      no IPv6 path exists: claude.ai AAAA now fast-rejects instead of timing out.
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      a7a51ff4
    • Vitaly Lipatov's avatar
      route-update: prune stale volatile_ips for domains removed from lists · 3b1e5c99
      Vitaly Lipatov authored
      expand_volatile_subnets() iterated the whole volatile_ips/ directory and
      re-resolved every saved entry as a domain, never removing ones whose domain
      was no longer in the .list. As a result, a domain removed from a list kept
      re-injecting its (stale) IPs into the table forever — on igw this had
      accumulated ~40 stale domains in web-bypass plus claude.ai/anthropic in ai,
      shadowing the dedicated fr/claude.ai group.
      
      Pass the current list file to expand_volatile_subnets and prune volatile_ips
      entries whose domain is absent from the list before resolving.
      Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
      3b1e5c99
  4. 04 Jul, 2026 12 commits
  5. 11 Jun, 2026 2 commits
  6. 31 May, 2026 3 commits
  7. 27 May, 2026 1 commit
    • Vitaly Lipatov's avatar
      route-update: flush table when .list moves between groups · 41bffb6b
      Vitaly Lipatov authored
      When a .list is moved between groups whose `gateway` files differ
      in metric semantics (e.g., failover→multipath), the previous code
      only deleted state and kept the table.  This caused stale routes
      with the old `metric N` to coexist with newly loaded multipath
      routes, because `ip route replace` keyed on dst+metric and treated
      them as distinct entries.
      
      Two related changes:
      - cleanup_state's "moved" branch now flushes the table before the
        new group loads it, so the table starts clean.
      - cleanup_state is invoked before process_routes so the flushes
        happen prior to the new group's load (otherwise a flush after
        load would wipe out the just-installed routes).
      Co-Authored-By: 's avatarClaude Opus 4.7 (1M context) <noreply@anthropic.com>
      41bffb6b
  8. 25 May, 2026 2 commits
  9. 13 May, 2026 3 commits
  10. 09 May, 2026 3 commits