Add optional SOCKS server authentication
This commit is contained in:
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
SERVER_JS="$ROOT_DIR/luci-app-forkop/htdocs/luci-static/resources/view/forkop/server.js"
|
||||
|
||||
node - "$SERVER_JS" <<'NODE'
|
||||
const fs = require("fs");
|
||||
const source = fs.readFileSync(process.argv[2], "utf8");
|
||||
|
||||
function fail(message) {
|
||||
console.error(`FAIL: ${message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function requiredIndex(needle, from = 0) {
|
||||
const index = source.indexOf(needle, from);
|
||||
if (index < 0) fail(`missing source contract: ${needle}`);
|
||||
return index;
|
||||
}
|
||||
|
||||
const flag = requiredIndex('"socks_auth_enabled"');
|
||||
const username = requiredIndex('"server_username", _("Username")', flag);
|
||||
const password = requiredIndex('"server_password", _("Password")', username);
|
||||
const nextOption = requiredIndex('"vmess_alter_id", _("Alter ID")', password);
|
||||
|
||||
const flagBlock = source.slice(flag, username);
|
||||
if (!flagBlock.includes('_("Enable authentication")') ||
|
||||
!flagBlock.includes('o.default = "1"') ||
|
||||
!flagBlock.includes('o.depends("protocol", "socks")')) {
|
||||
fail("SOCKS authentication switch must be enabled by default and limited to SOCKS servers");
|
||||
}
|
||||
|
||||
for (const block of [source.slice(username, password), source.slice(password, nextOption)]) {
|
||||
if (!block.includes('o.depends({ protocol: "socks", socks_auth_enabled: "1" })')) {
|
||||
fail("SOCKS credentials must only be required while authentication is enabled");
|
||||
}
|
||||
}
|
||||
|
||||
const link = source.slice(
|
||||
requiredIndex("function buildSocksLink"),
|
||||
requiredIndex("function normalizeSha256"),
|
||||
);
|
||||
if (!link.includes("isSocksAuthenticationEnabled(sectionId)") ||
|
||||
!link.includes('socks5://${userInfo}${uriHost}:${port}')) {
|
||||
fail("SOCKS share links must omit credentials when authentication is disabled");
|
||||
}
|
||||
NODE
|
||||
|
||||
printf 'LuCI SOCKS server authentication checks passed\n'
|
||||
@@ -78,6 +78,10 @@ forkop.vless.server_users=client|22222222-2222-4222-8222-222222222222|xtls-rprx-
|
||||
forkop.socks=server
|
||||
forkop.socks.protocol=socks
|
||||
forkop.socks.label=desk
|
||||
forkop.socks_open=server
|
||||
forkop.socks_open.protocol=socks
|
||||
forkop.socks_open.label=guest
|
||||
forkop.socks_open.socks_auth_enabled=0
|
||||
forkop.tailscale=server
|
||||
forkop.tailscale.protocol=tailscale
|
||||
forkop.json=server
|
||||
@@ -111,8 +115,12 @@ assert_value forkop.vless.reality_short_id abcd1234
|
||||
assert_value forkop.vless.reality_private_key private-key
|
||||
assert_value forkop.vless.reality_public_key public-key
|
||||
assert_value forkop.socks.security none
|
||||
assert_value forkop.socks.socks_auth_enabled 1
|
||||
assert_value forkop.socks.server_username desk
|
||||
assert_value forkop.socks.server_password generated-password
|
||||
assert_value forkop.socks_open.socks_auth_enabled 0
|
||||
assert_value forkop.socks_open.server_username guest
|
||||
assert_value forkop.socks_open.server_password generated-password
|
||||
assert_value forkop.tailscale.security none
|
||||
assert_value forkop.tailscale.tailscale_control_url https://controlplane.tailscale.com
|
||||
assert_value forkop.tailscale.tailscale_hostname forkop-tailscale
|
||||
|
||||
@@ -278,6 +278,18 @@ cat >"$WORK_DIR/server-inbound-fixture.json" <<'JSON'
|
||||
"server_username": "tester",
|
||||
"server_password": "secret",
|
||||
"routing_mode": "direct"
|
||||
},
|
||||
{
|
||||
".name": "open",
|
||||
".type": "server",
|
||||
"enabled": "1",
|
||||
"protocol": "socks",
|
||||
"listen": "0.0.0.0",
|
||||
"listen_port": "18081",
|
||||
"socks_auth_enabled": "0",
|
||||
"server_username": "ignored",
|
||||
"server_password": "ignored",
|
||||
"routing_mode": "direct"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1136,7 +1148,10 @@ assert(defaults.dns.strategy == "prefer_ipv4", "missing DNS strategy keeps the p
|
||||
let server = cfg("server");
|
||||
let socks = inbound(server, "server-edge-in");
|
||||
assert(socks && socks.type == "socks" && socks.listen_port == 18080, "server socks inbound");
|
||||
assert(socks.users && socks.users[0].username == "tester", "server socks auth");
|
||||
assert(socks.users && socks.users[0].username == "tester", "legacy server socks auth defaults to enabled");
|
||||
let open_socks = inbound(server, "server-open-in");
|
||||
assert(open_socks && open_socks.type == "socks" && open_socks.listen_port == 18081, "server open socks inbound");
|
||||
assert(open_socks.users == null, "disabled server socks auth omits users");
|
||||
assert(route_rule(server, r => r.inbound == "server-edge-in" && r.outbound == "direct-out") != null, "server direct route");
|
||||
|
||||
let matchers = cfg("matchers");
|
||||
|
||||
Reference in New Issue
Block a user