Недавно я установил новый сервер Ubuntu 10.04 и заметил, что мой UDP-сервер больше не может видеть какие-либо данные многоадресной рассылки, отправленные на интерфейс, даже после присоединения к группе многоадресной рассылки. У меня точно такая же настройка на двух других машинах Ubuntu 8.04.4 LTS, и нет проблем с получением данных после присоединения к той же группе многоадресной рассылки.
Карта Ethernet - это Broadcom netXtreme II BCM5709, и используемый драйвер:
b $ ethtool -i eth1
driver: bnx2
version: 2.0.2
firmware-version: 5.0.11 NCSI 2.0.5
bus-info: 0000:01:00.1
Я использую smcroute для управления своими многоадресными регистрациями.
b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71
После присоединения к группе ip maddr показывает добавленную регистрацию.
b$ ip maddr
1: lo
inet 224.0.0.1
inet6 ff02::1
2: eth0
link 33:33:ff:40:c6:ad
link 01:00:5e:00:00:01
link 33:33:00:00:00:01
inet 224.0.0.1
inet6 ff02::1:ff40:c6ad
inet6 ff02::1
3: eth1
link 01:00:5e:25:36:47
link 01:00:5e:25:36:3e
link 01:00:5e:25:36:3d
link 33:33:ff:40:c6:af
link 01:00:5e:00:00:01
link 33:33:00:00:00:01
inet 233.37.54.71 <------- McastGroup.
inet 224.0.0.1
inet6 ff02::1:ff40:c6af
inet6 ff02::1
Пока все хорошо, я вижу, что получаю данные для этой группы многоадресной рассылки.
b$ sudo tcpdump -i eth1 -s 65534 host 233.37.54.71
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65534 bytes
09:30:09.924337 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:09.947547 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:10.108378 IP 192.164.1.120.58866 > 233.37.54.71.15574: UDP, length 268
09:30:10.196841 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
...
Я также могу подтвердить, что интерфейс принимает пакеты mcast.
b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33
Теперь вот в чем проблема. Когда я пытаюсь захватить трафик с помощью простого UDP-сервера ruby, я получаю нулевые данные! Вот простой сервер, который считывает данные, отправленные через порт 15572, и печатает первые два символа. Это работает на двух серверах Ubuntu 8.04.4, но не на сервере 10.04.
require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
text, sender = s.recvfrom(2)
puts text
end
Если я отправлю UDP-пакет, созданный на ruby, на localhost, сервер получит его и распечатает первые два символа. Итак, я знаю, что указанный выше сервер работает правильно.
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> s = UDPSocket.new
=> #<UDPSocket:0x7f3ccd6615f0>
irb(main):003:0> s.send("I2 XXX", 0, 'localhost', 15572)
Когда я проверяю статистику протокола, я вижу, что InMcastPkts не увеличивается. В то время как на других серверах 8.04 в той же сети было получено несколько тысяч пакетов за 10 секунд.
b $ netstat -sgu ; sleep 10 ; netstat -sgu
IcmpMsg:
InType3: 11
OutType3: 11
Udp:
446 packets received
4 packets to unknown port received.
0 packet receive errors
461 packets sent
UdpLite:
IpExt:
InMcastPkts: 4654 <--------- Same as below
OutMcastPkts: 3426
InBcastPkts: 9854
InOctets: -1691733021
OutOctets: 51187936
InMcastOctets: 145207
OutMcastOctets: 109680
InBcastOctets: 1246341
IcmpMsg:
InType3: 11
OutType3: 11
Udp:
446 packets received
4 packets to unknown port received.
0 packet receive errors
461 packets sent
UdpLite:
IpExt:
InMcastPkts: 4656 <-------------- Same as above
OutMcastPkts: 3427
InBcastPkts: 9854
InOctets: -1690886265
OutOctets: 51188788
InMcastOctets: 145267
OutMcastOctets: 109712
InBcastOctets: 1246341
Если я попытаюсь принудительно переключить интерфейс в режим promisc, ничего не изменится.
На этом я застрял. Я подтвердил, что в конфигурации ядра включена многоадресная рассылка. Возможно, мне стоит проверить другие параметры конфигурации?
b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y
Есть мысли о том, куда идти дальше?
В нашем случае наша проблема была решена с помощью параметров sysctl, отличных от Maciej.
Обратите внимание, что я не говорю о OP (buecking), я пришел к этому сообщению из-за проблемы, связанной с основными деталями (отсутствие многоадресного трафика в пользовательском пространстве).
У нас есть приложение, которое считывает данные, отправленные на четыре адреса многоадресной рассылки и уникальный порт для каждого адреса многоадресной рассылки, с устройства, которое (обычно) подключено непосредственно к интерфейсу на принимающем сервере.
Мы пытались развернуть это программное обеспечение на сайте клиента, но при загадочном сбое по неизвестной причине. Попытки отладки этого программного обеспечения привели к проверке каждого системного вызова, и в конечном итоге все они сказали нам одно и то же:
Наше программное обеспечение запрашивает данные, а ОС их никогда не предоставляет.
Счетчик многоадресных пакетов увеличился, tcpdump показал, что трафик достигает интерфейса / бокса, но мы ничего не могли с этим поделать. SELinux был отключен, iptables работал, но не имел правил ни в одной из таблиц.
Мы были в тупике.
Случайно ковыряясь, мы начали думать о параметрах ядра, которые обрабатывает sysctl, но ни одна из задокументированных функций не была особенно актуальной, или, если они имели отношение к многоадресному трафику, они были включены. Да, и ifconfig действительно перечислил "MULTICAST" в строке функций (up, broadcast, running, multicast). Мы из любопытства посмотрели /etc/sysctl.conf
. И вот, к базовому изображению этого клиента добавлено несколько дополнительных строк внизу.
В нашем случае заказчик установил net.ipv4.all.rp_filter = 1
. rp_filter - это фильтр Route Path, который (насколько я понимаю) отклоняет весь трафик, который не мог достичь этого поля. Переключение между подсетями в сети с мыслью, что исходный IP-адрес подделывается.
Итак, этот сервер находился в подсети 192.168.1 / 24, а исходный IP-адрес устройства для многоадресного трафика находился где-то в сети 10. *. Таким образом, фильтр не позволял серверу делать что-либо значимое с трафиком.
Пару настроек, одобренных заказчиком; net.ipv4.eth0.rp_filter = 1
и net.ipv4.eth1.rp_filter = 0
и мы счастливо бежали.
TL / DR Также убедитесь, что ваша мультикастинг не исходит от vlan. tcpdump -e
поможет определить, есть ли у них.
Честно говоря, кто-то должен создать страницу с контрольным списком вещей, которые могут предотвратить попадание многоадресной рассылки в пользовательское пространство. Я боролся с этим пару дней, и, естественно, ничего, что я не мог найти в Интернете, не помогло.
Не только я мог видеть пакеты в tcpdump
, Я действительно мог бы получать другие многоадресные пакеты для других производителей только на другом интерфейсе. Команда, которую я использовал для проверки, могу ли я принимать многоадресную рассылку, была:
$ GRP=224.x.x.x # set me to the group
$ PORT=yyyy # set me to the receiving port
$ IFACE=mmmm # set me to the name or IP address of the interface
$ strace -f socat - UDP4-DATAGRAM:$GRP:$PORT,ip-add-membership=$GRP:$IFACE,bind=0.0.0.0:$PORT,multicast-loop=0
Причина для strace
вот что я действительно не мог сделать socat
распечатать пакеты на стандартный вывод, но в strace
вывод вы можете четко увидеть, если socat
получает фактические данные из привязанного сокета (в противном случае он будет отключен через пару начальных select
звонки)
rp_filter
sysctl - не применяется, системы находятся в одной IP-сети (я установил для них 0
все равно кажется что 1
сейчас это настройка по умолчанию, по крайней мере, для Ubuntu).-e
флаг tcpdump
и проверьте наличие тегов vlan. Перед тем, как пользовательская среда сможет получать эти пакеты, потребуется настроить интерфейс на правильный vlan. На самом деле отличием для меня было то, что производители многоадресной рассылки не будут пинговать, но даже не попадут в кеш ARP, хотя я мог ясно видеть ответы ARP.Чтобы запустить его с VLAN эта ссылка может быть полезно для настройки многоадресной маршрутизации. (К сожалению, я новичок в этом, поэтому Репутация не позволяет мне добавить ответ. Отсюда и это изменение.)
Вот что я сделал (при необходимости используйте sudo):
ip link add link eth0 name eth0_100 type vlan id 100
ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth0_100
ip link set dev eth0_100 up
ip maddr add 01:00:5e:01:01:01 dev eth0_100
route -n add -net 224.0.0.0 netmask 240.0.0.0 dev eth0_100
Таким образом создается дополнительный интерфейс для трафика vlan с идентификатором vlan 100. IP vlan может быть ненужным. Затем для нового интерфейса настраивается многоадресный адрес (01: 00: 5e: 01: 01: 01 - адрес канального уровня для 239.1.1.1), и весь входящий многоадресный трафик привязывается к eth0_100. Я также выполнил все возможные шаги в ответах выше (проверьте iptables, rp_filter и т. Д.).
Вы можете попробовать посмотреть на эти настройки:
proc
echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
sysctl.conf
sed -i -e 's|^net.ipv4.icmp_echo_ignore_broadcasts =.*|net.ipv4.icmp_echo_ignore_broadcasts = 0|g' /etc/sysctl.conf
Они использовались для включения многоадресной рассылки в RHEL.
Возможно, вы захотите убедиться, что ваш брандмауэр разрешает многоадресный трафик; снова с RHEL я включил следующее:
# allow anything in on multicast addresses
-A INPUT -s 224.0.0.0/4 -j ACCEPT
-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT
# needed for multicast ping responses
-A INPUT -p icmp --icmp-type 0 -j ACCEPT
Вы используете управляемый коммутатор? У некоторых есть опции для предотвращения «широковещательных штормов» или других проблем с многоадресной рассылкой, которые заставляют их блокировать определенные типы пакетов. Я бы посоветовал взглянуть на вашу документацию по коммутатору.
s.bind("", 15572)
Уверен в ""? Почему бы не использовать для привязки IP-адрес многоадресной рассылки?