Укладзены WireGuard: сярэдні скачок не можа адказаць на свой порт
Калі сярэдні скачок адпраўляе ўсё ў адзін тунель, адказы на яго ўваходную службу выходзяць няправільным шляхам. Правіла зыходнага порта на інтэрфейсе выпраўляе гэта.
Тры скачкі WireGuard дасягаюць сеткі без публічнага адрасу, і тады сярэдняя машына перастае адказваць на порце, на якім павінна была слухаць. Тунель далей па-ранейшаму працуе, далёкі хост па-ранейшаму адказвае, і толькі сам сярэдні сервер змоўк звонку. Гэтае спалучэнне блытае менавіта таму, што яно створана ім самім: сярэдні скачок слухаецца сваёй табліцы маршрутызацыі, а табліца адпраўляе яго адказы не ў той бок.
Ланцуг, які працуе, пакуль вы не загаворыце з сярэдняй скрыняй
Вазьміце ілюстратыўны ланцуг: кліент A дасягае сервер B праз UDP 500, а B ідзе далей да сервера C праз UDP 500. C прымае трафік толькі з адрасу свайго адзінага партнёра, што робіць яго канцавым вузлом і захоўвае простыя паводзіны. B не канцавы вузел, і ўсё цікавае ў гэтым збоі адбываецца там.
Гэтая розніца важная, бо ролі канцавога і сярэдняга вузла цягнуць у процілеглыя бакі. Канцавы вузел можа адпраўляць усё ў адзін тунель без наступстваў, бо ад яго нічога іншага не залежыць. Сярэдні скачок адначасова з’яўляецца канцавой кропкай для кліентаў і кліентам у бок далёкага боку, і гэтыя дзве задачы хочуць рознай маршрутызацыі.
Чаму адказ выходзіць праз тунель
На B інтэрфейс, які глядзіць на C, нясе AllowedIPs = 0.0.0.0/0 разам з адпаведным маршрутам па змаўчанні. Таму кожны пакет, які стварае B, ідзе ў гэты тунель, калі нешта больш канкрэтнае не мае перавагі.
Пакет ад A, адрасаваны B, прыходзіць і прымаецца, бо B — гэта пункт прызначэння, а лакальная дастаўка адбываецца першай. Адказ — гэта цалкам новы, лакальна створаны пакет, накіраваны на публічны адрас A, і гэтае прызначэнне адпавядае маршруту па змаўчанні ў тунель. C атрымлівае яго, не валодае гэтым адрасам і адкідвае яго.
Сімптом чытаецца як праблема фаервала або несупадзенне ключоў, і ні тое, ні другое тут не праўда. Захоп на тунелі ў бок C паказвае, што адказы ідуць у няправільным кірунку. Гэта адно назіранне эканоміць больш часу, чым любое чытанне канфігурацыі, таму запішыце яго, перш чым пачынаць мяняць ключы. Кожны, хто не бачыў захопу, будзе лічыць, што зламаны сам тунель.
Вузкі рамонт: правілы палітыкі, якія супадаюць з портам крыніцы
Адказы з сокета, які слухае B, выходзяць з портам крыніцы 500. Правіла палітыкі можа супасці з гэтым і накіраваць гэтыя пакеты назад у звычайную табліцу:
ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101
Правілы палітыкі разглядаюцца ў парадку прыярытэту, а галоўная табліца знаходзіцца на 32766, таму правіла на 100 пытаецца раней, чым маршрут па змаўчанні тунеля атрымае слова. Дадайце адзін запіс на кожны порт, які павінен заставацца дасягальным звонку, і больш нічога, каб перанакіраваны трафік працягваў выкарыстоўваць тунель, для якога ён быў пабудаваны.
Ведайце мяжу гэтага прыёму. Селектар sport супадае з лакальна створанымі пакетамі, што ахоплівае менавіта выпадак адказу і наўмысна не ахоплівае трафік, які B проста перанакіроўвае за кагосьці іншага. Служба, размешчаная за B, па-ранейшаму мае патрэбу ў сваім адказе, і імітацыя іншага дае выпраўленне, якое працуе для першай службы і не працуе для другой.
Дайце правілу ўладальніка
Правіла, набранае ў запыце, знікае наступны раз, калі інтэрфейс перабудоўваецца. У наладзе WireGuard змяшчайце яго там, дзе інтэрфейс ствараецца і выдаляецца:
PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100
Калі інтэрфейсам валодае NetworkManager, хук дыстрыбутыва або пункт уваходу кантэйнера, пара належыць гэтаму ўладальніку, а не файлу, які рэдагуецца ўручную. Правярайце эфектыўныя правілы пасля перападлучэння, а не толькі пасля першага запуску, бо першы запуск — гэта выпадак, які заўсёды працуе.
Параўнайце альтэрнатывы сумленна
Правіла порта крыніцы — адзін з чатырох выхадаў, і самы вузкі з іх. У яго перавага: ён зусім не чапае палітыку тунеля, таму звычайна перажывае наступныя змены. Вузкія выпраўленні таксама гучна правальваюцца, калі перастаюць дзейнічаць, тады як шырокае выключэнне працягвае ціха працаваць яшчэ доўга пасля знікнення прычыны. Гэтая розніца мае большае значэнне, чым элегантнасць, калі праз два гады скрыняй валодае хтосьці іншы.
| Approach | What it costs | Where it breaks |
|---|---|---|
| Source-port policy rule | One rule per exposed port | Anything B forwards rather than originates |
| Destination exception route | A route pinned to specific client addresses | Clients whose address changes |
| Stop full-tunnelling on B | Loses the catch-all path toward C | Designs that depend on it |
| Split into two tunnels | More interfaces and more policy | Nothing, at the cost of complexity |
Праверце з абодвух канцоў, калі выбар зроблены. З A пачніце злучэнне да порта B і патрымайце яго занятым некаторы час. На B прымусьце ядро абгрунтаваць шлях адказу нечым накшталт ip route get <address-of-A> sport 500 і пераканайцеся, што ў ім названы інтэрфейс WAN, а не тунель. Пасля гэтага праверце, што нешта за C па-ранейшаму адказвае праз ланцуг, што даказвае, што выключэнне засталося вузкім, а не ператварылася ў абыход. Нарэшце, запішыце порты ў нататках да дызайну, інакш наступны аператар знойдзе гэта на іншай службе.