iptables实现网卡包的转发

mips小板上有两个网卡eth0、eth1,如今要实现的是将eth0接收到的数据从eth1中转发出去。linux

 

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp -s ! 10.0.0.1 -d 12.0.0.1 --dport 21 -j DNAT --to-destination 10.0.0.2:8888
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 10.0.0.2 --dport 8888 -j SNAT --to-source 12.0.0.1
或者
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 10.0.0.2 --dport 8888 -j MASQUERADE
IP_FORWARD已经打开

这两条规则链转发没有问题
可是问题是  来源地址的IP被  POSTROUTING链给修改成了 12.0.0.1
有没有什么办法能够 让IPTABLES只作包转发   不改变 数据包的来源地址。
有哪位知道的话 告诉一下
谢谢!服务器

-------------[   ip 18.0.10.1      ]-------------------[ 12.0.0.1:21]
                                                                          |
                                                                          |
                                                                          |
                                                                  [   10.0.0.1:8888  ]
描述 。IP180.0.10.1访问  12.0.0.1:21端口
          12.0.0.1把来自21端口的访问 重定向道公网的  10.0.0.1:8888
          10.0.0.1:8888看到的来源地址  须要时   18.0.10.1 而不是  12.0.0.1网络

 

 设咱们有一台计算机,有两块网卡,eth0连外网,ip为1.2.3.4;eth1连内网,ip为192.168.0.1.如今须要把发往地址1.2.3.4的81端口的ip包转发到ip地址192.168.0.2的8180端口,设置以下:

  1. iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp -m tcp --dport 81 -j DNAT --to-destination192.168.0.2:8180

  2. iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.0.0 -d 192.168.0.2 -p tcp -m tcp --dport 8180 -j SNAT --to-source 192.168.0.1

  真实的传输过程以下所示:

  假设某客户机的ip地址为6.7.8.9,它使用本机的1080端口链接1.2.3.4的81端口,发出的ip包源地址为6.7.8.9,源端口为1080,目的地址为1.2.3.4,目的端口为81.

  主机1.2.3.4接收到这个包后,根据nat表的第一条规则,将该ip包的目的地址更该为192.168.0.2,目的端口更该为8180。同时在链接跟踪表中建立一个条目,(可从/proc/net/ip_conntrack文件中看到),而后发送到路由模块,经过查路由表,肯定该ip包应发送到eth1接口。在向eth1接口发送该ip包以前,根据nat表的第二条规则,若是该ip包来自同一子网,则将该ip包的源地址更该为192.168.0.1,同时更新该链接跟踪表中的相应条目,而后送0接口发出.

  此时链接跟踪表中有一项:

  链接进入: src=6.7.8.9 dst=1.2.3.4 sport=1080 dport=81

  链接返回: src=192.168.0.2 dst=6.7.8.9 sport=8180 dport=1080

  是否使用: use=1

  而从192.168.0.2发回的ip包,源端口为8180,目的地址为6.7.8.9,目的端口为1080,主机1.2.3.4的TCP/IP栈接收到该ip包后,由核心查找链接跟踪表中的链接返回栏目中是否有一样源和目的地址和端口的匹配项,找到后,根据条目中的记录将ip包的源地址由192.168.0.2更该为1.2.3.4, 源端口由8180更该为81,保持目的端口号1080不变.这样服务器的返回包就能够正确的返回发起链接的客户机,通信就这样开始.

  还有一点, 在filter表中还应该容许从eth0链接192.168.0.2地址的8180端口:

  iptables -A INPUT -d 192.168.0.2 -p tcp -m tcp --dport 8180 -i eth0 -j ACCEPT架构

 

 

什么是Iptables? 

iptables 是创建在 netfilter 架构基础上的一个包过滤管理工具,最主要的做用是用来作防火墙或透明代理。Iptables 从 ipchains 发展而来,它的功能更为强大。Iptables 提供如下三种功能:包过滤、NAT(网络地址转换)和通用的 pre-route packet mangling。app

包过滤:用来过滤包,可是不修改包的内容。Iptables 在包过滤方面相对于 ipchians 的主要优势是速度更快,使用更方便。socket

