You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+101Lines changed: 101 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,6 +24,9 @@ Dumbest HTTP proxy ever.
24
24
* Resilient to DPI (including active probing, see `hidden_domain` option for authentication providers)
25
25
* Connecting via upstream HTTP(S)/SOCKS5 proxies (proxy chaining)
26
26
* systemd socket activation
27
+
* Scripting with JavaScript:
28
+
* Access filter by JS function
29
+
* Upstream proxy selection by JS function
27
30
28
31
## Installation
29
32
@@ -175,6 +178,96 @@ Authentication parameters are passed as URI via `-auth` parameter. Scheme of URI
175
178
*`blacklist` - location of file with list of serial numbers of blocked certificates, one per each line in form of hex-encoded colon-separated bytes. Example: `ab:01:02:03`. Empty lines and comments starting with `#` are ignored.
176
179
*`reload` - interval for certificate blacklist file reload, if it was modified since last load. Use negative duration to disable autoreload. Default: `15s`.
177
180
181
+
## Scripting
182
+
183
+
With the dumbproxy, it is possible to modify request processing behaviour using simple scripts written in the JavaScript programming language.
184
+
185
+
### Access filter by JS script
186
+
187
+
It is possible to filter (allow or deny) requests with simple `access` JS function. Such function can be loaded with the `-js-access-filter` option. Option value must specify location of script file where `access` function is defined.
188
+
189
+
`access` function is invoked with following parameters:
190
+
191
+
1.**Request***(Object)*. It contains following properties:
192
+
***method***(String)* - HTTP method used in request (CONNECT, GET, POST, PUT, etc.).
193
+
***url***(String)* - URL parsed from the URI supplied on the Request-Line.
194
+
***proto***(String)* - the protocol version for incoming server requests.
195
+
***protoMajor***(Number)* - numeric major protocol version.
196
+
***protoMinor***(Number)* - numeric minor protocol version.
197
+
***header***(Object)* - mapping of *String* headers (except Host) in canonical form to an *Array* of their *String* values.
198
+
***contentLength***(Number)* - length of request body, if known.
199
+
***transferEncoding***(Array)* - lists the request's transfer encodings from outermost to innermost.
200
+
***host***(String)* - specifies the host on which the URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this is either the value of the "Host" header or the host name given in the URL itself. For HTTP/2, it is the value of the ":authority" pseudo-header field.
201
+
***remoteAddr***(String)* - client's IP:port.
202
+
***requestURI***(String)* - the unmodified request-target of the Request-Line (RFC 7230, Section 3.1.1) as sent by the client to a server.
203
+
2.**Destination address***(Object)*. It's an address where actual connection is about to be created. It contains following properties:
204
+
***network***(String)* - connection type. Should be `"tcp"` in most cases unless restricted to specific address family (`"tcp4"` or `"tcp6"`).
205
+
***originalHost***(String)* - original hostname or IP address parsed from request.
206
+
***resolvedHost***(String)* - resolved hostname from request.
207
+
***port***(Number)* - port number.
208
+
3.**Username***(String)*. Name of the authenticated user or an empty string if there is no authentication.
209
+
210
+
`access` function must return boolean value, `true` allows request and `false` forbids it. Any exception will be reported to log and the corresponding request will be denied.
211
+
212
+
Also it is possible to use builtin `print` function to print arbitrary values into dumbproxy log for debugging purposes.
213
+
214
+
Example:
215
+
216
+
```js
217
+
// Deny unsafe ports for HTTP and non-SSL ports for HTTPS.
218
+
219
+
constSSL_ports= [
220
+
443,
221
+
]
222
+
constSafe_ports= [
223
+
80, // http
224
+
21, // ftp
225
+
443, // https
226
+
70, // gopher
227
+
210, // wais
228
+
280, // http-mgmt
229
+
488, // gss-http
230
+
591, // filemaker
231
+
777, // multiling http
232
+
]
233
+
consthighPortBase=1025
234
+
235
+
functionaccess(req, dst, username) {
236
+
if (req.method=="CONNECT") {
237
+
if (SSL_ports.includes(dst.port)) returntrue
238
+
} else {
239
+
if (dst.port>= highPortBase ||Safe_ports.includes(dst.port)) returntrue
240
+
}
241
+
returnfalse
242
+
}
243
+
```
244
+
245
+
### Upstream proxy selection by JS script
246
+
247
+
dumbproxy can select upstream proxy dynamically invoking `getProxy` JS function from file specified by `-js-proxy-router` option.
248
+
249
+
Note that this option can be repeated multiple times, same as `-proxy` option for chaining of proxies. These two options can be used together and order of chaining will be as they come in command line. For generalization purposes we can say that `-proxy` option is equivalent to `-js-proxy-router` option with script which returns just one static proxy.
250
+
251
+
`getProxy` function is invoked with the [same parameters](#access-filter-by-js-script) as the `access` function. But unlike `access` function it is expected to return proxy URL in string format *scheme://[user:password@]host:port* or empty string `""` if no additional upstream proxy needed (i.e. direct connection if there are no other proxy dialers defined in chain).
252
+
253
+
Supported proxy schemes are:
254
+
*`http` - regular HTTP proxy with the CONNECT method support.
255
+
*`https` - HTTP proxy over TLS connection.
256
+
*`socks5`, `socks5h` - SOCKS5 proxy with hostname resolving via remote proxy.
257
+
258
+
Example:
259
+
260
+
```js
261
+
// Redirect .onion hidden domains to Tor SOCKS5 proxy
262
+
263
+
functiongetProxy(req, dst, username) {
264
+
if (dst.originalHost.replace(/\.$/, "").toLowerCase().endsWith(".onion")) {
265
+
return"socks5://127.0.0.1:9050"
266
+
}
267
+
return""
268
+
}
269
+
```
270
+
178
271
## Synopsis
179
272
180
273
```
@@ -224,6 +317,14 @@ Usage of /home/user/go/bin/dumbproxy:
224
317
sign username with specified key for given validity period. Positional arguments are: hex-encoded HMAC key, username, validity duration.
225
318
-ip-hints string
226
319
a comma-separated list of source addresses to use on dial attempts. "$lAddr" gets expanded to local address of connection. Example: "10.0.0.1,fe80::2,$lAddr,0.0.0.0,::"
320
+
-js-access-filter string
321
+
path to JS script file with the "access" filter function
322
+
-js-access-filter-instances int
323
+
number of JS VM instances to handle access filter requests (default 4)
324
+
-js-proxy-router value
325
+
path to JS script file with the "getProxy" function
326
+
-js-proxy-router-instances int
327
+
number of JS VM instances to handle proxy router requests (default 4)
0 commit comments