Practical automatic proxy configuration example

Automatic proxy access to the Internet is a relatively common requirement. For example, many test engineers need to configure a proxy when they use Charles to capture packets. Common browser plug-ins such as Proxy SwitchyOmega and so on are actually convenient for you to set up a proxy.

This article mainly talks about automatic proxy configuration. After the configuration yesterday, it is indeed very convenient and practical. It may be useful to readers, please share it.

First read the Wikipedia explanation and extract the core parts.

Proxy auto-config (English: Proxy auto-config, referred to as PAC) is a web browser technology that is used to define how the browser automatically selects an appropriate proxy server to access a URL.

A PAC file contains a JavaScript function "FindProxyForURL(url, host)", which returns a string containing one or more access rules. User agents use a specific proxy or access directly based on these rules, which are also prioritized. When access cannot be achieved using high-priority rules, low-priority access rules (if they exist) provide an alternative access method. Before the browser accesses the web page, it will first access this PAC file. The URL in the PAC file may be manually configured, or it may be automatically configured through the network proxy automatic discovery protocol of the web page.

Without further ado, let’s go directly to the pac code:

 1mephisto@RMBP ~/gfw> cat proxy.pac
 2function FindProxyForURL(url, host) {
 3
 4     var _http = 'PROXY 192.168.18.193:1081';
 5
 6     if (shExpMatch(host, '*.v2ex.com')) { return _http; }
 7     if (shExpMatch(host, '*.google.com')) { return _http; }
 8     if (shExpMatch(host, '*.gmail.com')) { return _http; }
 9     if (shExpMatch(host, '*.google.co.jp')) { return _http; }
10     if (shExpMatch(host, '*..googleusercontent.com')) { return _http; }
11     if (shExpMatch(host, '*.googleusercontent.com')) { return _http; }
12     if (shExpMatch(host, '*.googleapis.com')) { return _http; }
13     if (shExpMatch(host, '*.github.com')) { return _http; }
14     if (shExpMatch(host, '*.githubassets.com')) { return _http; }
15     if (shExpMatch(host, '*.githubusercontent.com')) { return _http; }
16     if (shExpMatch(host, '*.youtube.com')) { return _http; }
17     if (shExpMatch(host, '*.inkscape.org')) { return _http; }
18     if (shExpMatch(host, '*.bootstrapcdn.com')) { return _http; }
19     if (shExpMatch(host, '*.reddit.com')) { return _http; }
20     if (shExpMatch(host, '*.openvpn.net')) { return _http; }
21     if (shExpMatch(host, '*.wikipedia.org')) { return _http; }
22     if (shExpMatch(host, '*.wikimedia.org')) { return _http; }
23     if (shExpMatch(host, '*.medium.com')) { return _http; }
24     if (shExpMatch(host, '*.web.dev')) { return _http; }
25     if (shExpMatch(host, '*.openai.com')) { return _http; }
26     if (shExpMatch(host, '*.googleadservices.com')) { return _http; }
27     if (shExpMatch(host, '*.gstaic.com')) { return _http; }
28     if (shExpMatch(host, '*.ycombinator.com')) { return _http; }
29     if (shExpMatch(host, '*.ytimg.com')) { return _http; }
30     if (shExpMatch(host, '*.ggpht.com')) { return _http; }
31     if (shExpMatch(host, '*.googlevideo.com')) { return _http; }
32     if (shExpMatch(host, '*.x.com')) { return _http; }
33     if (shExpMatch(host, '*.twitter.com')) { return _http; }
34     if (shExpMatch(host, '*.twimg.com')) { return _http; }
35     if (shExpMatch(host, '*.hysteria.network')) { return _http; }
36     if (shExpMatch(host, '*.facebook.com')) { return _http; }
37     if (shExpMatch(host, '*.instagram.com')) { return _http; }
38
39     return 'DIRECT';
40   }

The code above isn't pretty, it's a bit ugly, but it works! If you are a germaphobe, you can change it yourself. The simple explanation is to match the target URL and use http proxy 192.168.18.193:1081. Others can be accessed directly without using a proxy.

What is the function of this? I think you can understand it by looking at the website address.

I have introduced the pac file, and of course I will also talk about how to set up a local proxy. I have written about server-side proxies before. Please search for related articles on my personal website.

1. Agency service

 1mephisto@RMBP ~/gfw> pwd
 2/Users/mephisto/gfw
 3mephisto@RMBP ~/gfw> ls
 4OmegaProfile_auto_switch.pac config.yaml hysteria-darwin-amd64* proxy.pac
 5mephisto@RMBP ~/gfw> cat config.yaml
 6server: stock.mephisto.cc:443
 7
 8auth: your_passwd
 9
