Image generated by StableDiffusionXL
Reverse split tunneling:
- ProtonVPN with WireGuard <– what I current use
- proton-privoxy <– what I used but broke one day
- forked protonvpn-cli-community
Bonus: A dedicated app like browser/terminal routing through VPN: vopono
Introduction
I use ProtonVPN when connecting to api.openai.com. For all other traffic, I don’t want need a VPN. Turned out it’s a feature called reverse split tunneling. This feature is only available on Windows and Android (ref), and not supported for the official Linux CLI (ref). I’ll introduction 3 ways to do this as mentioned above.
This guide is for the following target audience:
- Only use VPN for a handful of traffic like openai.com for using GPT-4
- Overkill for ProtonVPN Plus (their browser extension has the split-tunneling feature)
1. ProtonVPN with WireGuard
This is the method I use.
Follow the official guide How to download WireGuard configuration files.
Install WireGuard:
sudo pacman -S wireguard-tools
- Create a new WireGuard configuration file:
sudo vim /etc/wireguard/wg0.conf
- Paste the downloaded ProtonVPN WireGuard configuration file content
[Interface]
PrivateKey = ****
Address = 10.2.0.2/32
DNS = 10.2.0.1
[Peer]
PublicKey = ****
AllowedIPs = 104.18.6.192/32, 104.18.7.192/32, 104.16.154.36/32, 104.16.155.36/32
Endpoint = ***.***
Modify the line AllowedIPs
for the traffic to be routed through WireGuard.
104.18.6.192/32
and104.18.7.192/32
are api.openai.com104.16.154.36/32
and104.16.155.36/32
are whatismyipaddress.com (for testing)
- Start the WireGuard interface:
sudo wg-quick up wg0
Verified the traffic is routed through WireGuard
:
➜ ip route get 104.18.6.192
104.18.6.192 dev wg0 src 10.2.0.2 uid 1000
10.2.0.2
is the proof that the traffic is routed through ProtonVPN (ref).
Use systemd
to automatically start the WireGuard interface on system boot:
systemctl enable wg-quick@wg0.service
2. proton-privoxy
docker-compose.yml
:
version: "3"
services:
proton-privoxy:
image: walt3rl/proton-privoxy
container_name: proton-privoxy
environment:
- PVPN_USERNAME=username
- PVPN_PASSWORD=password
- PVPN_TIER=0
- PVPN_PROTOCOL=tcp
- PVPN_DEBUG=1
- PVPN_CMD_ARGS=connect US-FREE-52
volumes:
- /etc/localtime:/etc/localtime:ro
ports:
- 8888:8080
restart: unless-stopped
devices:
- /dev/net/tun
cap_add:
- NET_ADMIN
For the field PVPN_CMD_ARGS
, it took me some time to figure out that you can’t put double quotes around the value (i.e., PVPN_CMD_ARGS="connect US-FREE-52"
doesn’t work).
To run it:
docker-compose down && docker-compose up -d && docker-compose logs -f
To test, run curl --proxy http://127.0.0.1:8888 ifconfig.co/json
and you should see your VPN info. Any traffic with curl --proxy http://127.0.0.1:8888
will route through the VPN.
If you want to add request logs to make sure requests are routed through proton-privoxy
, see #42.
proton-privoxy with ChatGPT.nvim
If you’re using jackMort/ChatGPT.nvim, you can add the following line:
extra_curl_params = { "--proxy", "http://127.0.0.1:8888" },
This way, ChatGPT.nvim
will route through protonvpn
.
3. protonvpn-cli-community
The linux-cli-community doesn’t support reverse split tunneling: #230. Luckily, there is a fork that implements it (Thanks jonasjancarik!).
Installation
git clone https://github.com/jonasjancarik/protonvpn-cli-community.git
cd protonvpn-cli-community
pipx install -e .
Create ~/.pvpn-cli/pvpn-cli.cfg
:
[USER]
username = your/username/here
tier = 0
default_protocol = tcp
initialized = 1
dns_leak_protection = 1
custom_dns = None
check_update_interval = 3
api_domain = https://api.protonvpn.ch
killswitch = 0
ignore_ping_restart = 0
ping = 0
ping_exit = 0
split_tunnel = 1
split_type = whitelist
The last 5 fields are specific to this fork.
split_type = whitelist
is using the reverse split tunneling feature. For help, run sudo protonvpn --help
Create ~/.pvpn-cli/split_tunnel.txt
and add the following:
104.18.6.192
104.18.7.192
104.16.154.36
104.16.155.36
The first 2 values are for api.openai.com. The last 2 are whatismyipaddress.com for testing (i.e., ensure that the traffic on this list are really routed through ProtonVPN).
Run sudo protonvpn refresh
to update your config.
Let’s try connecting:
sudo protonvpn c JP-FREE-01 -p TCP
To test, go to whatismyipaddress.com and you should see you’re located in Japan. Go to whatismyip.com and you should see your real IP address.
Therefore, only the entries in ~/.pvpn-cli/split_tunnel.txt
are routed through ProtonVPN.
You can create a systemd
service to run the above command on startup.
4. Bonus: vopono
This is perfect if you use VPN only in an isolate browser, i.e., firefox without VPN and ungoogled-chromium with VPN. After following the installation and setup, run the following to use Chrome to establish a ProtonVPN connection to Japan:
vopono -v exec --firewall iptables --provider protonvpn --server japan "chromium"
I need the flag --firewall iptables
or else it doesn’t work for me. ymmv.
Conclusion
Hopefully at least one of the above methods works for you:)