ProtonVPN_Privoxy_Docker

Image generated by StableDiffusionXL

TL;DR: Use protonvpn-cli-community, proton-privoxy to enjoy ProtonVPN’s reverse split tunneling feature. Or use vopono for having a dedicated browser routing through VPN.

Introduction

I only need to use VPN when connecting to api.openai.com. For all other traffic I don’t want to route through the VPN. Turned out it’s a feature called reverse split tunneling.

I use ProtonVPN. I’ll introduction 3 ways here: protonvpn-cli-community, proton-privoxy and vopono.

This guide is for the following crowd:

  1. Using a Linux machine
  2. Only require VPN to circumvent geoblocking like openai.com for using ChatGPT
  3. Don’t want to pay for ProtonVPN Plus (their browser extension has split-tunneling feature)

1. protonvpn-cli-community

Split tunneling is only available on Windows and Android (ref), and not supported for the official Linux CLI:

[T]he new Proton VPN CLI doesn’t support Split Tunneling and doesn’t run on headless servers. (ref)

I found a community CLI linux-cli-community, but it 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.

2. proton-privoxy

This is the method I use.

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=udp
      - 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

I have a forked of jackMort/ChatGPT.nvim: kohane27/ChatGPT.nvim. I have added only the following two lines to api.lua:

"--proxy",
"http://127.0.0.1:8888",

api.lua:

    Api.exec(
      "curl",
      {
        "--proxy",
        "http://127.0.0.1:8888",
        "--silent",
        "--show-error",
        "--no-buffer",
        Api.CHAT_COMPLETIONS_URL,
        "-H",
        "Content-Type: application/json",
        "-H",
        "Authorization: Bearer " .. Api.OPENAI_API_KEY,
        "-d",
        vim.json.encode(params),
      },
    )

Such that when I use ChatGPT.nvim, it’s routed through ProtonVPN.

3. 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 three methods works for you!