29---iptables 原理与应用

============
iptables简介
我们知道协议栈是linux kernel中实现的,也就是数据的封装解封装都是由内核完成的,既然内核可以做这些事情,我们当然就可以让内核帮助我们对指定的包做指定的动作。那怎么指定包呢?无非就是根据报文的某些字段或者客观的条件,比如目的地址是192.168.10.129的报文,到达3层后就不要继续处理了,直接丢弃。比如23:00~05:00这个时间段drop所有来访数据包。这种对包的指定条件和处理动作,我们称之为rules。我们要告诉内核,就必然要发起系统调用,而且要按照系统调用接口规定的格式把我们的rule传给内核,这就涉及到了系统编程(这是对程序员来讲的)。对于普通用户,我们可以使用 iptables 这个工具向内核传递这些rules。举个例子,我们使用一个文本文件编辑器的时候,其实就是让该编辑器告诉内核,我要把刚刚键入的xxx内容存入xxx磁盘的xxx位置并且命名为xxx。同理iptables就是把我们想对哪些数据包做哪些动作告诉内核,他就是一个普通的程序,仅此而已。使用该工具,就要按照这个工具的指定的格式给出筛选数据包的条件和处理动作。我们下面就开始讲如何使用这个工具,不过在讲这个工具之前,得先清楚内核中包处理的几个概念。
=============
表,链,规则
/*-----这里以参加旅行社去美帝旅游为例进行类比-----*/
check point 1 ---> PREROUTING
check point 2 ---> INPUT
check point 3 ---> FORWARD
check point 4 ---> OUTPUT
check point 5 ---> POSTROUTING
机场A ---> 网卡接口
机场B ---> 网卡接口  //这里的机场A和机场B可以是同一个(物理网卡),也可以是不同的
海关A ---> 路由表
海关B ---> 路由表  //这里的海关A和海关B可以是一个地区(VPN-instance)的,也可以是不同地区的

场景描述:
我们参加某旅行社组织的美帝3日游,路线只有两条:
1. 过美帝海关入境后乘坐专列去拉斯维加斯的酒店赌场豪赌两把,输个精光,然后狼狈回国。
2.过美帝海关入境后在机场钱包被偷,求助无果,伤心改签当日机票回国。(机票始发可能变更哦)
由于近来美帝反恐局势愈加严重,街头哨卡(check point)一个接一个,针对来美赌客和倒霉蛋(钱包被偷者),一共会有5种哨卡等着他们。每个哨卡的条子都拿着一张张的表来检查,但是每一个哨卡的表和表中的内容还都不一样。
table: 条子手中的检查表
上面的头儿发话了,这一段时间的检查只检查如下几张表,上头会根据各哨卡单位警力配备和单位职责安排检查,各表有先后顺序,后面数字小的先检查。表模板写了如果在某哨卡检查的话,应该如何检查及检查结果如何处理。也就是rule。
犯罪记录(1)
     如果check point1要检查,请检查有无谋杀罪。我美帝已经不安全,不能再放坏蛋近来。
     如果check point2要检查,请检查有无偷盗罪。来赌场赌博,不能是小偷,否则还得雇人看场子,又得花钱。
     如果check point ###。。。。。
健康状况(2)
     如果check point1要检查,请检查有无传染病。
     如果check point2要检查,请检查有无偷窥的心理疾病。
     如果check point ###。。。。。
     check point5 就不要检查了,他都要走了,以后跟我们没有半毛钱关系。
学历能力(3)
     如果check point #要检查。。。。
财产状况(4)
     如果check point 5 要检查,检查下他这次在我们美帝赢了多少钱回去!大于5K就揩他油。
     如果check point #要检查。。。。
