Нэг Linux хост дээр хоёр дахь OpenVPN клиентийг нэмэх нь хоёр газрын аль нэгэнд нь бүтэлгүйтдэг. Эсвэл дотоод клиент өөрийн серверт хүрч чадахгүй, учир нь гадаад туннель тэр тээврийг эзэлсэн, эсвэл хоёр дахь клиент маршрутын хүснэгтийг дахин бичиж, эхний туннель ажиллахаа болино. Хоёр асуудал маршрутчлалд байгаа, шифрлэлтэд биш, мөн хоёулаа шинэ туннель ямар ч програмын урсгал дамжуулахаас өмнө шийдэгддэг. Эндхүү хаягууд нь жишээ юм: tun0 нь гадаад туннель, 203.0.113.9 нь дотоод сервер, TCP 9999 нь дотоод замыг ашиглах ёстой урсгал юм.

Хоёр бүтэлгүйтлийн горим, нэг маршрутын хүснэгт

Дотоод клиент өөрийн сервер рүү UDP сокет нээдэг, тэр сокет бусадтай адил одоогийн маршрутын хүснэгтийг дагадаг. Хэрэв гадаад туннель анхдагч маршрутыг аль хэдийн эзэмшиж байгаа бол гар барилтын пакетууд гадаад туннельд ордог. Энэ нь гадаад сервер дотоод серверт хүрч чадаж, нөгөө тал урсгалыг дамжуулахыг зөвшөөрсөн үед л ажиллана; өөрөөр бол гар барилт зогсч, клиент дахин оролдоно.

Хоёр дахь бүтэлгүйтэл нь серверийн push-аас гардаг. Ердийн push нь redirect-gateway def1 бөгөөд анхдагч маршрутыг солихын оронд 0.0.0.0/1 ба 128.0.0.0/1-ийг суулгадаг. Тиймээс тус тусын /1 хосыг суулгадаг хоёр клиент мөргөлдөж, шинэ хос бараг бүх очих газарт ялдаг. Хоёр дахь нь холбогдсоны дараа туннель үхэх үед хүснэгтээс тэр хоёр угтварыг харна уу, учир нь анхдагч маршрут өөрөө хэзээ ч өөрчлөгдөөгүй байж болно.

Урсгалыг тэмдэглэж, түүнд хүснэгт өг

Сонгосон урсгалыг mangle хүснэгтэд тэмдэглэж, бодлогын дүрэмд тэр тэмдэгтэй тааруулах замаар чиглүүлнэ. Дүрэм нь анхдагч маршрут нь дотоод төхөөрөмж болох тусгай хүснэгт рүү заадаг тул зөвхөн тэмдэглэгдсэн пакетууд дотоод замаар явна.

iptables -t mangle -A PREROUTING -p tcp -m multiport --dport 9999 -j MARK --set-mark 0x9999
ip rule add fwmark 0x9999 table 200 pref 1000
ip route add default dev tun1 table 200

Энэ дүрмийн багц дахь ихэнх бүтэлгүйтэл хоёр алдаанаас үүдэлтэй. Firewall-ын тогтоосон тэмдгийн утга ба дүрмийн тааруулж буй утга ижил байх ёстой, учир нь зөрүү нь алдаа ч, үр нөлөө ч өгөхгүй. Мөн PREROUTING нь зөвхөн гаднаас ирж буй пакетыг хардаг тул энэ хост дээр эхэлсэн холболт тэмдэглэгдэхийн өмнө ижил тааруулгатай OUTPUT дүрэм шаардлагатай.

Маршрутын эзэмшлийг хоёр дахь клиентээс ав

