Я пытаюсь настроить клиент OpenVPN на ArchLinux с PrivateInternetAccess. По умолчанию PIA проталкивает маршруты так, что весь трафик проходит через VPN. Я только хочу, чтобы некоторые приложения использовали VPN.
Для этого я использую "политику на основе маршрутизации". Я создал новую таблицу маршрутизации с именем "vpn" и буду выборочно отправлять пользователей в эту таблицу маршрутизации.
После этих команд пользователь "media" будет перенаправлен в таблицу маршрутизации "vpn":
$ echo 100 vpn >> /etc/iproute2/rt_tables
$ iptables -t mangle -I OUTPUT -m owner --uid-owner media -j MARK --set-mark 0x1
$ ip rule add fwmark 0x1 table vpn
Я дополнительно изменил свою конфигурацию клиента OpenVPN, чтобы мои таблицы маршрутизации были заполнены правильно:
$ cat /etc/openvpn/client.conf
client
dev tun
proto udp
remote us-newyorkcity.privateinternetaccess.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/openvpn/ca.crt
tls-client
remote-cert-tls server
auth-user-pass /etc/openvpn/login.conf
comp-lzo
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.pem
# This will override PIA so that traffic will route through our normal gateway
route 0.0.0.0 192.0.0.0 net_gateway
route 64.0.0.0 192.0.0.0 net_gateway
route 128.0.0.0 192.0.0.0 net_gateway
route 192.0.0.0 192.0.0.0 net_gateway
# Calling these scripts will add the PIA routes to the vpn table
script-security 2
up /etc/openvpn/up.sh
down /etc/openvpn/down.sh
$ cat /etc/openvpn/up.sh
#!/bin/sh
ip route add table vpn default via $ifconfig_remote
$ cat /etc/openvpn/down.sh
#!/bin/sh
ip route flush table vpn
Вот мои таблицы маршрутизации после запуска openvpn /etc/openvpn/client.conf
:
$ ip route show table main
0.0.0.0/2 via 192.168.1.1 dev eth0
0.0.0.0/1 via 10.197.1.5 dev tun0
default via 192.168.1.1 dev eth0 src 192.168.1.124 metric 202
10.197.1.1 via 10.197.1.5 dev tun0
10.197.1.5 dev tun0 proto kernel scope link src 10.197.1.6
64.0.0.0/2 via 192.168.1.1 dev eth0
128.0.0.0/2 via 192.168.1.1 dev eth0
128.0.0.0/1 via 10.197.1.5 dev tun0
192.0.0.0/2 via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.124 metric 202
209.95.50.86 via 192.168.1.1 dev eth0
$ ip route show table vpn
default via 10.197.1.5 dev tun0
Все работает как пользователь, который НЕ перенаправляется в таблицу "vpn":
$ whoami
jordan
$ ping -c 2 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=38.9 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=39.0 ms
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 38.952/38.999/39.047/0.203 ms
Тем не менее, происходит сбой для пользователя, который попадает в таблицу "vpn":
$ whoami
media
$ ping -c 2 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
Я посмотрел на tcpdump -i tun0
чтобы увидеть, что происходит. Кажется, что запрос icmp идет через tun0, но не возвращается?
$ tcpdump -i tun0
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
15:37:30.134399 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10256, seq 1, length 64
15:37:31.143217 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10256, seq 2, length 64
Мысли? :(
==== РЕДАКТИРОВАТЬ # 1 ====
В качестве проверки работоспособности, если мы отправляем весь трафик через VPN (удаляя строки «route xxxx 192.0.0.0 net_gateway» в /etc/openvpn/client.conf), мы получаем ответы icmp просто отлично:
$ tcpdump -i tun0
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
16:26:54.401732 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10480, seq 1, length 64
16:26:54.483122 IP google-public-dns-a.google.com > keep: ICMP echo reply, id 10480, seq 1, length 64
16:26:55.403465 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10480, seq 2, length 64
16:26:55.485068 IP google-public-dns-a.google.com > keep: ICMP echo reply, id 10480, seq 2, length 64
==== РЕДАКТИРОВАТЬ # 2 ====
Следуя совету MariusMatutiae, я попытался с помощью --route-noexec
вручную установить маршруты в /etc/openvpn/up.sh
. Мы также отключаем фильтрацию обратного пути в /etc/openvpn/up.sh
и повторно включаем его в /etc/openvpn/down.sh
:
$ cat /etc/openvpn/up.sh
#!/bin/sh
ip route add table vpn 0.0.0.0/1 via $ifconfig_remote
ip route add table vpn 128.0.0.0/1 via $ifconfig_remote
ip route add table vpn $route_network_1 via $ifconfig_remote
ip route add table vpn $trusted_ip via $route_net_gateway
ip route add table vpn $ifconfig_remote dev tun0 proto kernel src $ifconfig_local
ip route add table vpn 192.168.1.0/24 dev eth0 proto kernel src 192.168.1.124 metric 202
ip route del table main $ifconfig_remote
# Disable reverse path filtering
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 0 > $f;
done
$ cat /etc/openvpn/down.sh
#!/bin/sh
ip route flush table vpn
# Re-enable reverse path filtering
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $f;
done
После этого мои таблицы маршрутизации выглядят так:
$ ip route show table main
default via 192.168.1.1 dev eth0 src 192.168.1.124 metric 202
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.124 metric 202
$ ip route show table vpn
0.0.0.0/1 via 10.173.1.5 dev tun0
10.173.1.1 via 10.173.1.5 dev tun0
10.173.1.5 dev tun0 proto kernel scope link src 10.173.1.6
128.0.0.0/1 via 10.173.1.5 dev tun0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.124 metric 202
209.95.50.133 via 192.168.1.1 dev eth0
Тем не менее, пользователь "media" по-прежнему не может ping 8.8.8.8
. tcpdump -i tun0
прежнему сообщает, что ответы не возвращаются :(