歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> rp_filter及Linux下多網卡接收多播的問題

rp_filter及Linux下多網卡接收多播的問題

日期:2017/2/28 15:47:13   编辑:Linux教程

工作中曾遇到一個很奇怪的問題,我奉命調查。事情是這樣的,有一台雙網卡的機器,上面裝有Fedora8,運行一個程序。該程序分別在兩個網口上都接收多播數據,程序運行是正常的。但是,後來升級系統到Fedora13,發現就出問題了:在運行幾秒鐘後,第2個網口上就接收不到多播數據了。

能不能收到多播,取決於交換機是不是往這個網口上轉發多播數據。程序在起動的時候,會發一個IGMP的AddMembership的消息,交換機將把這個網口加入多播組。當在其他網口上收到該地址的多播包後,會轉至這個網口。其後,為了確認該接收者一直在線,交換機會發送一個IGMPQuery消息,接收者反饋一個IGMP Report消息,以確認自己的存在。如果交換機沒有收到IGMPReport,則認為該接收者已經斷線,就不再往該網口上轉發多播包了。

用抓包工具定位了一下,發現程序在啟動時確實發了AddMembership消息,這是正常的。在接收下來的5秒時間內,程序能夠收到多播數據。接著,交換機發來了一條IGMPQuery,問題來了,這個Fedora13系統卻沒有反饋Report。這是很奇怪的。按理說,IGMP屬於系統自動完成的協議,無需用戶干預;那麼按照預期,Linux會自動反饋IGMPReport的。事實上,Feodra8和WinXP系統就是這麼做的,都很正常。為什麼到了Fedora13反而不正常了呢?

在調查“為什麼不反饋IGMPReport”的事情上,花了一周時間都沒有進展,後來發現其實不至Fedora13,其他的主流linux如Ubuntu10,SUSE14也存在同樣的問題。

查了眾多論壇都沒有一點提示信息。後來,終於在一個英文網站上掃到了一個信息:rp_filter。後來證明,這個關鍵詞是解決問題的關鍵。reverse-pathfiltering,反向過濾技術,系統在接收到一個IP包後,檢查該IP是不是合乎要求,不合要求的IP包會被系統丟棄。該技術就稱為rpfilter。怎麼樣的包才算不合要求呢?例如,用戶在A網口上收到一個IP包,檢查其IP為B。然後考查:對於B這個IP,在發送時應該用哪個網口,“如果在不應該接收到該包的網口上接收到該IP包,則認為該IP包是hacker行為”。

例如:

A: 192.168.8.100

B: (IGMP Query) 10.0.0.1 來自路由器

查找路由表

網卡1為默認路由: 172.17.5.100 172.17.5.1

網卡2 192.168.8.100 192.168.8.1

系統根據路由表,認為10.0.0.1這個IP應該在第一個網卡172.17.5.100上收到,現實的情況是在第二張網卡192.168.8.100上收到了。認為這是不合理的,丟棄該包。致命的問題的,該包是來自路由器的IGMPQuery包。

The rp_filter can reject incoming packets if their sourceaddress doesn’t match the network interface that they’re arrivingon, which helps to prevent IP spoofing. Turning this on, however,has its consequences: If your host has several IP addresses ondifferent interfaces, or if your single interface has multiple IPaddresses on it, you’ll find that your kernel may end up rejectingvalid traffic. It’s also important to note that even if you do notenable the rp_filter, protection against broadcast spoofing isalways on. Also, the protection it provides is only against spoofedinternal addresses; external addresses can still be spoofed.. Bydefault, it is disabled.

解決方法:

系統配置文件
1. /etc/sysctl.conf
把 net.ipv4.conf.all.rp_filter和net.ipv4.conf.default.rp_filter設為0即可
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
系統啟動後,會自動加載這個配置文件,內核會使用這個變量

2. 命令行
顯示一個內核變量 sysctl net.ipv4.conf.all.rp_filter
設置一個內核變量 sysctl -w net.ipv4.conf.all.rp_filter=0
設置完後,會更新內核(實時的內存)中的變量的值,但不會修改sysctl.conf的值

3. 使用/proc文件系統
查看 cat /proc/sys/net/ipv4/conf/all/rp_filter
設置 echo "0">/proc/sys/net/ipv4/conf/all/rp_filter

Copyright © Linux教程網 All Rights Reserved