-----
如上文所述,并不是每个哨卡的检查表都一样,比如 check point 1,是刚刚到达机场,这时候遇到 FBI 可能就只会检查你的犯罪情况,而不会盘问你的学习能力。不过如果 FBI 警力和经费充足,他们可能也会根据这张表来盘问,是否按某张表检查,取决于上面的头儿,也就是表的指定者。(就是root啦)
chain: 从一个地点到达另一个地点经过的路线(我们在该路线上被盘查)
路(chain)上有check point,每条路上一个 check point,每个check point的条子手里或多或少都有几张表,当然一张表也没有,也是可能的,说明美帝真的是歌舞升平的太平盛世啦。
rule: 定义了如何盘查并处理,rule写在表上,作用在chain上。
比如犯罪记录表上要求检查某个人是不是来自叙利亚的阿勒颇,如果是就拒绝入境。
比如犯罪记录表上要求检查是否身上藏有危险品,如炸弹,如果有,就地枪毙。
比如财产状况表上要求检查是否年收入1M$,如果是,马上跪舔并免费赠送一套高逼格西装。
-----
上头的指示,也就是这张表怎么传达到各个check point呢?上面的头儿(root)发如下的命令给其秘书(iptables这个程序),秘书把表打印好交给各个check point。举例如下:
iptables -t 财产状况 -A check_point_2 -s 天朝 -d 美帝 -p 斗地主 --sport 澳门 --dport 拉斯维加斯 -j ACCEPT
解释:对check_point_2(-A指明)的“财产状况”这张盘(-t指明)问表上增加(-A指明)一条盘问,看看这个人是否来自天朝,是否目的地是美帝(这个子条目无用,都坐上去拉斯维加斯的专列了,目的地能不是美帝嘛),是不是来玩斗地主的,是不是来自澳门赌场,是不是去拉斯维加斯赌场,如果都是,放行!美帝欢迎你。
policy:默认策略
即某人不匹配指定table在指定check point(chain上)的盘问所有条目(rule),那在该check point如何处理?不用担心,该table在该chain上必然会有个policy兜底这种情况。比如来了一个外星人,chain上的check point都按手中的某张表一项项(rule)地匹配,发现都匹配不上,那就就会有个默认策略(policy)规定针对这种情况的处理动作,比如认为安全就放行了。
自定义chain: 小黑屋
然而万恶的资本主义美帝果然是堕落腐败,上头发的“财产状况”表上竟然写了如果被调查者年收入超过100W人民币,且学历为小学学历,则可以进“小黑屋”用上头给N条小黑屋法则对其盘问,说不定被盘问者可能是煤老板,也许能捞一笔。所以上面的人先收拾一个房间做小黑屋,然后又在“财产状况”表上添加了一些规则。
iptables -t 健康状况 -N black_room  //建立小黑屋,并在小黑屋的墙上贴了“健康状况”的表
iptables -t 健康状况 -A 身体不是很健壮&&经判断面对暴力不敢反击 -j 揩油&&遣返  //进了小黑屋就要按小黑屋的表处理,小黑屋的表也有优先级,每张表上的条目也有优先级,这里举例只有一张表一个条目。
iptables -t 财产状况 -A 小学学历&&年收入超100W -j black_room  //在“财产状况”表添加rule,满足规则就进小黑屋处理 
DNAT:瞒天过海
俄罗斯的间谍想去调查美国大选的组织结构,被美帝NSA成功策反,于是拿着美国给发的假身份去天朝东莞爽了一圈,然后回美国取回自己的身份证件,再启程回俄罗斯。然后禀告普京大帝,美帝已经堕落的不行不行的了,哎呀那楼梯上一排排的,啧啧啧.....
SNAT:偷梁换柱
俄罗斯的克格勃特工拉夫斯基被安排去调查美国大选的组织结构,还没到目的地,在飞机上这个克格勃特工就雇了一个屌丝潇洒哥,让潇洒哥以自己的身份配合其他特工去大选现场拍几张照片,而他自己去拉斯维加斯逍遥快活去了。潇洒哥拍完照片发给拉夫斯基,拉夫斯基就回俄罗斯复命。
===================
言归正传,看流程图

