How to force proxy for some domains/applications using PAC file on MacOS - Linux
In this post, I explain how I force selected domains and softwares to be passed through my proxy tunnel using pac file on MacOS (Linux too)
Hi there
Again me, faced another problem and I’m here to share my way to overcome this problem
Situation explained
Let me tell you…
Islamic Republic blocks different websites and several here and then; Discord is one of them.
Several month ago, I decided to find a solution to force my Discord app to use my proxy server (its local, by Clash or V2ray), I couldn’t find a proper way…
Today, I decided to do the same with several apps…. This ended up finding a solution for an old problem!
Solution
I signed up for Deepseek today 😂 and I decided to use it a little bit.
After searching, reading, testing, struggling and so on, I found out my solution is in learning .pac
file! (Notion AI help me 👇)
A PAC (Proxy Auto-Configuration) file is a JavaScript file that defines how web browsers and other user agents can automatically choose the appropriate proxy server for fetching a given URL. When implemented, a PAC file contains a JavaScript function called
FindProxyForURL
that determines whether requests should go directly to the destination or be forwarded to a proxy server. This functionality allows network administrators to implement sophisticated rules for routing traffic, such as using different proxies for internal versus external websites, or bypassing the proxy for specific domains. PAC files provide a flexible and efficient way to manage proxy settings across an organization or for individual use.
Setup
Okay…
I got a .pac
file content but it had a problem SOCKS5 127.0.0.1:2888
instead of SOCKS 127.0.0.1:2888
Then I found out MacOS does NOT support .pac
file as file
(instead of URL), so I have to load a python simple http server on localhost to serve the .pac
file
On the other hand, I had to make my local http server load automatically and reload on failure. For this purpose I know systemd
and its alternative in Linux, BUT MacOS? its my first time
After searching I realized MacOS’s LaunchAgents
is the exact stuff I want!, so I tried to set it up
.pac
file + a local http server
create a notion-proxy.pac
file:
1
2
3
4
5
6
7
8
9
10
function FindProxyForURL(url, host) {
// Check if the host is a Notion URL
if (shExpMatch(host, "*.example.com") || shExpMatch(host, "*.example.net") || shExpMatch(host, "*discord*") || dnsDomainIs(host, "check-host.net") || shExpMatch(host, "facebook.com") || dnsDomainIs(host, "discordapp.net")) {
// Proxy all Notion URLs through the SOCKS5 proxy
return "SOCKS 127.0.0.1:9999";
}
// Direct connection for all other URLs
return "DIRECT";
}
⚠️ You have to edit this file to seperate the tunneling process (the third line)
if (shExpMatch(host, "*.example.com") || shExpMatch(host, "*discord*") || dnsDomainIs(host, "check-host.net")) {
To find out more, google ‘.pac structure’
Then a pac.sh
file (bash script) to run the server
1
2
3
#!/bin/bash
python3 -m http.server -b 127.0.0.1 -d /path/to/pac/folder/ 1234
For security, I prefer to bind it to localhost
setup LaunchAgents
for automation
Now, its time for LaunchAgents
:
⚠️ Linux users, go with
systemd
,initd
or any other alternative
create a file using this command:
1
nano ~/Library/LaunchAgents/com.run.pac.server.plist
and its content is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- A unique identifier for the agent -->
<key>Label</key>
<string>com.run.pac.server</string>
<!-- Path to the script to run -->
<key>Program</key>
<string>/Library/Scripts/pac.sh</string>
<!-- Run the script at load -->
<key>RunAtLoad</key>
<true/>
<!-- Keep the job alive, restart on failure -->
<key>KeepAlive</key>
<true/>
<!-- Optional: Redirect stdout and stderr to log files -->
<key>StandardOutPath</key>
<string>/path/to/pac/folder/pac.log</string>
<key>StandardErrorPath</key>
<string>/path/to/pac/folder/pac-error.log</string>
<!-- Optional: Environment variables -->
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
</dict>
</plist>
Load this agent and then start it is not:
1
2
3
launchctl load ~/Library/LaunchAgents/com.run.pac.server.plist
launchctl start com.run.pac.server
Now, http://127.0.0.1:1234/notion-proxy.pac
is your PAC file address which you have to enter in “Network interface (Wifi, VPN, Lan, etc.) -> proxies -> Automatic proxy configuration ✔”
👋 Good Luck and text me for helping or asking