green-tunnel 1.7.1 → 1.7.5
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 +42 -11
- package/bin/gt.js +27 -7
- package/package.json +4 -2
- package/src/config.js +4 -1
- package/src/dns/base.js +1 -1
- package/src/dns/unencrypted.js +25 -0
- package/src/handlers/request.js +2 -0
- package/src/proxy.js +14 -9
- package/src/utils/analytics.js +16 -6
- package/src/utils/system-proxy.js +2 -0
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<img src="assets/logo.png" alt="green tunnel logo" width="200">
|
|
4
4
|
</p>
|
|
5
5
|
<p align="center">
|
|
6
|
-
<img src="https://img.shields.io/github/license/SadeghHayeri/GreenTunnel.svg?color=Green&style=
|
|
6
|
+
<img src="https://img.shields.io/github/license/SadeghHayeri/GreenTunnel.svg?color=Green&style=for-the-badge"> <img src="https://img.shields.io/github/repo-size/SadeghHayeri/GreenTunnel.svg?color=Green&style=for-the-badge"> <img src="https://img.shields.io/discord/707464295021019197?color=Green&style=for-the-badge">
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
GreenTunnel bypasses DPI (Deep Packet Inspection) systems found in many ISPs (Internet Service Providers) which block access to certain websites.
|
|
@@ -21,6 +21,13 @@ You can install GreenTunnel using [npm](https://www.npmjs.org/ "npm"):
|
|
|
21
21
|
```
|
|
22
22
|
$ npm i -g green-tunnel
|
|
23
23
|
```
|
|
24
|
+
|
|
25
|
+
or using [snap](https://snapcraft.io) (edge version):
|
|
26
|
+
```
|
|
27
|
+
sudo snap install --edge green-tunnel --devmode
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
24
31
|
after installation you can run it using `gt` or `green-tunnel` commands.
|
|
25
32
|
|
|
26
33
|
```
|
|
@@ -32,16 +39,19 @@ Options:
|
|
|
32
39
|
--help, -h Show help [boolean]
|
|
33
40
|
--version, -V Show version number [boolean]
|
|
34
41
|
--ip ip address to bind proxy server[string] [default: "127.0.0.1"]
|
|
42
|
+
--https-only Block insecure HTTP requests [boolean] [default: false]
|
|
35
43
|
--port port address to bind proxy server [number] [default: 8000]
|
|
36
44
|
--dns-type [string] [choices: "https", "tls"] [default: "https"]
|
|
37
45
|
--dns-server [string] [default: "https://cloudflare-dns.com/dns-query"]
|
|
46
|
+
--dns-ip IP address for unencrypted DNS [string][default: "127.0.0.1"]
|
|
47
|
+
--dns-port Port for unencrypted DNS [number] [default: 53]
|
|
38
48
|
--silent, -s run in silent mode [boolean] [default: false]
|
|
39
49
|
--verbose, -v debug mode [string] [default: ""]
|
|
40
50
|
--system-proxy automatic set system-proxy [boolean] [default: true]
|
|
41
51
|
|
|
42
52
|
Examples:
|
|
43
53
|
gt
|
|
44
|
-
gt --ip 127.0.0.1 --port 8000
|
|
54
|
+
gt --ip 127.0.0.1 --port 8000 --https-only
|
|
45
55
|
gt --dns-server https://doh.securedns.eu/dns-query
|
|
46
56
|
gt --verbose 'green-tunnel:proxy*'
|
|
47
57
|
|
|
@@ -59,6 +69,7 @@ $ docker run -p 8000:8000 sadeghhayeri/green-tunnel
|
|
|
59
69
|
```
|
|
60
70
|
> **envs**
|
|
61
71
|
* PORT
|
|
72
|
+
* HTTPS-ONLY
|
|
62
73
|
* VERBOSE
|
|
63
74
|
* SILENT
|
|
64
75
|
* DNS_TYPE
|
|
@@ -69,6 +80,20 @@ usage:
|
|
|
69
80
|
$ docker run -e 'PORT=1000' -p 8000:1000 sadeghhayeri/green-tunnel
|
|
70
81
|
```
|
|
71
82
|
|
|
83
|
+
#### On Raspberry Pi
|
|
84
|
+
```
|
|
85
|
+
$ docker run -p 8000:8000 sadeghhayeri/green-tunnel:arm
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If you want to make container keep running when reboot:
|
|
89
|
+
```
|
|
90
|
+
$ docker run -d --restart unless-stopped -p 8000:8000 sadeghhayeri/green-tunnel:arm
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Please make sure port `8000` is not blocked on Raspberry Pi firewall. (`sudo ufw allow 8000 comment Green-Tunnel`)
|
|
94
|
+
|
|
95
|
+
To use it on your other device, set http proxy to ```<Raspberry Pi IP Address>:<PORT>```. (PORT = `8000`)
|
|
96
|
+
|
|
72
97
|
### Tested on
|
|
73
98
|
- MacOS Catalina with node 12
|
|
74
99
|
- Ubuntu 18.04 with node 8
|
|
@@ -77,11 +102,6 @@ $ docker run -e 'PORT=1000' -p 8000:1000 sadeghhayeri/green-tunnel
|
|
|
77
102
|
|
|
78
103
|
## FAQ
|
|
79
104
|
> **How does it work?**
|
|
80
|
-
###### DNS
|
|
81
|
-
When you enter a URL in a Web browser, the first thing the Web browser does is to ask a DNS (Domain Name System) server, at a known numeric address, to look up the domain name referenced in the URL and supply the corresponding IP address.
|
|
82
|
-
If the DNS server is configured to block access, it consults a blacklist of banned domain names. When a browser requests the IP address for one of these domain names, the DNS server gives a wrong answer or no answer at all.
|
|
83
|
-
GreenTunnel use [DNS over HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS "doh (DNS over HTTPS)") and [DNS over TLS](https://en.wikipedia.org/wiki/DNS_over_TLS "DNS over TLS") to get real IP address and bypass DNS Spoofing.
|
|
84
|
-
|
|
85
105
|
###### HTTP
|
|
86
106
|
There are gaps in providers in DPI. They happen from what the DPI rules write for ordinary user programs, omitting all possible cases that are permissible by standards. This is done for simplicity and speed.
|
|
87
107
|
Some DPIs cannot recognize the HTTP request if it is divided into TCP segments. For example, a request of the form
|
|
@@ -96,6 +116,10 @@ we send it in 2 parts: first comes `GET / HTTP/1.0 \n Host: www.you` and second
|
|
|
96
116
|
###### HTTPS
|
|
97
117
|
Server Name Indication (SNI) is an extension to TLS (Transport Layer Security) that indicates the actual destination hostname a client is attempting to access over HTTPS. For this Web Filter feature, SNI hostname information is used for blocking access to specific sites over HTTPS. For example, if the administrator chooses to block the hostname **youtube** using this feature, all Website access attempts over HTTPS that contain **youtube** like **www.youtube.com** in the SNI would be blocked. However, access to the same hostname over HTTP would not be blocked by this feature. GreenTunnel tries to split first **CLIENT-HELLO** packet into small chunks and ISPs can't parse packet and found SNI field so bypass traffic!
|
|
98
118
|
|
|
119
|
+
###### DNS
|
|
120
|
+
When you enter a URL in a Web browser, the first thing the Web browser does is to ask a DNS (Domain Name System) server, at a known numeric address, to look up the domain name referenced in the URL and supply the corresponding IP address.
|
|
121
|
+
If the DNS server is configured to block access, it consults a blacklist of banned domain names. When a browser requests the IP address for one of these domain names, the DNS server gives a wrong answer or no answer at all.
|
|
122
|
+
GreenTunnel use [DNS over HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS "doh (DNS over HTTPS)") and [DNS over TLS](https://en.wikipedia.org/wiki/DNS_over_TLS "DNS over TLS") to get real IP address and bypass DNS Spoofing.
|
|
99
123
|
|
|
100
124
|
## Development notes
|
|
101
125
|
GreenTunnel is an open-source app and I really appreciate other developers adding new features and/or helping fix bugs. If you want to contribute to GreenTunnel, you can fork this repository, make the changes and create a pull request.
|
|
@@ -108,22 +132,29 @@ However, please make sure you follow a few rules listed below to ensure that you
|
|
|
108
132
|
- Commits in your fork should be informative, as well. Make sure you don't combine too many changes into a single commit.
|
|
109
133
|
|
|
110
134
|
## TODO List
|
|
111
|
-
- [
|
|
135
|
+
- [X] enable/disable proxy on windows
|
|
112
136
|
- [ ] HTTPHandler
|
|
113
137
|
- [X] add CLI arguments
|
|
114
|
-
- [
|
|
138
|
+
- [X] catch all exceptions
|
|
115
139
|
- [ ] add preferences menu
|
|
116
140
|
- [ ] fix close button
|
|
117
141
|
|
|
118
142
|
## Donation
|
|
119
143
|
> Love GreenTunnel? Please consider donating to sustain our activities.
|
|
120
144
|
|
|
121
|
-
**
|
|
145
|
+
**DOGECOIN!:** DTGjx8KKDCUkSEbtVHgQx1GYEnNaVVuXLa<br />
|
|
146
|
+
**BITCOIN:** bc1qknjsmsa98lljwxjwl4pmjh48s8su8r8ajkqd8w<br />
|
|
147
|
+
**ETHEREUM:** 0x018fbf3fAC7165b2c85f856cC90E2d9410415150<br />
|
|
148
|
+
**LITECOIN:** ltc1q5tfprazpkzjvzf5shgprkpkhnnku3p72feutxt<br />
|
|
149
|
+
**RIPPLE/XRP:** rt6ZTkKdBVYzBee9CpQsDTsewnTbAoV13<br />
|
|
122
150
|
|
|
123
151
|
[](https://payping.ir/d/TXTS)
|
|
124
152
|
<br />
|
|
125
153
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=HJ5TBXVYTHS7N¤cy_code=USD&source=url)
|
|
154
|
+
<br />
|
|
155
|
+
[](https://en.cryptobadges.io/donate/bc1qknjsmsa98lljwxjwl4pmjh48s8su8r8ajkqd8w)
|
|
156
|
+
[](https://en.cryptobadges.io/donate/0x018fbf3fAC7165b2c85f856cC90E2d9410415150)
|
|
157
|
+
[](https://en.cryptobadges.io/donate/rt6ZTkKdBVYzBee9CpQsDTsewnTbAoV13)
|
|
126
158
|
|
|
127
159
|
## License
|
|
128
160
|
Licensed under the MIT license. See [LICENSE](https://github.com/SadeghHayeri/GreenTunnel/blob/master/LICENSE "LICENSE").
|
|
129
|
-
|
package/bin/gt.js
CHANGED
|
@@ -7,11 +7,11 @@ const ora = require('ora');
|
|
|
7
7
|
const debug = require('debug');
|
|
8
8
|
const yargs = require('yargs');
|
|
9
9
|
const pkg = require('../package.json');
|
|
10
|
-
const {Proxy, config, getLogger} = require('../src/index.cjs');
|
|
10
|
+
const { Proxy, config, getLogger } = require('../src/index.cjs');
|
|
11
11
|
|
|
12
12
|
const logger = getLogger('cli');
|
|
13
13
|
|
|
14
|
-
const {argv} = yargs
|
|
14
|
+
const { argv } = yargs
|
|
15
15
|
.usage('Usage: green-tunnel [options]')
|
|
16
16
|
.usage('Usage: gt [options]')
|
|
17
17
|
.alias('help', 'h')
|
|
@@ -29,9 +29,15 @@ const {argv} = yargs
|
|
|
29
29
|
default: config.port,
|
|
30
30
|
})
|
|
31
31
|
|
|
32
|
+
.option('https-only', {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
describe: 'Block insecure HTTP requests',
|
|
35
|
+
default: config.httpsOnly,
|
|
36
|
+
})
|
|
37
|
+
|
|
32
38
|
.option('dns-type', {
|
|
33
39
|
type: 'string',
|
|
34
|
-
choices: ['https', 'tls'],
|
|
40
|
+
choices: ['https', 'tls', 'unencrypted'],
|
|
35
41
|
default: config.dns.type,
|
|
36
42
|
})
|
|
37
43
|
|
|
@@ -40,6 +46,16 @@ const {argv} = yargs
|
|
|
40
46
|
default: config.dns.server,
|
|
41
47
|
})
|
|
42
48
|
|
|
49
|
+
.option('dns-ip', {
|
|
50
|
+
type: 'string',
|
|
51
|
+
default: config.dns.ip,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
.option('dns-port', {
|
|
55
|
+
type: 'number',
|
|
56
|
+
default: config.dns.port,
|
|
57
|
+
})
|
|
58
|
+
|
|
43
59
|
.option('silent', {
|
|
44
60
|
alias: 's',
|
|
45
61
|
type: 'boolean',
|
|
@@ -104,10 +120,14 @@ async function main() {
|
|
|
104
120
|
const proxy = new Proxy({
|
|
105
121
|
ip: argv['ip'],
|
|
106
122
|
port: parseInt(argv['port'], 10),
|
|
123
|
+
httpsOnly: argv['https-only'],
|
|
107
124
|
dns: {
|
|
108
125
|
type: argv['dns-type'],
|
|
109
|
-
server: argv['dns-server']
|
|
110
|
-
|
|
126
|
+
server: argv['dns-server'],
|
|
127
|
+
ip: argv['dns-ip'],
|
|
128
|
+
port: argv['dns-port']
|
|
129
|
+
},
|
|
130
|
+
source: 'CLI',
|
|
111
131
|
});
|
|
112
132
|
|
|
113
133
|
const exitTrap = async () => {
|
|
@@ -130,12 +150,12 @@ async function main() {
|
|
|
130
150
|
process.on('unhandledRejection', errorTrap);
|
|
131
151
|
process.on('uncaughtException', errorTrap);
|
|
132
152
|
|
|
133
|
-
await proxy.start({setProxy: argv['system-proxy']});
|
|
153
|
+
await proxy.start({ setProxy: argv['system-proxy'] });
|
|
134
154
|
|
|
135
155
|
if (!argv['silent'] && !argv['verbose']) {
|
|
136
156
|
clear();
|
|
137
157
|
printBanner();
|
|
138
|
-
updateNotifier({pkg}).notify();
|
|
158
|
+
updateNotifier({ pkg }).notify();
|
|
139
159
|
printAlert(proxy);
|
|
140
160
|
showSpinner();
|
|
141
161
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "green-tunnel",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"HTTPS",
|
|
@@ -31,17 +31,19 @@
|
|
|
31
31
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"app-data-folder": "^1.0.0",
|
|
34
35
|
"chalk": "^2.4.2",
|
|
35
36
|
"clear": "^0.1.0",
|
|
36
37
|
"consola": "^2.11.0",
|
|
37
38
|
"debug": "^4.1.1",
|
|
38
39
|
"dns-over-http": "^0.1.2",
|
|
39
40
|
"dns-over-tls": "0.0.6",
|
|
41
|
+
"dns-socket": "^4.2.2",
|
|
40
42
|
"esm": "^3.2.22",
|
|
43
|
+
"is-docker": "^2.0.0",
|
|
41
44
|
"lru-cache": "^5.1.1",
|
|
42
45
|
"node-localstorage": "^2.1.5",
|
|
43
46
|
"ora": "^3.2.0",
|
|
44
|
-
"platform-folders": "^0.4.1",
|
|
45
47
|
"std-env": "^2.2.1",
|
|
46
48
|
"universal-analytics": "^0.4.20",
|
|
47
49
|
"update-notifier": "^2.5.0",
|
package/src/config.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
const config = {
|
|
2
2
|
ip: '127.0.0.1',
|
|
3
3
|
port: 8000,
|
|
4
|
+
httpsOnly: false,
|
|
4
5
|
clientHelloMTU: 100,
|
|
5
6
|
dns: {
|
|
6
|
-
type: 'https', // 'tls' or 'https'
|
|
7
|
+
type: 'https', // 'tls' or 'https' or 'unencrypted'
|
|
7
8
|
server: 'https://cloudflare-dns.com/dns-query',
|
|
9
|
+
ip: '127.0.0.1',
|
|
10
|
+
port: 53,
|
|
8
11
|
cacheSize: 1000,
|
|
9
12
|
}
|
|
10
13
|
};
|
package/src/dns/base.js
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import dnsSocket from 'dns-socket';
|
|
2
|
+
import BaseDNS from './base';
|
|
3
|
+
|
|
4
|
+
const socket = dnsSocket()
|
|
5
|
+
|
|
6
|
+
export default class DNSUnencrypted extends BaseDNS {
|
|
7
|
+
constructor(dnsIp, dnsPort) {
|
|
8
|
+
super();
|
|
9
|
+
this.dnsIp = dnsIp;
|
|
10
|
+
this.dnsPort = dnsPort;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
_lookup(hostname) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
socket.query({
|
|
16
|
+
questions: [{
|
|
17
|
+
type: 'A',
|
|
18
|
+
name: hostname
|
|
19
|
+
}]
|
|
20
|
+
}, this.dnsPort, this.dnsIp, (err, res, query) => {
|
|
21
|
+
resolve(res.answers[0].data);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/handlers/request.js
CHANGED
|
@@ -14,6 +14,8 @@ export default async function handleRequest(clientSocket, proxy) {
|
|
|
14
14
|
if (isStartOfHTTPRequest(strData)) {
|
|
15
15
|
if (isConnectMethod(strData)) {
|
|
16
16
|
await handleHTTPS(clientSocket, data, proxy);
|
|
17
|
+
} else if (proxy.config.httpsOnly) {
|
|
18
|
+
throw new Error('Insecure request blocked: ', strData);
|
|
17
19
|
} else {
|
|
18
20
|
await handleHTTP(clientSocket, data, proxy);
|
|
19
21
|
}
|
package/src/proxy.js
CHANGED
|
@@ -1,33 +1,38 @@
|
|
|
1
1
|
import net from 'net';
|
|
2
|
-
import {setProxy, unsetProxy} from './utils/system-proxy';
|
|
2
|
+
import { setProxy, unsetProxy } from './utils/system-proxy';
|
|
3
3
|
import handleRequest from './handlers/request';
|
|
4
4
|
import DNSOverTLS from './dns/tls';
|
|
5
5
|
import DNSOverHTTPS from './dns/https';
|
|
6
|
+
import DNSUnencrypted from './dns/unencrypted';
|
|
6
7
|
import config from './config';
|
|
7
8
|
import getLogger from './logger';
|
|
8
|
-
import {appInit} from './utils/analytics';
|
|
9
|
+
import { appInit } from './utils/analytics';
|
|
9
10
|
|
|
10
11
|
const logger = getLogger('proxy');
|
|
11
12
|
|
|
12
13
|
export default class Proxy {
|
|
13
14
|
constructor(customConfig) {
|
|
14
|
-
this.config = {...config, ...customConfig};
|
|
15
|
+
this.config = { ...config, ...customConfig };
|
|
15
16
|
this.server = undefined;
|
|
16
17
|
this.isSystemProxySet = false;
|
|
17
18
|
this.initDNS();
|
|
19
|
+
appInit(customConfig.source);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
initDNS() {
|
|
21
|
-
|
|
22
|
-
new DNSOverHTTPS(this.config.dns.server)
|
|
23
|
-
|
|
23
|
+
if (this.config.dns.type === 'https') {
|
|
24
|
+
this.dns = new DNSOverHTTPS(this.config.dns.server);
|
|
25
|
+
} else if (this.config.dns.type === 'tls') {
|
|
26
|
+
this.dns = new DNSOverTLS(this.config.dns.server);
|
|
27
|
+
} else {
|
|
28
|
+
this.dns = new DNSUnencrypted(this.config.dns.ip, this.config.dns.port);
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
async start(options = {}) {
|
|
27
|
-
appInit();
|
|
28
33
|
options.setProxy = options.setProxy === undefined ? false : options.setProxy;
|
|
29
34
|
|
|
30
|
-
this.server = net.createServer({pauseOnConnect: true}, clientSocket => {
|
|
35
|
+
this.server = net.createServer({ pauseOnConnect: true }, clientSocket => {
|
|
31
36
|
handleRequest(clientSocket, this).catch(err => {
|
|
32
37
|
logger.debug(String(err));
|
|
33
38
|
});
|
|
@@ -45,7 +50,7 @@ export default class Proxy {
|
|
|
45
50
|
this.server.listen(this.config.port, this.config.ip, () => resolve());
|
|
46
51
|
});
|
|
47
52
|
|
|
48
|
-
const {address, port} = this.server.address();
|
|
53
|
+
const { address, port } = this.server.address();
|
|
49
54
|
logger.debug(`server listen on ${address} port ${port}`);
|
|
50
55
|
|
|
51
56
|
if (options.setProxy) {
|
package/src/utils/analytics.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import ua from 'universal-analytics';
|
|
2
2
|
import uuid from 'uuid/v4';
|
|
3
3
|
import { JSONStorage } from 'node-localstorage';
|
|
4
|
-
import
|
|
4
|
+
import appData from 'app-data-folder';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import packageJson from '../../package.json'
|
|
7
|
+
import isDocker from 'is-docker';
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
const configFolder = path.join(getPath('appData'), 'greentunnel');
|
|
8
|
-
const nodeStorage = new JSONStorage(configFolder);
|
|
9
|
+
const nodeStorage = new JSONStorage(appData('greentunnel'));
|
|
9
10
|
const userId = nodeStorage.getItem('userid') || uuid();
|
|
10
11
|
nodeStorage.setItem('userid', userId);
|
|
11
12
|
|
|
12
13
|
var visitor = ua('UA-160385585-1', userId);
|
|
13
14
|
|
|
14
|
-
function appInit() {
|
|
15
|
-
|
|
15
|
+
function appInit(source = 'OTHER') {
|
|
16
|
+
const osPlatform = os.platform() + (isDocker() ? '-docker' : '')
|
|
17
|
+
|
|
18
|
+
visitor.set('version', packageJson.version);
|
|
19
|
+
visitor.set('os', osPlatform);
|
|
20
|
+
visitor.set('source', source);
|
|
21
|
+
|
|
22
|
+
visitor.event('gt-total', 'init').send();
|
|
23
|
+
visitor.event(`gt-${source}`, 'init').send();
|
|
24
|
+
visitor.event(`gt-${osPlatform}`, 'init').send();
|
|
25
|
+
visitor.event(`gt-${packageJson.version}`, 'init').send();
|
|
16
26
|
}
|
|
17
27
|
|
|
18
28
|
export {appInit};
|
|
@@ -24,6 +24,8 @@ class LinuxSystemProxy extends SystemProxy {
|
|
|
24
24
|
await exec('gsettings set org.gnome.system.proxy mode manual');
|
|
25
25
|
await exec(`gsettings set org.gnome.system.proxy.http host ${ip}`);
|
|
26
26
|
await exec(`gsettings set org.gnome.system.proxy.http port ${port}`);
|
|
27
|
+
await exec(`gsettings set org.gnome.system.proxy.https host ${ip}`);
|
|
28
|
+
await exec(`gsettings set org.gnome.system.proxy.https port ${port}`);
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
static async unsetProxy() {
|