4张表
raw: This  table  is  used mainly for configuring exemptions from connection tracking in combination with the NOTRACK  target.
mangle: This table is used for specialized packet alteration.
nat: network address translation 完成地址转换或端口转换
filter: 条件过滤,iptables 不加 -t 选项时,默认指的就是filter
优先级:raw>mangle>nat>filter
最常用的表是 filternat,下文会讲到如何在链上配置这两张表。
5条内置链(表即对链上的数据做检查)
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

上面说的4张表能够作用在哪些chain上?可以通过 iptables -t { filter | nat | mangle | raw } -L 来查看。
----filter: INPUT,FORWARD,OUTPUT(不使用-t指明,则默认为filter)
----nat: PREROUTING(DNAT),INPUT,OUTPUT,POSTROUTING(SNAT)
----mangle: PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
----raw: prerouting,output
每张表的链上的规则都统计了匹配这条规则的报文数和报文的字节数(total)
<=====下文仅对 filter 和 nat 两张表的操作做介绍=====>
iptables 语法规则和常用选项
对链做操作
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
iptables [-t table] -P chain target
iptables [-t table] -N chain
iptables [-t table] -X [chain]
iptables [-t table] -E old-chain-name new-chain-name
-F: flush 清空规则链,省略链表示清空指定table上的所有链(但不影响 Policy)
-L: list 列出指定链上的所有规则
        -n numeric 以数字形式显示地址和端口号
        -v 显示详细信息 -vv -vvv
        --line-numbers 显示规则所在行号,增删规则时常用这个行号
        -x exactly 显示计数器计数结果的精确值
        iptables -L -nv 是经常用的
-Z: 清零规则计数器
-P: 为指定链设置默认策略(可以认为是兜底rule),对filters表中的链而言,默认策略通常有accept(默认),drop,reject //DROP和REJECT的区别是什么
-N: 创建新的自定义规则链(可以认为是子链,即在主链上匹配到某规则后-j跳到该子链,子链再逐一拿rule匹配该packet,匹配不到再返回主链匹配队列,开始队列中下一条rule的匹配)
-X: 删除用户自定义的空的规则链(不空的话先用-F清空之;该链若被引用也无法删除)
-E: 重命名自定义链,引用计数器不为0的自定义链无法改名,也无法删除
对链上的规则做操作
iptables [-t table] -A chain rule-specification
iptables [-t table] -I chain [rulenum] rule-specification
iptables [-t table] -R chain rulenum rule-specification
iptables [-t table] -D chain rulenum
-A append 将新规则追加于指定链的位置
-I insert 将新规则插入至指定链的指定位置(默认插入到第一条)
-D delete 删除指定链上的指定规则
        两种指定方式:
            1.指定匹配条件
            2.指定规则编号(这个方便,所以常用)