NAT:NAT 能够分为源地址 NAT 和目的地址 NAT。 

Iptables 能够追加、插入或删除包过滤规则。实际上真正执行这些过虑规则的是 netfilter 及其相关模块(如 iptables 模块和 nat 模块)。tcp

Netfilter 是 Linux 核心中一个通用架构,它提供了一系列的 “表”(tables),每一个表由若干 “链”(chains)组成,而每条链中能够有一条或数条 “规则”(rule)组成。 工具

iptables 能够操纵3 个表:filter 表,nat 表,mangle 表。 
NAT 和通常的 mangle 用 -t 参数指定要操做哪一个表。filter 是默认的表,若是没有 -t 参数,就默认对 filter 表操做。
 “filter”表中包含了 INPUT、FORWARD 和 OUTPUT 3 个链。 

每一条链中能够有一条或数条规则,每一条规则都是这样定义的:若是数据包头符合这样的条件,就这样处理这个数据包。当一个数据包到达一个链时,系统就会从第一条规则开始检查,看是否符合该规则所定义的条件: 若是知足,系统将根据该条规则所定义的方法处理该数据包;若是不知足则继续检查下一条规则。最后,若是该数据包不符合该链中任一条规则的话,系统就会根据该链预先定义的策略来处理该数据包。 网站


 

 


规则:

Rule 规则:过滤规则,端口转发规则等,例如:禁止任何机器 ping 咱们的服务器,能够在服务器上设置一条规则: 

iptables -A INPUT -s ! 127.0.0.1 -p icmp -j DROP 

从 –s 开始便是一条规则,-j 前面是规则的条件,-j 开始是规则的行为(目的)。整条命令解释为,在filter 表中的 INPUT 规则链中插入一条规则,全部源地址不为 127.0.0.1 的 icmp 包都被抛弃。 
(下面的一些例子能够此例子为参考)代理


Chain (规则链):由一系列规则组成,每一个包顺序通过 chain 中的每一条规则。chain 又分为系统 chain和用户建立的 chain。下面先叙述系统 链。 

filter 表的系统 链: INPUT,FORWARD,OUTPUT 

nat 表的系统 链: PREROUTING,POSTROUTING,OUTPUT 

mangle 表的系统 链: PREROUTING,OUTPUT 

每条系统 chain 在肯定的位置被检查。好比在包过滤中,全部的目的地址为本地的包,则会进入INPUT 规则链,而从本地出去的包会进入 OUTPUT 规则链。 

全部的表(table) 和 链(chain) 开机时都为空,设置 iptables 的方法就是在合适的 table 和系统 chain 中添相应的规则。 
 

 



iptables:

表:   iptables从其使用的三个表(filter、nat、mangle)而得名, 对包过滤只使用 filter 表, filter仍是默认表,无需显示说4明. 

操做命令: 即添加、删除、更新等。 

链:  对于包过滤能够针对filter表中的INPUT、OUTPUT、FORWARD链,也能够操做用户自定义的链。 

规则匹配器: 能够指定各类规则匹配,如IP地址、端口、包类型等。 

目标动做: 当规则匹配一个包时,真正要执行的任务,经常使用的有: 

ACCEPT 容许包经过 

DROP 丢弃包 


 

一些扩展的目标还有: 

REJECT 拒绝包,丢弃包同时给发送者发送没有接受的通知 

LOG 包有关信息记录到日志 

TOS 改写包的TOS值 

 




为使FORWARD规则可以生效,可以使用下面2种方法的某种: 

[root@rhlinux root]# vi /proc/sys/net/ipv4/ip_forward 
[root@rhlinux root]# echo "1" > /proc/sys/net/ipv4/ip_forward 

[root@rhlinux root]# vi /etc/sysconfig/network 
[root@rhlinux root]# echo "FORWARD_IPV4=true" > /etc/sysconfig/network 

 

 




iptables语法能够简化为下面的形式: 

iptables [-t table] CMD [chain] [rule-matcher] [-j target] 

CMD  经常使用操做命令: 

-A 或 -append 在所选链尾加入一条或多条规则 


