iptables的四表五链
四表:filter、nat、mangle(做防火墙标记)、raw
五链:INPUT、OUTPUT、FORWARD、PREROUTING(路由前)、POSTROUTING(路由后)
filte:INPUT、OUTPUT、FORWARD
nat:PREROUTING、OUTPUT、POSTROUTING
mangle:PREOUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
3、配置原则
- 将控制强的放在前面,应用访问频繁的也要放在前面
- 查询条件
- IP:SIP、DIP
- TCP:SPORT、DPORT、FLags
- UDP:SPORT、DPORT
- ICMP:ICMP-TYPE
- 处理机制
- DROP(丢弃)
- REJECT(拒绝,并返回)
- ACCEPT(允许)
- SNAT
- DNAT
- RETURN(返回)
- REDIRECT(端口转发)
- LOG(只记录日志)
- 规则样式
- -t 表 -L 列出 -n 以数值方式显示
- iptables [-t table ] -N chain 创建一条新的链
- iptables [-t table ] -X chain 创建一条空规则的链
- iptables [-t table ] -E old-chain-name new-chain-name 修改链名
- iptables [-t table] -P chain—name target 为链指定默认策略,修改默认的属性
- iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
- -F 清空规则
- -L list 列出表中的所有规则
- -n 以数字格式显示ip和端口
- -v 显示信息
- pkts:packets,被本规则所有匹配到的报文的个数
- baytes:被本规则所匹配到的所有报文的大小子和,单位是字节,会执行单位换算
- target:目标,即处理机制
- port:协议一般为(TCP|UDP|ICMP)
- opt:可选项
- in:数据包的流入端口
- out:数据包的流出接口
- scource:源地址
- destination:目标地址
- -vv
- -vvv
- -x:exactly:精确值,不执行单位换
- --line-nambers:显示各规则的行号
- -Z:zero 把规则计数器清零
- iptables [-t table] {-A|-D} chain rule-specification
- -A:append,附加一条规则
- rule-specification 匹配条件 -j 处理机制
- 匹配条件:
- -s 匹配原地址,可以IP,也可以网络地址:可以使用!操作符取反,!172.168.0.0/16 相当于 --src,或 --source
- -d 匹配目标地址,可以IP,也可以网络地址:可以使用!操作符取反,!172.168.0.0/16
- -p 匹配协议,通常只能使用{TCP|UDP|ICMP}三者之一
- -i 数据报文流入的接口,通常只用于INPUT,FORWARD和PREROUTING
- -o 数据报文流出的接口,通常只用OUTPUT,FORWARD和POSTROUTING
- 保存规则:
- service iptables save 规则会被保存至/etc/sysconfig/iptables文件中
- iptables-save > /path/to/some_rulefile 保存iptables至别的位置
- iptables-restore < /path/to/some_rulefile 从自定义的位置读取并使之生效
- 规则命令
- -A:添加
- -D:删除
- 插入规则 iptables [-t table] -I chain [rulenum] rule-specification
- 替换规则(覆盖指定规则) iptables [-t table] -R chain rulenum rule-specification
- 显示指定链上的规则添加命令 iptables [-t table] -S [chain [rulenum]]
- 扩展匹配
- -p tcp
-
--dport m[-n],匹配的目标端口,可以是连续的多个端口
-
--sport:m[-n],匹配的源端口,可以是连续的多个端口
-
--tcp-flags URG PSH PST SYN ACK FIN
-
- -p udp
- --dport m[-n],匹配的目标端口,可以是连续的多个端口
- --sport:m[-n],匹配的源端口,可以是连续的多个端口
- -p icmp
- icmp-type
- -p tcp
- 显式扩展:必须要明确指定的扩展模块
- -m 扩展模块名称 --专用选项1 --专用选项2
- multiport:多端口匹配,一次指定多个离散端口
- state:状态追踪
4、配置filter
源地址转换
iptables -t nat -A POSTROUTING -s 10.60.196.211/32 -j SNAT --to-source 10.60.196.209
详述iptables五种链接
一、初识防火墙
Firewall:防火墙,隔离工具;工作于主机或网络边缘,对于进出本主机或本网络的报文根据事先定义的检查规则作匹配检测,对于能够被规则匹配到的报文作出相应处理的组件;
防火墙类型分为: 主机防火墙 和网络防火墙
实现方法分为:软件防火墙(软件逻辑)和硬件防火墙(硬件和软件逻辑)
二、iptables五种链接
iptables五种链接分别是prerouting、input 、output 、forward 、postrouting
- prerouting:流入的数据包进入路由表之前。
- input :通过路由表判断后目的地址是本机,然后进入本机内部资源。
- output :由本机产生的数据向外转发
- forward :通过路由表判断目的地址是本机,然后通过路由转发到其他地方。
- postrouting:传出的数据包到达网卡出口前。
iptables的四张表
现在用的比较多的表是前两个:
- 表(功能):
filter:过滤,防火墙;
nat:network address translation;用于修改源IP或目标IP,也可以改端口;
mangle:拆解报文,做出修改,并重新封装起来;
raw:关闭nat表上启用的连接追踪机制;
- 表(功能)和链对应关系:
raw:PREROUTING, OUTPUT
mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat:PREROUTING,[INPUT,]OUTPUT,POSTROUTING
filter:INPUT,FORWARD,OUTPUT
- 处理优先级:raw-->mangle-->nat-->filter
- 报文流向:
流入本机:PREROUTING --> INPUT
由本机流出:OUTPUT --> POSTROUTING
转发:PREROUTING --> FORWARD --> POSTROUTING
三、iptables规则
1、添加规则时的考量点:
(1) 要实现哪种功能:判断添加到哪个表上;
(2) 报文流经的路径:判断添加到哪个链上;
2、链的规则
链上的规则次序,即为检查的次序;因此,隐含一定的应用法则:
(1) 同类规则(访问同一应用),匹配范围小的放上面;
(2) 不同类的规则(访问不同应用),匹配到报文频率较大的放在上面;
(3) 将那些可由一条规则描述的多个规则合并起来;
(4) 设置默认策略;
3、匹配规则:
组成部分:根据规则匹配条件来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作作出处理;
匹配条件:
基本匹配条件:内建
扩展匹配条件:由扩展模块定义;
4、处理动作:
基本处理动作:内建
扩展处理动作:由扩展模块定义;
自定义处理机制:自定义链
四、iptables命令:
高度模块化,由诸多扩展模块实现其检查条件或处理动作的定义;
/usr/lib64/xtables/
适用IPv6报文:libip6t_
适用IPv4报文:libipt_, libxt_
规则格式:
iptables [-t table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
-t table:raw, mangle, nat, [filter]#表
rule-specification = [matches...] [target] #规则格式,matches匹配条件,target处理动作
match = -m matchname [per-match-options] #指明一个匹配模块 定义它的选项和值
target = -j targetname [per-target-options]#指明一个处理动作的扩展 并定义它的选项
- 查询filter表有三个链
[root@bogon ~]# iptables -t filter -L#查询filter表有三个链
Chain INPUT (policy ACCEPT) #指明那个表(默认法则+黑名单)
target prot opt source destination #(执行动作-端口-选择-原地址-目标地址)
ACCEPT all -- anywhere anywhere #(允许-所有端口-任意地址-任意地址) Chain FORWARD (policy ACCEPT) Chain OUTPUT (policy ACCEPT)
- 查询mangle表有五个链
[root@bogon ~]# iptables -t mangle -L#查询mangle表有五个链
Chain PREROUTING (policy ACCEPT)
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain POSTROUTING (policy ACCEPT)
- 查询nat表有四个链
[root@bogon ~]# iptables -t nat -L#查询nat表有四个链
Chain PREROUTING (policy ACCEPT)
Chain INPUT (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain POSTROUTING (policy ACCEPT)
- 查询raw表有两个链
[root@bogon ~]# iptables -t raw -L#查询raw表有两个链
Chain PREROUTING (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
五、链管理:
- 1、 -N:new, 自定义一条新的规则链;
[root@bogon ~]# iptables -N in_web_rules#只能调用內建链
- 2、 -X: delete,删除自定义的规则链;
[root@bogon ~]# iptables -X in_web_rules#注意:仅能删除 用户自定义的 引用计数为0的 空的 链;
- 3、 -P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
ACCEPT:接受(內建)
DROP:丢弃(內建)
REJECT:拒绝(扩展)
[root@bogon ~]# iptables -P FORWARD DROP或ACCEPT#关闭或打开转发报文
[root@bogon ~]# iptables -vnL#查询状态
- 4、 -E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除;
[root@bogon ~]# iptables -E in_web_rules in_web
六、规则管理:
- 1、-A:append,追加;
- 2、-I:insert, 插入,要指明位置,省略时表示第一条;
- 3、-D:delete,删除;
(1) 指明规则序号;
(2) 指明规则本身;
-
4、-R:replace,替换指定链上的指定规则;
-
5、-F:flush,清空指定的规则链;
[root@bogon ~]# iptables -F IN_public#清空指定的规则
- 6、-Z:zero,置零;
iptables的每条规则都有两个计数器:
(1) 匹配到的报文的个数;
(2) 匹配到的所有报文的大小之和;
[root@bogon ~]# iptables -Z INPUT_ZONES 1#把这个链第一条规则置零
- 7、查看:
-L:list, 列出指定鏈上的所有规则;
-n:numberic,以数字格式显示地址和端口号;
-v:verbose,详细信息;
-vv, -vvv
-x:exactly,显示计数器结果的精确值;
--line-numbers:显示规则的序号;
[root@bogon ~]# iptables -L -n --line-numbers #显示当前表链并编号
[root@bogon ~]# iptables -L -n --line-numbers -v#显示详细信息
[root@bogon ~]# iptables -vnL INPUT#显示INPUT信息
iptables详解(12):iptables动作总结之一
之前用到的ACCEPT与DROP都属于基础动作。
而REJECT则属于扩展动作。
之前举过很多例子,我们知道,使用-j可以指定动作,比如
-j ACCEPT
-j DROP
-j REJECT
其实,"动作"也有自己的选项,我们可以在使用动作时,设置对应的选项,此处以REJECT为例,展开与"动作"有关的话题。
动作REJECT
REJECT动作的常用选项为--reject-with
使用--reject-with选项,可以设置提示信息,当对方被拒绝时,会提示对方为什么被拒绝。
可用值如下
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable,
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited
当不设置任何值时,默认值为icmp-port-unreachable。
我们来动手实践一下,在主机139上设置如下规则,如下图所示,当没有明确设置--reject-with的值时,默认提示信息为icmp-port-unreachable,即端口不可达之意。
此时在另一台主机上向主机139发起ping请求,如下图所示,提示目标端口不可达。
那么我们将拒绝报文的提示设置为"主机不可达",示例如下
如上图所示,我们在设置拒绝的动作时,使用了--reject-with选项,将提示信息设置为icmp-host-unreachable,完成上述操作后,我们再次在在另一台主机上向主机139发起ping请求。
如下图所示。
可以看到,ping请求被拒绝时,提示信息已经从"目标端口不可达"变成了"目标主机不可达"。
动作LOG
在本博客中,前文并没有对LOG动作进行示例,此处我们来了解一下LOG动作。
使用LOG动作,可以将符合条件的报文的相关信息记录到日志中,但当前报文具体是被"接受",还是被"拒绝",都由后面的规则控制,换句话说,LOG动作只负责记录匹配到的报文的相关信息,不负责对报文的其他处理,如果想要对报文进行进一步的处理,可以在之后设置具体规则,进行进一步的处理。
示例如下,下例表示将发往22号端口的报文相关信息记录在日志中。
如上图所示,上述规则表示所有发往22号端口的tcp报文都符合条件,所以都会被记录到日志中,查看/var/log/messages即可看到对应报文的相关信息,但是上述规则只是用于示例,因为上例中使用的匹配条件过于宽泛,所以匹配到的报文数量将会非常之多,记录到的信息也不利于分析,所以在使用LOG动作时,匹配条件应该尽量写的精确一些,匹配到的报文数量也会大幅度的减少,这样冗余的日志信息就会变少,同时日后分析日志时,日志中的信息可用程度更高。
注:请把刚才用于示例的规则删除。
从刚才的示例中我们已经了解到,LOG动作会将报文的相关信息记录在/var/log/message文件中,当然,我们有可以将相关信息记录在指定的文件中,以防止iptables的相关信息与其他日志信息相混淆,修改/etc/rsyslog.conf文件(或者/etc/syslog.conf),在rsyslog配置文件中添加如下配置即可。
#vim /etc/rsyslog.conf
kern.warning /var/log/iptables.log
加入上述配置后,报文的相关信息将会被记录到/var/log/iptables.log文件中。
完成上述配置后,重启rsyslog服务(或者syslogd)
#service rsyslog restart
服务重启后,配置即可生效,匹配到的报文的相关信息将被记录到指定的文件中。
LOG动作也有自己的选项,常用选项如下(先列出概念,后面有示例)
--log-level选项可以指定记录日志的日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug。
--log-prefix选项可以给记录到的相关信息添加"标签"之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤。
注:--log-prefix对应的值不能超过29个字符。
比如,我想要将主动连接22号端口的报文的相关信息都记录到日志中,并且把这类记录命名为"want-in-from-port-22",则可以使用如下命令
完成上述配置后,我在IP地址为192.168.1.98的客户端机上,尝试使用ssh工具连接上例中的主机,然后查看对应的日志文件(已经将日志文件设置为/var/log/iptables.log)
如上图所示,ssh连接操作的报文的相关信息已经被记录到了iptables.log日志文件中,而且这条日志中包含"标签":want-in-from-port-22,如果有很多日志记录,我们就能通过这个"标签"进行筛选了,这样方便我们查看日志,同时,从上述记录中还能够得知报文的源IP与目标IP,源端口与目标端口等信息,从上述日志我们能够看出,192.168.1.98这个IP想要在14点11分连接到192.168.1.139(当前主机的IP)的22号端口,报文由eth4网卡进入,eth4网卡的MAC地址为00:0C:29:B7:F4:D1,客户端网卡的mac地址为F4-8E-38-82-B1-29。
除了ACCEPT、DROP、REJECT、LOG等动作,还有一些其他的常用动作,比如DNAT、SNAT等,我们会在之后的文章中对它们进行总结。
iptables详解(13):iptables动作总结之二
概述
SNAT、DNAT、MASQUERADE、REDIRECT
在认识它们之前,我们先来聊聊NAT,如果你对NAT的相关概念已经滚瓜烂熟,可以跳过如下场景描述。
NAT是Network Address Translation的缩写,译为"网络地址转换",NAT说白了就是修改报文的IP地址,NAT功能通常会被集成到路由器、防火墙、或独立的NAT设备中。
为什么要修改报文的IP地址呢?我们来描述一些场景,即可知道为什么有这方面的需求了。
场景1:
假设,网络内部有10台主机,它们有各自的IP地址,当网络内部的主机与其他网络中的主机通讯时,则会暴露自己的IP地址,如果我们想要隐藏这些主机的IP地址,该怎么办呢?可以这样办,如下。
当网络内部的主机向网络外部主机发送报文时,报文会经过防火墙或路由器,当报文经过防火墙或路由器时,将报文的源IP修改为防火墙或者路由器的IP地址,当其他网络中的主机收到这些报文时,显示的源IP地址则是路由器或者防火墙的,而不是那10台主机的IP地址,这样,就起到隐藏网络内部主机IP的作用,当网络内部主机的报文经过路由器时,路由器会维护一张NAT表,表中记录了报文来自于哪个内部主机的哪个进程(内部主机IP+端口),当报文经过路由器时,路由器会将报文的内部主机源IP替换为路由器的IP地址,把源端口也映射为某个端口,NAT表会把这种对应关系记录下来。
示意图如下:
于是,外部主机收到报文时,源IP与源端口显示的都是路由的IP与端口,当外部网络中的主机进行回应时,外部主机将响应报文发送给路由器,路由器根据刚才NAT表中的映射记录,将响应报文中的目标IP与目标端口再改为内部主机的IP与端口号,然后再将响应报文发送给内部网络中的主机。整个过程中,外部主机都不知道内部主机的IP地址,内部主机还能与外部主机通讯,于是起到了隐藏网络内主机IP的作用。
上述整个过程中,就用到了NAT功能,准确的说是用到了NAPT功能,NAPT是NAT的一种,全称为Network Address Port Translation,说白了就是映射报文IP地址的同时还会映射其端口号,就像刚才描述的过程一样。
刚才描述的过程中,"IP地址的转换"一共发生了两次。
内部网络的报文发送出去时,报文的源IP会被修改,也就是源地址转换:Source Network Address Translation,缩写为SNAT。
外部网络的报文响应时,响应报文的目标IP会再次被修改,也就是目标地址转换:Destinationnetwork address translation,缩写为DNAT。
但是,上述"整个过程"被称为SNAT,因为"整个过程"的前半段使用了SNAT,如果上述"整个过程"的前半段使用了DNAT,则整个过程被称为DNAT,也就是说,整个过程被称为SNAT还是DNAT,取决于整个过程的前半段使用了SNAT还是DNAT。
其实刚才描述的场景不仅仅能够隐藏网络内部主机的IP地址,还能够让局域网内的主机共享公网IP,让使用私网IP的主机能够访问互联网。
比如,整个公司只有一个公网IP,但是整个公司有10台电脑,我们怎样能让这10台电脑都访问互联网呢?我们可以为这10台电脑都配置上各自的私网IP,比如"192.168"这种私网IP,但是互联网是不会路由私网IP的,如果想要访问互联网,则必须使用公网IP,那么,我们就需要想办法,能让这10台主机共享公司仅有的一个公网IP,没错,这与刚才描述的场景其实完全一致,我们只要在路由器上配置公网IP,在私网主机访问公网服务时,报文经过路由器,路由器将报文中的私网IP与端口号进行修改和映射,将其映射为公网IP与端口号,这时,内网主机即可共享公网IP访问互联网上的服务了,NAT表示意图如下
综上所述,SNAT不仅能够隐藏网内的主机IP,还能够共享公网IP,这在IPV4地址较为紧张的今天,是非常有用的。
场景2:
场景1中,我们描述的过程为SNAT的过程,虽然其过程中也牵扯到DNAT,但是由于整个过程的前半段使用了SNAT,所以整个过程称之为SNAT,那么在什么情况下,整个过程能称之为DNAT呢?
没错,当整个过程的前半段使用了DNAT时,整个过程被称为DNAT,具体场景如下。
公司有自己的局域网,网络中有两台主机作为服务器,主机1提供web服务,主机2提供数据库服务,但是这两台服务器在局域网中使用私有IP地址,只能被局域网内的主机访问,互联网无法访问到这两台服务器,整个公司只有一个可用的公网IP,怎样通过这个公网IP访问到内网中的这些服务呢?我们可以将这个公网IP配置到公司的某台主机或路由器上,然后对外宣称,这个IP地址对外提供web服务与数据库服务,于是互联网主机将请求报文发送给这公网 IP地址,也就是说,此时报文中的目标IP为公网IP,当路由器收到报文后,将报文的目标地址改为对应的私网地址,比如,如果报文的目标IP与端口号为:公网IP+3306,我们就将报文的目标地址与端口改为:主机2的私网IP+3306,同理,公网IP+80端口映射为主机1的私网IP+80端口,当私网中的主机回应对应请求报文时,再将回应报文的源地址从私网IP+端口号映射为公网IP+端口号,再由路由器或公网主机发送给互联网中的主机。
上述过程也牵扯到DNAT与SNAT,但是由于整个过程的前半段使用了DNAT,所以上述过程被称为DNAT
其实,不管是SNAT还是DNAT,都起到了隐藏内部主机IP的作用。
实验环境准备
好了,我们已经了解了SNAT与DNAT的相关概念,那么现在,我们可以动动手了,首先,准备一下实验环境
大致的实验环境是这样的,公司局域网使用的网段为10.1.0.0/16,目前公司只有一个公网IP,局域网内的主机需要共享这个IP与互联网上的主机进行通讯。
由于我们没有真正的公网IP,所以,我们使用私网IP:192.168.1.146模拟所谓的公网IP,示意图如下
如上述示意图所示,实验使用4台虚拟机,A、B、C、D
主机A:扮演公网主机,尝试访问公司提供的服务,IP地址为192.168.1.147
主机B:扮演了拥有NAT功能的防火墙或路由器,充当网关,并且负责NAT,公网、私网通讯的报文通过B主机时,报文会被NAT
主机C:扮演内网web服务器
主机D:扮演内网windows主机
上图中圆形所示的逻辑区域表示公司内网,网段为10.1.0.0/16,主机B、C、D都属于内网主机,主机B比较特殊,同时扮演了网关与防火墙,主机B持有公司唯一的公网IP(我们用了一个假的公网IP),局域网内主机如果想与公网主机通讯,需要共享此公网IP,由B主机进行NAT,所以,我们为主机B准备了两块网卡,公网IP与私网IP分别配置到这两块网卡中,同时,在虚拟机中设置了一个"仅主机模式"的虚拟网络,以模拟公司局域网。
聪明如你,应该已经发现了,上述实验环境与之前描述的"网络防火墙"的实验环境相差无几,只不过之前的环境并没有公网,私网的概念,而此刻,圆形逻辑区域之内为私网,圆形逻辑区域之外为公网。
环境具体准备过程如下
首先,创建一个虚拟网络,模拟公司内网。
点击vmware虚拟机的编辑菜单,打开"虚拟网络编辑器",点击更改设置,添加"仅主机模式"的虚拟网络,下图中的VMnet6为已经添加过的虚拟网络,此处不再重复操作。
主机C与主机D的网关都指向主机B的私网IP,如下图所示
主机B有两块网卡,分别配置了私网IP与公网IP,私网IP为10.1.0.3,私网IP所在的网卡也存在于vmnet6中,模拟公网的IP为192.168.1.146,B主机的公网IP所在的网卡与A主机都使用桥接模式的虚拟网络,所以,B主机既能与私网主机通讯,也能与公网主机通讯。
由于B主机此时需要负责对报文的修改与转发,所以,需要开启B主机中的核心转发功能,Linux主机默认不会开启核心转发,这在前文中已经详细的描述过,此处不再赘述,如果你还不明白为什么,请回顾前文,使用临时生效的方法开启B主机的核心转发功能,如下图所示。
A主机的IP地址如下,可以与B主机进行通讯,但是不能与C、D进行通讯,因为此刻,A是公网主机,B既是公网主机又是私网主机,C、D是私网的主机,A是不可能访问到C和D的。
为了能够更好的区分公网服务与私网服务,我们分别在主机A与主机C上启动httpd服务,如下图所示。
好了,实验环境准备完毕,我们来一起动动手,实际操作一下。
动作:SNAT
在文章开头的场景中,我们已经描述过,网络内部的主机可以借助SNAT隐藏自己的IP地址,同时还能够共享合法的公网IP,让局域网内的多台主机共享公网IP访问互联网。
而此时的主机B就扮演了拥有NAT功能的设备,我们使用iptables的SNAT动作达到刚才所说的目的。
连接到B主机,添加如下规则。
如上图所示,上图中的规则表示将来自于10.1.0.0/16网段的报文的源地址改为公司的公网IP地址。
"-t nat"表示操作nat表,我们之前一直在灌输一个概念,就是不同的表有不同的功能,filter表的功能是过滤,nat表的功能就是地址转换,所以我们需要在nat表中定义nat规则。
"-A POSTROUTING"表示将SNAT规则添加到POSTROUTING链的末尾,在centos7中,SNAT规则只能存在于POSTROUTING链与INPUT链中,在centos6中,SNAT规则只能存在于POSTROUTING链中。
你可能会问,为什么SNAT规则必须定义在POSTROUTING链中,我们可以这样认为,POSTROUTING链是iptables中报文发出的最后一个"关卡",我们应该在报文马上发出之前,修改报文的源地址,否则就再也没有机会修改报文的源地址了,在centos7中,SNAT规则也可以定义在INPUT链中,我们可以这样理解,发往本机的报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。
"-s 10.1.0.0/16"表示报文来自于10.1.0.0/16网段,前文中一直在使用这个匹配条件,我想此处应该不用赘述了。
"-j SNAT"表示使用SNAT动作,对匹配到的报文进行处理,对匹配到的报文进行源地址转换。
"--to-source 192.168.1.146"表示将匹配到的报文的源IP修改为192.168.1.146,前文中,我们已经总结过,某些动作会有自己的选项,"--to-source"就是SNAT动作的常用选项,用于指定SNAT需要将报文的源IP修改为哪个IP地址。
好了,只要站在前文的基础上,理解上述语句应该是分分钟的事情,聪明如你应该已经学会了,那么我们来测试一下。
目前来说,我们只配置了一条SNAT规则,并没有设置任何DNAT,现在,我们从内网主机上ping外网主机,看看能不能ping通,登录内网主机C,在C主机上向A主机的外网IP发送评请求(假外网IP),示例如下
如上图所示,"内网主机"已经可以依靠SNAT访问"互联网"了。
为了更加清晰的理解整个SNAT过程,在C主机上抓包看看,查看一下请求报文与响应报文的IP地址,如下,在C主机上同时打开两个命令窗口,一个命令窗口中向A主机发送ping请求,另一个窗口中,使用tcpdump命令对指定的网卡进行抓包,抓取icmp协议的包。
从上图可以看到,10.1.0.1发出ping包,192.168.1.147进行回应,正是A主机的IP地址(用于模拟公网IP的IP地址)
看来,只是用于配置SNAT的话,我们并不用 手动的进行DNAT设置,iptables会自动维护NAT表,并将响应报文的目标地址转换回来。
那么,我们去A主机上再次重复一遍刚才的操作,在A主机上抓包看看,如下图所示,C主机上继续向A主机的公网IP发送ping请求,在主机A的网卡上抓包看看。
从上图可以看出,C主机向A主机发起ping请求时得到了回应,但是在A主机上,并不知道是C主机发来的ping请求,A主机以为是B主机发来的ping请求,从抓包的信息来看,A主机以为B主机通过公网IP:192.168.1.146向自己发起了ping请求,而A主机也将响应报文回应给了B主机,所以,整个过程,A主机都不知道C主机的存在,都以为是B主机在向自己发送请求,即使不是在公网私网的场景中,我们也能够使用这种方法,隐藏网络内的主机,只不过此处,我们所描述的环境就是私网主机共享公网IP访问互联网,那么可以看到,私网中的主机已经共享了192.168.1.146这个"伪公网IP",那么真的共享了吗?我们使用内网主机D试试,主机D是一台windows虚拟机,我们使用它向主机A发送ping请求,看看能不能ping通。如下
windows主机也ping通了外网主机,在A主机上抓包,看到的仍然是B主机的IP地址。
那么,C主机与D主机能够访问外网服务吗?我们来看看。
在C主机上访问A主机的web服务,如下图所示,访问正常。
同理,在windows主机中访问A主机的web服务,如下图所示,访问正常。
好了,源地址转换,已经完成了,我们只依靠了一条iptables规则,就能够是内网主机能够共享公网IP访问互联网了。
动作DNAT
公司只有一个公网IP,但是公司的内网中却有很多服务器提供各种服务,我们想要通过公网访问这些服务,改怎么办呢?
没错,使用DNAT即可,我们对外宣称,公司的公网IP上既提供了web服务,也提供了windows远程桌面,不管是访问web服务还是远程桌面,只要访问这个公网IP就行了,我们利用DNAT,将公网客户端发送过来的报文的目标地址与端口号做了映射,将访问web服务的报文转发到了内网中的C主机中,将访问远程桌面的报文转发到了内网中的D主机中。
好了,理论说完了,来动手实践一下。
如果我们想要实现刚才描述的场景,则需要在B主机中进行如下配置。
如上图所示,我们先将nat表中的规则清空了,从头来过,清空nat表规则后,定义了一条DNAT规则。
"-t nat -I PREROUTING"表示在nat表中的PREROUTING链中配置DNAT规则,DNAT规则只配置在PREROUTING链与OUTPUT链中,为什么DNAT规则只能存在与这两个链中呢?我们知道,PREROUTING链处于路由层面之前,如果我们不在PRERTOURING链中修改目标地址,当报文到达路由层面时,路由就会根据目标地址发送报文,所以,我们应该在报文到达路由层面之前就修改报文的目标地址,所以,我们应该在PREROUTING链或OUTPUT链中定义DNAT规则。
"-d 192.168.1.146 -p tcp --dport 3389"表示报文的目标地址为公司的公网IP地址,目标端口为tcp的3389号端口,而我们知道,windows远程桌面使用的默认端口号就是3389,当外部主机访问公司公网IP的3389号端口时,报文则符合匹配条件。
"-j DNAT --to-destination 10.1.0.6:3389"表示将符合条件的报文进行DNAT,也就是目标地址转换,将符合条件的报文的目标地址与目标端口修改为10.1.0.6:3389,"--to-destination"就是动作DNAT的常用选项。
那么综上所述,上图中定义的规则的含义为,当外网主机访问公司公网IP的3389时,其报文的目标地址与端口将会被映射到10.1.0.6:3389上。
好了,DNAT规则定义完了,现在能够直接使用外网主机访问私网中的服务了吗?
理论上只要完成上述DNAT配置规则即可,但是在测试时,只配置DNAT规则后,并不能正常DNAT,经过测试发现,将相应的SNAT规则同时配置后,即可正常DNAT,于是我们又配置了SNAT
示例如下。
注:理论上只配置DNAT规则即可,但是如果在测试时无法正常DNAT,可以尝试配置对应的SNAT,此处按照配置SNAT的流程进行。
没错,与刚才定义SNAT时使用的规则完全一样。
好了,完成上述配置后,我们则可以通过B主机的公网IP,连接D主机(windows主机)的远程桌面了,示例如下。
找到公网中的一台windows主机,打开远程程序
输入公司的公网IP,点击连接按钮
注意:没有指定端口的情况下,默认使用3389端口进行连接,同时,为了确保能够连接到windows虚拟主机,请将windows虚拟主机设置为允许远程连接。
输入远程连接用户的密码以后,即可连接到windows主机
连接以后,远程连接程序显示我们连接到了公司的公网IP,但是当我们查看IP地址时,发现被远程机器的IP地址其实是公司私网中的D主机的IP地址。
上图证明,我们已经成功的通过公网IP访问到了内网中的服务。
同理,使用类似的方法,我们也能够在外网中访问到C主机提供的web服务。
示例如下。
如上图所示,我们将公司公网IP的801号端口映射到了公司内网中C主机的80端口,所以,当外网主机访问公司公网IP的801端口时,报文将会发送到C主机的80端口上。
这次,我们不用再次定义SNAT规则了,因为之前已经定义过SNAT规则,上次定义的SNAT规则只要定义一次就行,而DNAT规则则需要根据实际的情况去定义。
好了,完成上述DNAT映射后,我们在A主机上访问B主机的801端口试试,如下
可以看到,我们访问的是B主机的公网IP,但是返回结果显示的却是C主机提供的服务内容,证明DNAT已经成功。
而上述过程中,外网主机A访问的始终都是公司的公网IP,但是提供服务的却是内网主机,但是我们可以对外宣称,公网IP上提供了某些服务,快来访问吧!
我觉得我说明白了,你听明白了吗?
动作MASQUERADE
上文中,我们已经描述了SNAT,也就是源地址转换,那么我们现在来认识一个与SNAT类似的动作:MASQUERADE
当我们拨号网上时,每次分配的IP地址往往不同,不会长期分给我们一个固定的IP地址,如果这时,我们想要让内网主机共享公网IP上网,就会很麻烦,因为每次IP地址发生变化以后,我们都要重新配置SNAT规则,这样显示不是很人性化,我们通过MASQUERADE即可解决这个问题,MASQUERADE会动态的将源地址转换为可用的IP地址,其实与SNAT实现的功能完全一致,都是修改源地址,只不过SNAT需要指明将报文的源地址改为哪个IP,而MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址,示例如下:
如上图所示,我们指定,通过外网网卡出去的报文在经过POSTROUTING链时,会自动将报文的源地址修改为外网网卡上可用的IP地址,这时,即使外网网卡中的公网IP地址发生了改变,也能够正常的、动态的将内部主机的报文的源IP映射为对应的公网IP。
可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效。
动作REDIRECT
使用REDIRECT动作可以在本机上进行端口映射
比如,将本机的80端口映射到本机的8080端口上
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
经过上述规则映射后,当别的机器访问本机的80端口时,报文会被重定向到本机的8080端口上。
REDIRECT规则只能定义在PREROUTING链或者OUTPUT链中。
小结
为了方便以后回顾,我们对上述命令进行总结。
如果想要NAT功能能够正常使用,需要开启Linux主机的核心转发功能。
1
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
SNAT相关操作
配置SNAT,可以隐藏网内主机的IP地址,也可以共享公网IP,访问互联网,如果只是共享IP的话,只配置如下SNAT规则即可。
1
|
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP
|
如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作,如下命令表示将10.1网段的报文的源IP修改为eth0网卡中可用的地址。
1
|
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
|
DNAT相关操作
配置DNAT,可以通过公网IP访问局域网内的服务。
注:理论上来说,只要配置DNAT规则,不需要对应的SNAT规则即可达到DNAT效果。
但是在测试DNAT时,对应SNAT规则也需要配置,才能正常DNAT,可以先尝试只配置DNAT规则,如果无法正常DNAT,再尝试添加对应的SNAT规则,SNAT规则配置一条即可,DNAT规则需要根据实际情况配置不同的DNAT规则。
1
2
3
|
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.1.0.1:80
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP
|
在本机进行目标端口映射时可以使用REDIRECT动作。
1
|
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
|
配置完成上述规则后,其他机器访问本机的80端口时,会被映射到8080端口。
iptables中DNAT、SNAT和MASQUERADE
DNAT(Destination Network Address Translation,目的地址转换) 通常被叫做目的映射,SNAT(Source Network Address Translation,源地址转换)通常被叫做源映射。
这是我们在设置Linux网关或者防火墙时经常要用来的两种方式,要理解iptables中DNAT、SNAT和MASQUERADE,我们要先了解一下IP包的结构,如下图所示:
在任何一个IP数据包中,都会有Source IP Address与Destination IP Address这两个字段,数据包所经过的路由器也是根据这两个字段是判定数据包是由什么地方发过来的,它要将数据包发到什么地方去。
iptables的DNAT与SNAT就是根据这个原理,对Source IP Address与Destination IP Address进行修改,然后我们再看看数据包在iptables中要经过的链(chain):
图中正菱形的区域是对数据包进行判定转发的地方,在这里,系统会根据IP数据包中的destination ip address中的IP地址对数据包进行分发。
如果destination ip adress是本机地址,数据将会被转交给INPUT链。如果不是本机地址,则交给FORWARD链检测。
这也就是说,我们要做的DNAT要在进入这个菱形转发区域之前,也就是在PREROUTING链中做,比如我们要把访问202.103.96.112的访问转发到192.168.0.112上:
# iptables -t nat -A PREROUTING -d 202.103.96.112 -j DNAT --to-destination 192.168.0.112
这个转换过程当中,其实就是将已经达到这台Linux网关(防火墙)上的数据包上的destination ip address从202.103.96.112修改为192.168.0.112然后交给系统路由进行转发。
而SNAT自然是要在数据包流出这台机器之前的最后一个链也就是POSTROUTING链来进行操作
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 58.20.51.66
这个语句就是告诉系统把即将要流出本机的数据的source ip address修改成为58.20.51.66。
这样,数据包在达到目的机器以后,目的机器会将包返回到58.20.51.66也就是本机。
如果不做这个操作,那么你的数据包在传递的过程中,reply的包肯定会丢失。
假如当前系统用的是ADSL/3G/4G动态拨号方式,那么每次拨号,出口IP都会改变,SNAT就会有局限性。
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
重点在那个『 MASQUERADE 』!这个设定值就是『IP伪装成为封包出去(-o)的那块装置上的IP』!
不管现在eth0的出口获得了怎样的动态ip,MASQUERADE会自动读取eth0现在的ip地址然后做SNAT出去,这样就实现了很好的动态SNAT地址转换。
总结:
# iptables -t nat -A PREROUTING -d destIP -j DNAT --to-destination newDestIP
# iptables -t nat -A POSTROUTING -s sourceIP -j SNAT --to-source newSourceIP
# iptables -t nat -A POSTROUTING -s sourceIP -o outInterface -j MASQUERADE
应用场景:
ipvs的nat模式
libvirt的net
# virsh net-dumpxml default
[root@ncpu-lxc2 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 1826K packets, 261M bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- eno1 virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- virbr0 eno1 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 1764K packets, 263M bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68
# iptables -nvL -t nat
Chain PREROUTING (policy ACCEPT 255K packets, 21M bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 255K packets, 21M bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 170 packets, 11596 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 170 packets, 11596 bytes)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- * eno1 192.168.122.0/24 224.0.0.0/24
0 0 RETURN all -- * eno1 192.168.122.0/24 255.255.255.255
0 0 MASQUERADE tcp -- * eno1 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE udp -- * eno1 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * eno1 192.168.122.0/24 !192.168.122.0/24
[root@ncpu-lxc2 ~]#
# iptables -nvL -t filter
Chain INPUT (policy ACCEPT 1828K packets, 261M bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- eno1 virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- virbr0 eno1 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 1766K packets, 263M bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68
IPtables中可以灵活的做各种网络地址转换(NAT)
网络地址转换主要有两种:SNAT和DNAT
SNAT是source network address translation的缩写即源地址目标转换
比如,多个PC机使用ADSL路由器共享上网,每个PC机都配置了内网IP。PC机访问外部网络的时候,路由器将数据包的报头中的源地址替换成路由器的ip。当外部网络的服务器比如网站web服务器接到访问请求的时候,他的日志记录下来的是路由器的ip地址,而不是pc机的内网ip。
这是因为,这个服务器收到的数据包的报头里边的“源地址”,已经被替换了。所以叫做SNAT,基于源地址的地址转换。
DNAT是destination network address translation的缩写即目标网络地址转换
典型的应用是,有个web服务器放在内网,配置内网ip,前端有个防火墙,配置公网ip,互联网上的访问者使用公网ip来访问这个网站。当访问的时候,客户端发出一个数据包,这个数据包的报头里边,目标地址写的是防火墙的公网ip。防火墙会把这个数据包的报头改写一次,将目标地址改写成web服务器的内网ip,然后再把这个数据包发送到内网的web服务器上这样,数据包就穿透了防火墙,并从公网ip变成了一个对内网地址的访问了,即DNAT,基于目标的网络地址转换 。
MASQUERADE,地址伪装,在iptables中有着和SNAT相近的效果,但也有一些区别:
SNAT,DNAT,MASQUERADE都是NAT,MASQUERADE是SNAT的一个特例。
SNAT是指在数据包从网卡发送出去的时候,把数据包中的源地址部分替换为指定的IP,这样,接收方就认为数据包的来源是被替换的那个IP的主机。
MASQUERADE是用发送数据的网卡上的IP来替换源IP,因此,对于那些IP不固定的场合,比如拨号网络或者通过dhcp分配IP的情况下,就得用MASQUERADE。
DNAT,就是指数据包从网卡发送出去的时候,修改数据包中的目的IP,表现为如果你想访问A,可是因为网关做了DNAT,把所有访问A的数据包的目的IP全部修改为B,那么,你实际上访问的是B。
因为,路由是按照目的地址来选择的,因此,DNAT是在PREROUTING链上来进行的,而SNAT是在数据包发送出去的时候才进行,因此是在POSTROUTING链上进行的
但使用SNAT的时候,出口ip的地址范围可以是一个,也可以是多个,例如:
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT –to-source 192.168.5.3
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT –to-source 192.168.5.3-192.168.5.5
但是,对于SNAT,不管是几个地址,必须明确的指定要SNAT的ip
假如当前系统用的是ADSL动态拨号方式,那么每次拨号,出口ip192.168.5.3都会改变
而且改变的幅度很大,不一定是192.168.5.3到192.168.5.5范围内的地址
这个时候如果按照现在的方式来配置iptables就会出现问题了
因为每次拨号后,服务器地址都会变化,而iptables规则内的ip是不会随着自动变化的
每次地址变化后都必须手工修改一次iptables,把规则里边的固定ip改成新的ip
这样是非常不好用的
比如下边的命令:
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j MASQUERADE
如此配置的话,不用指定SNAT的目标ip了
不管现在eth0的出口获得了怎样的动态ip,MASQUERADE会自动读取eth0现在的ip地址然后做SNAT出去
这样就实现了很好的动态SNAT地址转换
对于MASQUERADE,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE都要查找可用的IP地址,而不象SNAT用的IP地址是配置好的。当然,这也有好处,就是我们可以使用通过PPP、 PPPOE、SLIP等拨号得到的地址,这些地址可是由ISP的DHCP随机分配的。
我们可能需要将访问主机的7979端口映射到8080端口。也可以iptables重定向完成
iptables -t nat -A PREROUTING -p tcp --dport 7979 -j REDIRECT --to-ports 8080
更改iptables,使之实现nat映射功能
将外网访问192.168.75.5的80端口转发到192.168.75.3:8000端口。 # iptables -t nat -A PREROUTING -d 192.168.75.5 -p tcp --dport 80 -j DNAT --to-destination 192.168.75.3:8000 将192.168.75.3 8000端口将数据返回给客户端时,将源ip改为192.168.75.5 # iptables -t nat -A POSTROUTING -d 192.168.75.3 -p tcp --dport 8000 -j SNAT 192.168.75.5
IPtables中可以灵活的做各种网络地址转换(NAT),网络地址转换主要有两种:SNAT和DNAT。
SNAT是source networkaddress translation的缩写,即源地址目标转换。比如,多个PC机使用ADSL路由器共享上网,每个PC机都配置了内网IP,PC机访问外部网络的时候,路由器将数据包的报头中的源地址替换成路由器的ip,当外部网络的服务器比如网站web服务器接到访问请求的时候,他的日志记录下来的是路由器的ip地址,而不是pc机的内网ip,这是因为,这个服务器收到的数据包的报头里边的“源地址”,已经被替换了,所以叫做SNAT,基于源地址的地址转换。
DNAT是destination networkaddress translation的缩写,即目标网络地址转换,典型的应用是,有个web服务器放在内网配置内网ip,前端有个防火墙配置公网ip,互联网上的访问者使用公网ip来访问这个网站,当访问的时候,客户端发出一个数据包,这个数据包的报头里边,目标地址写的是防火墙的公网ip,防火墙会把这个数据包的报头改写一次,将目标地址改写成web服务器的内网ip,然后再把这个数据包发送到内网的web服务器上,这样,数据包就穿透了防火墙,并从公网ip变成了一个对内网地址的访问了,即DNAT,基于目标的网络地址转换。
MASQUERADE,地址伪装,算是snat中的一种特例,可以实现自动化的snat。
在iptables中有着和SNAT相近的效果,但也有一些区别,但使用SNAT的时候,出口ip的地址范围可以是一个,也可以是多个,例如:
如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3的ip然后发出去,
iptables-t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source 192.168.5.3
如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3/192.168.5.4/192.168.5.5等几个ip然后发出去
iptables-t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source 192.168.5.3-192.168.5.5
这就是SNAT的使用方法,即可以NAT成一个地址,也可以NAT成多个地址,但是,对于SNAT,不管是几个地址,必须明确的指定要SNAT的ip,假如当前系统用的是ADSL动态拨号方式,那么每次拨号,出口ip192.168.5.3都会改变,而且改变的幅度很大,不一定是192.168.5.3到192.168.5.5范围内的地址,这个时候如果按照现在的方式来配置iptables就会出现问题了,因为每次拨号后,服务器地址都会变化,而iptables规则内的ip是不会随着自动变化的,每次地址变化后都必须手工修改一次iptables,把规则里边的固定ip改成新的ip,这样是非常不好用的。
MASQUERADE就是针对这种场景而设计的,他的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT。
比如下边的命令:
iptables-t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j MASQUERADE
如此配置的话,不用指定SNAT的目标ip了,不管现在eth0的出口获得了怎样的动态ip,MASQUERADE会自动读取eth0现在的ip地址然后做SNAT出去,这样就实现了很好的动态SNAT地址转换。
LVS源码分析一---为什么是LVS?
版权:自由转载,说明出处,保留原作者名,需要商业用途,请联系作者me. 韩波 2009.12.31 email:yahoo邮箱GameProgramHack
刚进入互联网行业不久,从哪里开始呢?云计算,算了吧,... ...。还是从集群技术开始吧。至于集群当然就选LVS了。
个人认为集群技术是所有知名互联网企业都用到的基础技术。要想在互联网行业“混”,个人认为集群技术是必修课。
为什么源码分析?我google,baidu了一下,发现没有LVS源码分析的帖子。那就自己写吧。下个蛋方便后来的小朋友。年老的时候回顾一下co,co,co的这段生活。
先看完http://www.linuxvirtualserver.org/zh/index.html这个再说吧。
以上url读后感:
ipvs的3种技术。
1)VS/NAT机制,第一反应是,netfitler已经实现nat的功能,ipvs不会再自己实现一边相同的功能吧!?!
2)VS/TUN机制,应该和IPsec VPN的实现机制差不多吧。
3)VS/DR机制,以前做集群方案的时候听XX说过,原来起源于ipvs,当时XX还说是商业机密,不告诉我。无语。
ipvs这块总体感觉后续不会遇到多少阻力。
这里有两点值得高兴.
1)LVS是中国人搞的,开源社区很少看到中国人。
2)ipvs是基于netfilter机制的。娃哈哈。
ipvs代码。linux-2.6.31.4
net/netfilter/ipvs/*
include/linux/ip_vs.h
include/net/ip_vs.h
virsh虚拟网络管理命令
配置KVM虚拟机的网络,Bridge和Nat方式
1.bridged(桥接模式)
在bridged模式下,虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。同时,由于这个虚拟系统是局域网中的一个独立的主机系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。
使用bridged模式的虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑。想让它们相互通讯,你就需要为虚拟系统配置IP地址和子网掩码,否则就无法通信
(参考dhcp服务器是否开启,如果开启,则可以选择dhcp方式自动获取网络地址)。
这种方式最简单,直接将虚拟网卡桥接到一个物理网卡上面,和linux下一个网卡绑定两个不同地址类似,实际上是将网卡设置为混杂模式,从而达到侦听多个IP的能力。
在此种模式下,虚拟机内部的网卡(例如linux下的eth0)直接连到了物理网卡所在的网络上,可以想象为虚拟机和host机处于对等的地位,在网络关系上是平等的,没有谁在谁后面的问题。使用这种方式很简单,前提是你可以得到1个以上的地址。
用KVM配置Bridge方式:
首先需要确定你的host主机上用的网络连接方式为桥接方式,我的机器上的用的是一个叫br0的网桥。创建网桥的方式也很简单,以我的系统为例,网卡一个eno16777736,在目
录/etc/sysconfig/network-scripts/下创建文件ifcfg-br0,然后修改文件ifcfg-eno16777736为:
BOOTPROTO=none
DEVICE=eno16777736
HWADDR=00:0c:29:09:0d:3d
NM_CONTROLLED=no
ONBOOT=yes
BRIDGE=br0
修改文件ifcfg-br0的内容为:
BOOTPROTO=static
DEVICE=br0
TYPE=Bridge
NM_CONTROLLED=no
IPADDR=192.168.7.183
NETMASK=255.255.255.0
GATEWAY=192.168.7.254
在虚拟机的XML配置文件中device下添加interface标签即可,标签如下:
当然也可以先定义一下这个网络,然后在添加到虚拟机的XML文件中,给它起名为br0.xml,这个文件中可以写一些网络的详细配置参数,大致的形式如下:
然后用libvirt来定义并开启这个网络,配置文件中的interface标签当然还是不能少,用上面的就好,名字正好一致了:
virsh net-define br0.xml
virsh net-start br0
然后就可已启动客户机,检查网络连接了。
2.NAT(网络地址转换模式)
使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟系统里访问互联网。很显然,如果你只有一个外网地址,此种方式很合适。
KVM虚拟机Nat方式上网:
virsh net-list
查看当前活跃的网络,可以看到一个default网络,这个就是一个默认的Nat网络了。
virsh net-dumpxml default
可以查看该网络的详细配置如下:
可以看到该网络搭建在一个网桥virbr0上,这个网桥在安装并启动libvirt的时候自动生成。然后在客户机的XML配置文件中添加标签interface内容如下:
则可以让客户机用nat方式来上网了,经验证,客户机可以获取到122网段,2到254之间的一个ip地址。
我们可以直接编辑修改default网络的配置:
virsh net-edit default
也可以直接将default网络干掉,然后再重新定义:
virsh net-undefine default
重新创建一个default.xml文件,自定义其中的内容,可以指定某个mac地址对应某个ip,指定某个ip段。例如下面的内容,name对应的是客户机的名字。
然后用命令:
virsh net-define default.xml
virsh net-start default
启用一个客户机,检查网络时候可用。
KVM 客户机网络连接有两种方式:
用户网络(User Networking):让虚拟机访问主机、互联网或本地网络上的资源的简单方法,但是不能从网络或其他的客户机访问客户机,性能上也需要大的调整。NAT方式。
虚拟网桥(Virtual Bridge):这种方式要比用户网络复杂一些,但是设置好后客户机与互联网,客户机与主机之间的通信都很容易。Bridge方式。
本文主要解释NAT方式的配置。
NAT方式原理
NAT方式是kvm安装后的默认方式。它支持主机与虚拟机的互访,同时也支持虚拟机访问互联网,但不支持外界访问虚拟机。
检查当前的网络设置:
#virsh net-list --all
Name State Autostart
default active yes
default是宿主机安装虚拟机支持模块的时候自动安装的。
检查当前的网络接口:
#ifconfig
eth0 Link encap:Ethernet HWaddr 44:37:E6:4A:62:AD
inet6 addr: fe80::4637:e6ff:fe4a:62ad/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:987782 errors:0 dropped:0 overruns:0 frame:0
TX packets:84155 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:109919111 (104.8 MiB) TX bytes:12695454 (12.1 MiB)
Interrupt:17
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:240 (240.0 b) TX bytes:240 (240.0 b)
virbr0 Link encap:Ethernet HWaddr 52:54:00:B9:B0:96
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2126 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:100387 (98.0 KiB)
virbr0-nic Link encap:Ethernet HWaddr 52:54:00:B9:B0:96
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
其中virbr0是由宿主机虚拟机支持模块安装时产生的虚拟网络接口,也是一个switch和bridge,负责把内容分发到各虚拟机。
virbr0是一个桥接器,接收所有到网络192.168.122.*的内容。从下面命令可以验证:
brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.525400b9b096 yes virbr0-nic
route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.122.0 * 255.255.255.0 U 0 0 0 virbr0
同时,虚拟机支持模块会修改iptables规则,通过命令可以查看:
iptables -t nat -L -nv
Chain PREROUTING (policy ACCEPT 16924 packets, 2759K bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 2009 packets, 125K bytes)
pkts bytes target prot opt in out source destination
421 31847 MASQUERADE all -- 192.168.122.0/24 !192.168.122.0/24 ----------->这条是关键,它配置了NAT功能。
Chain OUTPUT (policy ACCEPT 2011 packets, 125K bytes)
pkts bytes target prot opt in out source destination
iptables -t filter -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1 74 ACCEPT udp -- virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:53 ---->由libvirt脚本自动写入
0 0 ACCEPT tcp -- virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 ---->由libvirt脚本自动写入
3 984 ACCEPT udp -- virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:67 ---->由libvirt脚本自动写入
0 0 ACCEPT tcp -- virbr0 0.0.0.0/0 0.0.0.0/0 tcp dpt:67 ---->由libvirt脚本自动写入
178K 195M ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ---->iptables的系统预设
2 168 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 ---->iptables的系统预设
1148 216K ACCEPT all -- lo 0.0.0.0/0 0.0.0.0/0 ---->iptables的系统预设
1 60 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 ---->iptables的系统预设
16564 2721K REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ---->iptables的系统预设
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
3726 3485K ACCEPT all -- virbr0 0.0.0.0/0 192.168.122.0/24 state RELATED,ESTABLISHED ---->由libvirt脚本自动写入
3491 399K ACCEPT all -- virbr0 192.168.122.0/24 0.0.0.0/0 ---->由libvirt脚本自动写入
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0 ---->由libvirt脚本自动写入
0 0 REJECT all -- virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable ---->由libvirt脚本自动写入
0 0 REJECT all -- virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable ---->由libvirt脚本自动写入
0 0 REJECT all -- * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ---->iptables的系统预设
Chain OUTPUT (policy ACCEPT 181K packets, 138M bytes)
pkts bytes target prot opt in out source destination
如果没有default的话,或者需要扩展自己的虚拟网络,可以使用命令重新安装NAT。
NAT方式的适用范围
桌面主机虚拟化。
创建步骤
#virsh net-define /usr/share/libvirt/networks/default.xml
此命令定义一个虚拟网络,default.xml的内容:
也可以修改xml,创建自己的虚拟网络。
标记为自动启动:
#virsh net-autostart default
Network default marked as autostarted
启动网络:
#virsh net-start default
Network default started
网络启动后可以用命令brctl show 查看和验证。
修改/etc/sysctl.conf中参数,允许ip转发:
net.ipv4.ip_forward=1
客户机安装
客户机安装时注意,网络要选择用NAT方式。
编辑修改虚拟机配置文件 /etc/libvirt/qemu/v1.xml,增加如下内容
<interface type='network'> <mac address='52:54:00:4f:1b:07'/> <source network='default'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> interface>
虚拟机启动后,验证网络接口是否正常:
brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.525400b9b096 yes virbr0-nic
vnet0
Bridge方式的影响
Bridge方式配置出来的接口对NAT方式没有影响,因为NAT方式并没有使用物理网卡。但作为客户机,只能选择其中的一种。
Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。
场景说明:KVM虚拟机之前没有设置为Bridge模式,然后就直接创建虚拟机了(当时网卡模式选择的为default),后来调整KVM网卡模式为Bridge后,虚拟机没法正常联网。
[root@node160 ~]# virsh shudown CentOS-7.3-X86_64
[root@node160 ~]# virsh edit CentOS-7.3-X86_64
将xml配置文件中的:
修改为:
由于kvm虚拟机使用的是bridge模式,可以把virbr0接口(即NAT方式里面的default虚拟网络)删除
[root@node160 ~]# ip add list
1: lo:
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0:
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
4: virbr0:
link/ether 52:54:00:9f:ad:48 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
5: virbr0-nic:
link/ether 52:54:00:9f:ad:48 brd ff:ff:ff:ff:ff:ff
7: br0:
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
inet 10.10.10.160/24 brd 10.10.10.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe14:2b9a/64 scope link
valid_lft forever preferred_lft forever
8: vnet0:
link/ether fe:54:00:71:7b:aa brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fe71:7baa/64 scope link
valid_lft forever preferred_lft forever
10: vnet1:
link/ether fe:54:00:e4:7c:77 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fee4:7c77/64 scope link
valid_lft forever preferred_lft forever
[root@node160 ~]# virsh net-list --all
Name State Autostart Persistent
default active yes yes
[root@node160 ~]# brctl show
bridge namebridge idSTP enabledinterfaces
br08000.000c29142b9anoeth0
vnet0
vnet1
virbr08000.5254009fad48yesvirbr0-nic
[root@node160 ~]# virsh net-destroy default
Network default destroyed
[root@node160 ~]# virsh net-undefine default
Network default has been undefined
配置完成后,再次查看网卡信息
[root@node160 ~]# ip add list
1: lo:
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0:
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
7: br0:
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
inet 10.10.10.160/24 brd 10.10.10.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe14:2b9a/64 scope link
valid_lft forever preferred_lft forever
8: vnet0:
link/ether fe:54:00:71:7b:aa brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fe71:7baa/64 scope link
valid_lft forever preferred_lft forever
10: vnet1:
link/ether fe:54:00:e4:7c:77 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fee4:7c77/64 scope link
valid_lft forever preferred_lft forever