-R replace 替换指定链上的指定规则(by rulenum)
匹配条件:
    基本匹配:(包解析只在物理层和IP层,支持感叹号取反)
        [!]-s,--src,--source IP|NetAddr  设定检查的项为源地址
        [!]-d,--dst,--destination IP|NetAddr  设定检查的项为目的地址
        [!]-p,--protocol {tcp|udp|icmp}   协议(IP头中标识的上层协议)
        [!]-i,--in-interface IF_name  数据报文的流入接口 ---仅用于prerouting,input,forward
        [!]-o,--out-interface IF_name  数据报文的流出接口 ---仅用于output,forward,postrouting
      扩展匹配:-m match_name match_option
        隐式扩展:对 -p protocol 指明的协议进行的扩展,可省略-m tcp|udp|icmp
            -p tcp
                --dport PORT[:PORT2]  单个或者连续的多个端口
                --sport PORT[:PORT2]
                --tcp-flags LIST1 LIST2  检查LIST1中的TCP标志位,要求若标志位位于LIST2值须为1,不在LIST2须为0
                                                      SYN,ACK,FIN,RST,PSH,URG
                --syn 等价于 --tcp-flags SYN,ACK,FIN SYN ,即检查3次握手的第一次请求
            -p udp
                --dport
                --sport
            -p icmp
                --icmp-type
                    0  即 echo-reply
                    8  即 echo-request
      显式扩展:-m match_name match_option不能省
            必须显式指明使用的扩展模块(rpm -ql iptables | grep "\.so")
            CentOS6 : man iptables
            CentOS7 : man iptables-extensions
            常用的显式扩展:支持[!]
                1.multiport
                    This  module  matches  a  set of source or destination ports.  Up to 15 ports can be specified.  A port range (port:port) counts as two  ports.  It can only be used in conjunction with --pp ttccpp or --pp uuddpp.
                    --source-port, --sports port[,port|,port:port] 端口range用冒号隔开,离散端口用逗号隔开 f
                    --destination-ports, --dports
                    --ports
                    举例                   
                    iptables -I INPUT -s 172.16.0.0/16 -d 172.16.100.1 -p tcp -m multiport --dports 22,80 -j ACCEPT
                    iptables -I OUTPUT -d 172.16.0.0/16 -s 172.16.100.1 -p tcp -m multiport --sports 22,80 -j ACCEPT
                2.iprange
                    指明连续的ip地址范围时使用
                    --src-range from[-to]
                    --dst-range from[-to]
                    iptables -I INPUT -d 192.168.10.129 -p tcp -m multiport --dports 22:23,80 -m iprange --src-range 172.16.100.1-172.16.100.254 -j ACCEPT
                    iptables -I OUTPUT -s 192.168.10.129 -p tcp -m multiport --sports 22:23,80 -m iprange --src-range 172.16.100.1-172.16.100.254 -j ACCEPT
                3.string
                    检查报文中传输的字符串
                    --algo {bm|kmp} //搜索算法,必选项
                    --string PATTERN
                    --hex-string PATTERN
                    iptables -I OUTPUT -m string --algo bm --string 'movie' -j REJECT
                4.time(接收到报文时检查时间)
                    --datestart
                    --datestop
                    --timestart
                    --timestop
                    --monthdays
                    --weekdays
                    iptables -I INPUT -d 192.168.10.129 -p tcp --dport 80 -m time --timestart 14:00 --timestop 16:00 -j DROP
                5. connlimit <--SecureCRT克隆SSH会话,仍属于一个连接,可以通过 ss -nte 得到多个会话仅有一个 established 状态的连接
                    对每个IP限制其连接数
                    --connlimit-above # 连接数量大于#
                    --connlimit-upto #  连接数量小于等于#
                    iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT
                6. limit
                    基于收发报文的速率做匹配
                    令牌桶过滤器
                    iptables -A INPUT -d 192.168.10.129 -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 30/minute -j ACCEPT
                    iptables -A OUTPUT
                    --syn -m limit --limit 100/second 新的建立连接的请求限制到每秒100以内
                7. state(非TCP状态)
                    状态扩展,根据连接追踪机制,跟踪每一个连接请求来检查连接的状态
                    防火墙内部维护每一条连接记录,并分配一个老化定时器
                    追踪模块需要一个内核模块:(rmmod就关闭了追踪)
                        nf_conntrack_ipv4
                    调整连接追踪功能所能记录的连接相关的最大条目
                        /proc/sys/net/nf_conntrack_max  <-- 调大该值,或者关闭追踪
                    已经追踪并记录的连接
                        cat /proc/net/nf_conntrack
                    报文状态
                        NEW 连接追踪记录中无记录者,将报文识别为NEW
                        ESTABLISHED 报文通过检查并记录,之后相同5元组(ip,协议,端口)的报文被识别为ESTABLISHED
                        RELATED 与现存连接相关,如ftp中被动数据连接
                        INVALID 无法识别的报文
                        对于没有问题的报文,先记录连接为ESTABLISHED,再给response包。
                    iptables -I INPUT -d 192.168.10.129 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
                    iptables -I OUTPUT -s 192.168.10.129 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT  //怎么能用established呢?服务器响应的第一个报文时,还没有established啊!!!!!理解为:收到request后就认为established了?YES!
疑问:
FTP的数据链路,如何判断是related? 和上面说的established有什么区别?
/proc/sys/net/netfilter <--不同协议或连接类型追踪的时长,单位是什么????
                        nf_conntrack_tcp_timeout
                        nf_conntrack_udp_timeout
