利用iptables修改UDP报文源IP地址的方法
来源:互联网 发布:手机淘宝旧版5.2.2 编辑:程序博客网 时间:2024/05/21 09:33
1. 问题起因:
最近在一个项目中,有一个模块是基于UDP的服务端,为了保证系统的高可用性,方案中采用了KeepAlive做主备切换,拓扑模型如下:
客户端访问系统的入口地址是VIP,此时VIP落在UDP Server主上,也就是说,此时实际上UDP Server主有两个IP,一个是自己的实际IP地址,即IP1,另一个是VIP。理想情况下,系统是通过VIP接受了UDP报文,回报文的时候也应该是通过VIP回。但是不幸的是,系统实际以IP1回复了。客户端发送的IP地址和接受报文的IP地址不一致,造成客户端不识别报文。
2. 解决方案
为了在不修改代码的情况下解决这个问题,笔者选择了通过linux的iptables报文转发功能来实现修改报文的源IP地址的目的,但解决的过程比较曲折,下面笔者跟大家分享下整个过程,以加深对iptables的理解。
本实验中VIP=10.0.255.33,实际的IP1=10.0.255.2,服务器的监控端口为2000
客户端将报文发送到VIP(10.0.255.33),但系统确以IP1(10.0.255.2)回复,从而造成通信失败。
此时,笔者直接想到的解决方案是,通过iptables修改出口报文的IP地址,语句如下:
-A POSTROUTING -s 10.0.255.0/24 -p udp -mudp --sport 2000 -j SNAT --to-source 10.0.255.33:2000
实验中,抓包发现,回复报文的IP地址是对了,成功从IP1(10.0.255.2)修改成为VIP(10.0.255.2),本以为大功告成了,但又产生了新的问题!回复的端口号不对了!
端口号本应该以2000作为源端口发出去的,但是确以2001发出去了,但我在规则里写明了是以2000发出去啊。
思索再三,终于找出了原因,iptables修改报文的IP地址,也能修改端口号,但是修改后的端口号绝对不能是已经被监听的端口号,即便该报文本来就是从监听该端口号的进程发出来的。
根据以上思路,笔者决定,修改监听服务的端口号为2001端口,报文进来的时候,通过POSTROUTING重定向UDP 2000的报文到2001端口,而从2001端口发出去的报文再通过POSTROUTING修改报文的源IP地址和端口号,此时的端口号重新修改到2000.而对于客户端并不会感知到这些行为,客户端从头到尾都是与一个UDP 2000的服务器进行通信。
下面是实验的iptables配置
# Generated by iptables-save v1.4.7 on FriDec 2 13:23:33 2016
*filter
:INPUT ACCEPT [439:20767]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [3849:433903]
-A INPUT -m state --stateRELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp--dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp--dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp--dport 3000 -j ACCEPT
-A INPUT -p udp -m udp --dport 3799 -jACCEPT
COMMIT
# Completed on Fri Dec 2 13:23:332016
# Generated by iptables-save v1.4.7 on FriDec 2 13:23:33 2016
*nat
:PREROUTING ACCEPT [10:3664]
:POSTROUTING ACCEPT [475:41448]
:OUTPUT ACCEPT [475:41448]
-A PREROUTING -p udp -m udp --dport 2000 -jREDIRECT --to-ports 2001
-A POSTROUTING -s 10.0.255.0/24 -p udp -mudp --sport 2001 -j SNAT --to-source 10.0.255.33:2000
COMMIT
整个配置的关键在标红色的两行,下面分别讲解
-A PREROUTING -p udp -m udp --dport 2000 -jREDIRECT --to-ports 2001
此处PREROUTING的作用是修改人口的报文,此处的作用是将入口的2000端口的报文重定向到2001
-A POSTROUTING -s 10.0.255.0/24 -p udp -mudp --sport 2001 -j SNAT --to-source 10.0.255.33:2000
此处POSTROUTING的作用是有两个:修改源IP地址为VIP(10.0.255.33)和将源端口号重新修改为2000
经过以上的曲折配置,实验终于成功!
- 利用iptables修改UDP报文源IP地址的方法
- TCP,IP,UDP,帧的报文格式
- TCP,IP,UDP,帧的报文格式
- Linux系统修改IP地址的方法
- 修改IP地址及DNS的方法
- Oracle服务器修改IP地址的方法
- Linux中修改ip地址的方法
- IP地址的修改
- 禁止修改IP地址 方法
- qnx修改ip地址方法
- linux 修改IP地址方法
- Linux 修改IP地址方法
- IP UDP TCP报文格式
- TCP、UDP、IP报文格式
- IP TCP UDP 报文格式
- ip udp tcp 报文格式
- 利用端口号扩展IP地址的方法争议很大
- 利用java获取本机IP地址的方法
- HDU 5239 Doom(线段树)
- Jsp的内置对象之Reques
- JAVA学习笔记(2)
- 欢迎使用CSDN-markdown编辑器
- CRAB手语
- 利用iptables修改UDP报文源IP地址的方法
- 实验一 Linux操作系统的安装
- 日记—9.21
- 基本类型转换规则和sizeof的用法
- opencv学习笔记—8,阈值操作
- 欢迎使用CSDN-markdown编辑器
- POJ 3461 (kmp)
- 9.21(周四)
- jQuery——对象样式操作