-D 或 -delete 在所选链尾部删除一条或者多条规则 

-R 或 -replace 在所选链中替换一条匹配规则 

-I 或 -insert 以给出的规则号在所选链中插入一条或者多条规则. 若是规则号为1,即在链头部. 

-L 或 -list 列出指定链中的全部规则,若是没有指定链,将列出链中的全部规则. 

-F 或 -flush 清除指定链和表中的所由规则, 假如不指定链,那么全部链都将被清空. 

-N 或 -new-chain 以指定名建立一条新的用户自定义链,不能与已有链名相同. 

-X 或 -delete-chain 删除指定的用户定义帘,必需保证链中的规则都不在使用时才能删除,若没有指定链,则删除全部用户链. 

-P 或 -policy 为永久帘指定默认规则(内置链策略),用户定义帘没有缺省规则,缺省规则也使规则链中的最后一条规则,用-L显示时它在第一行显示. 

-C 或 -check 检查给定的包是否与指定链的规则相匹配. 

-Z 或 -zero 将指定帘中所由的规则包字节(BYTE)计数器清零. 

-h 显示帮助信息. 

matcher  经常使用匹配规则器: 

-p , [!] protocol 指出要匹配的协议,能够是tcp, udp, icmp, all, 前缀!为逻辑非,表示除该协议外的全部协议. 

-s [!] address[/mask] 指定源地址或者地址范围. 

-sport [!] port[:port] 指定源端口号或范围,能够用端口号也能够用/ETC/SERVICES文件中的名子. 

-d [!] address[/mask] 指定目的地址或者地址范围. 

-dport [!] port[:port] 指定目的端口号或范围,能够用端口号也能够用/ETC/SERVICES文件中的名子. 

-icmp-type [!] typename 指定匹配规则的ICMP信息类型(可使用 iptables -p icmp -h 查看有效的ICMP类型名) 

-i [!] interface name[+] 匹配单独或某种类型的接口,此参数忽略时,默认符合全部接口,接口可使用"!"来匹配捕食指定接口来的包.参数interface是接口名,如 eth0, eht1, ppp0等,指定一个目前不存在的接口是彻底合法的,规则直到接口工做时才起做用,折中指定对于PPP等相似链接是很是有用的."+"表示匹配全部此类型接口.该选项只针对于INPUT,FORWARD和PREROUTING链是合法的. 

-o [!] interface name[+] 匹配规则的对外网络接口,该选项只针对于OUTPUT,FORWARD,POSTROUTING链是合法的. 

[!] --syn 仅仅匹配设置了SYN位, 清除了ACK, FIN位的TCP包. 这些包表示请求初始化的TCP链接.阻止从接口来的这样的包将会阻止外来的TCP链接请求.但输出的TCP链接请求将不受影响.这个参数仅仅当协议类型设置为了TCP才能使用. 此参数可使用"!"标志匹配已存在的返回包,通常用于限制网络流量,即只容许已有的,向外发送的链接所返回的包. 

 -m module_name 使用扩展模块来进行数据包的匹配。如: 

        -m tcp 的意思是使用 tcp 扩展模块的功能 (tcp扩展模块提供了 --dport, --tcp-flags, --sync等功能).

 

 


-j target :

 ACCEPT target

这个target没有任何选项和参数,使用也很简单,指定-j ACCEPT便可。一旦包知足了指定的匹配条件,就会被ACCEPT,而且不会再去匹配当前链中的其余规则或同一个表内的其余规则,但它还要经过其余表中的链,并且在那儿可能会百DROP也说不许哦

 

DNAT target 

这个target是用来作目的网络地址转换的,就是重写包的目的IP地址。若是一个包被匹配了,那么和它属于同一个流的全部的包都会被自动转换,而后就能够被路由到正确的主机或网络。DNAT target是很是有用的。

好比,你的Web服务器在LAN内部,并且没有可在Internet上使用的真实IP地址,那就可使用这个 target让防火墙把全部到它本身HTTP端口的包转发给LAN内部真正的Web服务器。目的地址也能够是一个范围,这样的话,DNAT会为每个流随机分配一个地址。所以,咱们能够用这个target作某种类型地负载平衡。

