Bagaimana cara mencegah koneksi TCP membeku melalui jaringan OpenVPN?

19

Rincian baru ditambahkan di akhir pertanyaan ini; mungkin saya memusatkan perhatian pada penyebabnya.

Saya memiliki VPN berbasis UDP OpenVPN yang diatur dalam tapmode (saya perlu tapkarena saya membutuhkan VPN untuk melewati paket multicast, yang sepertinya tidak mungkin dilakukan dengan tunjaringan) dengan beberapa klien di Internet. Saya sering mengalami koneksi TCP yang membeku melalui VPN. Yaitu, saya akan membuat koneksi TCP (mis. Koneksi SSH, tetapi protokol lain memiliki masalah yang sama), dan pada beberapa titik selama sesi, tampaknya lalu lintas akan berhenti ditransmisikan melalui sesi TCP.

Ini tampaknya terkait dengan titik-titik di mana transfer data besar terjadi, seperti jika saya menjalankan lsperintah dalam sesi SSH, atau jika saya catfile log yang panjang. Beberapa pencarian Google menghasilkan sejumlah jawaban seperti ini sebelumnya di Server Fault , menunjukkan bahwa kemungkinan penyebabnya adalah masalah MTU: bahwa selama periode lalu lintas tinggi, VPN sedang mencoba mengirim paket yang jatuh di suatu tempat di dalam pipa di antara Titik akhir VPN. Jawaban yang ditautkan di atas menyarankan menggunakan pengaturan konfigurasi OpenVPN berikut untuk mengurangi masalah:

fragment 1400
mssfix

Ini harus membatasi MTU yang digunakan pada VPN hingga 1400 byte dan memperbaiki ukuran segmen maksimum TCP untuk mencegah pembuatan paket apa pun yang lebih besar dari itu. Ini agak mengurangi masalah, tapi saya masih sering melihat pembekuan. Saya telah mencoba sejumlah ukuran sebagai argumen untuk fragmentarahan: 1200, 1000, 576, semua dengan hasil yang serupa. Saya tidak dapat memikirkan topologi jaringan aneh antara kedua ujung yang dapat memicu masalah seperti itu: server VPN sedang berjalan pada a mesin pfSense yang terhubung langsung ke Internet, dan klien saya juga terhubung langsung ke Internet di lokasi lain.

Satu teka-teki aneh lainnya: jika saya menjalankan tracepathutilitas, maka itu tampaknya membantu masalah. Contoh menjalankan terlihat seperti:

[~]$ tracepath -n 192.168.100.91
 1:  192.168.100.90                                        0.039ms pmtu 1500
 1:  192.168.100.91                                       40.823ms reached
 1:  192.168.100.91                                       19.846ms reached
     Resume: pmtu 1500 hops 1 back 64 

Jalankan di atas adalah antara dua klien di VPN: Saya memulai jejak dari 192.168.100.90ke tujuan 192.168.100.91. Kedua klien dikonfigurasikan denganfragment 1200; mssfix; upaya membatasi MTU yang digunakan pada tautan. Hasil di atas tampaknya menunjukkan bahwa tracepathmampu mendeteksi jalur MTU sebesar 1500 byte antara kedua klien. Saya akan berasumsi bahwa itu akan menjadi lebih kecil karena pengaturan fragmentasi yang ditentukan dalam konfigurasi OpenVPN. Saya menemukan hasil yang agak aneh.

Namun yang lebih aneh lagi: jika saya memiliki koneksi TCP dalam status macet (mis. Sesi SSH dengan daftar direktori yang membeku di tengah), kemudian menjalankan tracepathperintah yang ditunjukkan di atas menyebabkan koneksi untuk memulai lagi ! Saya tidak dapat menemukan penjelasan yang masuk akal mengapa ini bisa terjadi, tetapi saya merasa ini mungkin mengarah ke solusi untuk akhirnya memberantas masalah.

Adakah yang punya rekomendasi untuk mencoba hal lain?

Sunting: Saya telah kembali dan melihat ini sedikit lebih jauh, dan hanya menemukan informasi yang lebih membingungkan:

  • Saya mengatur koneksi OpenVPN ke fragmen pada 1400 byte, seperti yang ditunjukkan di atas. Kemudian, saya terhubung ke VPN dari seluruh Internet dan menggunakan Wireshark untuk melihat paket-paket UDP yang dikirim ke server VPN ketika kios itu terjadi. Tidak ada yang lebih besar dari jumlah 1400 byte yang ditentukan, sehingga fragmentasi tampaknya berfungsi dengan baik.

  • Untuk memverifikasi bahwa MTU 1400 byte saja sudah cukup, saya melakukan ping server VPN menggunakan perintah (Linux) berikut:

    ping <host> -s 1450 -M do
    

    Ini (saya percaya) mengirimkan paket 1450-byte dengan fragmentasi dinonaktifkan (setidaknya saya memverifikasi bahwa itu tidak berfungsi jika saya mengaturnya ke nilai yang jelas terlalu besar seperti 1600 byte). Ini tampaknya berfungsi dengan baik; Saya mendapatkan balasan kembali dari tuan rumah tanpa masalah.

Jadi, mungkin ini bukan masalah MTU sama sekali. Saya hanya bingung untuk apa lagi!

