The process of skipping ChatGPT from WireGuard or OpenVPN on Linux

The logic is simple. Find the chat.openai.com IP address and set the routing policy to skip the VPN interface. By default, or All traffic will be routed through the VPN interface, but I will set the metrics lower than the WireGuard or OpenVPN interface and route chat.openai.com traffic directly through my router instead of the VPN. My setup is as follows:

  • Debian or Ubuntu Linux Desktop
  • WireGuard or OpenVPN on Linode or AWS
  • Default router IPv4: 192.168.2.254
Notice:Enter these commands on the Linux WireGuard VPN client, not on the WireGuard Linux server. In other words, this only works on Linux desktop operating systems, not macOS or Windows 10/11 desktops.

Step 1 – Find the default route information

Once connected to WireGuard/OpenVPN, use the ip command to list the routing table:

This is what I see:ip route show

default via 192.168.2.254 dev enp0s31f6 proto dhcp metric 100 10.83.200.0/24 dev lxdbr0 proto kernel scope link src 10.83.200.1 169.254.0.0/16 dev ln-sg scope link metric 1000 172.16.0.0/24 dev ln-sg proto kernel scope link src 172.16.0.6 metric 50 192.168.2.0/24 dev enp0s31f6 proto kernel scope link src 192.168.2.25 metric 100

 

My WireGuard interface named “ln-sg” uses metric 50 over the default metric 100. So the trick is to add the chat.openai.com IP address with a lower metric, passing directly through the 192.168.2.254 default gateway IP address.

Description of the automatic metrics feature for IPv4 routing

Router MetricsIs a configuration value used to make routing decisions. Router metrics help routers choose the best route among multiple possible routes to a destination. Routes will go in the direction of the gateway with the lowest metric. Router metrics are typically based on information such as path length, bandwidth, load, number of hops, path cost, latency, maximum transmission unit (MTU), reliability, and communication cost.

Table 1: The following table summarizes
The conditions my Linux desktop uses to assign metrics to routes
Link/Target/Routemeasure
chat.openai.com (or any other IP/domain of your choice)10
WireGuard/OpenVPN50
Breach of Contract100

Step 2 – Find the chat.openai.com IP address

Use the dig command or the host command:

$ d='chat.openai.com' $ dig +short A "$d" | grep -v '\.$' $ ips="$(dig +short A "$d" | grep -v '\.$')" $ echo "$ips"

Step 3 – Add chat.openai.com IP address to the routing table

Let's set some shell variables:

Let's use a bash for loop to add these IPs:my_gw="192.168.2.254" #Default GW
metric="10" #Routing metric value

for i in $ips do sudo ip route add "$i" via "$my_gw" metric "$metric" done

Want to list newly added IP addresses? Use the ip command:

This is what I see:

$ ip route show $ ip route show | grep -w 'metric 10'

 

104.18.2.161 via 192.168.2.254 dev enp0s31f6 metric 10 104.18.3.161 via 192.168.2.254 dev enp0s31f6 metric 10 

Step 4 – Testing

Launch a web browser and access https://chat.openai.com/ URL to test:

The process of skipping ChatGPT from WireGuard or OpenVPN on Linux

click to enlarge

Voila. That’s all you can jump from to WireGuard or OpenVPN on Linux. Domain method.

 

Step 5 – Remove the chat.openai.com IP address from the routing table

Use the ip command again as follows:
for i in $ips; do sudo ip route del "$i"; done

Step 6 – Create a shell script for automation

chat.openai.com will change its IP address from time to time. So here is a general script to add, remove and list the chat.openai.com domain and some other domains that refuse to work when connected to a VPN.

routing.policy shell script

