- DOCS/Operations: current-state SUMMARY of the ENTRY deployment (access, install, egress via Hysteria2, security findings and fixes, risk assessment, commits/backups, open items), the Hysteria chain manifest with an OpenVPN Monitor section, reboot test results, and the plan and rollout records for settings validation and privilege separation. - Link them from README and DOCS/General/Index.md. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6.8 KiB
Reboot test: ENTRY (Timeweb) and EXIT (Hel)
Date: 2026-09-30. Goal: confirm the Hysteria 2 chain recovers by itself after a reboot of each node, with no manual steps.
Nodes: ENTRY 213.226.125.13 (Alpine, OpenRC), EXIT 85.234.86.140 (Debian 13, systemd).
Methodology
Order: ENTRY first, then EXIT. Each node is rebooted separately, so the other side is always up and its reconnect behavior is observable.
1. Pre-flight (before each reboot)
| Check | ENTRY | EXIT |
|---|---|---|
| Services enabled | rc-update show default (hysteria, hysteria-route, hysteria-edge) |
systemctl is-enabled hysteria-server |
| Kernel module for TUN persists | lsmod | grep tun, grep -x tun /etc/modules |
not needed |
| sysctl persisted | ls /etc/sysctl.d/ (99-hytun.conf, 99-quic.conf) |
ls /etc/sysctl.d/99-quic.conf |
| Temporary test settings removed | n/a | grep -c speedTest /etc/hysteria/config.yaml = 0 |
Any gap found is fixed before rebooting.
2. Reboot
sync, then a delayed reboot / systemctl reboot (detached, so the SSH command returns). Wait 45 s, then poll SSH every 6 s (up to 20 tries) until uptime answers.
3. Post-boot verification
ENTRY:
rc-service hysteria|hysteria-route|hysteria-edge status→started.ls -l /dev/net/tun,ip -br a show hytun.ip rule | grep -E '^10[01]'andip route show table 100→ both rules, default via hytun, blackhole fallback.sysctl net.ipv4.conf.all.rp_filter net.core.rmem_max→ 2 and 7500000.ss -lunp | grep :443→hysteria-edgelistening.- Tunnel TCP:
su -s /bin/sh hyedge -c 'curl -4 -s https://ifconfig.me'→ must equal the EXIT IP. - Tunnel UDP:
su -s /bin/sh hyedge -c 'nslookup example.com 1.1.1.1'→ address returned. - Logs:
/var/log/hysteria.log,/var/log/hysteria-edge.log; a real client (mobile) reconnecting is a bonus signal.
EXIT:
systemctl is-active hysteria-server,ss -lunp | grep :443.sudo /usr/sbin/sysctl net.core.rmem_max net.core.wmem_max(sysctlis not in a non-root user's PATH).journalctl -u hysteria-server -b→ "server up and running" and "client connected" from ENTRY.- From ENTRY: client log shows a new
connected to server(count incremented) and thehyedgecurl test (step 6 above) returns the EXIT IP.
Results
ENTRY reboot (Timeweb)
| Check | Result |
|---|---|
| Pre-flight | Gap found: module tun loaded by hand but absent from /etc/modules → after reboot /dev/net/tun could be missing and the tunnel would not start. Fixed (echo tun >> /etc/modules) before rebooting. |
| SSH back | Yes, about 45-60 s after the reboot command |
| Services | hysteria, hysteria-route, hysteria-edge all started |
| TUN / routing | /dev/net/tun present, hytun up (100.100.100.101/30), rules 100 and 101 present, table 100: default dev hytun + blackhole |
| sysctl | rp_filter=2, rmem_max=7500000 applied |
| Listener | hysteria-edge on UDP 443 |
| Tunnel TCP | 85.234.86.140 (EXIT IP) |
| Tunnel UDP | DNS answer received |
| Client | Hiddify (mobile) reconnected on its own right after boot |
| Noise in logs | A few dial timeouts to individual remote hosts (unreachable destinations, not a tunnel fault) |
Verdict: PASS (after the /etc/modules fix).
EXIT reboot (Hel)
| Check | Result |
|---|---|
| Pre-flight | hysteria-server enabled, 99-quic.conf present, speedTest absent from config (0) |
| SSH back | Yes, about 45-50 s after the reboot command |
| Service | hysteria-server active, listening on UDP 443 |
| sysctl | rmem_max and wmem_max = 7500000 |
| Journal | "server up and running" at boot, then "client connected" from 213.226.125.13 about 30 s later |
| ENTRY side | Client reconnected automatically (connected to server, count: 2); brief TUN UDP error ... EOF while EXIT was down; hyedge curl returned 85.234.86.140 |
Verdict: PASS.
Conclusions
- Both nodes recover unattended; the ENTRY hysteria client (supervise-daemon,
lazy: true) reconnects without restart when EXIT comes back. - During an EXIT outage the anti-leak blackhole route in table 100 keeps
hyedgetraffic from leaving via ENTRY's own uplink (leak test done separately: removing the tun default route makes the test curl fail instead of exposing the ENTRY IP). - Not covered: simultaneous reboot of both nodes, power-loss/unclean shutdown, and IKE/strongSwan (separate task,
charonis not enabled at boot).
ENTRY reboot after the OpenVPN Monitor deployment (2026-09-30)
Goal: confirm the whole ENTRY stack (Hysteria chain + OpenVPN Monitor, OpenVPN, egress rules, hardening) recovers by itself. Only ENTRY was rebooted; EXIT stayed up.
Pre-flight
rc-update show default:hysteria,hysteria-route,hysteria-edge,ovpn-hytun,openvpn,ovpmon-api,ovpmon-gatherer,ovpmon-profiler,nginx,fail2ban,sshd,chronydenabled.tunin/etc/modules; sysctl files present (ip_forward=1,rp_filter=2);sshd -tanddoas -C /etc/doas.d/ovpmon.confvalid.- Baseline snapshot
/root/pre-reboot-snapshot.txt: service states,ip rule 100-102, table 100, nat/FORWARD rules, listeners, process owners.
Reboot and result
sync, detached reboot; SSH answered again after ~45 s. Post-boot snapshot /root/post-reboot-snapshot.txt is identical to the baseline.
| Check | Result |
|---|---|
All services in default |
started by themselves |
| API processes | gunicorn/uvicorn/gatherer run as ovpmon |
hytun, tun0, rp_filter=2, ip_forward=1 |
present |
ip rule 100/101/102, table 100 (hytun + blackhole), MASQUERADE to hytun, FORWARD DROP guard |
restored by hysteria-route / ovpn-hytun |
Tunnel TCP as hyedge |
85.234.86.140 (EXIT) |
| Hysteria client | reconnected to EXIT |
| Panel | https://…:8088/ 200, profiler without token 401, HTTP→HTTPS 301, login tstark works |
| Helper/doas | service status and process stats OK; gatherer reads openvpn-status.log (root:ovpmon 640 persisted) |
/etc/openvpn/crl.pem, /var/lib/ovpmon ownership |
intact |
| fail2ban | 3 jails active |
| SSH | passwordauthentication no, permitrootlogin prohibit-password |
Errors in ovpmon-* logs since boot |
none (older entries predate the boot) |
| Real VPN client | reconnected by itself ~3.5 min after boot (UDP client waits for its keepalive 10 120 timeout); ~5 MB downloaded through the tunnel, MASQUERADE counters rose, leak guard FORWARD DROP counter stayed 0 |
Notes
- Expected client gap after a server reboot is up to ~2-4 minutes for UDP OpenVPN clients (ping-restart), not a fault of the server.
openvpn-status.logkeepsroot:ovpmon 640because the file persists on disk; if it is ever deleted, OpenVPN recreates it as600and the gatherer cannot read it until the nextovpmon-helper service start|restart(which fixes the mode). Not triggered by a reboot.