green-tunnel 2.0.2 → 3.0.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/dist/core/config.d.ts +13 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +87 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/dns/decode.d.ts +12 -0
- package/dist/core/dns/decode.d.ts.map +1 -0
- package/dist/core/dns/decode.js +23 -0
- package/dist/core/dns/decode.js.map +1 -0
- package/dist/core/dns/doh.d.ts +19 -0
- package/dist/core/dns/doh.d.ts.map +1 -0
- package/dist/core/dns/doh.js +54 -0
- package/dist/core/dns/doh.js.map +1 -0
- package/dist/core/dns/dot.d.ts +13 -0
- package/dist/core/dns/dot.d.ts.map +1 -0
- package/dist/core/dns/dot.js +79 -0
- package/dist/core/dns/dot.js.map +1 -0
- package/dist/core/dns/index.d.ts +8 -0
- package/dist/core/dns/index.d.ts.map +1 -0
- package/dist/core/dns/index.js +18 -0
- package/dist/core/dns/index.js.map +1 -0
- package/dist/core/dns/plain.d.ts +17 -0
- package/dist/core/dns/plain.d.ts.map +1 -0
- package/dist/core/dns/plain.js +45 -0
- package/dist/core/dns/plain.js.map +1 -0
- package/dist/core/dns/resolver.d.ts +27 -0
- package/dist/core/dns/resolver.d.ts.map +1 -0
- package/dist/core/dns/resolver.js +81 -0
- package/dist/core/dns/resolver.js.map +1 -0
- package/dist/core/errors.d.ts +32 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +37 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/http/head.d.ts +40 -0
- package/dist/core/http/head.d.ts.map +1 -0
- package/dist/core/http/head.js +122 -0
- package/dist/core/http/head.js.map +1 -0
- package/dist/core/http/rewriter.d.ts +20 -0
- package/dist/core/http/rewriter.d.ts.map +1 -0
- package/dist/core/http/rewriter.js +184 -0
- package/dist/core/http/rewriter.js.map +1 -0
- package/dist/core/index.d.ts +28 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +27 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +38 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +92 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/net/socket.d.ts +30 -0
- package/dist/core/net/socket.d.ts.map +1 -0
- package/dist/core/net/socket.js +98 -0
- package/dist/core/net/socket.js.map +1 -0
- package/dist/core/proxy/connect-tunnel.d.ts +14 -0
- package/dist/core/proxy/connect-tunnel.d.ts.map +1 -0
- package/dist/core/proxy/connect-tunnel.js +44 -0
- package/dist/core/proxy/connect-tunnel.js.map +1 -0
- package/dist/core/proxy/connection.d.ts +12 -0
- package/dist/core/proxy/connection.d.ts.map +1 -0
- package/dist/core/proxy/connection.js +88 -0
- package/dist/core/proxy/connection.js.map +1 -0
- package/dist/core/proxy/context.d.ts +15 -0
- package/dist/core/proxy/context.d.ts.map +1 -0
- package/dist/core/proxy/context.js +2 -0
- package/dist/core/proxy/context.js.map +1 -0
- package/dist/core/proxy/index.d.ts +33 -0
- package/dist/core/proxy/index.d.ts.map +1 -0
- package/dist/core/proxy/index.js +162 -0
- package/dist/core/proxy/index.js.map +1 -0
- package/dist/core/proxy/pipe.d.ts +12 -0
- package/dist/core/proxy/pipe.d.ts.map +1 -0
- package/dist/core/proxy/pipe.js +42 -0
- package/dist/core/proxy/pipe.js.map +1 -0
- package/dist/core/proxy/plain-tunnel.d.ts +12 -0
- package/dist/core/proxy/plain-tunnel.d.ts.map +1 -0
- package/dist/core/proxy/plain-tunnel.js +29 -0
- package/dist/core/proxy/plain-tunnel.js.map +1 -0
- package/dist/core/system-proxy/darwin.d.ts +32 -0
- package/dist/core/system-proxy/darwin.d.ts.map +1 -0
- package/dist/core/system-proxy/darwin.js +146 -0
- package/dist/core/system-proxy/darwin.js.map +1 -0
- package/dist/core/system-proxy/driver.d.ts +21 -0
- package/dist/core/system-proxy/driver.d.ts.map +1 -0
- package/dist/core/system-proxy/driver.js +2 -0
- package/dist/core/system-proxy/driver.js.map +1 -0
- package/dist/core/system-proxy/exec.d.ts +21 -0
- package/dist/core/system-proxy/exec.d.ts.map +1 -0
- package/dist/core/system-proxy/exec.js +62 -0
- package/dist/core/system-proxy/exec.js.map +1 -0
- package/dist/core/system-proxy/index.d.ts +45 -0
- package/dist/core/system-proxy/index.d.ts.map +1 -0
- package/dist/core/system-proxy/index.js +151 -0
- package/dist/core/system-proxy/index.js.map +1 -0
- package/dist/core/system-proxy/linux.d.ts +18 -0
- package/dist/core/system-proxy/linux.d.ts.map +1 -0
- package/dist/core/system-proxy/linux.js +100 -0
- package/dist/core/system-proxy/linux.js.map +1 -0
- package/dist/core/system-proxy/recovery.d.ts +23 -0
- package/dist/core/system-proxy/recovery.d.ts.map +1 -0
- package/dist/core/system-proxy/recovery.js +147 -0
- package/dist/core/system-proxy/recovery.js.map +1 -0
- package/dist/core/system-proxy/windows.d.ts +15 -0
- package/dist/core/system-proxy/windows.d.ts.map +1 -0
- package/dist/core/system-proxy/windows.js +96 -0
- package/dist/core/system-proxy/windows.js.map +1 -0
- package/dist/core/tls/fragment.d.ts +28 -0
- package/dist/core/tls/fragment.d.ts.map +1 -0
- package/dist/core/tls/fragment.js +81 -0
- package/dist/core/tls/fragment.js.map +1 -0
- package/dist/core/types.d.ts +138 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +7 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +155 -0
- package/dist/main.js.map +1 -0
- package/dist/options.d.ts +25 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +144 -0
- package/dist/options.js.map +1 -0
- package/dist/ui.d.ts +17 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +89 -0
- package/dist/ui.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/package.json +31 -30
- package/LICENSE +0 -21
- package/README.md +0 -172
- package/bin/gt.js +0 -170
- package/src/config.js +0 -15
- package/src/dns/base.js +0 -47
- package/src/dns/https.js +0 -30
- package/src/dns/tls.js +0 -15
- package/src/dns/unencrypted.js +0 -25
- package/src/handlers/http.js +0 -65
- package/src/handlers/https.js +0 -78
- package/src/handlers/request.js +0 -32
- package/src/http/request.js +0 -45
- package/src/http/response.js +0 -45
- package/src/http/utils.js +0 -86
- package/src/index.cjs +0 -7
- package/src/index.js +0 -4
- package/src/logger.js +0 -11
- package/src/proxy.js +0 -74
- package/src/scripts/windows/wininet-reset-settings.ps1 +0 -14
- package/src/utils/analytics.js +0 -59
- package/src/utils/buffer.js +0 -35
- package/src/utils/socket.js +0 -32
- package/src/utils/system-proxy.js +0 -153
package/dist/ui.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
const BRAND = [132, 198, 111];
|
|
3
|
+
const ESC = '\u001B[';
|
|
4
|
+
const RESET = `${ESC}0m`;
|
|
5
|
+
// `isTTY` is typed as `boolean` but is genuinely `undefined` when stdout is a
|
|
6
|
+
// pipe — falsy either way, which is what we want.
|
|
7
|
+
const colorEnabled = process.stdout.isTTY && process.env['NO_COLOR'] === undefined && process.env['TERM'] !== 'dumb';
|
|
8
|
+
function paint(code, text) {
|
|
9
|
+
return colorEnabled ? `${ESC}${code}m${text}${RESET}` : text;
|
|
10
|
+
}
|
|
11
|
+
const [R, G, B] = BRAND;
|
|
12
|
+
/** A run of brand-coloured background — the pixels the logo is drawn with. */
|
|
13
|
+
function block(width) {
|
|
14
|
+
if (!colorEnabled)
|
|
15
|
+
return '#'.repeat(width);
|
|
16
|
+
return paint(`48;2;${String(R)};${String(G)};${String(B)}`, ' '.repeat(width));
|
|
17
|
+
}
|
|
18
|
+
const brand = (text) => paint(`38;2;${String(R)};${String(G)};${String(B)}`, text);
|
|
19
|
+
const bold = (text) => paint('1', text);
|
|
20
|
+
const dim = (text) => paint('2', text);
|
|
21
|
+
const red = (text) => paint('31', text);
|
|
22
|
+
const PAD = ' ';
|
|
23
|
+
export function printBanner() {
|
|
24
|
+
const lines = [
|
|
25
|
+
`${PAD} ${block(4)}`,
|
|
26
|
+
`${PAD} ${block(10)}`,
|
|
27
|
+
`${PAD}${block(12)}`,
|
|
28
|
+
`${PAD}${block(5)} ${block(5)}`,
|
|
29
|
+
`${PAD}${block(3)} ${block(3)}`,
|
|
30
|
+
`${PAD}${block(1)} ${block(1)}`,
|
|
31
|
+
];
|
|
32
|
+
console.log(`\n${lines.join('\n')}\n`);
|
|
33
|
+
console.log(`${PAD}${brand(bold('Green'))} ${bold('Tunnel')}\n`);
|
|
34
|
+
}
|
|
35
|
+
export function printStatus(address, settings, systemProxy) {
|
|
36
|
+
const endpoint = `${address.host}:${String(address.port)}`;
|
|
37
|
+
const fragmentation = settings.fragment.enabled
|
|
38
|
+
? `${settings.fragment.tlsRecords ? 'TLS records' : 'TCP segments'} of ${String(settings.fragment.size)}B`
|
|
39
|
+
: 'off';
|
|
40
|
+
console.log(`${PAD}${brand('●')} running on ${bold(endpoint)}`);
|
|
41
|
+
console.log(`${PAD}${dim(`fragmentation ${fragmentation}`)}`);
|
|
42
|
+
console.log(`${PAD}${dim(`dns ${describeDns(settings)}`)}`);
|
|
43
|
+
console.log(`${PAD}${dim(`system proxy ${systemProxy ? 'managed by GreenTunnel' : 'untouched'}`)}`);
|
|
44
|
+
if (!systemProxy) {
|
|
45
|
+
console.log(`\n${PAD}${dim('Point your client at it, or export:')}`);
|
|
46
|
+
console.log(`${PAD}${dim(`export http_proxy=http://${endpoint} https_proxy=http://${endpoint}`)}`);
|
|
47
|
+
}
|
|
48
|
+
console.log(`\n${PAD}${dim('GreenTunnel does not hide your IP address.')}`);
|
|
49
|
+
console.log(`${PAD}${dim('Press Ctrl+C to stop.')}\n`);
|
|
50
|
+
}
|
|
51
|
+
function describeDns(settings) {
|
|
52
|
+
switch (settings.dns.mode) {
|
|
53
|
+
case 'doh':
|
|
54
|
+
return `DoH via ${new URL(settings.dns.dohUrl).host}`;
|
|
55
|
+
case 'dot':
|
|
56
|
+
return `DoT via ${settings.dns.dotHost}:${String(settings.dns.dotPort)}`;
|
|
57
|
+
case 'plain':
|
|
58
|
+
return settings.dns.plainServers.length > 0
|
|
59
|
+
? `plain via ${settings.dns.plainServers.join(', ')}`
|
|
60
|
+
: 'plain via system resolvers';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Acknowledge the stop request before teardown starts.
|
|
65
|
+
*
|
|
66
|
+
* Restoring the system proxy means several `networksetup`/`gsettings` calls,
|
|
67
|
+
* which take long enough that a silent CLI looks wedged — and the user's next
|
|
68
|
+
* move is a second Ctrl-C, the one thing that can strand their network
|
|
69
|
+
* settings. So say what is happening, and say it is worth waiting for.
|
|
70
|
+
*/
|
|
71
|
+
export function printStopping(restoresSystemProxy) {
|
|
72
|
+
// Ctrl+C echoes `^C` with no trailing newline, so open on a fresh line.
|
|
73
|
+
console.error(`\n${PAD}${brand('◆')} ${bold('Stopping GreenTunnel…')}`);
|
|
74
|
+
console.error(`${PAD}${dim(restoresSystemProxy
|
|
75
|
+
? "Restoring your system proxy settings — please don't force-quit."
|
|
76
|
+
: 'Closing connections — one moment.')}`);
|
|
77
|
+
}
|
|
78
|
+
/** Confirm teardown finished, so the user knows the machine is clean. */
|
|
79
|
+
export function printStopped(restoredSystemProxy) {
|
|
80
|
+
const detail = restoredSystemProxy ? ' Your network settings are back to how they were.' : '';
|
|
81
|
+
console.error(`${PAD}${brand('✔')} Stopped.${detail}\n`);
|
|
82
|
+
}
|
|
83
|
+
export function printError(message) {
|
|
84
|
+
console.error(`${PAD}${red('✖')} ${message}`);
|
|
85
|
+
}
|
|
86
|
+
export function printNotice(message) {
|
|
87
|
+
console.error(`${PAD}${dim(message)}`);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=ui.js.map
|
package/dist/ui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAMA,8EAA8E;AAC9E,eAAO,MAAM,OAAO,EAAE,MAA8B,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
/** Read from the manifest next to `dist/` so there is one source of truth. */
|
|
3
|
+
export const VERSION = readManifestVersion();
|
|
4
|
+
function readManifestVersion() {
|
|
5
|
+
try {
|
|
6
|
+
const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');
|
|
7
|
+
return JSON.parse(raw).version ?? '0.0.0';
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return '0.0.0';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMvC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,OAAO,GAAW,mBAAmB,EAAE,CAAC;AAErD,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9E,OAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC,OAAO,IAAI,OAAO,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "green-tunnel",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"description": "Bypass DPI censorship — the engine and the command line tool",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
6
|
+
"dpi",
|
|
7
|
+
"censorship",
|
|
8
|
+
"sni",
|
|
9
|
+
"tls",
|
|
10
|
+
"proxy",
|
|
11
|
+
"doh",
|
|
12
|
+
"dot"
|
|
9
13
|
],
|
|
10
14
|
"homepage": "https://github.com/SadeghHayeri/GreenTunnel#readme",
|
|
11
15
|
"bugs": {
|
|
@@ -13,43 +17,40 @@
|
|
|
13
17
|
},
|
|
14
18
|
"repository": {
|
|
15
19
|
"type": "git",
|
|
16
|
-
"url": "git+https://github.com/SadeghHayeri/GreenTunnel.git"
|
|
20
|
+
"url": "git+https://github.com/SadeghHayeri/GreenTunnel.git",
|
|
21
|
+
"directory": "packages/cli"
|
|
17
22
|
},
|
|
18
23
|
"license": "MIT",
|
|
19
24
|
"author": "Sadegh Hayeri",
|
|
20
|
-
"files": [
|
|
21
|
-
"bin",
|
|
22
|
-
"src"
|
|
23
|
-
],
|
|
24
25
|
"type": "module",
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
".": "./src/index.js"
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=24.0.0"
|
|
28
28
|
},
|
|
29
29
|
"bin": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
30
|
+
"gt": "./dist/main.js",
|
|
31
|
+
"green-tunnel": "./dist/main.js"
|
|
32
32
|
},
|
|
33
|
-
"
|
|
34
|
-
|
|
33
|
+
"main": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"exports": {
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
}
|
|
35
40
|
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist"
|
|
43
|
+
],
|
|
36
44
|
"scripts": {
|
|
37
|
-
"
|
|
45
|
+
"build": "tsc --build tsconfig.build.json",
|
|
46
|
+
"dev": "tsc --build tsconfig.build.json && node dist/main.js",
|
|
47
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
38
48
|
},
|
|
39
49
|
"dependencies": {
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"debug": "^4.4.0",
|
|
43
|
-
"dns-over-tls": "^0.0.9",
|
|
44
|
-
"dns-socket": "^4.2.2",
|
|
45
|
-
"lru-cache": "^11.2.6",
|
|
46
|
-
"ora": "^9.3.0",
|
|
47
|
-
"validator": "^13.15.26",
|
|
48
|
-
"winreg": "^1.2.5",
|
|
49
|
-
"yargs": "^18.0.0"
|
|
50
|
+
"dns-packet": "^5.6.1",
|
|
51
|
+
"lru-cache": "^11.5.2"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
|
-
"
|
|
53
|
-
"eslint-config-xo": "^0.49.0"
|
|
54
|
+
"@types/dns-packet": "^5.6.5"
|
|
54
55
|
}
|
|
55
56
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019 Sadegh Hayeri
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/README.md
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# Green Tunnel
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<img src="assets/logo.png" alt="green tunnel logo" width="200">
|
|
5
|
-
</p>
|
|
6
|
-
<p align="center">
|
|
7
|
-
<img src="https://img.shields.io/github/license/SadeghHayeri/GreenTunnel.svg?color=Green&style=for-the-badge">
|
|
8
|
-
<img src="https://img.shields.io/npm/v/green-tunnel?color=Green&style=for-the-badge">
|
|
9
|
-
<img src="https://img.shields.io/github/repo-size/SadeghHayeri/GreenTunnel.svg?color=Green&style=for-the-badge">
|
|
10
|
-
</p>
|
|
11
|
-
|
|
12
|
-
GreenTunnel bypasses DPI (Deep Packet Inspection) systems found in many ISPs (Internet Service Providers) which block access to certain websites.
|
|
13
|
-
|
|
14
|
-
> **Note:** GreenTunnel does not hide your IP address. It only bypasses DPI-based censorship.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
<table>
|
|
19
|
-
<tr>
|
|
20
|
-
<td width="340"><img src="assets/new-version.png" alt="GreenTunnel v2.0.0 new UI" width="320"></td>
|
|
21
|
-
<td valign="top" style="padding-left: 24px;">
|
|
22
|
-
|
|
23
|
-
**GreenTunnel v2 — with the help of [Claude Code](https://code.claude.com/docs/en/overview) — is out now.**
|
|
24
|
-
|
|
25
|
-
After years of silence, this project is alive again. The entire codebase has been rebuilt from the ground up: native ESM, Node.js 20+, a brand new dark UI, and a clean dependency tree with zero known vulnerabilities.
|
|
26
|
-
|
|
27
|
-
Open-source tools that help people reach the free internet shouldn't die — and with AI-assisted development, they don't have to. We'll keep doing our best to help people access the open internet, one packet at a time.
|
|
28
|
-
|
|
29
|
-
</td>
|
|
30
|
-
</tr>
|
|
31
|
-
</table>
|
|
32
|
-
|
|
33
|
-
<p align="center">
|
|
34
|
-
<img src="assets/demo.gif" alt="green tunnel demo">
|
|
35
|
-
</p>
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Installation
|
|
40
|
-
|
|
41
|
-
### Requirements
|
|
42
|
-
|
|
43
|
-
- **Node.js 20+**
|
|
44
|
-
|
|
45
|
-
### npm (recommended)
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npm install -g green-tunnel
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
After installation, run with `gt` or `green-tunnel`.
|
|
52
|
-
|
|
53
|
-
### Docker
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
docker run -p 8000:8000 sadeghhayeri/greentunnel
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Usage
|
|
62
|
-
|
|
63
|
-
### CLI
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
Usage: green-tunnel [options]
|
|
67
|
-
Usage: gt [options]
|
|
68
|
-
|
|
69
|
-
Options:
|
|
70
|
-
--ip IP address to bind proxy server [string] [default: "127.0.0.1"]
|
|
71
|
-
--port Port to bind proxy server [number] [default: 8000]
|
|
72
|
-
--https-only Block insecure HTTP requests [boolean] [default: false]
|
|
73
|
-
--dns-type DNS resolver type [string] [choices: "https", "tls", "unencrypted"] [default: "https"]
|
|
74
|
-
--dns-server DNS server URL [string] [default: "https://cloudflare-dns.com/dns-query"]
|
|
75
|
-
--dns-ip IP for unencrypted DNS [string] [default: "127.0.0.1"]
|
|
76
|
-
--dns-port Port for unencrypted DNS [number] [default: 53]
|
|
77
|
-
--tls-record-frag... Enable TLS record fragmentation [boolean] [default: false]
|
|
78
|
-
--silent, -s Run in silent mode [boolean] [default: false]
|
|
79
|
-
--verbose, -v Debug mode (e.g. 'green-tunnel:*') [string]
|
|
80
|
-
--system-proxy Auto-set system proxy [boolean] [default: true]
|
|
81
|
-
--help, -h Show help
|
|
82
|
-
--version, -V Show version number
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Examples:**
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# Basic usage (auto-sets system proxy)
|
|
89
|
-
gt
|
|
90
|
-
|
|
91
|
-
# Custom port
|
|
92
|
-
gt --port 9000
|
|
93
|
-
|
|
94
|
-
# Use a different DoH server
|
|
95
|
-
gt --dns-server https://doh.securedns.eu/dns-query
|
|
96
|
-
|
|
97
|
-
# Enable TLS record fragmentation (for stricter DPI)
|
|
98
|
-
gt --tls-record-fragmentation
|
|
99
|
-
|
|
100
|
-
# Debug mode
|
|
101
|
-
gt --verbose 'green-tunnel:*'
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Docker
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
# Basic
|
|
108
|
-
docker run -p 8000:8000 sadeghhayeri/greentunnel
|
|
109
|
-
|
|
110
|
-
# Custom port
|
|
111
|
-
docker run -e PORT=9000 -p 9000:9000 sadeghhayeri/greentunnel
|
|
112
|
-
|
|
113
|
-
# Run in background, restart on reboot
|
|
114
|
-
docker run -d --restart unless-stopped -p 8000:8000 sadeghhayeri/greentunnel
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**Environment variables:**
|
|
118
|
-
|
|
119
|
-
| Variable | Description | Default |
|
|
120
|
-
|---|---|---|
|
|
121
|
-
| `PORT` | Proxy port | `8000` |
|
|
122
|
-
| `HTTPS_ONLY` | Block HTTP traffic | `false` |
|
|
123
|
-
| `DNS_TYPE` | `https`, `tls`, or `unencrypted` | `https` |
|
|
124
|
-
| `DNS_SERVER` | DNS server URL | Cloudflare DoH |
|
|
125
|
-
| `SILENT` | Suppress output | `false` |
|
|
126
|
-
| `VERBOSE` | Debug namespace | — |
|
|
127
|
-
|
|
128
|
-
### Graphical Interface (GUI)
|
|
129
|
-
|
|
130
|
-
Download the pre-built installer for your OS from the [releases](https://github.com/SadeghHayeri/GreenTunnel/releases) page.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## How It Works
|
|
135
|
-
|
|
136
|
-
### HTTP
|
|
137
|
-
|
|
138
|
-
Some DPI systems fail to detect blocked content when an HTTP request is split across multiple TCP segments. GreenTunnel splits the request so the `Host` header straddles a segment boundary, preventing the DPI from matching the blocked hostname.
|
|
139
|
-
|
|
140
|
-
### HTTPS / SNI Fragmentation
|
|
141
|
-
|
|
142
|
-
TLS's Server Name Indication (SNI) extension sends the target hostname in plaintext during the handshake. DPI systems use this to block HTTPS connections. GreenTunnel splits the initial `ClientHello` TLS record into small fragments so the DPI cannot reassemble and inspect the SNI field.
|
|
143
|
-
|
|
144
|
-
Optionally, `--tls-record-fragmentation` breaks the TLS record at a lower level for stricter DPI environments.
|
|
145
|
-
|
|
146
|
-
### Encrypted DNS
|
|
147
|
-
|
|
148
|
-
Standard DNS lookups can be intercepted or spoofed by ISPs to block domains at the DNS level. GreenTunnel uses **DNS over HTTPS (DoH)** or **DNS over TLS (DoT)** to get the real IP address, bypassing DNS-based blocking.
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## Contributing
|
|
153
|
-
|
|
154
|
-
Pull requests and issues are always welcome.
|
|
155
|
-
|
|
156
|
-
- Use `FIX:`, `ADD:`, `UPDATE:` prefixes in PR titles.
|
|
157
|
-
- Keep commits focused and descriptive.
|
|
158
|
-
- Make sure `npm install` passes and `node -e "import('./src/index.js')"` works.
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## Donation
|
|
163
|
-
|
|
164
|
-
> Love GreenTunnel? Please consider donating to sustain development.
|
|
165
|
-
|
|
166
|
-
**Ethereum / USDT (ERC-20):** `0xB116a6AE50c38a455944A65f9cEE4D54CEceF080`
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## License
|
|
171
|
-
|
|
172
|
-
Licensed under the [MIT License](https://github.com/SadeghHayeri/GreenTunnel/blob/main/LICENSE).
|
package/bin/gt.js
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
import clear from 'clear';
|
|
5
|
-
import ora from 'ora';
|
|
6
|
-
import debug from 'debug';
|
|
7
|
-
import yargs from 'yargs';
|
|
8
|
-
import { hideBin } from 'yargs/helpers';
|
|
9
|
-
import { Proxy, config, getLogger } from '../src/index.js';
|
|
10
|
-
|
|
11
|
-
const logger = getLogger('cli');
|
|
12
|
-
|
|
13
|
-
const argv = yargs(hideBin(process.argv))
|
|
14
|
-
.usage('Usage: green-tunnel [options]')
|
|
15
|
-
.usage('Usage: gt [options]')
|
|
16
|
-
.alias('help', 'h')
|
|
17
|
-
.alias('version', 'V')
|
|
18
|
-
|
|
19
|
-
.option('ip', {
|
|
20
|
-
type: 'string',
|
|
21
|
-
describe: 'ip address to bind proxy server',
|
|
22
|
-
default: '127.0.0.1',
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
.option('port', {
|
|
26
|
-
type: 'number',
|
|
27
|
-
describe: 'port address to bind proxy server',
|
|
28
|
-
default: config.port,
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
.option('https-only', {
|
|
32
|
-
type: 'boolean',
|
|
33
|
-
describe: 'Block insecure HTTP requests',
|
|
34
|
-
default: config.httpsOnly,
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
.option('dns-type', {
|
|
38
|
-
type: 'string',
|
|
39
|
-
choices: ['https', 'tls', 'unencrypted'],
|
|
40
|
-
default: config.dns.type,
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
.option('dns-server', {
|
|
44
|
-
type: 'string',
|
|
45
|
-
default: config.dns.server,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
.option('dns-ip', {
|
|
49
|
-
type: 'string',
|
|
50
|
-
default: config.dns.ip,
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
.option('dns-port', {
|
|
54
|
-
type: 'number',
|
|
55
|
-
default: config.dns.port,
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
.option('silent', {
|
|
59
|
-
alias: 's',
|
|
60
|
-
type: 'boolean',
|
|
61
|
-
describe: 'run in silent mode',
|
|
62
|
-
default: false,
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
.option('verbose', {
|
|
66
|
-
alias: 'v',
|
|
67
|
-
type: 'string',
|
|
68
|
-
describe: 'debug mode',
|
|
69
|
-
default: '',
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
.option('system-proxy', {
|
|
73
|
-
type: 'boolean',
|
|
74
|
-
describe: 'automatic set system-proxy',
|
|
75
|
-
default: true,
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
.option('tls-record-fragmentation', {
|
|
79
|
-
type: 'boolean',
|
|
80
|
-
describe: 'enable TLS record fragmentation',
|
|
81
|
-
default: false
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
.example('$0')
|
|
85
|
-
.example('$0 --ip 127.0.0.1 --port 8000')
|
|
86
|
-
.example('$0 --dns-server https://doh.securedns.eu/dns-query')
|
|
87
|
-
.epilog('ISSUES: https://github.com/SadeghHayeri/GreenTunnel/issues\n' +
|
|
88
|
-
'DONATE: https://github.com/SadeghHayeri/GreenTunnel#donation')
|
|
89
|
-
.parseSync();
|
|
90
|
-
|
|
91
|
-
const MAIN_COLOR = '84C66F';
|
|
92
|
-
|
|
93
|
-
function printBanner() {
|
|
94
|
-
console.log();
|
|
95
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR)(' '));
|
|
96
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR)(' '));
|
|
97
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR)(' '));
|
|
98
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR)(' ') + ' ' + chalk.bgHex(MAIN_COLOR)(' '));
|
|
99
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR)(' ') + ' ' + chalk.bgHex(MAIN_COLOR)(' '));
|
|
100
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR)(' ') + ' ' + chalk.bgHex(MAIN_COLOR)(' '));
|
|
101
|
-
console.log();
|
|
102
|
-
console.log(' ' + chalk.hex(MAIN_COLOR).bold('Green') + ' ' + chalk.bold.white('Tunnel'));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function printAlert(proxy) {
|
|
106
|
-
console.log('\n');
|
|
107
|
-
console.log(' ' + chalk.bgHex(MAIN_COLOR).black(' Note: GreenTunnel does not hide your IP address '));
|
|
108
|
-
console.log(' ' + chalk.hex(MAIN_COLOR)(' https://github.com/SadeghHayeri/GreenTunnel '));
|
|
109
|
-
console.log('\n ' + chalk.white(` GreenTunnel is running at ${proxy.server.address().address}:${proxy.server.address().port}. `));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function showSpinner() {
|
|
113
|
-
console.log('');
|
|
114
|
-
ora({
|
|
115
|
-
indent: 27,
|
|
116
|
-
text: '',
|
|
117
|
-
color: 'green'
|
|
118
|
-
}).start();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async function main() {
|
|
122
|
-
if (argv['verbose']) {
|
|
123
|
-
debug.enable(argv['verbose']);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const proxy = new Proxy({
|
|
127
|
-
ip: argv['ip'],
|
|
128
|
-
port: parseInt(argv['port'], 10),
|
|
129
|
-
httpsOnly: argv['https-only'],
|
|
130
|
-
dns: {
|
|
131
|
-
type: argv['dns-type'],
|
|
132
|
-
server: argv['dns-server'],
|
|
133
|
-
ip: argv['dns-ip'],
|
|
134
|
-
port: argv['dns-port']
|
|
135
|
-
},
|
|
136
|
-
source: 'CLI',
|
|
137
|
-
'tlsRecordFragmentation': argv['tls-record-fragmentation']
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const exitTrap = async () => {
|
|
141
|
-
logger.debug('Caught interrupt signal');
|
|
142
|
-
await proxy.stop();
|
|
143
|
-
logger.debug('Successfully Closed!');
|
|
144
|
-
|
|
145
|
-
if (!argv['silent']) {
|
|
146
|
-
clear();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
process.exit(0);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const errorTrap = error => {
|
|
153
|
-
logger.error(error);
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
process.on('SIGINT', exitTrap);
|
|
157
|
-
process.on('unhandledRejection', errorTrap);
|
|
158
|
-
process.on('uncaughtException', errorTrap);
|
|
159
|
-
|
|
160
|
-
await proxy.start({ setProxy: argv['system-proxy'] });
|
|
161
|
-
|
|
162
|
-
if (!argv['silent'] && !argv['verbose']) {
|
|
163
|
-
clear();
|
|
164
|
-
printBanner();
|
|
165
|
-
printAlert(proxy);
|
|
166
|
-
showSpinner();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
main().catch(logger.error);
|
package/src/config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
const config = {
|
|
2
|
-
ip: '127.0.0.1',
|
|
3
|
-
port: 8000,
|
|
4
|
-
httpsOnly: false,
|
|
5
|
-
clientHelloMTU: 100,
|
|
6
|
-
dns: {
|
|
7
|
-
type: 'https', // 'tls' or 'https' or 'unencrypted'
|
|
8
|
-
server: 'https://cloudflare-dns.com/dns-query',
|
|
9
|
-
ip: '127.0.0.1',
|
|
10
|
-
port: 53,
|
|
11
|
-
cacheSize: 1000,
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default config;
|
package/src/dns/base.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { LRUCache } from 'lru-cache';
|
|
2
|
-
import validator from 'validator';
|
|
3
|
-
const { isIP } = validator;
|
|
4
|
-
import getLogger from '../logger.js';
|
|
5
|
-
import config from '../config.js';
|
|
6
|
-
|
|
7
|
-
const logger = getLogger('dns');
|
|
8
|
-
|
|
9
|
-
function _isIP(v) {
|
|
10
|
-
return v && isIP(v);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default class BaseDNS {
|
|
14
|
-
constructor() {
|
|
15
|
-
this.cache = new LRUCache({max: config.dns.cacheSize});
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async lookup(hostname) {
|
|
19
|
-
try {
|
|
20
|
-
let ip = this.cache.get(hostname);
|
|
21
|
-
if (ip) {
|
|
22
|
-
return ip;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const t = new Date();
|
|
26
|
-
|
|
27
|
-
ip = hostname;
|
|
28
|
-
for (let depth = 0; !_isIP(ip) && depth < 5; depth++) {
|
|
29
|
-
ip = await this._lookup(ip).catch(error => {
|
|
30
|
-
logger.debug(error);
|
|
31
|
-
return ip;
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!_isIP(ip)) {
|
|
36
|
-
throw new Error(`BAD IP FORMAT (${ip})`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
logger.debug(`[DNS] ${hostname} -> ${ip} (${new Date() - t} ms)`);
|
|
40
|
-
this.cache.set(hostname, ip);
|
|
41
|
-
return ip;
|
|
42
|
-
} catch (error) {
|
|
43
|
-
logger.debug(`[DNS] cannot resolve hostname ${hostname} (${error})`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
package/src/dns/https.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import BaseDNS from './base.js';
|
|
2
|
-
|
|
3
|
-
export default class DNSOverHTTPS extends BaseDNS {
|
|
4
|
-
constructor(dnsServer) {
|
|
5
|
-
super();
|
|
6
|
-
this.dnsServer = dnsServer;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
async _lookup(hostname) {
|
|
10
|
-
const url = new URL(this.dnsServer);
|
|
11
|
-
url.searchParams.set('name', hostname);
|
|
12
|
-
url.searchParams.set('type', 'A');
|
|
13
|
-
|
|
14
|
-
const response = await fetch(url.toString(), {
|
|
15
|
-
headers: {Accept: 'application/dns-json'},
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
if (!response.ok) {
|
|
19
|
-
throw new Error(`DoH request failed: ${response.status}`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const result = await response.json();
|
|
23
|
-
|
|
24
|
-
if (!result.Answer || result.Answer.length === 0) {
|
|
25
|
-
throw new Error(`No DNS answers for ${hostname}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return result.Answer[0].data;
|
|
29
|
-
}
|
|
30
|
-
}
|