Три Linux домаќини, еден дизајн: јавно достапен OpenVPN центар, потрошувачки лаптоп и излезна машина зад обичен домашен рутер што ништо не проследува кон внатре. Излезот сам се јавува на центарот. Потоа интернет сообраќајот на потрошувачот влегува во тунелот на лаптопот и излегува низ сопствениот нагорен канал на излезот. Сѐ што е изненадувачко во овој распоред произлегува од еден детаљ: излезот ја започна врската, затоа патот кон внатре веќе постои и не е потребно проследување на порта за да се создаде.

Следново го следи патот на пакетот, а не редоследот на конфигурацијата, бидејќи конфигурацијата има смисла само кога знаете која компонента носи која одлука. Секој слој носи точно една одлука, а грешките се собираат таму каде што два слоја се земаат како еден.

Две транспортни сесии, еден внатрешен пат

Секој домаќин ја држи сопствената надворешна врска кон центарот, и ниту една од тие врски не знае за другата. Сообраќајот на потрошувачот кон интернет е одделен внатрешен тек што случајно се пренесува во тунелот на потрошувачот и потоа повторно се емитува од тунелот на излезот. Центарот треба да го рутира токму тој внатрешен тек, а излезот треба да го проследи.

outer: consumer --TLS--> hub
outer: exit     --TLS--> hub
inner: consumer --tun--> hub --internal--> exit --tun--> uplink

Бидејќи двете надворешни врски излегуваат од страната на клиентот, рутерот на излезот никогаш не гледа влезен SYN и никогаш не му треба правило за одредишен NAT. Треба само да го одржува воспоставениот транспорт жив, што веќе го прави за секоја долготрајна врска. Ништо на јавниот интернет не мора прво да стигне до излезот, затоа динамичната адреса на тој нагорен канал не е проблем. Рутерот сепак мора да ја дозволи излезната сесија, но тоа е истото дозвола што веќе ја користи прелистувачот.

Што всушност инсталира iroute во серверот

Центарот е единствениот уред што одлучува кој партнер поседува која одредиште, и таа одлука ја носи во сопствената табела за рутирање во кориснички простор, а не во табелата на јадрото. Запис client-config-dir за излезот со име exit-node може таму да го бара стандардниот префикс:

# /etc/openvpn/server/ccd/exit-node
iroute 0.0.0.0 0.0.0.0

Таа линија му кажува на серверскиот процес "внатрешни пакети со кое било одредиште припаѓаат на овој клиент". Не додава стандардна рута во оперативниот систем на центарот и не го прави центарот интернет портал. OpenVPN 2.6 прирачник го држи внатрешното рутирање специфично за клиентот и рутирањето на јадрото како одделни механизми, и токму тоа раздвојување е причината зошто дизајнот работи без допирање на стандардната рута на центарот.

На потрошувачот му треба огледална инструкција, доставена како push, за неговиот сообраќај да влезе во тунелот наместо да излезе низ локалниот портал. Со подмрежна топологија базенот е поврзана рута на tun уредот на излезот, затоа повратниот правец не бара дополнителен push; она што излезот не смее да го добие е пренасочувањето подолу, кое би го вратило неговиот нагорен сообраќај во тунелот што се обидува да го користи. Испратете го само до потрошувачот и читајте ги применетите рути на клиентот наместо да верувате дека CCD датотеката е избрана.

# /etc/openvpn/server/ccd/consumer-01
push "redirect-gateway def1"

Проследувањето го прави јадрото на излезот

Внатре во излезот пакет од потрошувачот пристигнува на tun интерфејсот, адресиран до некој интернет домаќин. Јадрото ја прегледува својата табела за рутирање, го наоѓа вистинскиот нагорен канал како најдобро совпаѓање и потоа применува две независни политики: смее ли овој пакет воопшто да се проследи и смее ли да излезе низ тој интерфејс со таа изворна адреса. Проследувањето е sysctl и во многу дистрибуции е исклучено по стандард.

Затоа на излезот му треба трајно вклучено IPv4 проследување, правило што ги прима изворите на тунелот на потрошувачот кон нагорниот канал и патот на одговорот назад низ tun. Вклучувањето проследување за целиот домаќин го менува и однесувањето на сѐ друго што се рутира низ него, затоа правилото треба да ги именува изворите и интерфејсите наместо да прифати сѐ.

Повратниот пат го купува преводот на изворот

Интернет домаќинот нема рута до адреса 10.90.0.x, затоа одговорите би биле отфрлени пред воопшто да стигнат до излезот. Препишувањето на изворот додека пакетот го напушта нагорниот канал го решава тоа, а следењето на врските го враќа препишувањето на повратниот пат.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp1s0 -j MASQUERADE
ip -4 route get 10.90.0.9   # run on the exit: must point at the tun

Правилото погоре е почетна точка за еден нагорен интерфејс, не firewall политика. Стеснете го изворот на задачите што навистина сте ги овластиле и држете ја сопствената влезна политика на излезот одделна, за да не ги изложи маскирањето на тунелскиот сообраќај тивко локалните услуги. На домаќин со динамична нагорна адреса, маскирањето ве штеди и од рачно следење на адресата.

Каде центарот може да спроведе, а каде не

Со client-to-client и традиционалниот кориснички податочен пат, центарот ги предава внатрешните пакети меѓу партнерите во серверскиот процес. Тие никогаш не ја поминуваат FORWARD веригата на јадрото на центарот, затоа правило во јадрото таму не може да го ограничи преминот меѓу партнерите, колку и внимателно да е напишано. Спроведувањето мора да живее во сопствената политика на серверот: кој смее да се поврзе, која CCD датотека ја добива и дали воопшто се дава стандардното владение на излезот.

Затоа стандардниот iroute е широка одлука за доверба. Излезот мора законски да прима повратен сообраќај од произволни интернет адреси и мора да биде машина што ја контролирате, ажурирате и надгледувате. Да се даде истото владение на партнер на кого не би му дале рутер е грешката кон која повикува овој дизајн.

Членството е вистинската контрола. Секој клиент што може да ги конфигурира сопствените рути може да се обиде да го користи излезот, затоа ограничувањето кој смее да се поврзе или на кои партнери излезот ќе им служи е дел од дизајнот, а не подоцнежна мисла.

Безбедно откажување кога излезот исчезнува

Исклучете го излезот и внатрешното стандардно владение исчезнува со неговата сесија. Она што не смее да се случи е центарот тивко да стане заменски излез: ниту стандардна рута од VPN базенот кон нагорниот канал на центарот, ниту широко правило за маскирање на центарот што со задоволство би го проследило истиот сообраќај. Тестирајте го тоа откажување намерно, а потоа тестирајте го закрепнувањето со свеж тек, а не со страница што веќе била отворена.

# on the consumer, with the exit up and then down
ip -4 route get 1.1.1.1
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com

Ако сообраќајот на потрошувачот сѐ уште стигнува до интернет откако излезот исчезнал, носи го нешто друго и границата што сте ја замислиле не постои. Третирајте ги DNS и IPv6 исто така како одделни одлуки: IPv4 рутата со маскирање не кажува ништо за AAAA сообраќајот, а резолверот што го турка центарот ќе одговара од онаму од каде барањето навистина излегува.

Поврзани статии