Соединение двух интерфейсов крана

Я абсолютный новичок, это мой первый эксперимент с сетевым ядром. Я пытаюсь создать мост между двумя tap интерфейсы, и попробуйте отправить трафик через. Это скорее эксперимент, чем для какой-то конкретной цели.

$ brctl showstp br0
br0
bridge id      8000.46846e0c0ff9
designated root    8000.46846e0c0ff9
root port         0            path cost          0
max age          20.00         bridge max age        20.00
hello time        2.00         bridge hello time      2.00
forward delay        15.00         bridge forward delay      15.00
ageing time         300.00
hello timer           1.98         tcn timer          0.00
topology change timer     0.00         gc timer         115.04
flags          


tap1 (1)
port id        8001            state            forwarding
designated root    8000.46846e0c0ff9   path cost        100
designated bridge  8000.46846e0c0ff9   message age timer      0.00
designated port    8001            forward delay timer   10.34
designated cost       0            hold timer         0.98
flags          

tap2 (2)
port id        8002            state            forwarding
designated root    8000.46846e0c0ff9   path cost        100
designated bridge  8000.46846e0c0ff9   message age timer      0.00
designated port    8002            forward delay timer    0.00
designated cost       0            hold timer         0.98
flags          

У меня есть мост br0 создан с обоими tap1 а также tap2 добавлено. У меня есть программа, внедряющая пакеты ARP в tap1 с помощью libpcap, Wireshark правильно показывает входящие пакеты tap1, Тем не менее, ни один пакет не отображается в tap2, Я попытался добавить следующее правило в ebtables:

sudo ebtables -I INPUT --log --log-level debug

Пакеты не отображаются в журналах. Я буду признателен за любые материалы.

РЕДАКТИРОВАТЬ: Добавление дополнительной информации. Внедрение поддельных пакетов - это действительно приложение. Мое намерение состоит в том, чтобы смоделировать, полностью программно и без виртуальных машин, как пакеты перенаправляются через стек ядра Linux. Я не создаю новые сетевые пространства имен. Возможно в этом проблема?

