Две виртуални машини на един и същ хост достигат LAN през мост, а правило, поставено във веригата ip forward, показва брояч, който никога не се движи. Кадрите са реални, трафикът минава и правилото просто не е на пътя му. Сравняването на двата начина, по които Linux показва мостовия трафик, обяснява тишината и обяснява също защо зареждането на един стар модул е по-лош отговор, отколкото изглежда.

Два пътя през един хост

Пакетът може да напусне този хост по два много различни начина и разликата решава кои hook-ове ще го видят. Ако дестинацията е отвъд физически порт и кадърът се комутира между два порта на моста, хостът препраща Ethernet кадър; кодът за маршрутизация не се вика и не се случва маршрутизиран преход. Ако дестинацията е самият хост или мрежа, достигната през тунелен интерфейс, пакетът се маршрутизира и hook-овете на IP слоя наистина се прилагат. Дръжте това разклонение в ума, защото всеки следващ въпрос за вериги и семейства следва от това кой от двата пътя поема кадърът.

Това разграничение е цялата история зад правило, което не брои нищо. Кадър през мост от veth9a1 към enp3s0 пресича моста, а не IP стека, така че верига ip forward не вижда нищо за съпоставяне. Имената на интерфейсите в по-стар пример не решават кой път имате и затова първата стъпка е да погледнете топологията, а не набора от правила.

Тунелът добавя трети случай, който заслужава име. Устройство TUN доставя IP пакети към хоста, затова те се маршрутизират и наистина минават през IP вериги, докато устройство TAP, свързано към мост, доставя кадри и се държи като мостовия случай. Типът на устройството, а не името на продукта, решава.

Сравнете двете семейства, които могат да видят кадър през мост

Linux поддържа родна филтрация на мост чрез семейство bridge на nftables и не се нуждае от стар модул, за да преглежда и изхвърля кадри в движение. Собствената документация за моста на ядрото дава тази препоръка директно, което си струва да се знае, преди резултат от търсене да ви каже да заредите модул.

Observation pointWhat it seesWhat it costs
nftables bridge family chainsEthernet frames forwarded between bridge ports, in both directionsRules must be written in bridge syntax with link-layer matches
Legacy br_netfilter plus an ip chainBridged IPv4 and IPv6 packets, re-exposed through IP-layer hooksExisting host rules may begin matching traffic they never saw before
inet chain for routed trafficPackets the host routes, including traffic arriving from a TUN deviceNo visibility into purely switched frames

Използването на командата nft вместо iptables само по себе си не поставя правило в правилното семейство. Верига, декларирана в семейство bridge, вижда кадри; верига, декларирана в ip, ip6 или inet, не вижда, независимо кой двоичен файл я е създал. Семейството е свойство на веригата, не на инструмента, който я е написал.

Старият път работи различно и точно затова си струва да сравнявате, вместо да избирате страна по навик. Зареждането на br_netfilter и включването на настройките bridge-nf-call отново показва мостовия IPv4 и IPv6 трафик през hook-овете на IP слоя, така че обикновено правило в iptables най-накрая може да го съпостави. Кадрите не се променят; променя се наборът от hook-ове, през които минават, което означава, че всяко съществуващо правило на хоста вече има нова публика.

Прочетете ефективния път, преди да добавите правило

Три команди установяват къде сте: към какво е свързан мостът, дали старият модул е активен и какви вериги вече съществуват в семейство bridge. Изпълнете ги, преди да пишете каквото и да е, защото отговорът решава кой от двата дизайна разширявате. Пропускането на тази стъпка е начинът, по който правилно правило попада във верига, през която нищо не минава.

bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"

Изходът разделя случаите чисто. Портовете, изброени под моста, ви казват кои интерфейси се комутират; празен резултат от lsmod означава никаква видимост на IP слоя за кадрите през мост; съществуваща верига forward в семейство bridge означава, че собственик на политика вече има и вашето правило принадлежи там, а не в нова собствена верига.

След това добавете едно правило, което лесно се чете обратно, с брояч и без промяна на решението, и пуснете един представителен поток през моста. Брояч, който се движи, доказва, че кадърът е достигнал правилото. Това е всичко, което доказва, затова го последвайте и с отказания път, тъй като политика, която приема всичко, също дава движещ се брояч.

nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter accept

Къде старият модул променя поведението

Включването на стария път на работещ мост не е неутрално добавяне на видимост. Правила, които преди бяха недостъпни за мостовия трафик, стават достъпни, включително правила на хоста, писани за друг интерфейс, и политика drop по подразбиране във веригата ip forward може изведнъж да се приложи към кадри, които преди са минавали недокоснати. На хост, управляван през този мост, резултатът е заключване без конзола. Това не е хипотетичен режим на отказ; това е обичайната последица от разширяване на набор от hook-ове на машина, до която достигате през пътя, който току-що разширихте.

По-безопасната последователност е да решите кое семейство притежава политиката, да напишете правилата там и да запазите независим път за възстановяване, преди да промените какъвто и да е sysctl. Ако две семейства държат правила, документирайте кое е авторитетно; две припокриващи се политики са начинът пакет да бъде приет на едно място и изхвърлен на друго без нито един файл за четене.

Изолацията сама по себе си все още изисква пълен дизайн. Разрешаването на един източник към една дестинация доказва само, че един поток работи, докато изискването обикновено е ВМ да не може да достигне съседите си или хоста. Броячите на правилата за отказ са по-важни от брояча на правилото за приемане, защото броячът за приемане е този, който вече очаквахте да се движи.

Накрая, дръжте случая с входящия трафик на хоста отделно. Трафикът, адресиран до собствения IP на моста, пристига на input, не на forward, и правило във forward никога няма да го види, независимо кое семейство изберете. Три случая, две семейства, един урок: пътят решава hook-а, а hook-ът решава дали правилото ви съществува изобщо.

Подобни статии