Thursday, 12 July 2018

networking - Linux: routing based on domain names


On ubuntu 16.04, I would like to route my traffic either through the direct internet eth0 or my VPN tun0 based on the domain name entered into the browser. The reason being local sites are either slow or location dependent.


I realize the kernel routing table is IP based and domain names are usually resolved in the software layer, but with linux being a script friendly platform, I'm hoping for a workaround. Though, I have no idea how to write such a script.


So far I've found the dig example.com +short @8.8.8.8 command will list the IPs associated with a domain, and I've figured out the sudo route add -net 8.8.8.8 netmask 255.255.255.255 gw 192.168.2.1 command will bypass the VPN for a given IP (where 192.168.2.1 is my default eth0). Would somebody be kind enough to template a script which reads a file containing the domain names and enters the route rules upon system boot. Bonus points for allowing masked sub domains *.example.com.


If there is an easier method to this madness I'll accept it as a solution.


Note: I could very easily hard code the IPs into /etc/network/interfaces but then they become hard to manage. I also tried hard coding all known IPs for my country into this file, but it was very hit and miss along with a delayed boot up time.



Answer



I'd recomend you to avoid managing routing based on domain names (by the way, it is also impossible to resolve wildcard subdomain, whether it is bonus points for it or not :D)


To be a bit descriptive, you shouldn't do that because:


1) some domains changes their IPs time to time,


2) it is impossible to match wildcards in subdomains


3) it is impossible to know/fetch all subdomains of any domain


4) any random subdomain can have any random IP address.


So, the solution as browser addon (and/or custom local proxy like squid) is the best option for your issue.


But, I guess, "FoxyProxy" addon (it is originally Firefox addon, but AFAIRC, it is alfo Chrome version exists) is exactly what you want.


And, also, answering to your notice that "FoxyProxy is paid service and you already have your vpn":


FoxyProxyPlus is paid service, but not FoxyProxy.


FoxyProxy is addon, available for major browsers:


Standard Edition (Firefox) | Basic Edition (Firefox)


Standard Edition (Chrom{e,ium}) | Basic Edition (Chrom{e,ium})


So, if you want to go to some domains through VPN, you should:


1) write rules for foxyproxy to go through you squid instance for the list of domains


2) and/or write the rules list for squid


3) capture http/https traffic not owned by squid with iptables and point it to squid by rule like this:


iptables -m owner -m multiport -t nat -A OUTPUT ! -o lo ! --uid-owner $squid_user_id -p tcp --dports 80,443,8080,... -j REDIRECT --to-ports $SQUID_PORT

(--syn option may be needed for -p tcp)


4) capture http/https traffic owned by squid, and mark it for next routing it to VPN with rule like this:


iptables -A OUTPUT -m owner --uid-owner $squid_user_id -j MARK --set-mark 11

5)


echo 11 forcevpn >> /etc/iproute2/rt_tables
ip rule add fwmark 11 table forcevpn
ip route add default via 10.0.0.1 table forcevpn

where 10.0.0.1 is you gateway inside VPN. Or you can use dev $VPN_IF instead of via 10.0.0.1 if you have no gateway and just want to push all the traffic in the vpn interface.


6) optionally, you may be need to run sudo sysctl ipv4.conf.all.rp_filter =0


===


And one more thing:


If you want to do same magick with non-http(s) TCP traffic, you'll be need something like proxychains, and perform similar capturing magic.


And, if you want to do that magic with UDP, I've a bad news: I don't know any proxy capable of proxying of UDP (because of the nature of this protocol) :)


⇓⇓⇓ EDIT ⇓⇓⇓


In case, you want the reverse thing (default gw = vpn, and rule some domains directly through ISP), it can be:


1) write rules for foxyproxy to go through you squid instance for the list of domains


2) capture traffic owned by squid, and mark it for next routing it another way with rule like this:


iptables -A OUTPUT -m owner --uid-owner $squid_user_id -j MARK --set-mark 11

3)


echo 11 novpn >> /etc/iproute2/rt_tables
ip rule add fwmark 11 table novpn
ip route add default via ${ISP_GW} table novpn

where ISP_GW is the gateway you use to route traffic to your VPN server. Some users may want to use dev ppp0 (or ppp1, ..., pppN) instead of via ${ISP_GW} in case if they use pptp to connect to the internet.


No comments:

Post a Comment

Where does Skype save my contact's avatars in Linux?

I'm using Skype on Linux. Where can I find images cached by skype of my contact's avatars? Answer I wanted to get those Skype avat...