I have this set up actually, took me a while to set up too...
If you're using OpenVPN you can use my up/down script for OpenVPN/squid. You'll also need to set up BIND to go thru the VPN too:
#!/usr/bin/env bash
status="$1"
ip="$5"
configdir_squid="/etc/squid/proxyoff"
configdir_bind="/etc/named"
if [ "$status" = "up" ]; then
echo "tcp_outgoing_address $ip" > "$configdir_squid/tcp_outgoing_address.conf"
echo "http_access allow localnet" > "$configdir_squid/http_access.conf"
echo "query-source address $ip;" > "$configdir_bind/query_source.conf"
else
echo "" > "$configdir_squid/tcp_outgoing_address.conf"
echo "http_access deny localnet" > "$configdir_squid/http_access.conf"
echo "" > "$configdir_bind/query_source.conf"
fi
systemctl restart named squid transmission-daemon
Then create a folder, called proxyoff inside /etc/squid. Then set up the scripts in OpenVPN:
up "/opt/scripts/openvpn_tun1.sh up"
down "/opt/scripts/openvpn_tun1.sh down"
You'll need IPtables rules which control communication from squid and bind (you'll need to set up static routes for your VPN provider):
-A vyprvpn-only -o lo -j ACCEPT
-A vyprvpn-only -d 192.168.1.0/24,10.8.0.0/24 ! -o tun1 -j ACCEPT
-A vyprvpn-only ! -o tun1 -j REJECT --reject-with icmp-net-unreachable
-A OUTPUT -m owner --gid-owner transmission -j vyprvpn-only
-A OUTPUT -m owner --gid-owner squid -j vyprvpn-only
-A OUTPUT -m owner --gid-owner named -j vyprvpn-only
Add somewhere at the bottom of your http_access rules in squid, but BEFORE http_access deny all:
include /etc/squid/proxyoff/http_access.conf
Also add, after http_port or after your http_access rules:
include /etc/squid/proxyoff/tcp_outgoing_address.conf
Set your nameservers so that they reflect a DNS server on the LAN which will go through the VPN or to an internet DNS server which'll go through the DNS by the iptables rules:
dns_v4_first on
dns_nameservers 8.8.8.8 8.8.4.4
For example, I have my dns_nameservers as 3 Windows DNS servers which handle AD and then send any queries they don't know, back to BIND servers running on the same servers as the VPN.
Add a gateway failure for the localnet ACL in squid or rename the ACL and the ACL in the scripts:
deny_info ERR_GATEWAY_FAILURE localnet
Then just set up a proxy autoconfig:
function FindProxyForURL(url, host) {
var proxy_on = "PROXY 192.168.1.20:3128; PROXY 192.168.1.21:3128";
var proxy_off = "DIRECT";
var network = "192.168.1.0";
var subnet = "255.255.255.0";
var proxy_bypass = new Array(
"pyronexus.lan", "*.pyronexus.lan",
"pyronexus.com", "*.pyronexus.com",
"amazon.com", "*.amazon.com",
"amazon.co.uk", "*.amazon.co.uk",
"channel4.com", "*.channel4.com",
"c4assets.com", "*.c4assets.com",
"ipv6-test.com", "*.ipv6-test.com",
// Banks
"tsb.co.uk", "*.tsb.co.uk",
"bankofscotland.co.uk", "*.bankofscotland.co.uk",
"barclays.co.uk", "*.barclays.co.uk",
"halifax.co.uk", "*.halifax.co.uk",
"rbs.co.uk", "*.rbs.co.uk",
"natwest.com", "*.natwest.com"
);
var blockedsites = new Array(
"trafficstars.com", "*.trafficstars.com",
"trafficfactory.biz", "*.trafficfactory.biz"
);
// Blocked websites (block them in the proxy server configuration to prevent circumvention
for (var i = 0; i < blockedsites.length; i++) {
if (shExpMatch(host, blockedsites[i])) {
return "proxy 127.0.0.1";
}
}
// Below here evaluates the above.
// Bypass proxy for local web servers in the same subnet as the client.
if (isInNet(host, network, subnet)) {
return proxy_off;
}
// Bypass proxy for those listed under proxy_bypass.
for (var i = 0; i < proxy_bypass.length; i++) {
if (shExpMatch(host, proxy_bypass[i])) {
return proxy_off;
}
}
// Everything else not caught by the above, should be checked to see if it is HTTP, HTTPS or FTP
// before sending to a proxy server.
if (shExpMatch(url, "http:*") ||
shExpMatch(url, "https:*") ||
shExpMatch(url, "ftp:*")) {
return proxy_on;
}
// Finally, send all other requests direct.
return proxy_off;
}
Add this to /etc/named.conf under options (add forwarders to internet DNS servers but delete the root hints):
include "/etc/named/query_source.conf";
Add the VPN's IP to /etc/hosts:
209.99.22.37 uk1.vyprvpn.com
And add the route:
ip route add 209.99.22.37/32 via 192.168.1.1 dev eth0
You can see some of my other guides about proxying at https://pyronexus.com