Linux Çekirdeği çok noktaya yayın UDP paketlerinden geçmiyor


35

Son zamanlarda, yeni bir Ubuntu Sunucusu 10.04 kurdum ve UDP sunucumun artık çok noktaya yayın grubuna katıldıktan sonra bile arayüze gönderilen çok noktaya yayın verilerini göremediğini fark ettim. Diğer iki Ubuntu 8.04.4 LTS makinesinde de aynı ayarları yaptım ve aynı çok noktaya yayın grubuna katıldıktan sonra veri alma konusunda hiçbir sorun yok.

Ethernet kartı bir Broadcom netXtreme II BCM5709 ve kullanılan sürücü:

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

Çok noktaya yayın kayıtlarımı yönetmek için smcroute kullanıyorum.

b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71

Gruba katıldıktan sonra ip maddr yeni eklenen kaydı gösterir.

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

Şimdiye kadar çok iyi, bu çok noktaya yayın grubu için veri aldığımı görebiliyorum.

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
...

Arabirimin mcast paketleri aldığını da doğrulayabilirim.

b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33

Şimdi sorun burada. Basit bir yakut UDP sunucusu kullanarak trafiği yakalamaya çalıştığımda sıfır veri alıyorum! 15572 numaralı bağlantı noktasına gönderilen verileri okuyan ve ilk iki karakteri yazdıran basit bir sunucu. Bu, iki 8.04.4 Ubuntu Sunucusunda çalışır, ancak 10.04 sunucusunda çalışmaz.

require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
  text, sender = s.recvfrom(2)
  puts text
end

Localhost'a yakutta hazırlanmış bir UDP paketi gönderirsem, sunucu bunu alır ve ilk iki karakteri yazdırır. Bu yüzden yukarıdaki sunucunun doğru çalıştığını biliyorum.

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)

Protokol istatistiklerini kontrol ettiğimde InMcastPkts'in artmadığını görüyorum. Diğer 8.04 sunucularda, aynı ağda, 10 saniyede birkaç bin paket aldı.

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

Arabirimi promisc moda zorlamaya çalışırsam hiçbir şey değişmez.

Bu noktada sıkışıp kaldım. Çekirdek yapılandırmasının çoklu yayın etkin olduğunu onayladım. Belki de kontrol etmem gereken başka yapılandırma seçenekleri var?

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

Buradan nereye gideceğine dair bir fikrin var mı?


