@qpjoy/tunnel-cli 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/README.setup.md +10 -0
- package/dist/index.js +124 -2
- package/package.json +1 -1
- package/resources/mihomo-client.sh +32 -9
package/README.md
CHANGED
|
@@ -27,6 +27,18 @@ proxy and configures shell, SSH, Docker/containerd/buildkit proxy drop-ins witho
|
|
|
27
27
|
enabling TUN route takeover. Reserve `tun-on` for machines that are not serving
|
|
28
28
|
public inbound traffic.
|
|
29
29
|
|
|
30
|
+
Run any command through the active Mihomo local proxy:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
qp-tunnel-cli ./electron-server/scripts/manage.sh redeploy
|
|
34
|
+
qp-tunnel-cli -- docker compose build
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For host commands, `HTTP_PROXY` points at `127.0.0.1:<mixed-port>`. For
|
|
38
|
+
Docker/Compose build containers, the CLI also injects container-facing variables
|
|
39
|
+
such as `MARKET_CONTAINER_HTTP_PROXY` and `QP_TUNNEL_CONTAINER_HTTP_PROXY`
|
|
40
|
+
pointing at `host.docker.internal:<mixed-port>`.
|
|
41
|
+
|
|
30
42
|
Install the bundled script as a normal Linux command:
|
|
31
43
|
|
|
32
44
|
```bash
|
package/README.setup.md
ADDED
package/dist/index.js
CHANGED
|
@@ -10,6 +10,28 @@ const packageRoot = (0, node_path_1.resolve)(__dirname, '..');
|
|
|
10
10
|
const bundledClientScript = (0, node_path_1.resolve)(packageRoot, 'resources/mihomo-client.sh');
|
|
11
11
|
const repoClientScript = (0, node_path_1.resolve)(packageRoot, '../../../scripts/mihomo-client.sh');
|
|
12
12
|
const defaultInstallTarget = '/usr/local/bin/mihomo-client';
|
|
13
|
+
const defaultMihomoConfigFile = '/etc/mihomo-client/config.yaml';
|
|
14
|
+
const defaultNoProxyEntries = [
|
|
15
|
+
'localhost',
|
|
16
|
+
'127.0.0.1',
|
|
17
|
+
'::1',
|
|
18
|
+
'postgres',
|
|
19
|
+
'market',
|
|
20
|
+
'db',
|
|
21
|
+
'redis',
|
|
22
|
+
'host.docker.internal',
|
|
23
|
+
'docker.for.mac.host.internal',
|
|
24
|
+
'docker.for.win.localhost',
|
|
25
|
+
'kubernetes.docker.internal',
|
|
26
|
+
'10.0.0.0/8',
|
|
27
|
+
'172.16.0.0/12',
|
|
28
|
+
'192.168.0.0/16',
|
|
29
|
+
'100.64.0.0/10',
|
|
30
|
+
'100.88.0.0/16',
|
|
31
|
+
'100.89.0.0/16',
|
|
32
|
+
'100.90.0.0/16',
|
|
33
|
+
'.local',
|
|
34
|
+
];
|
|
13
35
|
const clientCommands = new Set([
|
|
14
36
|
'setup',
|
|
15
37
|
'install',
|
|
@@ -50,6 +72,8 @@ Usage:
|
|
|
50
72
|
qp-tunnel-cli script-path
|
|
51
73
|
qp-tunnel-cli client-help
|
|
52
74
|
qp-tunnel-cli <mihomo-client command> [options]
|
|
75
|
+
qp-tunnel-cli -- <command> [args...]
|
|
76
|
+
qp-tunnel-cli <command-path> [args...]
|
|
53
77
|
|
|
54
78
|
Common commands:
|
|
55
79
|
qp-tunnel-cli install --url http://IP:3434/peer_user01.mihomo.yaml --user download --password pass
|
|
@@ -60,10 +84,16 @@ Common commands:
|
|
|
60
84
|
qp-tunnel-cli tun-off
|
|
61
85
|
qp-tunnel-cli update-subscription
|
|
62
86
|
qp-tunnel-cli uninstall --purge
|
|
87
|
+
qp-tunnel-cli ./electron-server/scripts/manage.sh redeploy
|
|
63
88
|
|
|
64
89
|
The npm package is a thin distributor for the Linux mihomo-client script. Client
|
|
65
90
|
commands re-run through sudo when needed, then execute the bundled shell script.
|
|
66
91
|
|
|
92
|
+
Unknown commands are executed with QPJoy proxy variables injected. Host commands
|
|
93
|
+
receive HTTP_PROXY=http://127.0.0.1:<mixed-port>; Docker/Compose build contexts
|
|
94
|
+
also receive container-facing variables such as MARKET_CONTAINER_HTTP_PROXY and
|
|
95
|
+
QP_TUNNEL_CONTAINER_HTTP_PROXY=http://host.docker.internal:<mixed-port>.
|
|
96
|
+
|
|
67
97
|
Install the script as a normal server command:
|
|
68
98
|
sudo qp-tunnel-cli install-script
|
|
69
99
|
sudo mihomo-client status
|
|
@@ -129,6 +159,94 @@ function runClientCommand(scriptArgs) {
|
|
|
129
159
|
}
|
|
130
160
|
runScriptWithoutSudo(scriptArgs);
|
|
131
161
|
}
|
|
162
|
+
function mixedPortFromConfig() {
|
|
163
|
+
const explicit = process.env.QP_TUNNEL_MIXED_PORT || process.env.MIHOMO_MIXED_PORT;
|
|
164
|
+
if (explicit && /^\d+$/.test(explicit)) {
|
|
165
|
+
return explicit;
|
|
166
|
+
}
|
|
167
|
+
const configFile = process.env.MIHOMO_CONFIG_FILE || defaultMihomoConfigFile;
|
|
168
|
+
if (!(0, node_fs_1.existsSync)(configFile)) {
|
|
169
|
+
process.stderr.write(`Mihomo config not found: ${configFile}\nRun: sudo qp-tunnel-cli install ... && sudo qp-tunnel-cli server-on\n`);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
const content = (0, node_fs_1.readFileSync)(configFile, 'utf8');
|
|
173
|
+
const match = /^\s*mixed-port\s*:\s*(\d+)/m.exec(content);
|
|
174
|
+
if (!match) {
|
|
175
|
+
process.stderr.write(`Could not detect mixed-port from ${configFile}\n`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
return match[1];
|
|
179
|
+
}
|
|
180
|
+
function mergeCsvValues(...values) {
|
|
181
|
+
const seen = new Set();
|
|
182
|
+
const merged = [];
|
|
183
|
+
for (const value of values) {
|
|
184
|
+
for (const item of (value || '').split(',')) {
|
|
185
|
+
const trimmed = item.trim();
|
|
186
|
+
if (!trimmed || seen.has(trimmed))
|
|
187
|
+
continue;
|
|
188
|
+
seen.add(trimmed);
|
|
189
|
+
merged.push(trimmed);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return merged.join(',');
|
|
193
|
+
}
|
|
194
|
+
function proxyEnvironment() {
|
|
195
|
+
const port = mixedPortFromConfig();
|
|
196
|
+
const hostProxy = `http://127.0.0.1:${port}`;
|
|
197
|
+
const hostSocksProxy = `socks5://127.0.0.1:${port}`;
|
|
198
|
+
const containerHost = process.env.QP_TUNNEL_CONTAINER_HOST || 'host.docker.internal';
|
|
199
|
+
const containerProxy = `http://${containerHost}:${port}`;
|
|
200
|
+
const noProxy = mergeCsvValues(process.env.NO_PROXY, process.env.no_proxy, defaultNoProxyEntries.join(','));
|
|
201
|
+
const containerNoProxy = mergeCsvValues(process.env.MARKET_CONTAINER_NO_PROXY, process.env.QP_TUNNEL_CONTAINER_NO_PROXY, noProxy);
|
|
202
|
+
return {
|
|
203
|
+
...process.env,
|
|
204
|
+
HTTP_PROXY: hostProxy,
|
|
205
|
+
HTTPS_PROXY: hostProxy,
|
|
206
|
+
ALL_PROXY: hostSocksProxy,
|
|
207
|
+
http_proxy: hostProxy,
|
|
208
|
+
https_proxy: hostProxy,
|
|
209
|
+
all_proxy: hostSocksProxy,
|
|
210
|
+
NO_PROXY: noProxy,
|
|
211
|
+
no_proxy: noProxy,
|
|
212
|
+
npm_config_proxy: hostProxy,
|
|
213
|
+
npm_config_https_proxy: hostProxy,
|
|
214
|
+
npm_config_noproxy: noProxy,
|
|
215
|
+
pnpm_config_proxy: hostProxy,
|
|
216
|
+
pnpm_config_https_proxy: hostProxy,
|
|
217
|
+
pnpm_config_noproxy: noProxy,
|
|
218
|
+
QP_TUNNEL_MIXED_PORT: port,
|
|
219
|
+
QP_TUNNEL_HOST_HTTP_PROXY: hostProxy,
|
|
220
|
+
QP_TUNNEL_HOST_HTTPS_PROXY: hostProxy,
|
|
221
|
+
QP_TUNNEL_HOST_ALL_PROXY: hostSocksProxy,
|
|
222
|
+
QP_TUNNEL_CONTAINER_HTTP_PROXY: containerProxy,
|
|
223
|
+
QP_TUNNEL_CONTAINER_HTTPS_PROXY: containerProxy,
|
|
224
|
+
QP_TUNNEL_CONTAINER_NO_PROXY: containerNoProxy,
|
|
225
|
+
CONTAINER_HTTP_PROXY: containerProxy,
|
|
226
|
+
CONTAINER_HTTPS_PROXY: containerProxy,
|
|
227
|
+
CONTAINER_NO_PROXY: containerNoProxy,
|
|
228
|
+
BUILD_CONTAINER_HTTP_PROXY: containerProxy,
|
|
229
|
+
BUILD_CONTAINER_HTTPS_PROXY: containerProxy,
|
|
230
|
+
BUILD_CONTAINER_NO_PROXY: containerNoProxy,
|
|
231
|
+
MARKET_CONTAINER_HTTP_PROXY: process.env.MARKET_CONTAINER_HTTP_PROXY || containerProxy,
|
|
232
|
+
MARKET_CONTAINER_HTTPS_PROXY: process.env.MARKET_CONTAINER_HTTPS_PROXY || containerProxy,
|
|
233
|
+
MARKET_CONTAINER_NO_PROXY: containerNoProxy,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function runExternalCommand(commandArgs) {
|
|
237
|
+
if (commandArgs.length === 0) {
|
|
238
|
+
process.stderr.write('Missing command after qp-tunnel-cli --\n');
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
const [rawCommand, ...rawArgs] = commandArgs;
|
|
242
|
+
const command = rawCommand === 'sudo' && !rawArgs.includes('-E') ? 'sudo' : rawCommand;
|
|
243
|
+
const commandArgsWithSudoEnv = rawCommand === 'sudo' && !rawArgs.includes('-E') ? ['-E', ...rawArgs] : rawArgs;
|
|
244
|
+
const result = (0, node_child_process_1.spawnSync)(command, commandArgsWithSudoEnv, {
|
|
245
|
+
stdio: 'inherit',
|
|
246
|
+
env: proxyEnvironment(),
|
|
247
|
+
});
|
|
248
|
+
exitFromSpawn(result);
|
|
249
|
+
}
|
|
132
250
|
function parseInstallScriptArgs(scriptArgs) {
|
|
133
251
|
let target = defaultInstallTarget;
|
|
134
252
|
for (let index = 0; index < scriptArgs.length; index += 1) {
|
|
@@ -192,6 +310,9 @@ async function printScriptPath() {
|
|
|
192
310
|
}
|
|
193
311
|
async function main() {
|
|
194
312
|
const command = args[0] ?? 'help';
|
|
313
|
+
if (command === '--') {
|
|
314
|
+
runExternalCommand(args.slice(1));
|
|
315
|
+
}
|
|
195
316
|
if (command === 'help' || command === '--help' || command === '-h') {
|
|
196
317
|
help();
|
|
197
318
|
return;
|
|
@@ -215,9 +336,10 @@ async function main() {
|
|
|
215
336
|
if (passthroughCommand && clientCommands.has(passthroughCommand)) {
|
|
216
337
|
runClientCommand(args);
|
|
217
338
|
}
|
|
218
|
-
|
|
339
|
+
if (args.length > 0) {
|
|
340
|
+
runExternalCommand(args);
|
|
341
|
+
}
|
|
219
342
|
help();
|
|
220
|
-
process.exitCode = 1;
|
|
221
343
|
}
|
|
222
344
|
main().catch((error) => {
|
|
223
345
|
const message = error instanceof Error ? error.message : String(error);
|
package/package.json
CHANGED
|
@@ -97,6 +97,7 @@ Examples:
|
|
|
97
97
|
sudo bash ./scripts/mihomo-client.sh ssh-proxy-on
|
|
98
98
|
sudo bash ./scripts/mihomo-client.sh daemon-proxy-on
|
|
99
99
|
sudo bash ./scripts/mihomo-client.sh run curl -I https://www.google.com/generate_204
|
|
100
|
+
sudo bash ./scripts/mihomo-client.sh run ./electron-server/scripts/manage.sh redeploy
|
|
100
101
|
sudo bash ./scripts/mihomo-client.sh print-env
|
|
101
102
|
EOF
|
|
102
103
|
}
|
|
@@ -532,10 +533,10 @@ docker_proxy_env_lines() {
|
|
|
532
533
|
cat <<EOF
|
|
533
534
|
HTTP_PROXY=http://127.0.0.1:$port
|
|
534
535
|
HTTPS_PROXY=http://127.0.0.1:$port
|
|
535
|
-
NO_PROXY
|
|
536
|
+
NO_PROXY=$MIHOMO_NO_PROXY
|
|
536
537
|
http_proxy=http://127.0.0.1:$port
|
|
537
538
|
https_proxy=http://127.0.0.1:$port
|
|
538
|
-
no_proxy
|
|
539
|
+
no_proxy=$MIHOMO_NO_PROXY
|
|
539
540
|
EOF
|
|
540
541
|
}
|
|
541
542
|
|
|
@@ -814,16 +815,38 @@ server_off_command() {
|
|
|
814
815
|
}
|
|
815
816
|
|
|
816
817
|
run_command() {
|
|
817
|
-
local port
|
|
818
|
+
local port host_proxy host_socks_proxy container_host container_proxy
|
|
818
819
|
[[ $# -gt 0 ]] || die "Usage: sudo bash ./scripts/mihomo-client.sh run <command> [args...]"
|
|
819
820
|
port="$(mixed_port_from_config)"
|
|
820
821
|
[[ -n "$port" ]] || die "Could not detect mixed-port from $MIHOMO_CONFIG_FILE"
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
822
|
+
host_proxy="http://127.0.0.1:$port"
|
|
823
|
+
host_socks_proxy="socks5://127.0.0.1:$port"
|
|
824
|
+
container_host="${QP_TUNNEL_CONTAINER_HOST:-host.docker.internal}"
|
|
825
|
+
container_proxy="http://${container_host}:$port"
|
|
826
|
+
http_proxy="$host_proxy" \
|
|
827
|
+
https_proxy="$host_proxy" \
|
|
828
|
+
HTTP_PROXY="$host_proxy" \
|
|
829
|
+
HTTPS_PROXY="$host_proxy" \
|
|
830
|
+
all_proxy="$host_socks_proxy" \
|
|
831
|
+
ALL_PROXY="$host_socks_proxy" \
|
|
832
|
+
no_proxy="$MIHOMO_NO_PROXY" \
|
|
833
|
+
NO_PROXY="$MIHOMO_NO_PROXY" \
|
|
834
|
+
QP_TUNNEL_MIXED_PORT="$port" \
|
|
835
|
+
QP_TUNNEL_HOST_HTTP_PROXY="$host_proxy" \
|
|
836
|
+
QP_TUNNEL_HOST_HTTPS_PROXY="$host_proxy" \
|
|
837
|
+
QP_TUNNEL_HOST_ALL_PROXY="$host_socks_proxy" \
|
|
838
|
+
QP_TUNNEL_CONTAINER_HTTP_PROXY="$container_proxy" \
|
|
839
|
+
QP_TUNNEL_CONTAINER_HTTPS_PROXY="$container_proxy" \
|
|
840
|
+
QP_TUNNEL_CONTAINER_NO_PROXY="$MIHOMO_NO_PROXY" \
|
|
841
|
+
CONTAINER_HTTP_PROXY="$container_proxy" \
|
|
842
|
+
CONTAINER_HTTPS_PROXY="$container_proxy" \
|
|
843
|
+
CONTAINER_NO_PROXY="$MIHOMO_NO_PROXY" \
|
|
844
|
+
BUILD_CONTAINER_HTTP_PROXY="$container_proxy" \
|
|
845
|
+
BUILD_CONTAINER_HTTPS_PROXY="$container_proxy" \
|
|
846
|
+
BUILD_CONTAINER_NO_PROXY="$MIHOMO_NO_PROXY" \
|
|
847
|
+
MARKET_CONTAINER_HTTP_PROXY="${MARKET_CONTAINER_HTTP_PROXY:-$container_proxy}" \
|
|
848
|
+
MARKET_CONTAINER_HTTPS_PROXY="${MARKET_CONTAINER_HTTPS_PROXY:-$container_proxy}" \
|
|
849
|
+
MARKET_CONTAINER_NO_PROXY="${MARKET_CONTAINER_NO_PROXY:-$MIHOMO_NO_PROXY}" \
|
|
827
850
|
"$@"
|
|
828
851
|
}
|
|
829
852
|
|