处理动作(TARGET)
现在我们已经知道rule里面包括了匹配规则和处理动作,上面讲了匹配规则,下面我们讲下处理动作。iptables中把处理动作叫做 TARGET,匹配规则匹配成功后通过 -j 跳转(jump)到指定目标处理。
    -j TARGET 指定jump到指定的TARGET
        ACCEPT
        DROP
        REJECT
        RETURN  返回主链匹配队列
        -----
        REDIRECT  端口重定向
        LOG  记录日志
        MARK  做防火墙标记
        DNAT  目标地址转换
        SNAT  源地址转换
        自定义链  跳到自定义链上的规则进行匹配检查
问题:DROP和REJECT的区别是什么?DROP是直接把包丢弃,REJECT是回复ICMP信息给源端。
 --reject--with type
              The  type  given can be icmp-net-unreachable, icmp-host-unreachable,icmp-port-unreachable,icmp-proto-unreachable,icmp-net-prohibited,icmp-host-prohibited or icmp-admin-prohibited(*) which  return  the  appropriate  ICMP  error  message (port-unreachable is the default).
自定义链
<-----自定义链举例如下----->
自定义链只有被内置链引用才能生效,通过 iptables -t table_name -L -n 可以看到内置链后的括号中是policy,二自定义链后的括号中是被引用的次数。
iptables -N clean_in    //在 filter 表定义
iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
iptables -A clean_in -d 192.168.10.129 -j RETURN    //自定义链处理完,若没有匹配到任何rule,则返回主链继续匹配

iptables -A INPUT -d 192.168.10.129 -j clean_in
iptables -A INPUT -p tcp --dports 22,139,445 -j ACCEPT
iptables -A INPUT -p udp --dports 137,138 -j ACCEPT
iptables -A OUTPUT -p tcp --sports 22.,139,445 -j ACCEPT
iptables -A OUTPUT -p udp --sports 137,138 -j ACCEPT
DNAT & SNAT
上文讲到的都是对 filter 表的操作,对 filter 表的操作可以省略 -t 选项。现在我们讲下 NAT 表的操作。
一般来讲对 filter 表的操作可以在主机上,也可以在网关上,但对 NAT 的操作往往是在网关上。
Linux 系统的网关需要打开路由转发功能,若 cat /proc/sys/net/ipv4/ip_forward 的值为 1 则代表路由转发功能已经打开,若为 0 则可以通过如下两种方式将该值设置为 1 
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
这两种方法都是临时的,若想永久生效,需要改变配置文件 /etc/sysctl.conf 中 net.ipv4.ip_forward=1 这样开机会自动打开 ip 转发功能。
ok,我们按照下图搭建实验

