Add direct gateway forwarding when VPN is off
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 14s
Build and Deploy Gateway / deploy (push) Successful in 1s

This commit is contained in:
2026-07-11 11:37:08 +03:00
parent 9d4f312595
commit 41922ad30b
14 changed files with 264 additions and 46 deletions

View File

@@ -8,8 +8,11 @@ const entrypoint = fs.readFileSync(
'utf8',
);
test('gateway intercepts all public TCP and UDP traffic without source bypasses', () => {
test('gateway keeps direct forwarding active while TProxy interception is switchable', () => {
assert.match(entrypoint, /-p tcp -j TPROXY --on-port "\$TPROXY_PORT"/);
assert.match(entrypoint, /-p udp -j TPROXY --on-port "\$TPROXY_PORT"/);
assert.match(entrypoint, /-I FORWARD 1 -j "\$GATEWAY_FORWARD_CHAIN"/);
assert.match(entrypoint, /-I POSTROUTING 1 -j "\$GATEWAY_NAT_CHAIN"/);
assert.doesNotMatch(entrypoint, /-A PREROUTING -j "\$TPROXY_CHAIN"/);
assert.doesNotMatch(entrypoint, /TPROXY_BYPASS_SOURCE_CIDRS|DIRECT_BYPASS_CACHE|ipset/);
});

View File

@@ -0,0 +1,28 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { setGatewayInterception } from '../../src/server/gatewayRouting.js';
test('gateway switches only the TProxy PREROUTING jump', () => {
const calls = [];
const missing = (command, args) => {
calls.push([command, args]);
return { status: args.includes('-C') ? 1 : 0, stderr: '' };
};
setGatewayInterception(true, 'VPN_PROXY_TPROXY', missing);
assert.deepEqual(calls.map(([, args]) => args), [
['-w', '-t', 'mangle', '-C', 'PREROUTING', '-j', 'VPN_PROXY_TPROXY'],
['-w', '-t', 'mangle', '-I', 'PREROUTING', '1', '-j', 'VPN_PROXY_TPROXY'],
]);
calls.length = 0;
const existing = (command, args) => {
calls.push([command, args]);
return { status: 0, stderr: '' };
};
setGatewayInterception(false, 'VPN_PROXY_TPROXY', existing);
assert.deepEqual(calls.map(([, args]) => args), [
['-w', '-t', 'mangle', '-C', 'PREROUTING', '-j', 'VPN_PROXY_TPROXY'],
['-w', '-t', 'mangle', '-D', 'PREROUTING', '-j', 'VPN_PROXY_TPROXY'],
]);
});

View File

@@ -3,6 +3,7 @@ import test from 'node:test';
import {
connectionAction,
copyText,
formatConnectionDuration,
localProxyUrls,
subscriptionDomain,
@@ -54,6 +55,26 @@ test('gateway proxy URLs use its network address', () => {
});
});
test('copy uses the synchronous native path available on gateway HTTP', async () => {
const textarea = {
style: {},
setAttribute() {},
select() { this.selected = true; },
remove() { this.removed = true; },
};
const documentRef = {
body: { append(node) { node.appended = true; } },
createElement: () => textarea,
execCommand: (command) => command === 'copy',
};
await copyText('192.168.50.111', { documentRef });
assert.equal(textarea.value, '192.168.50.111');
assert.equal(textarea.selected, true);
assert.equal(textarea.removed, true);
});
test('subscription usage combines traffic and caps progress', () => {
assert.deepEqual(subscriptionUsage({ upload: 30, download: 80, total: 100, expire: 2 }), {
upload: 30,