Koneksi OpenVPN yang berlebihan dengan perutean Linux tingkat lanjut melalui jaringan yang tidak dapat diandalkan

9

Saat ini saya tinggal di negara yang memblokir banyak situs web dan memiliki koneksi jaringan yang tidak dapat diandalkan ke dunia luar. Saya memiliki dua titik akhir OpenVPN (katakan: vpn1 dan vpn2) di server Linux yang saya gunakan untuk menghindari firewall. Saya memiliki akses penuh ke server ini. Ini bekerja cukup baik, kecuali untuk paket tinggi kehilangan koneksi VPN saya. Kehilangan paket ini bervariasi antara 1% dan 30% tergantung pada waktu dan tampaknya memiliki korelasi yang rendah, sebagian besar waktu tampaknya acak.

Saya berpikir untuk menyiapkan router rumah (juga di Linux) yang memelihara koneksi OpenVPN untuk kedua titik akhir dan mengirim semua paket dua kali, ke kedua titik akhir. vpn2 akan mengirim semua paket dari rumah ke vpn1. Return trafic akan dikirim baik langsung dari vpn1 ke rumah, dan juga melalui vpn2.

       +------------+
       |    home    |
       +------------+
        |          |
        | OpenVPN  |
        |  links   |
        |          |
     ~~~~~~~~~~~~~~~~~~ unreliable connection
        |          |
+----------+   +----------+
|   vpn1   |---|   vpn2   |
+----------+   +----------+
        |
       +------------+
       | HTTP proxy |
       +------------+
             |
         (internet)

Untuk kejelasan: semua paket antara rumah dan proksi HTTP akan digandakan dan dikirim melalui jalur yang berbeda, untuk meningkatkan kemungkinan salah satu dari mereka akan tiba. Jika keduanya tiba, yang kedua pertama dapat secara diam-diam dibuang.

Penggunaan bandwidth tidak menjadi masalah, baik di sisi rumah maupun sisi titik akhir. vpn1 dan vpn2 dekat satu sama lain (ping 3ms) dan memiliki koneksi yang dapat diandalkan.

Adakah petunjuk tentang bagaimana hal ini dapat dicapai dengan menggunakan kebijakan perutean lanjutan yang tersedia di Linux?

konrad
sumber

Jawaban:

8

Gunakan infrastruktur ikatan di sisi 'rumah' dan 'vpn1', dan secara khusus dengan pengaturan mode = 3 yang menyiarkan lalu lintas pada semua antarmuka yang dimiliki oleh ikatan.

Untuk informasi lebih lanjut tentang cara mengonfigurasi ikatan, lihat manual yang bagus di http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f = Dokumentasi / jaringan / bonding.txt; h = 5dc638791d975116bf1a1e590fdfc44a6ae5c33c; hb = HEAD

jap
sumber
Saya menguji pengaturan ini dan berfungsi dengan sangat baik. Paket yang hilang berkurang dari sekitar 5% menjadi 0,0-0,1% dengan koneksi yang berlebihan ke hanya satu server!
konrad
7

Saya menggunakan jawaban yang diberikan oleh @ user48116 dan berfungsi seperti pesona. Penyiapannya sebenarnya cukup mudah!

CATATAN : Saya menerapkan ini dengan dua koneksi ke hanya satu server tunggal, karena ini sudah memecahkan masalah bagi saya. Jika Anda ingin mencoba pengaturan dengan dua server, cara termudah mungkin adalah menggunakan penerusan port untuk meneruskan port UDP dari server kedua ke yang pertama, dan menggunakan resep yang sama seperti dijelaskan di sini. Saya belum menguji ini sendiri.

Pertama, pastikan Anda memiliki kernel 2.6 dengan dukungan bonding (default di semua distribusi modern) dan Anda telah menginstal ifenslave.

Selanjutnya, masukkan ini ke /etc/rc.local atau tempat lain yang Anda suka, tetapi pastikan itu dijalankan sebelum openvpn dimulai (karena akan mencoba mengikat ke bond0):

Klien:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.2 netmask 255.255.255.0 up

Anda dapat menambahkan beberapa perutean jika diperlukan di sini, pastikan Anda melakukan semua perutean yang tepat dari sisi lain juga.

route add -net 10.7.0.0/24 gw 10.10.0.1

Server:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.1 netmask 255.255.255.0 up

Buat skrip /etc/openvpn/tap-up.sh (dan jangan lupa menandainya dapat dijalankan dengan chmod a + x tap-up.sh):

#!/bin/sh
# called as: cmd tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ]
ifenslave bond0 "$1"

Selanjutnya, tambahkan bridge0a.conf dan bridge0b.conf ke / etc / openvpn / bersama dengan kunci bersama. File-file tersebut sama untuk a dan b, kecuali untuk port yang berbeda (misalnya, gunakan 3002 untuk b). Ganti 11.22.33.44 dengan IP publik server Anda.

Klien:

remote 11.22.33.44
dev tap
port 3001
rport 3001
secret bridge.key
comp-lzo
verb 4
nobind
persist-tun
persist-key
script-security 2
up /etc/openvpn/tap-up.sh

Server:

local 11.22.33.44
dev tap
port 3001
lport 3001
secret bridge.key
comp-lzo
verb 4
script-security 2
up /etc/openvpn/tap-up.sh

Jangan lupa mengedit / etc / defaults / openvpn untuk memastikan konfigurasi VPN baru Anda dimulai. Mulai ulang komputer Anda, atau muat rc.local dan mulai ulang openvpn secara manual.

Sekarang Anda siap untuk menguji pengaturan Anda:

# ping 10.10.0.1
PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data.
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=50.4 ms
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=52.0 ms
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=52.2 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=53.0 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=53.1 ms (DUP!)
--- 10.10.0.1 ping statistics ---
2 packets transmitted, 2 received, +6 duplicates, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 50.428/51.786/53.160/0.955 ms

Jika semuanya berjalan dengan baik dan salurannya bagus, Anda akan melihat empat balasan untuk setiap paket ICMP: paket Anda digandakan di sisi lokal, dan balasan untuk dua paket ini digandakan lagi di sisi yang jauh. Ini tidak akan menjadi masalah untuk koneksi TCP, karena TCP hanya akan mengabaikan semua duplikat.

Ini merupakan masalah untuk paket UDP, karena tergantung pada perangkat lunak untuk menangani duplikat. Misalnya, kueri DNS akan menghasilkan empat balasan alih-alih dua yang diharapkan (dan menggunakan empat kali bandwidth normal untuk respons, bukan dua kali):

# tcpdump -i bond0 -n port 53
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
13:30:39.870740 IP 10.10.0.2.59330 > 10.7.0.1.53: 59577+ A? serverfault.com. (33)
13:30:40.174281 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)
13:30:40.174471 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)
13:30:40.186664 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)
13:30:40.187030 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)

Semoga berhasil!

konrad
sumber