4

I want to route around openvpn for a specific domain. I have tried:

allow-pull-fqdn
route specificdomain.com 255.255.255.255 net_gateway

But this simply does a DNS lookup of the domain and adds whatever IP it gets to the routing table to use a default route.

The problem is, the specific domain has multiple IP addresses, and they don't seem to be on a simple network that I could just use a netmask for.

I've also tried to:

push "route specificdomain.com 255.255.255.255 net_gateway"

Though I confess from reading the docs I still haven't figured out what the difference is - though here it doesn't show up in my routing table and it doesn't work (even if I use a domain with a single IP address)

Is there a way to get openvpn to not route domains with multiple IP addresses like this, or is it too late in the routing for openvpn to know what the domain was that we were initially requesting and my best bet is to try to come up with a collection of IP addresses that currently match the domain?

  • May I ask what you'd like to accomplish? None of routers I heard of will allow to do such things (cisco, linux, mikrotik, freebsd, windows). I don't count scripting. – Michal Sokolowski Jun 24 '16 at 0:27
  • I'd like to accomplish not using my VPN for specific domains - isn't that clear in the question? The reason is because I use a VPN for most of my traffic, but some websites forbid connections from serverfarms such as where my VPN is hosted, so I want to make an exception for those domains. – David Ljung Madison Stellar Jun 24 '16 at 2:47
  • I thought about lots of different reasons, this one was not on the top of list. There's no such functionality in the OpenVPN itself, you need to use IP blocks instead (so called prefixes), you can use BGP AS number for this - check it out: bgp.he.net/AS15169#_prefixes. Or write some script on the client, which would check DNS cache and update routing table accordingly. OpenVPN server cannot be aware what is inside DNS Client cache or how local DNS server resolve that name. Are you aware that google.com can be resolved for different addresses from EU and Europe? ... – Michal Sokolowski Jun 24 '16 at 11:12
  • Results can differ even between ISPs in the same country... – Michal Sokolowski Jun 24 '16 at 11:12
  • 1
    I do not see anything usable instead using prefixes/IP blocks, moreover, sites like google requires a looot of different domains to work like gstatic.*, gmail.* etc... IP block classification is way easier to implement IMHO. Some AS -> IP Blocks -> use gateway. – Michal Sokolowski Jun 24 '16 at 17:56
4

What you want is, sadly, impossible. Routing works based on IP addresses, and the domain name simply isn't present in the IP packets, so it cannot be used to make routing decisions.

When adding routes, you can add a route to a specific domain name, but that name gets DNS resolved into an IP address before it is added to the routing table. Also note that your routing table will not get updated if the IP address in the DNS entry changes.

Basically your options are:

1: at VPN startup, add a route to all the specific host names that you are going to access without VPN. The names will immediately get resolved, but that might not matter, unless the IP addresses change really quickly.

2: figure out all the netblocks that the target domain uses and setup routing without VPN for them. In some cases it is impossible to figure the netblocks out, though.

3: reverse your routing logic: drop the "route everything through vpn" rule, only route specific netblocks through vpn (you are more likely to know these than the netblocks of a specific domain you don't control), and let the default route take all non-vpn traffic to the internet without vpn.

| improve this answer | |
  • 2
    Doesn't the VPN have to do the DNS resolution for any domains before figuring out how to route them? In other words, isn't this technically feasible to be handled by the VPN software? – David Ljung Madison Stellar Sep 28 '17 at 21:02
  • The DNS resolution is done by the client (say, firefox or an ssh client), before sending any packets. The decision of whether to route any packets to the VPN tunnel(s) is made by the OS kernel when the packets are actually sent, and at that phase, the DNS name is no longer known. When a VPN client starts, it first sets up a secure (IPsec) tunnel to the VPN provider, and then tells the OS to route certain netblocks through the tunnel. When running, the VPN client doesn't usually take part in DNS or routing. – Bass Sep 30 '17 at 8:51
  • Yes, but that DNS resolution (unless it's cached) will go through the network and hence the VPN tunnel. A clever VPN tunnel could see the DNS request for google, note the IP address that is returned, and then intelligently route it accordingly. – David Ljung Madison Stellar Oct 2 '17 at 4:50
  • 1
    At the VPN startup, setting up an alternate nameserver is a standard procedure, so you wouldn't even have to snoop the traffic; you can just tell the OS to use your own, hacked-together resolver that does routing magic as a side effect of DNS resolution. Just to be clear, that is not a very good idea, since choppy DNS (a likely result of adding any such magic) is at least as much a nuisance than having to manually add missing routes every now and then. – Bass Oct 2 '17 at 5:20
0

As others explained, in theory this is impossible, because routing does not know the destination DNS name that was used to obtain destination IP address. However, you can do what @Bass described as "chopped" DNS. First, set up your own DNS (I use Raspberry Pi as VPN router, so I have all benefits of Linux, I advise you don't do it on your Windows workstation :). Use dnsmasq with DHCP disabled, and at first, set it up as pure caching DNS server, with the dnsmasq.conf as follows:

log-queries          # Logging
log-async            # Async logging    
domain-needed        # Don't forward short names
bogus-priv           # Never forward addresses in the non-routed address spaces.
server=8.8.8.8       # Use Google DNS 1 upstream
server=8.8.4.4       # Use Google DNS 2 upstream

After you manage to force your own DNS to the machines (desktops and other stuff, e.g. chromecast, tv, etc), and confirm it is working, you can start hacking away. Run the program/app or access the website you want to redirect, and then on the routing machine you do:

sudo killall -SIGUSR1 dnsmasq
tail /var/log/syslog

Now you have nice dump of recently accessed IP addresses along with their names (any decent application will try to access DNS, I believe no one would hard-code IPs any more).

Now you restart dnsmasq or the routing machine (just to be sure to clear the cache) and force access to google DNS which bypasses the OpenVPN, e.g. by doing something like this:

sudo route add -net 8.8.8.8 netmask 255.255.255.255 gw 192.168.1.1 dev eth0
sudo route add -net 8.8.4.4 netmask 255.255.255.255 gw 192.168.1.1 dev eth0

Just to be clear, the eth0 is the network interface that goes to my internet provider, and 192.168.1.1 is the gateway address which bypasses the VPN. Now you repeat the exercise with starting the app/website/device and dumping the names and IP numbers. They should be different now.

Restart the routing machine again (to get rid of the above temporary routes) and do the following two things for each IP:

  1. Add address line to dnsmasq.conf for each address to force resolving to the off-vpn-IP you obtained in the second step, as follows:

    address=/www.avoidvpn.com/off.vpn.ip.obtained

  2. Add the address-specific route to your routing configuration (needs to be done after each reboot or saved as permanent route)

    sudo route add -net off.vpn.ip.obtained netmask 255.255.255.255 gw 192.168.1.1 dev eth0

Again, assuming 192.168.1.1 is the non-vpn gateway.

Caveats

  1. This is terrible solution
  2. It works for me
  3. IPs may change at any moment and the setup becomes invalid
  4. Fortunately, the scenario from 3. is not frequent if different IPs are used for load balancing or content restrictions (e.g. you would bypass these mechanisms, but the IPs would be working anyway)
  5. Have no idea what the people maintaining server will think when they get the traffic from the IPs that should not exist (e.g. someone trying to transfer the load to other IP while you happily keep accessing the server that in theory should not be under load).

Hope it helps, but yes, it is a terrible solution. Have fun and good luck!

| improve this answer | |
-1
  allow-pull-fqdn
  push "dhcp-option DNS 10.0.0.1"

  route thehost.com 255.255.255.255 vpn_gateway
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.