注意,DANT target只能用在nat表的PREROUTING和OUTPUT链中,或者是被这两条链调用的链里。但还要注意的是,包含DANT target的链不能被除此以外的其余链调用,如POSTROUTING。

例:

 

Option

--to-destination

Example

iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10 

解释

指定要写入IP头的地址,这也是包要被转发到的地方。上面的例子就是把全部发往地址15.45.23.67的包都转发到一段LAN使用的私有地址中,即192.168.1.1到 192.168.1.10。如前所述,在这种状况下,每一个流都会被随机分配一个要转发到的地址,但同一个流老是使用同一个地址。咱们也能够只指定一个IP地址做为参数,这样全部的包都被转发到同一台机子。咱们还能够在地址后指定一个或一个范围的端口。好比:--to-destination 192.168.1.1:80或 --to-destination 192.168.1.1:80-100。SNAT的语法和这个target的同样,只是目的不一样罢了。要注意,只有先用--protocol指定了TCP或 UDP协议,才能使用端口。

 

 

由于DNAT要作不少工做,因此我要再罗嗦一点。咱们经过一个例子来大体理解一下它是如何工做的。好比,我想经过Internet链接发布咱们的网站,可是HTTP server在咱们的内网里,并且咱们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还有一个内网的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (这固然是内网的了)。为了完成咱们的设想,要作的第一件事就是把下面的这个简单的规则加入到nat表的PREROUTING链中:

iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP 

如今,全部从Internet来的、到防火墙的80端口去的包都会被转发(或称作被DNAT )到在内网的HTTP服务器上。若是你在Internet上试验一下,一切正常吧。再从内网里试验一下,彻底不能用吧。这实际上是路由的问题。下面咱们来好好分析这个问题。为了容易阅读,咱们把在外网上访问咱们服务器的那台机子的IP地址记为$EXT_BOX。

 

DROP target

顾名思义,若是包符合条件,这个target就会把它丢掉,也就是说包的生命到此结束,不会再向前走一步,效果就是包被阻塞了。在某些状况下,这个target会引发意外的结果,由于它不会向发送者返回任何信息,也不会向路由器返回信息,这就可能会使链接的另外一方的sockets因苦等回音而亡:) 解决这个问题的较好的办法是使用REJECT target,(译者注:由于它在丢弃包的同时还会向发送者返回一个错误信息,这样另外一方就能正常结束),尤为是在阻止端口扫描工具得到更多的信息时,能够隐蔽被过滤掉的端口等等(译者注:由于扫描工具扫描一个端口时,若是没有返回信息,通常会认为端口未打开或被防火墙等设备过滤掉了)。还要注意若是包在子链中被DROP了,那么它在主链里也不会再继续前进,不论是在当前的表仍是在其余表里。总之,包死翘翘了。


 

 


如何制定永久规则集: /etc/sysconfig/iptables 文件是 iptables 守护进程调用的默认规则集文件. 可使用如下命令保存执行过的IPTABLES命令: /sbin/iptables-save > /etc/sysconfig/iptables 要恢复原来的规则库,可使用: /sbin/iptables-restore < /etc/sysconfig/iptables iptables命令和route等命令同样,重启以后就会恢复,因此: [root@rhlinux root]# service iptables save 将当前规则储存到 /etc/sysconfig/iptables: [ 肯定 ] 令一种方法是 /etc/rc.d/init.d/iptables 是IPTABLES的启动脚本,因此: [root@rhlinux root]# /etc/rc.d/init.d/iptables save 将当前规则储存到 /etc/sysconfig/iptables: [ 肯定 ] 以上几种方法只使用某种便可. 若要自定义脚本,可直接使用iptables命令编写一个规则脚本,并在启动时执行: 例如若规则使用脚本文件名/etc/fw/rule, 则能够在/etc/rc.d/rc.local中加入如下代码: if [-x /etc/fw/rule]; then /etc/fw/sule; fi; 这样每次启动都执行该规则脚本,若是用这种方法,建议NTSYSV中中止IPTABLES. 

相关文章
相关标签/搜索