Хаст бразіць праз тунэль, а кантэйнер побач не дасягае нічога. Апублікаваць порт з кантэйнера, які мае ўласны кліент VPN, яшчэ горш: запыт прыходзіць, а адказ ніколі не выходзіць. Абодва — гэта рашэнні аб маршрутызацыі на хасце, а Docker — толькі пасыльны.

Тры пытанні вызначаюць, які з двух выпадкаў перад вамі, і гэта займае каля хвіліны.

Дзве паломкі, якія выглядаюць аднолькава

Першая — праблема зваротнага шляху. Апублікаваны порт транслюецца ў кантэйнер, запыт прыходзіць, а адказ маршрутызуецца праз маршрут па змаўчанні хаста, які кліент OpenVPN накіраваў на tun0. Адказ выходзіць з адраса, якога аддалены партнёр не чакае, і адкідваецца. Другая — сутыкненне прэфіксаў: маст Docker па змаўчанні валодае 172.17.0.0/16, а карпаратыўны тунэль прасоўвае той жа дыяпазон.

Адна выпраўляецца табліцай маршрутызацыі, другая — перанумарацыяй моста. Рэдагаваць, пакуль не ведаеш, што ёсць што, — гэта спосаб зламаць працоўны кантэйнер.

Вырашыце трыма пытаннямі

Пытанне першае: ці знікае памылка, калі вы спыняеце VPN? Калі ўсё працуе пры адключаным тунэлі, падазравайце зваротны шлях. Пытанне другое: ці пералічвае ip route show table all той самы прэфікс двойчы — адзін раз на мосце, адзін раз на tun0? Гэта і ёсць сутыкненне. Пытанне трэцяе: пацярпелы адрас — гэта кантэйнер, госць NAT ці госць, падключаны праз мост?

Трэцяе пытанне важнае, бо ў кожнага сваё правільнае рашэнне, а прымяненне рашэння для кантэйнера да госця libvirt марнуе вечар.

ip route
ip route show table all | grep -E '172\.1[7-9]|10\.8'
docker network inspect bridge --format '{{.IPAM.Config}}'

Зваротны шлях: табліца для аднаго адраса крыніцы

Калі трафік кантэйнера павінен выходзіць праз фізічны інтэрфейс, пакуль сам хаст выкарыстоўвае тунэль, маршрутызацыя па крыніцы — гэта найменшае змяненне. Дадайце правіла, якое супадае з адрасам кантэйнера, і накіруйце яго ў асобную табліцу. Больш нішто на хасце не рухаецца.

ip rule add from 172.22.0.3 lookup 10
ip route add default via 172.22.0.1 table 10

Кожны пакет, крыніца якога — гэты адрас, спачатку звяртаецца да табліцы 10, і табліца 10 накіроўвае яго на шлюз моста, а не ў тунэль.

Праверце з дапамогай ip route get 1.1.1.1 from 172.22.0.3. Адказ павінен называць інтэрфейс моста, а не tun0. Правілы, дададзеныя такім чынам, знікаюць пры перазагрузцы, таму змясціце іх у unit або сеткавы хук, які валодае кантэйнерам.

Той жа шаблон працуе для кантэйнера WireGuard, дзе зваротны шлях таксама патрабуе яўнага правіла.

Сутыкненне прэфіксаў: перанумаруйце мост

Табліца маршрутаў накіроўвае адзін прэфікс у адно месца. Калі VPN прасоўвае 172.17.0.0/16, а мост Docker ужо там, перамагае меншая метрыка: Docker усталёўвае свой падключаны маршрут з метрыкай 0, а прасунуты маршрут прыходзіць з 50. Тады тунэль выглядае зламаным, пакуль Docker працягвае працаваць, або наадварот — у залежнасці ад парадку ўсталявання. Перанумаруйце мост замест барацьбы з метрыкай.

{
  "bip": "10.200.0.1/24",
  "default-address-pools": [{"base": "10.201.0.0/16", "size": 24}]
}

Перазапусціце Docker пасля змены і перастварыце сеткі, пабудаваныя на старым пуле. Змена метрыкі замест гэтага толькі пераносіць канфлікт на наступную загрузку.

VM патрабуюць яшчэ іншага адказу

Госць libvirt у сетцы NAT па змаўчанні ўспадкоўвае маршрутызацыю хаста і перастае дасягаць знешняга свету, як толькі тунэль хаста авалодвае маршрутам па змаўчанні. Пераключэнне госця на мост або прыладу macvtap дае яму ўласны шлях у фізічнай сетцы. У virt-manager дадайце абсталяванне, выберыце Network, задайце крыніцу як хост-прыладу macvtap, пакіньце virtio у якасці мадэлі, затым адключыце стары інтэрфейс NAT.

Госць macvtap звычайна не можа дасягнуць свайго хаста. Гэта чаканыя паводзіны, а не памылка, і гэта варта запісаць у нататку, якую вы пакідаеце.

Для госця, якому патрэбна толькі LAN хаста, у кліенце пастаўшчыка можа быць адсутны перамыкач: з Mullvad mullvad lan set allow аднаўляе лакальную дасяжнасць, не закранаючы libvirt. А калі кантэйнер павінен быць дасяжным толькі праз тунэль, прывяжыце апублікаваны порт да адраса тунэля, -p 10.8.0.5:8080:8080, замест публікацыі на кожным адрасе.

Падобныя артыкулы