Ich habe einen Ubuntu 16.04 lxd-Container erstellt und darin Stunnel, Tinyproxy und einen OpenVPN-Client eingerichtet.
Das Ziel besteht darin, über Stunnel eine Verbindung zu Tinyproxy herzustellen und Tinyproxy zu zwingen, die OpenVPN-Schnittstelle für ausgehende Verbindungen zu verwenden.
Stunnel -> Tinyproxy funktioniert einwandfrei – Seiten im Browser werden wie erwartet geladen. Sobald ich jedoch den OpenVPN-Dienst starte, schlägt Stunnel auf der Clientseite mit einem Timeout fehl und der Browser wartet weiter auf eine Antwort.
Da Tinyproxy 1.8.3 (die neueste Version für Ubuntu 16.04) keine Option zum Binden ausgehender Verbindungen an eine bestimmte Schnittstelle unterstützt, musste ich OpenVPN die Standardrouten über seine tun0
Schnittstelle hinzufügen lassen.
Der OpenVPN-Client funktioniert wie erwartet – alle Pakete vom Container gehen über VPN. Der Host mit dem Container ist ein Remote-Host mit öffentlicher IP. DNAT ist für den Container eingerichtet.
Ich kenne mich mit den internen Vorgängen beim Routing nicht wirklich aus. Ich konnte SNAT/DNAT und Filterung nur mit iptables einrichten. Daher verstehe ich die Ursache des Problems nicht.
Hier die wichtigsten Parameter der Umgebung:
ifconfig
$ ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:16:3e:5f:46:ba
inet addr:10.227.60.197 Bcast:10.227.60.255 Mask:255.255.255.0
inet6 addr: fe80::216:3eff:fe5f:46ba/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:16291 errors:0 dropped:0 overruns:0 frame:0
TX packets:15632 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5044056 (5.0 MB) TX bytes:4171187 (4.1 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:2446 errors:0 dropped:0 overruns:0 frame:0
TX packets:2446 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:2483699 (2.4 MB) TX bytes:2483699 (2.4 MB)
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.3 P-t-P:10.8.0.3 Mask:255.255.255.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:252 (252.0 B) TX bytes:252 (252.0 B)
Route
$ route -v -e
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
default 10.8.0.1 128.0.0.0 UG 0 0 0 tun0
default 10.227.60.1 0.0.0.0 UG 0 0 0 eth0
10.8.0.0 * 255.255.255.0 U 0 0 0 tun0
10.227.60.0 * 255.255.255.0 U 0 0 0 eth0
128.0.0.0 10.8.0.1 128.0.0.0 UG 0 0 0 tun0
<vpn server IP> 10.227.60.1 255.255.255.255 UGH 0 0 0 eth0
stunnel.cong
...
accept = 10.227.60.197:8081
connect = 127.0.0.1:8080
...
tinyproxy.conf
...
Port 8080
Listen 127.0.0.1
...
vpnclient.conf
dev tun
proto udp
remote <vpn server ip> 1195
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
key-direction 1
verb 3
#route-nopull
...
iptablessind leer.
Antwort1
Das Problem lag bei der Konfiguration der Routingtabelle.
Folgendes ist mir beim Entfernen von von OpenVPN hinzugefügten Routen aufgefallen:
Destination Gateway Genmask Flags MSS Window irtt Iface
default 10.8.0.1 128.0.0.0 UG 0 0 0 tun0
und versuche, Pakete auszuführen ping 8.8.8.8 -I tun0
und gleichzeitig zu überwachen tcpdump -nn icmp
, antworte auf ICMP-Anfragen, treffe zwar tatsächlich, eth0
komme aber nicht weiter. Nach einigen Nachforschungen habe ich herausgefunden, dass es auch eine separate Routing-Tabelle tun0
und Regeln dafür geben sollte, da der Server über zwei Schnittstellen verfügt.
Schließlich habe ich tinyproxy auf die neueste Version aktualisiert, um die ausgehende Schnittstelle angeben zu können, und OpenVPN deaktiviert, um Standardrouten wie die oben entfernte zu pushen.
Dann habe ich die Tabelle hinzugefügt /etc/iproute2/rt_tables
:
...
12 vpn
Routen zu dieser Tabelle und Regeln hinzugefügt:
ip route add 10.8.0.0/24 dev tun0 src 10.8.0.3 table vpn
ip route add default via 10.8.0.1 dev tun0 table vpn
ip rule add from 10.8.0.3/32 table vpn
ip rule add to 10.8.0.3/32 table vpn
Danach begann alles wie erwartet zu funktionieren.