Sunting 2: Lubang kelinci terus semakin dalam: Sekarang saya telah mengisolasi masalahnya sedikit lagi. Tampaknya terkait dengan OS yang tepat yang digunakan klien VPN. Saya telah berhasil menggandakan masalah pada setidaknya tiga mesin Ubuntu (versi 12.04 hingga 13.04). Saya dapat menduplikasi koneksi SSH secara membeku dalam waktu sekitar satu menit atau lebih dengan hanyacat menggunakan file log yang besar.

Namun , jika saya melakukan tes yang sama menggunakan mesin CentOS 6 sebagai klien, maka saya tidak melihat masalah! Saya telah diuji menggunakan versi klien OpenVPN yang sama persis seperti yang saya gunakan pada mesin Ubuntu. Saya dapat catmencatat file selama berjam-jam tanpa melihat koneksi membeku. Ini tampaknya memberikan beberapa wawasan tentang penyebab utama, tapi saya tidak yakin apa wawasan itu.

Saya telah memeriksa lalu lintas melalui VPN menggunakan Wireshark. Saya bukan pakar TCP, jadi saya tidak yakin apa yang harus dilakukan tentang detail berdarah, tetapi intinya adalah bahwa pada titik tertentu, paket UDP akan terhenti karena terbatasnya bandwidth tautan Internet, menyebabkan transmisi ulang TCP di dalam terowongan VPN. Pada klien CentOS, transmisi ulang ini terjadi dengan benar dan segala sesuatunya berjalan dengan bahagia. Namun, pada beberapa titik dengan klien Ubuntu, ujung jarak jauh mulai mentransmisikan kembali segmen TCP yang sama (dengan penundaan pengiriman meningkat di antara setiap pengiriman ulang). Klien mengirim apa yang tampak seperti ACK TCP yang valid untuk setiap pengiriman ulang, tetapi ujung jarak jauh masih terus mengirimkan segmen TCP yang sama secara berkala. Ini memperluas infinitum iklan dan koneksi terhenti. Pertanyaan saya di sini adalah:

  • Apakah ada yang punya rekomendasi untuk bagaimana memecahkan masalah dan / atau menentukan akar penyebab masalah TCP? Seolah-olah ujung jarak jauh tidak menerima pesan ACK yang dikirim oleh klien VPN.

Satu perbedaan umum antara simpul CentOS dan berbagai rilis Ubuntu adalah bahwa Ubuntu memiliki versi kernel Linux yang jauh lebih baru (dari 3,2 di Ubuntu 12,04 menjadi 3,8 di 13,04). Pointer ke beberapa bug kernel baru mungkin? Saya berasumsi bahwa jika demikian, maka saya tidak akan menjadi satu-satunya yang mengalami masalah; Saya tidak berpikir ini sepertinya setup yang sangat eksotis.

Jason R
sumber
Routing paket multicast melalui tunjaringan harus dimungkinkan dengan menjalankan multicast routing daemon (seperti pimd ) dan memiliki server OpenVPN menggunakan --topologyopsi yang diatur ke "subnet" - lihat manual
kostix
Apakah klien VPN atau server mengindikasikan sesuatu dalam log pada saat masalah ini terjadi?
mgorven
@ Morven: Jelas bukan pada klien. Saya harus melakukan beberapa pekerjaan untuk mendapatkan log server.
Jason R
@ Morven: Saya akhirnya memiliki kesempatan untuk kembali ke ini. Tidak ada sama sekali dalam log klien atau server ketika ini terjadi. Benar-benar membingungkan.
Jason R
1
Apakah ada kemungkinan bahwa klien yang membeku memiliki firewall lokal yang menjatuhkan paket ICMP-fragmentasi-diperlukan, sedangkan yang tidak, dan karena itu memecah-mecah dengan benar?
MadHatter mendukung Monica

Jawaban:

10

Perintah ini menyelesaikannya untuk saya:

$ sudo ip link set dev tun0 mtu 1350 && echo ":)"

Anda dapat Memverifikasi pengaturan tun0 dengan

$ ip a s

Bersulang!

Sebastián A. La Spina
sumber
Di sisi klien atau server ??
Matt
Terima kasih banyak! @ Mat, itu tergantung di mana masalahnya berada. Bagi kami itu di server, tetapi mungkin di sisi klien. Juga nilainya dapat berbeda, Anda dapat menguji dengan ping <host> -s 1350 -M dountuk menemukan nilai yang tepat
Eino Gourdin
2

Nonaktifkan Penskalaan Jendela dalam TCP, dengan:

sysctl -w net.ipv4.tcp_window_scaling=0

Setelah melakukan itu, SSH ke Sistem Debian / Ubuntu melalui VPN bekerja dengan baik untuk saya.

Mifpi
sumber
0

Pada Windows menggunakan Putty, Anda harus mengubah MTU dengan membuka koneksi lokal untuk koneksi vpn -> detail pada antarmuka jaringan (TAP windows Adapter atau semacamnya) -> Advanced -> Properties -> MTU (ubah ke sesuatu lebih rendah dari 1500). Anda mungkin harus menyambung kembali. Ini bekerja untuk saya di Windows dan Putty

Nick_K
sumber
-1

Sepertinya ini adalah masalah buffering. Saya memiliki masalah yang sama, dan saya bisa menghindarinya dengan membatasi kecepatan transfer. Bukan cara terbaik, tetapi mungkin membantu seseorang menemukan solusi yang lebih baik untuk ini.

Lihat pembaruan 1 di sini: Cara mencegah SSH membeku melalui klien openvpn untuk koneksi klien

Atomo
sumber