Ядро Linux, не проходячи через багатоадресні пакети UDP


35

Нещодавно я створив новий сервер 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-сервера, я отримую нульові дані! Ось простий сервер, який зчитує дані, що надсилаються на порт 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, створений в рубіні, на 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 серверах, у тій самій мережі за декілька секунд надійшло кілька тисяч пакетів.

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

Якщо я спробую примусити інтерфейс у перспективний режим, нічого не зміниться.

На цьому момент я застряг. Я підтвердив, що в налаштуваннях ядра ввімкнено багатоадресну передачу. Можливо, є інші параметри конфігурації, які я повинен перевірити?

b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y

Будь-які думки про те, куди подітися звідси?


Піди розберися. Я йду, щоб ввести нове запитання, пов'язаний алгоритм із задоволенням показує, що це питання існує, але на нього немає змістовних відповідей. Бу :(.
VxJasonxV

Я не впевнений, як саме я збираюся вручити винагороду. Співробітник знайшов проблему, і я зрозумів, ЧОМУ це сталося, як це сталося. Я більше ніж готовий розважитися пропозиціями щодо того, як присвоїти винагороду.
VxJasonxV

ти все ще навколо? У мене є питання до вас.
VxJasonxV

У мене є і ця проблема. Шановний підступ, ти це вирішуєш?

Іншим, хто мав цю проблему - прочитайте всі відповіді на це питання, оскільки є 2-3 налаштування O / S, які потрібно виправити. Ми вирішили цю проблему шляхом зміни rp_filterі /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsпотім він почав працювати.
Сем Голдберг

Відповіді:


35

У нашому випадку нашу проблему вирішили параметри sysctl, які відрізняються від Maciej.

Зверніть увагу, що я не розмовляю за ОП (розслідування), я прийшов на цю посаду через проблему, пов’язану з основною деталлю (відсутність багатоадресної передачі в користувальницькій мережі).

У нас є програма, яка зчитує дані, що надсилаються на чотири адреси багатоадресної пошти, і унікальний порт на адресу багатоадресної пошти, з пристрою, який (як правило) підключений безпосередньо до інтерфейсу на приймальному сервері.

Ми намагалися розгорнути це програмне забезпечення на сайті клієнта, коли воно загадково вийшло з невідомої причини. Спроби налагодження цього програмного забезпечення привели до перевірки кожного системного виклику, зрештою, вони всі нам сказали те саме:

Наше програмне забезпечення запитує дані, а ОС ніколи не надає.

Зростання лічильника пакетів багатоадресної передачі, tcpdump показав трафік, що досягає коробки / конкретного інтерфейсу, але ми з цим нічого не могли зробити. SELinux був відключений, iptables був запущений, але не мав правил у жодній із таблиць.

Ступали, ми були.

Мимоволі роздумуючи, ми почали думати про параметри ядра, якими керує sysctl, але жодна із задокументованих особливостей не була особливо актуальною, або якщо вони мали відношення до трафіку багатоадресної передачі, вони були включені. О, і якщоconfig зробив список "MULTICAST" у рядку функцій (вгору, трансляція, запуск, багатоадресна передача). З цікавості ми подивилися /etc/sysctl.conf. ось ось ось базовий образ цього клієнта внизу додано кілька додаткових ліній.

У нашому випадку замовник встановив net.ipv4.all.rp_filter = 1. rp_filter - це фільтр "Шлях маршруту", який (наскільки я розумію) відхиляє весь трафік, який не міг би досягти цього вікна. Прискорення мережевої підмережі, маючи на увазі, що IP-код джерела підробляє.

Ну, цей сервер знаходився в підмережі 192.168.1 / 24, і IP-адреса джерела пристрою для багатоадресного трафіку була десь у мережі 10. *. Таким чином, фільтр заважав серверу робити щось значиме з трафіком.

Пару настроїв, затверджених замовником; net.ipv4.eth0.rp_filter = 1і net.ipv4.eth1.rp_filter = 0ми радісно бігали.


