summaryrefslogtreecommitdiff
path: root/tests/vm_tun_acceptance.py
diff options
context:
space:
mode:
authorAndrew Guschin <guschin@altlinux.org>2026-10-30 13:20:18 +0400
committerAndrew Guschin <guschin@altlinux.org>2026-10-30 13:20:18 +0400
commit0b898d982549eab1ba12bf743d001aee6c2e27f9 (patch)
treeca2689cd63ce7f89584e95c5ce88bbb22b817f47 /tests/vm_tun_acceptance.py
parent3c8b130be89fbb0e58e2ee23f07ad56a3b9de2e7 (diff)
Validate real TUN forwarding and fix firewall routingmain
- Move the default-drop guard to POSTROUTING so it sees final TUN egress - Treat a missing TUN interface as absent and add acceptance coverage - Document successful real-subscription validation on ALT Xray 26.10.29
Diffstat (limited to 'tests/vm_tun_acceptance.py')
-rw-r--r--tests/vm_tun_acceptance.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/vm_tun_acceptance.py b/tests/vm_tun_acceptance.py
new file mode 100644
index 0000000..619459e
--- /dev/null
+++ b/tests/vm_tun_acceptance.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+"""Verify a selected real configuration on the authorized disposable ALT VM."""
+import argparse
+import ipaddress
+import json
+import os
+import socket
+import subprocess
+
+
+def command(*args):
+ return subprocess.run(args, check=True, capture_output=True, text=True, timeout=35).stdout.strip()
+
+
+def public_ipv4():
+ value = command('curl', '-4', '--noproxy', '*', '--fail', '--silent', '--show-error',
+ '--connect-timeout', '5', '--max-time', '15', 'https://ifconfig.me')
+ return str(ipaddress.IPv4Address(value))
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('--expected-ip', required=True, type=ipaddress.IPv4Address)
+ args = parser.parse_args()
+ assert os.geteuid() == 0 and socket.gethostname() == 'altctlrs'
+ binary = '/usr/local/bin/roentgen'
+ status = json.loads(command(binary, 'status', '--json'))
+ assert not status['requested_enabled'], 'Start with proxying disabled'
+ assert status['selected_configuration'], 'Select the real configuration before running'
+ direct = public_ipv4()
+ try:
+ command(binary, 'enable')
+ status = json.loads(command(binary, 'status', '--json'))
+ assert status['requested_enabled'] and status['routing'] == 'tun', status
+ proxied = public_ipv4()
+ assert proxied == str(args.expected_ip), (proxied, str(args.expected_ip))
+ assert proxied != direct, 'Proxy IPv4 must differ from direct IPv4'
+ finally:
+ command(binary, 'disable')
+ restored = public_ipv4()
+ assert restored == direct, (restored, direct)
+ print(json.dumps({'direct_ipv4': direct, 'tun_ipv4': proxied, 'restored_ipv4': restored}))
+
+
+if __name__ == '__main__':
+ main()