Zde je kompletní řešení využívající kontrolní skupiny (cgroups), které umožňuje řízení prostředků pro jednotlivé procesy. Síťová řídicí skupina umožňuje izolovat cestu VPN, snadno umožňuje selektivní spouštění jakéhokoli procesu a jeho potomků, umožňuje uživatelům bez oprávnění root získat přístup k běžícím procesům v rámci cgroup a pomocí druhé instance dnsmasq lze izolovat DNS. také dotazy. To předpokládá, že máte nainstalované openvpn, dnsmasq, cgroup a iptables verze 1.6+ s podporou cgroup. To vše bylo provedeno na Debianu Jessie
Prvním krokem je vytvoření cgroup a odpovídající nastavení iptables. To by mělo být provedeno při každém restartu, takže do /etc/rc.local umístím následující
# enable ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# create cgroup for 3rd party VPN (can change 'vpn' to your name of choice)
mkdir -p /sys/fs/cgroup/net_cls/vpn
# give it an arbitrary id
echo 11 > /sys/fs/cgroup/net_cls/vpn/net_cls.classid
# grant a non-root user access (change user:group accordingly)
cgcreate -t user:group -a user:group -g net_cls:vpn
# mangle packets in cgroup with a mark
iptables -t mangle -A OUTPUT -m cgroup --cgroup 11 -j MARK --set-mark 11
# NAT packets in cgroup through VPN tun interface
iptables -t nat -A POSTROUTING -m cgroup --cgroup 11 -o tun0 -j MASQUERADE
# redirect DNS queries to port of second instance, more on this later
iptables -t nat -A OUTPUT -m cgroup --cgroup 11 -p tcp --dport 53 -j REDIRECT --to-ports 5354
iptables -t nat -A OUTPUT -m cgroup --cgroup 11 -p udp --dport 53 -j REDIRECT --to-ports 5354
# create separate routing table
ip rule add fwmark 11 table vpn
# add fallback route that blocks traffic, should the VPN go down
ip route add blackhole default metric 2 table vpn
# disable reverse path filtering for all interfaces
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $i; done
Dalším krokem je úprava konfiguračního souboru klienta VPN třetí strany, např. /etc/openvpn/client.conf . Zbytek konfigurace ponechte beze změny.
# redirect-gateway def1 <--- comment or remove the redirect-gateway line if it exists
# disable automatically configuring routes and run our own routeup.sh script instead
route-noexec
route-up /etc/openvpn/routeup.sh
# run our own update-dnsmasq-conf script on interface up/down; comment out existing up/down lines
up /etc/openvpn/update-dnsmasq-conf
down /etc/openvpn/update-dnsmasq-conf
Nyní musíme vytvořit /etc/openvpn/routeup.sh skript
#!/bin/bash
# add default route through vpn gateway to our separate routing table
/sbin/ip route add default via $route_vpn_gateway dev $dev metric 1 table vpn
exit 0
A nyní potřebujeme vytvořit upravenou verzi update-resolv-conf, který se obvykle instaluje do /etc/openvpn, abychom vytvořili druhou instanci dnsmasq. Říkám tomu /etc/openvpn/update-dnsmasq-conf
#!/bin/bash
[ "$script_type" ] || exit 0
split_into_parts()
{
part1="$1"
part2="$2"
part3="$3"
}
case "$script_type" in
up)
NMSRVRS=""
for optionvarname in ${!foreign_option_*} ; do
option="${!optionvarname}"
split_into_parts $option
if [ "$part1" = "dhcp-option" ] ; then
if [ "$part2" = "DNS" ] ; then
NMSRVRS="${NMSRVRS:+$NMSRVRS }--server $part3"
fi
fi
done
dnsmasq $NMSRVRS --no-hosts --no-resolv --listen-address=127.0.0.1 \
--port=5354 --bind-interfaces --no-dhcp-interface=* \
--pid-file=/var/run/dnsmasq/dnsmasq2.pid
;;
down)
kill -9 $(cat /var/run/dnsmasq/dnsmasq2.pid)
;;
esac
A to by mělo být ono. Nyní můžete spustit připojení vpn a selektivně spouštět procesy přes toto rozhraní (volba --sticky zajišťuje, že podřízené procesy budou spuštěny ve stejné cgroup).
cgexec -g net_cls:vpn --sticky chromium &
POZNÁMKA:U dnsmasq se ujistěte, že /etc/resolv.conf ukazuje na localhost (nameserver 127.0.0.1). Vaše hlavní instance dnsmasq bude zpracovávat dotazy na vaší normální trase bez VPN a používat (/var/run/dnsmasq/resolv.conf), která se obvykle skládá z vaší výchozí brány nebo nějakého veřejného DNS (např. Google 8.8.8.8). Druhou instanci používá pouze izolovaná cgroup