Как захватить трафик на виртуальных интерфейсах?

12

Я хотел бы захватывать трафик на виртуальных интерфейсах Linux, для целей отладки. Я экспериментировал с veth, tunи dummyинтерфейсом типа; на всех трех у меня проблемы с тем, tcpdumpчтобы показать что-либо.

Вот как я настраивал фиктивный интерфейс:

ip link add dummy10 type dummy
ip addr add 99.99.99.1 dev dummy10
ip link set dummy10 up

В одном терминале смотрите это с tcpdump:

tcpdump -i dummy10

Через секунду послушайте nc:

nc -l 99.99.99.1 2048

В-третьих, сделайте HTTP-запрос с curl:

curl http://99.99.99.1:2048/

Хотя в терминале 2 мы можем видеть данные из curlзапроса, ничего не видно из tcpdump.

В руководстве по Tun / Tap проясняются некоторые ситуации, когда ядро ​​может фактически не отправлять какие-либо пакеты, когда оно работает на локальном интерфейсе:

Глядя на вывод tshark, мы видим ... ничего. Там нет трафика, проходящего через интерфейс. Это правильно: поскольку мы проверяем IP-адрес интерфейса, операционная система правильно решает, что пакет не должен отправляться «по проводам», и само ядро ​​отвечает на эти запросы. Если подумать, это именно то, что произойдет, если вы пропингуете IP-адрес другого интерфейса (например, eth0): пакеты не будут отправлены. Это может показаться очевидным, но поначалу может вызвать путаницу (это было для меня).

Однако трудно понять, как это может применяться к пакетам данных TCP.

Может быть, tcpdumpследует связать интерфейс с другим способом?

solidsnack
источник
Не уверен, почему трудно увидеть, что происходит с TCP-пакетами. Как и пинги, они обрабатываются в ядре. То же самое происходит.
Дероберт
@derobert В случае пингов ядро ​​может ответить. В случае пакетов данных, я скорее предполагал, что им придется «пройти» через интерфейс, чтобы приложение могло на них реагировать.
solidsnack
1
Приложения обращаются к ядру, используя чтение, запись и т. Д. Многие сетевые приложения даже не должны знать о существовании интерфейсов. Чтобы заставить трафик проходить через один из них, ядро ​​должно видеть его как нелокальный. Например, настройте туннель OpenVPN, тогда вы сможете захватывать трафик, проходящий через tun0. (Конечно, tun0 - это особый способ для приложений общаться с ядром, чтобы реализовать сетевой интерфейс в пользовательском пространстве, что и делает OpenVPN.)
derobert

Ответы:

8

Трафик идет через loинтерфейс.

Когда IP-адрес добавляется в поле, маршрут для этого адреса добавляется в «локальную» таблицу. Все маршруты в этой таблице направляют трафик через интерфейс обратной связи.

Вы можете просмотреть содержимое «локальной» таблицы следующим образом:

ip route show table local

Который в моей системе выглядит так:

local 10.230.134.38 dev tun0  proto kernel  scope host  src 10.230.134.38 
broadcast 10.230.134.38 dev tun0  proto kernel  scope link  src 10.230.134.38 
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
broadcast 172.17.0.0 dev docker0  proto kernel  scope link  src 172.17.42.1 
local 172.17.42.1 dev docker0  proto kernel  scope host  src 172.17.42.1 
broadcast 172.17.255.255 dev docker0  proto kernel  scope link  src 172.17.42.1 
broadcast 192.168.0.0 dev enp6s0  proto kernel  scope link  src 192.168.0.20 
local 192.168.0.20 dev enp6s0  proto kernel  scope host  src 192.168.0.20 
broadcast 192.168.0.255 dev enp6s0  proto kernel  scope link  src 192.168.0.20 

Поэтому в основном , если я отправить любой трафик 10.230.134.38, 127.0.0.0/8, 127.0.0.1(резервный) , 172.17.42.1или 192.168.0.20, трафик будет назначь через интерфейс обратной петли, даже если этот IP - адрес действительно на другой интерфейсе.

Патрик
источник
1

Вы можете использовать tcpdumpс любым интерфейсом на хосте ( tcpdump -i any ...)

Чарльз Нахель
источник
0

Это должно быть возможно путем вызова второй системы (может быть даже виртуальной машины на этом хосте).

Вы можете использовать DNATв OUTGOINGцепочке natтаблицы и перенаправить пакеты на интерфейс, который не контролируется ядром. Вы должны отразить их там:

iptables -t nat -A OUTPUT -p tcp -d 99.99.99.1 --dport 2048 \
  -j DNAT --to-destination 1.2.3.4
Хауке Лагинг
источник