#!/bin/bash # routing.policy - Main script to add, remove and list routing policy # Author : Vivek Gite {www.cyberciti.biz} under GPLv 2.x+ # ------------------------------------------------------------------------------- set -e # Set metric and gateway as per your needs metric="10" my_gw="192.168.2.254" domain="chat.openai.com facebook.com fbcdn.net static.xx.fbcdn.net www.facebook.com" ips="" me="${0##*/}" # who am I? get_domain_ip_lists(){ for d in $domain do ips="${ips} $(dig +short A "$d" | grep -v '\.$')" done ips="${ips/$'\n'/ }" # remove '\n' ips="$(tr ' ' '\n'<<<"${ips}" | sort -u | check_for_root_user echo "Adding ${ips/$'\n'/,} to routing table ..." 1>&2 for i in $ips do if ! is_route_exists "$i" then sudo ip route add "$i" via "$my_gw" metric "$metric" else echo "$me route for $i already exists, skipping..." fi done } remove_opneapi_route(){ check_for_root_user echo "Removing ${ips/$'\n'/,} from routing table ..." 1>&2 for i in $ips do if is_route_exists "$i" then sudo ip route del "$i" via "$my_gw" else echo "$me route for $i not found, skiping ..." fi done } show_openapi_route_status(){ echo "Routing info for the '$domain' (${ips/$'\n'/,}) ..." # remove newline from the ${ips} for i in $ips do ip route show "$i" done } check_for_root_user(){ if [[ $EUID-ne 0 ]]; then echo "$me script must be run as root" 1>&2 exit 1 fi } ## main ## get_domain_ip_lists # set '$ips' case "$me" in routing.policy.add) add_opneapi_route;; routing.policy.delete) remove_opneapi_route;; routing.policy.remove) remove_opneapi_route;; routing.policy.show) show_openapi_route_status;; routing.policy.status) show_openapi_route_status;; *) echo "Usage: routing.policy.add|routing.policy.delete|routing.policy.status";;

 

Use the ln command to create a soft link

First, use the chmod command
Set execute permissions Now set these links:

Use the ls command to verify:

Output:chmod +x -v routing.policy
mode of 'routing.policy' changed from 0664 (rw-rw-r--) to 0775 (rwxrwxr-x)
ln -sv routing.policy routing.policy.add
ln -sv routing.policy routing.policy.remove
ln -sv routing.policy routing.policy.delete
ln -sv routing.policy routing.policy.show
ln -sv routing.policy routing.policy.status
ls -l routing.policy*

-rwxrwxr-x 1 vivek vivek 1913 Feb 3 00:07 routing.policy lrwxrwxrwx 1 vivek vivek 14 Feb 3 00:08 routing.policy.add -> routing.policy lrwxrwxrwx 1 vivek vivek 14 Feb 3 00:08 routing.policy.delete -> routing.policy lrwxrwxrwx 1 vivek vivek 14 Feb 3 00:08 routing.policy.remove -> routing.policy lrwxrwxrwx 1 vivek vivek 14 Feb 3 00:08 routing.policy.show -> routing.policy lrwxrwxrwx 1 vivek vivek 14 Feb 3 00:08 routing.policy.status -> routing.policy

Test it out:
sudo ./routing.policy.add
sudo ./routing.policy.status
traceroute chat.openai.com #<--test routing
sudo ./routing.policy.delete

Summarize

I tested it with WireGuard and OpenVPN on my Debian and Ubuntu Linux desktops. It works like a charm and should work with any other Linux distribution as long as the ip command works. In a nutshell, we can skip routing specific IP addresses through VPN connections on Linux (or any other OS like macOS or BSD) as long as you can add routing rules to the system’s routing table. You can automatically run this script when NetworkManager connects to your OpenVPN or WireGuard interface by adding a hook. For example, place the script in /etc/network/if-up.d/ and make it executable. This will run the script when the VPN interface comes online. Similarly, when you want to run the script when the VPN interface is down, place the script in /etc/network/if-down.d/. Refer to the NetworkManager man page using the man command:
man 8 NetworkManager

1/5 - (3 votes)

Leave a Reply

Your email address will not be published. Required fields are marked *