我们在CentOS 6-A 上做NAT,把 CentOS 6-B 作为 Web Server,CentOS 7 作为 Web Client。实验之前最好确保图中5个IP两两可达。
注意:在CentOS 7 上添加默认路由的时候一定要指明网关,否则ARP广播会有问题,描述如下:
ip route add 192.168.10.0/24 dev ens33  <--- 错误配置,仅指明接口,未指明下一跳
ip route add 192.168.10.0/24 via 192.168.20.128 dev ens33  <--- 正确配置
区别在哪里?区别就是ping 192.168.10.0/24 这个网段的地址的时候,前者直接对目标地址做ARP,因为ens33在192.168.20.0/24这个网络,所以压根没人理会这个ARP。而后者是对网关或下一跳(192.168.20.128)做ARP,拿到网关的MAC后将报文发给网关,网关再转发之。这一点还是需要注意的!
SNAT:只修改请求报文的源地址
iptables -t nat -A POSTROUTING -s 192.168.20.0/24 -d 192.168.10.0/24 -j SNAT --to-source 192.168.10.128(该地址需要存在,可以是loopback IP,可以是IFIP)
添加一条规则即可,此时CentOS 6-A内部会维护一张NAT转换表,自动对上下行数据做转换。(注意不仅仅是对上行数据哦)其实这个实验中,即使CentOS 6-B 没有到 192.168.20.0/24 网段的路由条目也没有问题,但是 CentOS 7 一定要有到 192.168.10.0/24 这个网段的路由条目。
此时在 CentOS7 上访问 CentOS 6-B,然后打开CentOS 6-B上的访问日志,可以看到访问源是192.168.10.128,而非CentOS7的192.168.20.129
补充:可以把-j SNAT --to-source 192.168.10.128 改为 -j MASQUERADE 这会自动搜寻一个可用的IP。对于浮动的IP来讲挺有用。
DNAT:只修改请求报文的目标地址
iptables -t nat -A PREROUTING -d 192.168.20.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.129:10086
同DNAT,这条 rule 添加后,CenOS 6-A内部也会维护一张NAT转换表,自动对上下行数据做转化。此时 CentOS 7 访问 CentOS 6-A的80端口(虽然CentOS6-A并未开启该端口),然后CentOS 6-A 接收到报文后,将报文的目的地址替换为CentOS 6-B的IP,端口号替换为10086(CentOS 6-B在此端口监听web服务请求,霸气!)。
再举一个例子:
iptables -t nat -A PREROUTING -d 192.168.20.128 -p tcp --dport 22 -j DNAT --to-destination 192.168.10.129
此时如果要SSH到 192.168.20.128,会被NAT,SSH连接请求会发给 192.168.10.129
DNAT的 --to-destination 可以指定多个IP,内核会round-robin使用这些IP,这样就可以做服务器的负载均衡了。lvs之前,好像确实是iptables来做负载均衡的。
重点关注:
SNAT:SNAT是作用在POSTROUTING链上的,不能作用在PREROUTING,因为还不知道是送往本机还是其他机器。而这种场景下作用在INPUT和OUTPUT则没有意义,因为数据报文根本不进入用户空间。
DNAT:DNAT作用于PREROUTING,否查则路由表之后一看是dst ip为本机,就进入input处理了。
===============
保存和重载规则
遗憾的是,我们辛辛苦苦写的 规则表 当机器重启后就会丢失,怎么办?找个文件存起来,对!
iptables-save > /path/to/your/file  //把现有规则重定向到制定文件
iptables-restore < /path/from/your/file  //需要规则时重载进来;注意重载会覆盖当前规则表!!!

CentOS6
    iptables是一个脚本,可用于规则的重载
    service iptables save
        == iptables-save > /etc/sysconfig/iptables
    service iptables restart 
        == iptables-restore < /etc/sysconfig/iptables

    chkconfig --list iptables
    /etc/rc.d/init.d/iptables <-- 配置文件

CentOS7
    引入了iptables的前端管理服务工具 firewalld
    firewalld-cmd 要使用iptables,需要停用firewalld
        systemctl disables firewalld.service  //禁止开机启动
        systemctl stop firewalld.service
    firewalld-config 图形界面   
=======
配置建议
同一类表的访问同一类应用的规则,匹配范围小的放在前面,匹配到规则后即执行动作,后续的规则不再尝试匹配。
同一类表的访问不同类应用的规则,被匹配概率大的放前面,如web服务器上80就比21端口访问频率要高 。
设置白名单:每一类表都设置默认策略为ACCEPT,再自己加一条兜底的rules用于DROP。


习题:如何开放"被动模式"的FTP服务?
1.装载模块
    modeprobe nf_conntrack_ftp
    lsmod | grep ftp
    modinfo nf_conntrack_ftp
2.放行请求报文
    命令连接:ESTABLISHED,NEW
    数据连接:ESTABLISHED,RELATED
    iptables -A INPUT -d 192.168.10.129 -p tcp --dport 21 -m state --state ESTABLISHED,NEW -j ACCEPT
    iptables -A INPUT -d 192.168.10.129 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
3.放行应答报文
    命令连接:ESTABLISHED
    数据连接:ESTABLISHED
    iptables -A OUTPUT -s 192.168.10.129 -p tcp -m state --state ESTABLISED -j ACCEPT





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值