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

Два шляхі праз адзін хост

Пакет можа пакінуць гэты хост двума вельмі рознымі шляхамі, і гэтая розніца вызначае, якія хукі яго ўбачаць. Калі прызначэнне знаходзіцца за фізічным портам і кадр камутуецца паміж двума партамі моста, хост перасылае кадр Ethernet; код маршрутызацыі не задзейнічаецца, і ніводзін маршрутызаваны пераход не адбываецца. Калі прызначэнне — сам хост або сетка, дасяжная праз інтэрфейс тунеля, пакет маршрутызуецца, і хукі ўзроўню 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 праз мост праз хукі ўзроўню IP, так што звычайнае правіла iptables урэшце можа яго супаставіць. Кадры не змяняюцца; змяняецца набор хукаў, праз якія яны праходзяць, а гэта значыць, што кожнае існуючае правіла хоста атрымала новую аўдыторыю.

Прачытайце эфектыўны шлях перад даданнем правіла

Тры каманды вызначаюць, дзе вы: да чаго далучаны мост, ці актыўны састарэлы модуль і якія ланцугі ўжо існуюць у сямействе 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 можа раптам пачаць дзейнічаць на кадры, якія праходзілі некранутымі. На хосце, якім кіруюць праз гэты мост, вынік — блакаванне без кансолі. Гэта не гіпатэтычны рэжым адмовы; гэта звычайны вынік пашырэння набору хукаў на машыне, да якой вы дабіраецеся праз шлях, які вы толькі што пашырылі.

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

Ізаляцыя сама па сабе ўсё яшчэ патрабуе поўнага дызайну. Дазвол адной крыніцы да аднаго прызначэння даказвае толькі, што адзін паток працуе, а патрабаванне звычайна ў тым, што ВМ не можа дасягнуць суседзяў або хоста. Лічыльнікі на правілах адмовы важнейшыя за лічыльнік на правіле прыёму, бо лічыльнік прыёму — гэта той, які вы ўжо чакалі ўбачыць рухомым.

Нарэшце, трымайце выпадак уваходу хоста асобна. Трафік, адрасаваны ўласнаму IP моста, прыходзіць на input, а не на forward, і правіла ў forward ніколі яго не ўбачыць, якое б сямейства вы ні выбралі. Тры выпадкі, два сямействы, адзін урок: шлях вызначае хук, а хук вызначае, ці існуе вашае правіла наогул.

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