У меня только два процесса. Процесс "чтения" имеет файловый дескриптор, открытый для tap2и постоянно пытается читать с него. Процесс записи имеет файловый дескриптор, открытый для tap1 и ждет, пока пользователь не отправит запрос ARP. ARP-запрос имеет случайный IP-адрес источника. MAC-адрес источника устанавливается как MAC-адрес tap1, Вот вывод команды tcpdump:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tap1, link-type EN10MB (Ethernet), capture size 262144 bytes
^[[A07:19:57.752990 ARP, Request who-has google-public-dns-a.google.com tell 0.0.248.17, length 28
    0x0000:  ffff ffff ffff ba9c 0589 16ad 0806 0001
    0x0010:  0800 0604 0001 ba9c 0589 16ad 0000 f811
    0x0020:  0000 0000 0000 0808 0808

Я настроил tap1 а также tap2 не иметь IP-адресов. Может ли это быть проблема?

brctl addbr br0
ip tuntap add name tap1 mode tap
ip tuntap add name tap2 mode tap
brctl addif br0 tap1
brctl addif br0 tap2
ifconfig tap1 0.0.0.0 up
ifconfig tap2 0.0.0.0 up
ifconfig br0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255
ip link set br0 up
ip link set tap1 up
ip link set tap2 up

Основываясь на ответе, я проверил прикрепление различных приложений к tap2, Я замечаю это: когда ни одно приложение не использует tap1 или же tap2оба интерфейса не имеют установленного флага LOWER_UP.

4: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff
25: tap1: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 500
    link/ether ba:9c:05:89:16:ad brd ff:ff:ff:ff:ff:ff
26: tap2: <NO-CARRIER,BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT group default qlen 500

Когда я запускаю приложения, устанавливается флаг LOWER_UP:

4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff
25: tap1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT group default qlen 500
    link/ether ba:9c:05:89:16:ad brd ff:ff:ff:ff:ff:ff
26: tap2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP mode DEFAULT group default qlen 500
    link/ether 46:84:6e:0c:0f:f9 brd ff:ff:ff:ff:ff:ff

Мне жаль, что это оказывается длинным, я просто надеюсь, что информации достаточно, чтобы разобраться в проблеме.

1 ответ

На всякий случай, потому что вы сказали, что вы полный нуб: интерфейс tun (уровень 3) или tap (уровень 2) является конечной точкой сетевого интерфейса приложения, и приложение может считывать и записывать пакеты из этого сетевого интерфейса. Что вы создаете с ip tuntap add ... или устаревший tunctl являются постоянными именами для таких конечных точек, и вы, как правило, по-прежнему будете запускать приложение, и оно ничего не сделает, если вы не запустите приложение.

Поскольку приложение взаимодействует с сетевым интерфейсом в целях проектирования, нет необходимости "внедрять" пакеты в стороннее приложение, если вы не подразумеваете под "внедрением" это нормальное взаимодействие, которое я описал.

Также, если вы хотите поиграть с сетью, я могу порекомендовать вам использовать сетевые пространства имен и пары веток. По сути, вы можете настроить на своем компьютере множество виртуальных компьютеров, которые могут имитировать обмен данными между реальными компьютерами в сети.

Поэтому, если вы хотите сделать это и не хотите играть с собственным приложением, создающим и принимающим пакеты, вам не нужен интерфейс tun / tap.

Тем не менее, я только что проверил вашу настройку, с небольшим изменением, потому что вы не сказали, что вы используете для "инъекции" пакетов: я использовал два socat s, чтобы создать, чтобы коснуться конечной точки tap0a а также tap1a Затем я соединил их и использовал еще два socatS в двух разных пространствах имен, чтобы создать правильные пакеты для меня. Они должны находиться в другом пространстве имен, так как локальные пакеты всегда будут доставляться через обратную связь lo,

И, как и ожидалось, мостовые отводные устройства работают просто отлично.

Итак, я полагаю, что проблема в пакете, который вы вводите: неверный адрес Ethernet или нет широковещательной рассылки. Пожалуйста, измените ваш вопрос с помощью tcpdump -xx ... вывод, когда вы вводите пакет ARP.

Или, может быть, вы хотите создать сетевые пространства имен и соединить две конечные точки двух пар веток? Это намного проще.

редактировать

Пакет ARP выглядит хорошо. Кажется, что нет приложения, подключенного к tap2, Если вы делаете ip link, вы не должны видеть LOWER_UP флаг для tap2, Угадайте: мост обнаруживает, что устройство работает только частично, и не отправляет пакеты на этот порт.

Попробуйте заменить его на tap с которым связано приложение, что-то вроде

sudo socat TUN:10.0.2.2/24,tun-name=tapx,tun-type=tap,iff-up - | hexdump -C

(10.0.2.2/24 адрес ничего не делает, но socat не будет работать, если вы не укажете адрес), а в другом терминале

sudo ip link set tapx master br0

(который заменяет brctl addif), затем внедрите ваш пакет несколько раз и посмотрите, нет ли в первом окне hexdump. Также проверьте для LOWER_UP с ip link show dev tapx,

КСТАТИ, ifconfig а также brctl устарели. использование ip а также bridge вместо.

Не назначать IP-адреса для портов моста не имеет значения, поскольку порты моста не имеют IP-адресов (если они получили некоторые назначенные им до того, как они были порабощены мостом, они игнорируются). Смотрите, например, здесь.

Я боролся с этим и думаю, что нашел решение. Или, по крайней мере, лучшее понимание того, что происходит.

Важно помнить, что единственный способ доставить пакет в интерфейс крана на принимающей стороне ("RX") - записать этот пакет в дескриптор сокета, созданный процессом, который открыл крана (через open("/dev/net/tun",...) а также ioctl). Только один процесс может иметь этот файловый дескриптор одновременно. Если устройство крана открыто, и другой процесс пытается повторно открыть другое устройство с тем же именем, этот системный вызов не будет выполнен.

Поэтому, когда у вас есть какой-либо другой процесс, например, wireshark, откройте необработанный сокет и затем привязайте его к tap0, он способен только выводить трафик из системы (с точки зрения ядра). То есть, Wireshark должен быть н TX счетчик tap0, и только RX пакеты будут перенаправлены на мостовой интерфейс.

Вы можете проверить счетчики для каждого, как:

#!/bin/bash
for if in tap{0,1}; do
    stats=/sys/class/net/$if/statistics/
    rx=$(cat $stats/rx_packets)
    tx=$(cat $stats/tx_packets)
    echo "$if: rx=$rx, tx=$tx"
done

который выводит что-то вроде:

tap0: rx=0, tx=6
tap1: rx=0, tx=5

Так что в вашем конкретном случае я подозреваю, что проблема здесь:

У меня есть программа инъекций ARP пакеты в tap1 используя libpcap. Wireshark правильно показывает входящие пакеты tap1, Тем не менее, ни один пакет не отображается в tap2,

Как вы вводите пакеты ARP в tap1? Я полагаю, Wireshark не звонит fd = open("/dev/net/tun", ...) а также ioctl(fd, TUNSETIFF, ...) Таким образом, отправленные пакеты будут передаваться по TX и, следовательно, не будут соединены.

Вам понадобится программа, которая открывается tap0 записывать пакеты в tap0 файловый дескриптор, чтобы получить эти пакеты для пересылки br0 и появиться на tap1,

Другие вопросы по тегам