10bandwidth:
11   up: 20mbps
12   down: 100mbps
13
14tls:
15   insecure: true
16
17
18socks5:
19   listen: 127.0.0.1:1080
20
21http:
22   listen: 0.0.0.0:1081
23mephisto@RMBP ~/gfw> ./hysteria-darwin-amd64 -c config.yaml
242024-04-25T17:07:17+08:00 INFO client mode
252024-04-25T17:07:18+08:00 INFO connected to server {"udpEnabled": true, "tx": 2500000, "count": 1}
262024-04-25T17:07:18+08:00 INFO HTTP proxy server listening {"addr": "0.0.0.0:1081"}
272024-04-25T17:07:18+08:00 INFO SOCKS5 server listening {"addr": "127.0.0.1:1080"}
282024-04-25T17:07:21+08:00 INFO update available {"version": "v2.4.1", "url": "https://github.com/apernet/hysteria/releases", "urgent" : false}

I operate on a Mac, so that I can start a hysteria client agent locally. Use different protocols, one is socks5 and one is http. For http, I chose full network card monitoring. It is convenient to connect other devices at home, and socks5 is used by Mac itself.

1mephisto@RMBP ~> ip a
2lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
3         inet 127.0.0.1/8 lo0
4         inet6::1/128
5         inet6 fe80::1/64 scopeid 0x1
6en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
7         ether 34:36:3b:c6:68:b6
8         inet6 fe80::1462:852a:9b96:efa2/64 secured scopeid 0x4
9         inet 192.168.18.193/24 brd 192.168.18.255 en0

Since the IP assigned to my local machine is 192.168.18.193, the corresponding http proxy is 192.168.18.193:1081.

In fact, you can also find a router or a Raspberry Pi to run it, assign a fixed IP, or even make a local dnsmasq and bind it to a custom domain name. Of course, that would be complicated. This article is mainly written for non-experts.

2. Configure automatic proxy

On Mac, I usually use the browser plug-in Proxy SwitchyOmega to configure the socks5 proxy. There are many tutorials on the Internet for this part, so I won’t go into details here. Mainly surfing the Internet to meet personal needs.

Configure automatic proxy on iPhone or iPad:

Click this place to enter the wifi settings. There is a section for http proxy settings at the bottom.

wifi settings

Fill in the download address of the pac file.

pac settings

Careful readers may ask where this download address came from. Don’t worry, read below.

3. Start a static file server on this machine

Here I use dufs, a rust tool, to provide static file download services (I personally like this gadget).

Of course you can use Nginx, Apache, even python3 -m http.sever, or other gadgets.

1mephisto@RMBP ~/gfw> dufs proxy.pac
2Listening on:
3   http://127.0.0.1:5000/
4   http://192.168.18.193:5000/
5   http://[::1]:5000/

It is worth mentioning that:

Although most modern clients will correctly handle whatever MIME type is returned from the HTTP request, for completeness and best compatibility, we should set the web server to declare the MIME type of this file as application/x -ns-proxy-autoconfig or application/x-javascript-config. (application/x-ns-proxy-autoconfig is supported by more clients than application/x-javascript-config because it was originally defined in the Netscape specification, and the latter has only recently begun to be used.)

When I actually use dufs, iPhone and iPad can be used normally without setting MIME. I have not tested other systems or hardware.

4. Finally

The access link is like this.

Your mobile device--》http automatic proxy--》Local hysteria client--》Overseas hysteria server--》Free World Internet

This way you don’t even need to download additional software for your mobile device. Of course, the premise is that you use a Wi-Fi network. For mobile networks, you still need to use software such as Small Plane. There is no way to set http proxy on mobile networks such as 4G/5G.

Please believe me, using this pac method directly to access Google, Twitter, etc. is really very fast. After all, there is no performance loss of intermediate software. The same server, small planes and other daisy transfers, this is very smooth!

Later, I want to run the client on my gray Raspberry Pi, plug the Raspberry Pi into the router at home, and configure a fixed IP. Then configure the entire dnsmasq with an intranet domain name, which is more convenient and does not need to remember various IPs.

Of course, Ubuntu/Mac OS/Windows, etc. can configure global http proxy. I usually only play on my mobile phone or pad, and don’t turn on my computer very much when I go home. So I just configure the proxy in the browser, which is enough for me.

Lastmod: Thursday, April 25, 2024

See Also:

Translations: