如果一个主机绑定有多个 IP地址,那么在被动响应和主动发起连接两种方式中,源 IP 地址的选择机制肯定是有所差异的。
主机在接收外部数据包,并发送响应数据包时,响应源地址显然就是客户端请求的地址,这是非常容易理解的,如客户端向主机的1.1.2.3:80 发起请求,那么主机响应数据包的源 IP 地址一定是 1.1.2.3 。
那么当主机对外主动发起请求时,数据包的源IP 地址如何选择?这个问题我们可能一般很少深入了解, 为了弄清楚这个问题,我发了不少时间,广泛查阅各种资料,目前得出的结论如下:
当一个主机创建IP 数据包时,必须选择正确的源IP地址,这是至关重要的,因为只有源地址正确,才能让接收者正确响应。如果源地址错误,则无法得到对端主机的任何回应。
Linux 2.2 选择源 IP 地址使用以下三种机制:
1. 应用程序可以通过bind(2) 系统调用,应用至 sendmsg(2) 调用上,并通过辅助数据对象 IP_PKTINFO ,从而显式指定源 IP 地址。在这种情况下,操作系统内核仅仅检查其源 IP 地址是否正确,否则产生相应的错误。
2. 如果应用程序没有指定源IP 地址,包含源 IP 的路由表将决定数据包源 IP 地址,通过设置 ip route 命令的 src 参数,从而指定源 IP 地址。如果路由表没有包含 src 属性,则使用主要 IP 地址。
3. 其它情况下内核搜寻绑定定数据包路由接口上的IP 地址, IPv6 选择第一个可用的 IP 地址。 IPv4 情况下,尽量选择与目标 IP 处于同一子网的源 IP ,如果目标 IP 与自己的所有 ip 没有处于同一子网,则使用第二种算法。
相应的参照文章:
http://linux-ip.net/gl/ip-cref/node155.html
http://serverfault.com/questions/12285/when-ip-aliasing-how-does-the-os-determine-which-ip-address-will-be-used-as-sour
默认情况下,如果Linux 的网卡有多个 IP 且位于不同的子网之中,如果数据包目标地址为某个子网中的 IP, 那么对应的与目标同子网的 IP 将会被使用。如果 eth0 有两个 IP 192.168.1.12/24, 10.1.1.1/8 ,那么到 10.0.0.0 子网的数据包的源地址将使用 10.1.1.1 。 当然可以使用 ip route 的 src 属性指定源址。
如果绑定的几个IP 处于同一个子网内,那么主要 IP 地址将被使用(如 eth0 接口上的 IP ) , 也可以使用 iptables 修改数据包的源地址实现之,如:
iptables -t nat -I POSTROUTING -o eth0 -d 1.2.3.4/0 -s 192.168.100.1 -j SNAT --to-source 192.168.100.2
原理分析及处理办法我们已经分析完毕,接下来使用实际的例子展示
Linux 主机绑定有以下几个 IP (网关为 192.168.0.1 )
eth0 192.168.0.250/24, eth0: 1 192.168.0.22/24, eth0:2 192.168.0.23/24
另外,绑定多个IP 可使用 ip addr add 命令,不产生子接口。
在上述案例中192.168.0.250 将成为默认主要 IP 。
目标:当此主机对外发起新连接时,源IP 地址使用 192.168.0.22, 不使用默认的 192.168.0.250 。
方法:修改路由表的源IP 属性
一. 查看系统的 ip 地址及路由表详细信息 ( 加粗字体是输入的内容 )
[root@localhost ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet 192.168.100.250/32 scope global lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether f4:6d:04:76:ca:98 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.250/24 brd 192.168.0.255 scope global eth0
inet 172.16.25.1/24 scope global eth0
inet 192.168.0.22/24 scope global secondary eth0
inet 192.168.0.23/24 scope global secondary eth0
请注意 192.168.0.250 是 global 状态,而其它地址是 secondary 状态。
[root@localhost ~]# ip route
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.250
172.16.25.0/24 dev eth0 proto kernel scope link src 172.16.25.1
169.254.0.0/16 dev eth0 scope link
default via 192.168.0.1 dev eth0
注意以上输出,会发现到同一子网的路由的源IP 地址会使用主要 IP 地址。而到默认网关的路由没有指定源 IP (实际上会用与网关同一子网的主要 IP )。
修改路由表,让系统使用指定IP(192.168.0.22) 作为源址:
[root@localhost ~]# ip route change default dev eth0 src 192.168.0.22
[root@localhost ~]# ip route change to 192.168.0.0/24 dev eth0 src 192.168.0.22
[root@localhost ~]# ip route
192.168.0.0/24 dev eth0 scope link src 192.168.0.22
172.16.25.0/24 dev eth0 proto kernel scope link src 172.16.25.1
169.254.0.0/16 dev eth0 scope link
default dev eth0 scope link src 192.168.0.22
通过最后的输出,我们发现修改生效,然后使用其它主机实际测试一下。如果有任何疑惑,请联系zhangxugg@163.com 。
另外还有一种方式,使用iptables 修改源 IP 地址:
iptables -t nat -I POSTROUTING -o eth0 -d 0.0.0.0 /0 -s 192.168.0. 250 -j SNAT --to-source 192.168. 0.22
经过实验,测试也通过,显然修改路由表的方式要更好一些。
相关推荐
行业文档-设计装置-提高授时输出可靠性的时源选择及切换方法
行业文档-设计装置-智能多时源自动优化、协商授时时间同步系统.zip
行业文档-设计装置-智能多时源自动优化、协商授时时间同步系统及授时方法.zip
·独立的多任务模式,可以同时对多个不同的文件夹进行不同的备份与同步操作 ·支持单向同步、双向同步、增量备份、完全备份等各种类型的文件同步与备份方式 ·具有多种任务自动触发模式,能实时、定时、间隙、...
9、支持多频率备份选择,能按月、按周、按日、按时、间隔或手动地启动任务。 10、智能的增量备份恢复功能,能够恢复出与每次执行时源目录完全一样的目录结构和文件。 11、异地容灾备份功能:文件一旦备份,可以在...
9、支持多频率备份选择,能按月、按周、按日、按时、间隔或手动地启动任务。 10、智能的增量备份恢复功能,能够恢复出与每次执行时源目录完全一样的目录结构和文件。 11、异地容灾备份功能:文件一旦备份,可以在...
9、支持多频率备份选择,能按月、按周、按日、按时、间隔或手动地启动任务。 10、智能的增量备份恢复功能,能够恢复出与每次执行时源目录完全一样的目录结构和文件。 11、异地容灾备份功能:文件一旦备份,...
(2)使用时源盘符、源目标路径名、源文件名至少指定一个; (3)选用/S时对源目录下及其子目录下的所有文件进行COPY。除非指定/E参数,否则/S不会拷贝空目录,若不指定/S参数,则XCOPY只拷贝源目录本身的文件,而...
有关更多详细信息,请参阅每个项目的自述文件。 背对背检测器: 该项目显示了以级联模式使用2个检测器 异常检测: 该项目包含辅助dsdirection插件,以显示DeepstreamSDK在异常检测中的功能。 运行时源添加删除: ...
r,s)的容错路由,解决多节点故障时源节点如何快速建立和目的节点之间的路由。首次提出故障节点封闭区和节点逃逸区,在此基础上提出多节点故障时容错路由最优算法,并用实例验证算法的正确性。
该算法延长进程在源节点上的执行时间并对该过程中访问的地址空间页面加以记录,迁移时源节点优先迁移被记录的页面,然后继续推送剩余地址空间页面,保证在缺页错误发生频率最高的进程恢复运行初期能够获取所需内存页面....
LCM显示使用太阳人SMG12864K9无字库显示屏和使用新型时钟日历芯片 DS12C887作为实时电子时钟时源(该芯片可以保留时间为10年)
超级包一个很小的javascript打包器来练习。 受启发。megumin-pack和minipack的区别运行时模块缓存。 没有运行时源映射。项目结构src捆绑器代码。 example捆绑的示例代码。 dist捆绑目的地。