Commit Graph
5 Commits
Author SHA1 Message Date
DmitryandClaude Sonnet 5 c5c33986da fix(openvpn-phone): add <ca> to the client profile for ics-openvpn
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
"OpenVPN for Android" fails at "Building configuration" ("Used 101 tries
to get current version of the profile") for a `client`-mode profile with
no <ca> block. The earlier tls-client p2p profile had no CA either but the
app treated it as a custom tunnel; `client` mode makes the CA mandatory in
the app's config builder.

Inline the server's self-signed certificate as <ca> (it is its own trust
anchor); peer-fingerprint still does the actual verification. Server config
unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
2026-09-03 10:09:20 +03:00
DmitryandClaude Sonnet 5 203751d874 fix(openvpn-phone): use OpenVPN server mode, push routes to the client
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
The TLS tunnel came up but no LAN traffic flowed: "OpenVPN for Android"
does not install the config-local `route` statements from a route-based
p2p setup, so nothing was directed into tun. Zero packets ever reached
tun2 on ru-vps.

Switch the instance to a real `server` (topology subnet, 10.80.0.0/29
pool) and hand the LAN routes to the client via `push "route ..."`.
Pushed routes are installed by every OpenVPN client, mobile included.
The client profile drops to a plain `client` config (pull), keeping
peer-fingerprint auth and inline cert/key.

Also: widen NAT/forward from /30 to /29 (server mode needs a pool) and
drop the now-stale /30 ufw route + MASQUERADE left by the p2p version.

Verified on ru-vps: "Initialization Sequence Completed", tun2 10.80.0.1/29,
ufw shows only the /29 forward rule, make openvpn-phone idempotent. The
regenerated ada-phone.ovpn must be re-imported on the phone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
2026-09-03 09:58:17 +03:00
DmitryandClaude Sonnet 5 dfcee00232 fix(openvpn-phone): open FORWARD for road-warrior traffic into the LAN
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
The phone tunnel established fine (TLS peer-fingerprint OK) but no traffic
reached the LAN: ru-vps has policy FORWARD DROP and only per-service game
ACCEPTs. The site tunnel never needed a FORWARD rule because it carries
ru-vps's own traffic, not forwarded packets; the road-warrior instance is
the first forwarded path.

Add a `ufw route allow` (tun2 -> tun0, 10.80.0.0/30 -> 192.168.1.0/24). ufw
route rules survive `ufw reload`, unlike a raw `iptables -I FORWARD` which
would sit before the ufw chains and be flushed on reload. Return traffic is
covered by the global RELATED,ESTABLISHED accept in ufw-before-forward.

Verified on ru-vps: `ufw status` shows "192.168.1.0/24 on tun0 ALLOW FWD
10.80.0.0/30 on tun2"; make openvpn-phone idempotent.

Same gap exists in openvpn-laptop.yml (tun1) — still not deployed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
2026-09-03 09:50:01 +03:00
DmitryandClaude Sonnet 5 1f27756afd fix(openvpn-phone): switch from static key to TLS peer-fingerprint
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
The Android client ships OpenVPN 2.7, which refuses a --secret config
("Options error: No tls-client or tls-server option"; 2.8 drops it
entirely). Rework the phone instance to a CA-less TLS point-to-point:
two self-signed EC keypairs generated on ru-vps (server.* / client.*),
each side pins the other by SHA256 with peer-fingerprint, data-ciphers
AES-256-GCM. Everything else unchanged (tcp/9444, tun2, 10.80.0.0/30,
NAT via tun0, systemd unit, shared homelab_vpn_client_routes).

Verified on ru-vps 2026-09-03: openvpn 2.6.19 starts clean ("Using
certificate fingerprint to verify peer"), listens on 9444, tun2 up,
make openvpn-phone idempotent (changed=0 on rerun), make lint green.
The regenerated ansible/generated/ada-phone.ovpn (self-contained
cert+key, gitignored) was handed to the operator.

openvpn-laptop.yml is left on static key — not deployed; needs the same
TLS treatment when someone actually uses it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
2026-09-03 09:44:19 +03:00
DmitryandClaude Sonnet 5 4b54e44116 feat: road-warrior OpenVPN profile for the phone (Android, static key)
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
playbooks/openvpn-phone.yml (make openvpn-phone) stands up a separate
point-to-point static-key instance on ru-vps: tcp/9444, tun2, 10.80.0.0/30,
homelab-openvpn-phone unit, NAT 10.80.0.0/30 -> LAN via tun0. The client
profile (with the secret) lands in ansible/generated/ada-phone.ovpn
(gitignored). Android client: "OpenVPN for Android" (Arne Schwabe) — the
official OpenVPN Connect does not support static-key configs.

- homelab_vpn_client_routes in group_vars/all/main.yml: shared surgical
  route list for both road-warrior profiles; not the whole /24, since the
  phone's home network is almost certainly 192.168.1.0/24 too
- openvpn-laptop.yml reuses that list instead of its own literal copy
- both playbooks: local profile write moved from `become: false` to
  `vars: {ansible_connection: local, ansible_become: false}` — the keyword
  did not suppress the inherited ansible_become on delegate_to: localhost

Deployed and verified on ru-vps 2026-09-03: service active, tun2 up, ufw
9444/tcp, NAT rule present, make openvpn-phone idempotent (changed=0 on
rerun), 192.168.1.30:8082 reachable from ru-vps. openvpn-laptop.yml is
still not applied on the live host.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
2026-09-03 09:33:18 +03:00