Docker контейнерлеринин трафигин гана OpenVPN аркылуу багыттоо
Хостту кадимки uplink-те калтырып, бир контейнер ички тармагын туннелге салыңыз: NAT тартиби, булак эрежелери, OpenVPN iroute жана MSS текшерүүлөрү.
Контейнердин пакети эч качан tun0 -га жетпейт жана контейнердеги кошумча мүмкүнчүлүктөр муну өзгөртпөйт. Конок менен туннелдин ортосунда эки маршрут издөө бар: бири коноктун тармактык ат мейкиндигинде, экинчиси кадр көпүрөгө түшкөндөн кийин хостто, ал эми экинчиси башка дал келүү эрежелери бар башка таблицадан сурайт. Менин эталондук схемам — Linux хосту, анда OpenVPN кардары иштейт, ал 10.8.0.10 -ны tun0 -да кармайт, 172.18.0.0/16 -да Docker көпүрөсү жана туннел тарабы гана жете алган жеке дарек бар. Максат тар бойдон калат: ошол конок ички тармагы туннел аркылуу чыгат, хост кадимки uplink-ин сактайт.
VPN кардарын контейнердин ичинде жүргүзүү башка дизайн, кыска жол эмес. Анда контейнер өз туннелине жана каттоо маалыматтарына ээ болот, ал эми жумуш iptables-те калбай Dockerfile-га өтөт.
Кайра жиберүү маршрутту багыт боюнча тандайт, анан NAT булакты кайра жазат
Орнотулганда net.ipv4.ip_forward=1 , кайра жиберилген пакет негизги таблицада багыт боюнча гана маршрутталат. Булак бул чечимге катышпайт. Маршрут тандалгандан кийин гана ядро POSTROUTING -ны аткарат, жана дал ошол жерде Docker'дин өз эрежеси турат: -s 172.18.0.0/16 ! -o br-appnet -j MASQUERADE. Көпүрөдөн башка интерфейске чыккандын баары которулат, ал эми ал кандай дарекке айланары маршрут аны кайсы интерфейске жибергенине байланыштуу.
Бул эреже мага көп берилген симптомдордун көбүн түшүндүрөт. Эгер негизги таблицада жеке багытка маршрут жок болсо, пакет хосттун физикалык дареги менен uplink-тен чыгат. Провайдериңиз багытты таштайт, же алыскы сайт күтпөгөн RFC 1918 булагын таштайт, ал эми туннел туруп, соо турганда контейнер убакыттан өтөт. tun0 -дагы кармоо эч нерсе көрсөтпөйт, жана бул — белги. Эгер маршрут чындап tun0 -га багытталса, MASQUERADE булакты 10.8.0.10 -га кайра жазат, жана ошол эле контейнер сиз эч нерсеге тийбестен иштейт.
Коноктун булагын атаган издөөнү сураңыз. from жана iif жок болсо, хост өз сокети үчүн жооп берет жана кайра жиберилген пакет эч качан баспай турган жолду билдирет:
ip route get 192.168.11.222 from 172.18.0.5 iif br-appnetЭгер бул жооп uplink-ти атаса, туннел сүрөттө жок, жана туннел тараптагы эч бир параметр жардам бербейт.
Конокту туннелдин өз дарегине көчүрүңүз
Эң кичине иштеген өзгөртүү — чыгууда булакты ачык кайра жазуу. Аны кошуунун ордуна киргизиңиз: Docker буга чейин POSTROUTING -нын башында отурат, ошондуктан -A - менен кошулган эреже Docker'дикинен кийин бааланат жана эч качан иштебейт.
iptables -t nat -I POSTROUTING 1 -s 172.18.0.0/16 -o tun0 -j SNAT --to-source 10.8.0.10Бул сакталабы, аны эки шарт чечет. Дарек кардар чындап кармаган дарек болушу керек, ошондуктан аны ар бир кардар үчүн ifconfig-push 10.8.0.10 255.255.255.0 -ны камтыган жазуу менен бекитиңиз; эч качан берилбеген даректи атаган эреже тынч таштоолорду жаратат, ката эмес. Ал эми алыс тарап бул булакты кабыл алып, жоопторду кайра багыттоого тийиш, ошондуктан ал жердеги уруксат тизмеси конок ички тармагын эмес, туннел дарегин атайт. Кардар дареги динамикалык болсо, -j MASQUERADE - менен -o tun0 интерфейстегини ээрчийт, бирок туруктуу мааниге каршы жаза албаган алыс саясаттын баасы менен.
Чыпкалоо — экинчи жарымы. Docker FORWARD саясатын drop-ко коёт жана ар бир демон кайра башталганда өзүнө таандык чынжырларды тазалайт, ошондуктан жергиликтүү саясатты DOCKER-USER -га салыңыз, ал аман калат:
iptables -I DOCKER-USER -i br-appnet -o tun0 -j ACCEPT
iptables -I DOCKER-USER -i tun0 -o br-appnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTКайтаруу эрежеси маанилүү: tun0 -га келген жооп көпүрө аркылуу ачылган байланыш үчүн чыгуу багыты кабыл алынгандыктан гана кабыл алынбайт.
Хостту булак эрежеси менен түз кармаңыз
Бүт көпүрө туннелди колдонушу керек, бирок хосттогу башка эч нерсе колдонбошу керек болсо, NAT-ты өткөрүп жиберип, ошол булакка өз таблицасын бериңиз. Конок даректери анда башынан аягына чейин көрүнүп турат.
echo "200 vpnbox" >> /etc/iproute2/rt_tables
ip rule add from 172.18.0.0/16 lookup vpnbox pref 1000
ip route add default dev tun0 table vpnboxЭрежелер негизги таблицадан мурун каралат, жана from булакка дал келет. Туннелдин өз сырткы пакеттери хосттун физикалык булагын алып жүрөт, ошондуктан алар эч качан from 172.18.0.0/16 -га дал келбейт, жана туннел өзүн өзүнө кайра багыттай албайт. Дал ушул өзүн-өзү чыгарып салуу схеманы туруктуу кылат.
Кайтаруу жолуна эми жардам керек. Алыс тарап которулбаган 172.18.0.x -ны көрөт жана анын кайда жашаарын билүүгө себеби жок. Серверде ар бир кардар үчүн файлга iroute 172.18.0.0 255.255.0.0 керек, сервердин ички таблицасы ошол префиксти ушул кардарга берсин, жана түртүлгөн route 172.18.0.0 255.255.0.0 керек, башка кардарлар анын бар экенин билсин.
Ишенүүнүн алдында эки текшерүү. Иштетиңиз ip route show default -ды: redirect-gateway def1 - менен таблицада 0.0.0.0/1 жана 128.0.0.0/1 бар tun0 аркылуу, ал эми хост такыр түз эмес, анткени бул жарым-демейкилер default -ны алмаштырбастан жеңет. ip rule add - менен кошулган эрежелер да кайра жүктөөдө жоголот, ошондуктан аларды up скриптке алып жүрүңүз.
Пакеттин өлчөмү — экинчи жолуга турган бузулуу
1500 байттык көпүрө интерфейси сырткы UDP жана IP аталыштары кошулганда туннелге ал көтөрө алгандан көбүрөөк берет. Кичине алмашуулар өтөт, ошондуктан DNS чечилет жана TLS кол алышуусу бүтөт, анан чоңураак жүктөө эч жерде катасыз илинип калат. Жөнөтүүчү ошол эле сегмент өлчөмүн кайталай берет, анткени ага кичирейтиш керек деп айта турган ICMP фрагментация керектиги тууралуу билдирүү эч качан жетпейт.
Аны интерфейсте, MSS-те же экөөндө тең оңдоңуз. Кысуу коноктун кызматташуусун талап кылбайт:
ip link set dev tun0 mtu 1400
iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtuКысуу тек TCP-ны кайра жазат. UDP, QUIC кошо, анын ордуна төмөндөгөн конок интерфейсин талап кылат, --opt com.docker.network.driver.mtu=1400 - менен тармак түзүүдө же тиешелүү compose ачкычы менен.
DNS жана кайталоого татыктуу текшерүүлөр
Аттарды чечүү ошол эле жол менен жүрөт. Docker'дин курулган чечүүчүсү 127.0.0.11 -да хосттун конфигурацияланган серверлерине жиберет, ошондуктан контейнер хост колдонгонду мураска алат. Жеке зонага туннел аркылуу гана жетүүчү чечүүчү жооп берсе, конокту ошол дарекке багыттаңыз, жана getent hosts - менен контейнердин ичинде текшериңиз, хостто эмес.
- Ийгиликсиз сурамды коноктун ичинде иштетиңиз; хост тараптагы сыноо башка булак дарегин колдонот жана маселени жашырат.
- Кошкон NAT жана чыпка эрежелеринин эсептегичтерин окуңуз. Нөл дал келүүсү бар эреже — маршруттоо катасы, саясат катасы эмес.
- SNAT эрежеңиздеги туннел дареги кардар чындап кармаган дарек экенин ырастаңыз.
- Серверди токтоп калганы үчүн күнөөлөөдөн мурун коноктун MTU-сун төмөндөтүңүз же MSS-ти кысыңыз.
Тизмени ылдый жүрүп, биринчи бузулууда токтоңуз. Дал ошол катмарды оңдоо керек; төмөнүрөөк кошулгандын баары сынып жаткан чекти гана жашырат.