Excellent software and practical tutorials
The logic is simple. Find the chat.openai.com IP address and set the routing policy to skip the VPN interface. By default,WireGuard or OpenVPN 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
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.
Link/Target/Route | measure |
---|---|
chat.openai.com (or any other IP/domain of your choice) | 10 |
WireGuard/OpenVPN | 50 |
Breach of Contract | 100 |
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:
Voila. That’s all you can jump from to WireGuard or OpenVPN on Linux. ChatGPT 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