Git figürü. Yeni bir soru girmeye gideceğim, ilgili algoritma mutlulukla bana bu sorunun var olduğunu gösteriyor, ancak anlamlı bir cevabı yok. Boo :(.
VxJasonxV

Tam olarak nasıl ödül kazanacağımdan emin değilim. Bir meslektaş problemi buldu ve bunun neden böyle olduğunu NEDEN anladım. Ödülün nasıl verileceğine dair önerileri eğlendirmekten daha fazla istekliyim.
VxJasonxV

hala buralarda mısın? sana bazı sorularım var.
VxJasonxV

Benim de bu problemim var. Sevgili tomurcuklama, çözüyor musunuz?

Bu sorunu yaşayanlara - bu soruya verilen tüm cevapları okuyun, çünkü düzeltilmesi gereken 2-3 O / S ayarları vardır. Biz değiştirerek bu sorunu çözüldü rp_filterve /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsdaha sonra da çalışmaya başladı.
Sam Goldberg

Yanıtlar:


35

Bizim örneğimizde, sorunumuz Maciej'den farklı olan sysctl parametreleriyle çözüldü.

Lütfen OP (konuşma) için konuşmadığımı, bu yazının temel detaylarla (kullanıcı bölgesinde çok noktaya yayın trafiği olmaması) ilgili sorun nedeniyle geldiğimi unutmayın.

(Genellikle) doğrudan alıcı sunucudaki bir arabirime bağlı bir cihazdan dört çok noktaya yayın adresine gönderilen verileri ve çok noktaya yayın adresi için benzersiz bir bağlantı noktasını okuyan bir uygulamamız var.

Bu yazılımı, bilinmeyen bir sebep olmadan gizlice başarısızlığa uğradığında bir müşteri sitesinde dağıtmaya çalışıyorduk. Bu yazılımda hata ayıklama girişimleri, her sistem çağrısının denetlenmesiyle sonuçlandı, sonuçta hepsi aynı şeyi söyledi:

Yazılımımız veri ister ve işletim sistemi hiçbir zaman bir şey sağlamaz.

Çok noktaya yayın paket sayacı artmış, tcpdump trafiğe kutuya / belirli bir arabirime ulaştığını gösterdi, ancak bununla hiçbir şey yapamadık. SELinux devre dışı bırakıldı, iptables çalışıyordu ancak tabloların hiçbirinde kural yoktu.

Stumped, öyleydik.

Rasgele dolaşırken, sysctl'in uyguladığı çekirdek parametrelerini düşünmeye başladık, ancak belgelenen özelliklerin hiçbiri özellikle ilgili değildi ya da çok noktaya yayın trafiği ile ilgiliyse, etkinleştirildiler. Oh, ve ifconfig, özellik satırında (yukarı, yayın, çalışan, çok noktaya yayın) "MULTICAST" yazdı. Merak etmeden baktık /etc/sysctl.conf. Bakalım, bu müşterinin temel görüntüsünde altta birkaç ekstra satır vardı.

Bizim durumumuzda müşteri belirledi net.ipv4.all.rp_filter = 1. rp_filter (anladığım kadarıyla) bu kutuya ulaşmamış olabilecek tüm trafiği reddeden Rota Yolu filtresidir. Ağ alt ağ atlamalı, düşünce IP kaynağının sahte olduğu düşüncesindeydi.

Peki, bu sunucu bir 192.168.1 / 24 alt ağındaydı ve çok noktaya yayın trafiği için cihazın kaynak IP adresi 10 * ağında bir yerdeydi. Böylece, filtre, sunucunun trafikle anlamlı bir şey yapmasını engelliyordu.

Müşteri tarafından onaylanan birkaç tweaks; net.ipv4.eth0.rp_filter = 1ve net.ipv4.eth1.rp_filter = 0mutlu bir şekilde koşuyorduk.


2
Bu çalıştı! rp_filterBizim 10 Gb ağ arabirimi için bizim UDP noktaya yayın paketlerinin tüm damping edildi. Filtreyi kapatmak, her şeyin içinden geçmesine izin verir.
chrisaycock

Bir Ubuntu alıcısındaki tun cihaz üzerinden AMT çok noktaya yayın üzerinden akış kurarken sorun yaşıyorduk ve tcpdump aracılığıyla cihaza paketlerin teslim edildiğini görebiliyoruz, ancak uygulama akış sağlamak istemiyor. Bu yazı bizi kurtardı!
yazılım mühendisi

2
Ubuntu 14.04 ile çalıştığımda, bu ayarladıktan sonra sadece benim için çalıştı net.ipv4.all.rp_filter = 0. Özellikle, çok noktaya veri eth2 gelmeden, ben her iki ayarlamak zorunda kaldı net.ipv4.eth2.rp_filter = 0ve net.ipv4.all.rp_filter = 0.
T-Hawk

4

TL / DR Ayrıca, çok noktaya yayınınızın bir vlandan gelmediğinden emin olun. tcpdump -eyapıp yapmadıklarını belirlemeye yardımcı olur.

Adil olmak gerekirse, biri çok noktaya yayının kullanıcı alanına ulaşmasını engelleyebilecek şeylerin kontrol listesini içeren bir sayfa oluşturmalıdır. Birkaç gündür bununla mücadele ediyorum ve doğal olarak internette bulabildiğim hiçbir şey yoktu.

Paketleri yalnızca göremedim, tcpdumpaslında diğer üreticiler için, başka bir çok noktaya yayın paketlerini yalnızca farklı bir arabirimde alabilirdim. Çok noktaya yayın alıp alamayacağımı test etmek için kullandığım komut şuydu:

$ 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

Bunun sebebi straceaslında socatpaketleri stdout'a yazdıramadım, ancak straceçıktıda socatbağlı soketten gerçek veri alıp almadığını net bir şekilde görebilirsiniz (aksi halde birkaç ilk selectçağrıdan sonra sessiz olur )

  • rp_filtersysctl - geçerli değil, sistemler aynı IP ağında (hepsini 0aynı şekilde 1ayarlarım, şu anda varsayılan ayar, en azından Ubuntu için görünüyor).
  • güvenlik duvarları / etc - alıcı sistemde güvenlik duvarı ücretsizdir (güvenlik duvarı kullanılıyorsa paketlerin tcpdump'ta görüneceğini sanmıyorum, ancak güvenlik duvarı komikse mümkün olduğunu sanıyorum)
  • IP / Multicast yönlendirme ve çoklu arayüzler - Gruba açıkça doğru arayüzde katıldım
  • Kaçık ağ donanımı - bu benim son çaredi, ancak bazı dizüstü bilgisayarları Intel NUC olarak değiştirmek yardımcı olmadı. Bu, dirseklerimi çiğnemeye başladığım ve bunu SE'ye gönderdiğim yerle ilgili.
  • Benim durumumdaki sorun, bu çok noktaya yayın paketlerini üreten uzman donanım tarafından VLAN kullanımıydı. Sorunun bu olup olmadığını anlamak için -ebayrak tcpdumpeklediğinizden ve vlan etiketlerini kontrol ettiğinizden emin olun . Kullanıcı bu paketleri alabilmesi için bir arayüzün doğru vlan içine yapılandırılması gerekecektir. Aslında benim için en önemli şey, çok noktaya yayın yapan üreticilerin ping yapamayacakları, ancak ARP yanıtlarını açıkça görebildiğim halde ARP önbelleğine bile girmeyecekleriydi.

VLAN ile çalışmasını sağlamak için bu bağlantı çok noktaya yayın yönlendirmesini yapılandırmak için yardımcı olabilir. (Ne yazık ki bu konuda yeniyim, böylece İtibar bir cevap eklememe izin vermiyor. Bu nedenle bu düzenleme.)

İşte yaptığım şey (gerekirse sudo kullanın):

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

Bu şekilde, vlan kimliği 100 ile vlan trafiği için oluşturulmuşsa ek bir arabirim olabilir. Vlan ip gerekli olmayabilir. Ardından, yeni arabirim için çok noktaya yayın adresi yapılandırılır (01: 00: 5e: 01: 01: 01, 239.1.1.1 için bağlantı katmanı adresidir) ve gelen tüm çok noktaya yayın trafiği eth0_100'e bağlanır. Ayrıca yukarıdaki cevaplarda da mümkün olan bütün adımları attım (iptables, rp_filter vb. Kontrol edin).


@Gero: Çok noktaya yayın yolu eklemek , gelen çok noktaya yayın değil giden çok noktaya yayın kurar . Çok noktaya yayın IP adreslerini doğrudan arabirimlere bağlamamalısınız, eğer korkak bir şey yapmazsanız, normalde bu uygulamanın işidir.
Pawel Veselov

2

Bu ayarlara bakmak isteyebilirsiniz:

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

Bunlar RHEL'de çok noktaya yayın sağlamak için kullanılmıştır.

Güvenlik duvarınızın ortak yayın trafiğine izin verdiğinden emin olmak isteyebilirsiniz; tekrar RHEL ile aşağıdakileri etkinleştirdim:

# 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

"yayın" seçenekleri de "çok noktaya yayın" için de geçerlidir?
Raedwald

0

Yönetilen bir anahtar kullanıyor musunuz? Bazılarının 'yayın fırtınasını' veya diğer çok noktaya yayın sorunlarını engelleme seçenekleri vardır; bu da bazı paket türlerini engellemelerine neden olur. Anahtar belgelerinize bir göz atmanızı öneririm.


0
s.bind("", 15572)

"" Hakkında emin misin? Bağlanmak için çok noktaya yayın IP adresini neden kullanmıyorsunuz?


Boş host adresleri genellikle "tüm arayüzler" anlamına gelir.
VxJasonxV
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.