Хоёр сонголт хоёр дахь клиентийг хүснэгтийг засахаас сэргийлдэг бөгөөд тэд өөр өөр цэгт үйлчилдэг. route-nopull нь push хийсэн маршрутын сонголтыг үл тоомсорлодог тул юу ч суулгагдахгүй. route-noexec нь push хийсэн сонголтыг клиентийн орчинд хүлээн авдаг ч хүснэгтийн өөрчлөлтийг hook-т үлдээдэг бөгөөд сервер юу санал болгосныг харах шаардлагатай үед яг үүнийг хүснэ.

Hook нь push хийсэн утгуудтайгаа өөрийн орчинд ажилладаг бөгөөд зөвхөн таний зөвшөөрсөн бичлэгүүдийг нэмэх ёстой. Үүнийг idempotent болго: дахин барихаас өмнө өөрийн эзэмшилд буй хүснэгтийг хоосло, мөн өмнөх ажиллагаа цэвэр төлөв үлдээсэн гэж бүү бод. Дахин холбогдох үед hook дахин дуудагдах бөгөөд цэвэрлэхгүйгээр нэмдэг hook давхардсан маршрутыг хуримтлуулна.

Нэг эзнийг сонгоод бичиж үлдээ. Хоёр сонголтыг хоёуланг нь тогтоодог профайл эсвэл гарын скрипттэй өрсөлддөг hook нь дараа нь хэн ч тайлбарлаж чадахгүй хүснэгт үүсгэдэг.

Хоёр серверийн хаягыг бэхэл

Дотоод клиент холбогдохын өмнө дотоод серверт гадаад төхөөрөмжөөр дамжих хост-маршрут хэрэгтэй. Тэр бичлэг нь дотоод тээврийг анхдагч маршрутыг дагахыг зөвшөөрөхгүйгээр гадаад туннель дотор барина.

ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9

Үндсэн хүснэгтэд гадаад серверт ч тохирох хост-маршрут нэм, эс бөгөөс дахин холбогдох үед гадаад клиентийн өөрийн тээвэр өөрийн туннель рүү маршрутлагдаж болно. Дараалал заавал байх ёстой: эдгээр бичлэгийг холбогдох интерфэйс үүссэний дараа нэм, өөрөөр хэлбэл холболтын дараа ажилладаг hook эсвэл скрипт. Унтарсан төхөөрөмж рүү заасан маршрут устгагдах эсвэл үл тоомсорлогдох тул ачаалах үед бичсэн бичлэг таний таамагласан дарааллыг давахгүй.

Бүх хүснэгтийг уншихын оронд хайлтыг шалга. Маршрутын хайлтын гаралт нь kernel-ийн ашиглах төхөөрөмж ба эх хаягыг заадаг бөгөөд клиент сокетоо нээх үед яг үүнийг авдаг.

Гинжийг туршиж, бүтэлгүйтлийг харагдахуйц болго

Дотоод клиент холбогдож байх үед гадаад интерфэйс дээр бариул. Дотоод гар барилт гадаад туннель дотор шифрлэгдсэн ачаа болж харагдах ёстой; хэрэв 203.0.113.9 рүү энгийн UDP болж харагдвал хост-маршрут байхгүй бөгөөд гинж хэзээ ч баригдаагүй.

Физик uplink руу чимээгүйгээр буцаж буй гинж нь хамгийн муу үр дүн, учир нь интерфэйсийн төлөв юу ч зарладаггүй, дотоод урсгал буруу эх хаягаас гардаг. Гадаад туннель унах үед хоёр дахь клиент шууд дахин холбогдож чаддаг бол тэр замыг унтраа эсвэл бүтэлгүйтэл харагдахын тулд гадаад интерфэйстэй холбо.

Хоёр урсгал ба нэг дүрмийн dump-аар дуусга: тэмдэглэгдсэн ба тэмдэглэгдээгүй холболт өөр өөр замаар явах ёстой, ip rule show нь таний зорьсон эрэмбийг жагсаах ёстой. Хоёр урсгал нэг замаар явбал тэмдэг таний бодож буй газарт хэрэглэгдэхгүй байна.

Холбоотой нийтлэлүүд