Едно приложение през WireGuard: обвързването не е маршрутизация
Обвързването на приложение към wg0 задава само неговия адрес на източника. Ядрото все още се нуждае от таблица с маршрутите на тунела и от правило, което изпраща този източник там.
Настройката изглежда като превключвател за отделно приложение, затова хората обвързват клиента с интерфейса WireGuard и очакват само този клиент да използва тунела. Обвързването всъщност избира адрес на източника. След това ядрото търси маршрут за дестинацията, намира обичайния маршрут по подразбиране и изпраща пакета през физическата връзка с прикачен адрес на тунела. Само маршрут, избран за този адрес на източника, изпълнява намерението.
Механизмът има две половини: таблица за маршрутизация, която само трафикът на тунела трябва да използва, и правило, което изпраща съответстващия източник там.
Обвързването задава адрес на източника и нищо повече
Linux избира изходящ интерфейс, като търси дестинацията в таблица за маршрутизация, след като правилата на политиката са получили шанс да пренасочат това търсене. Правилата могат да избират по адрес на източника, маркер на защитната стена, входящия интерфейс, UID или дори порт; всяко от тях е друг начин да се каже този трафик, а не целият. Конфигурацията на VPN клиента избира таблицата, която съдържа маршрутите на тунела; правилото избира кой трафик има право да се обръща към нея. Самото обвързване не дава нито едно от двете.
Ето защо отказът изглежда толкова странно. Приложението със сигурност използва адреса на тунела, тунелът със сигурност работи и трафикът със сигурност излиза през грешния интерфейс. Всяко твърдение е вярно, а заедно те описват система, в която нищо не е свързало адреса с маршрута.
Дайте на тунела собствена таблица
wg-quick инсталира маршрути там, където му каже профилът. Добавянето на Table = 40 под [Interface] ги премества в таблица 40 вместо в основната таблица. Вдигнете интерфейса и потвърдете, че са пристигнали: ip -4 route ls table 40 трябва да покаже маршрутите на тунела, а ip -4 route get 10.66.127.142 показва как ядрото в момента разрешава един от тях. С маршрутите в собствена таблица основната таблица продължава да работи за всичко останало.
Направете същото за IPv6, вместо да съпоставяте широк префикс. ip -6 rule add from fd00::2/128 lookup 40 заковава един адрес; fc00::/8 може да се сблъска с други интерфейси на хоста и да създаде правило, което съвпада с повече от предвиденото.
Добавете правилото за източника и следете броячите
След това свържете половинките: ip -4 rule add from 10.66.127.142/32 lookup 40, със същия адрес, прикачен към интерфейса WireGuard. Сложете двете правила в PostUp, за да ги възстанови повторното свързване. Проверете с истинска заявка, а не с настройка: ip route get 1.1.1.1 from 10.66.127.142 трябва да назове устройството на тунела, а curl --interface wg0 ifconfig.me да съобщи адреса на тунела, а не домашния.
Когато все още не работи, прочетете ip -s rule. Правило, което съществува, но никога не е съвпаднало, показва нулеви броячи и това разграничава грешно правило от липса на правило. Тази една команда спестява много догадки дали приложението е пренебрегнало настройката за интерфейс.
Обратният случай: задръжте SSH извън тунела
Обратният проблем е също толкова често срещан: wg-quick притежава маршрута по подразбиране и SSH сесията към сървъра умира по средата. Правилата му стоят на нисък номер за приоритет, затова изключение трябва да се оценява по-рано от тях. ip rule add dport 22 ipproto tcp table main priority 123 прави това в скорошен iproute2; където селекторът липсва, маркирайте потока в nftables и съпоставете маркера.
Проверете и пътя на отговора. SSH сесия, която се установява и след това замлъква, обикновено има асиметрична маршрутизация: едната посока излиза през тунела, а другата през физическия интерфейс. ip route get за адреса на сървъра ви казва накъде ще тръгне отговорът.
Запишете номера на таблицата, правилото за източника и изключението в самия профил. И трите принадлежат към един дизайн и ще се редактират заедно.