2
Це спрацювало! rp_filterДля нашого 10 мережевого інтерфейсу Gb був демпінг всіх наших широкомовних пакетів UDP. Відключивши фільтр, все пропустить.
chrisaycock

У нас виникли проблеми під час налаштування потокової передачі через багатоадресову передачу AMT через пристрій Tun на приймачі Ubuntu, і ми могли побачити, як пакети надходять на пристрій через tcpdump, але програма просто не хоче передавати потоки. Ця публікація врятувала нас!
інженер програмного забезпечення

2
Працюючи на Ubuntu 14.04, це працювало для мене лише після того, як я також встановив net.ipv4.all.rp_filter = 0. Зокрема, маючи дані, що надходять на багатоадресну передачу на eth2, я повинен був встановити і net.ipv4.eth2.rp_filter = 0та, і net.ipv4.all.rp_filter = 0.
T-Hawk

4

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роздрукування пакетів у stdout, але у straceвисновку ви можете чітко побачити, чи socatотримує фактичні дані з пов'язаного сокета (інакше він буде відключений через пару початкових selectвикликів)

  • rp_filtersysctl - не застосовується, системи знаходяться в одній і тій самій мережі IP (я встановлюю їх на 0все те саме, здається, 1це налаштування за замовчуванням зараз, принаймні для Ubuntu).
  • брандмауери / тощо - система прийому не є брандмауером (я не думаю, що пакети відображатимуться в tcpdump, якщо вони були брандмауерами, але я думаю, що це можливо, якщо брандмауер смішний)
  • IP / Multicast маршрутизація та декілька інтерфейсів - я явно приєднався до групи на правильному інтерфейсі
  • Дурне мережеве обладнання - це було моїм останнім засобом, але зміна якогось ноутбука на Intel NUC не допомогла. Це про те, звідки я почав жувати лікті і вчиняти повідомлення про це в SE.
  • Проблема в моєму випадку полягала у використанні VLAN за допомогою спеціалізованого обладнання, яке виробляло ці пакети для багатоадресної передачі. Щоб дізнатись, чи це ваша проблема, обов'язково додайте -eпрапор до tcpdumpта перевірте наявність тегів vlan. Потрібно буде налаштувати інтерфейс у правильний vlan, перш ніж userland зможе отримати ці пакети. Для мене насправді було те, що виробники багатоадресної передачі не пінгують, але навіть не потраплять у кеш ARP, хоча я чітко бачу відповіді ARP.

Щоб запустити його з VLAN, ця посилання може бути корисною для налаштування маршрутизації для багатоадресної передачі. (На жаль, я новачок у цьому, тому Репутація не дозволяє мені додати відповідь. Отже, це редагування.)

Ось що я зробив (використовуйте судо, якщо потрібно):

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 id 100. ip vlan може бути непотрібним. Тоді для нового інтерфейсу налаштовується адреса багатоадресної передачі (01: 00: 5e: 01: 01: 01 - адреса шару зв'язку 239.1.1.1), і весь вхідний трафік багатоадресної пошти пов'язаний з eth0_100. Я також зробив усі можливі кроки у відповідях вище (перевірити iptables, rp_filter тощо).


@Gero: Додавання маршруту для багатоадресної передачі налаштовує вихідну багатоадресову пошту , а не вхідну групову передачу. Ви не повинні прив'язувати IP-адреси багатоадресної пошти до інтерфейсів безпосередньо, якщо ви не робите щось фанк, це зазвичай робота програми.
Павло Веселов

2

Ви можете спробувати переглянути ці налаштування:

проц

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

Параметри "широкомовної передачі" застосовуються і до "багатоадресної передачі"?
Raedwald

0

Ви використовуєте керований перемикач? У деяких є варіанти запобігання "трансляція штормів" або інших багатоадресних проблем, які б змусили їх запобігти певним типам пакетів. Я б запропонував переглянути вашу документацію на комутатор.


0
s.bind("", 15572)

Впевнені в ""? Чому б не використовувати IP-адресу багатоадресної пошти для прив’язки?


порожні адреси хостів зазвичай означають "всі інтерфейси".
VxJasonxV
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.