主要内容
iptables是什么
iptables通常被称为防火墙,个人认为这个称呼并不十分准确,准确来说,它是一个防火墙前端,用于配置防火墙的过滤规则。iptables的核心是netfilter,而netfilter是Linux的内核组件,netfilter通过iptables配置的规则来进行网络封包的过滤,因此,iptables和netfilter才是一个完整的防火墙组件。
iptables的组成部分
顾名思义,iptables是由一系列表组成,而表则是通过一条条的规则链(chain)构成,每条链里面保存的就是具体的防火墙规则。
表(tables)
iptables里面有多种类型的表格,分别是filter、nat、mangle、raw和security,其中filter是最常用的表格类型,它还是系统默认的表。
链(chain)
既然filter表是最常用的,就那它作为例子。filter表由3种链则组成,它们是
- INPUT
- OUTPUT
- FORWARD
INPUT链定义的是进站规则,例如通过ssh客户端连接服务器,这个客户端发出的数据对于服务器来说就是一个进站的数据。
OUTPUT链和INPUT相反,它定义的是出站规则,即从本地程序发送到外部网络的数据包。上面例子中的本地ssh客户端向服务器发出的数据就是一个出站数据包。
FORWARD链定义的是数据转发规则,例如当服务器作为一台路由的时候,就需要使用这个规则链。
iptables实战
前面说过,规则是保存到链中的,因此,我们添加一个规则,就是向指定表格的特定链中插入一条数据。
添加规则
例如,如果要限制22端口(ssh)被外部网络访问,可以定义下面的规则
1 |
iptables -t filter -A INPUT -i ens37 -p tcp --dport 22 -j DROP |
简单介绍下上面命令的意思:
向filter表的INPUT链追加一条规则,凡是从ens37网卡进入,且协议是tcp,访问本机22端口的数据全部丢弃。
每一个参数代表的意思如下:
- -t 用于指定表格类型,如果没有这个参数,默认操作的是filter表
- -A 向指定链追加规则,区别-I(insert)参数,追加的位置总是在链的最后,而插入可以指定插入位置
- -i -in-interface,即从哪张网卡来的数据
- -p 协议(protocol)
- –dport 目标端口(destination port)
- -j 跳转(jump)到目标,目标可以是DROP、ACCEPT等
target(目标)
上面的例子中,-j参数就是用于指定数据的跳转目标,这个目标可以是内置的:DROP、ACCEPT和REJECT,也可以是用户自定义的链。内置目标的含义如下:
- DROP 丢弃数据,且不返回任何提示,客户端只能等待超时返回
- ACCEPT 允许数据通过
- REJECT 和DROP相似,不同的是客户端可以得到返回的错误信息,REJECT还可以指定返回信息的类型。
默认策略
如果希望所有的链允许/禁止数据通过,可以使用默认策略,系统默认策略为:允许一切数据同行,即:
1 2 3 4 |
[root@study normal]# iptables -S -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT |
如果希望禁止所有数据通过,可以使用下面的命令
1 2 3 |
[root@study normal]# iptables -P INPUT DROP [root@study normal]# iptables -P OUTPUT DROP [root@study normal]# iptables -P FORWARD DROP |
更灵活的规则
上面的规则阻止了所有访问22端口的进站数据,但是,为了方便管理,很多时候都需要额外开放权限给指定的ip地址。下面展示这个方法:
1 |
iptables -t filter -A INPUT -i ens37 -p tcp --dport 22 -s 192.168.0.2 -j ACCEPT |
通过-s参数(source),可以指定特定的ip地址。
规则的生效顺序
现在,我们的表中有两个规则,可以使用iptables -L查看
1 2 3 4 5 |
[root@study normal]# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere anywhere tcp dpt:ssh ACCEPT tcp -- 192.168.0.2 anywhere tcp dpt:ssh |
一条是拒绝访问的,一条是允许访问的。那么第二条规则是否真的已经生效了?然而并没有,你会发现,该ip地址依然没有办法连上ssh端口,原因是iptables的生效顺序是从上往下的,一旦第一条规则匹配,便不会继续往下找。上面的规则中,第一条规则匹配了任何来源,包括了192.168.0.2的IP,所有,第二条规则不再进行匹配。因此,如果希望规则优先生效,就必须放到规则的前面。
所以,前面的规则应该这样放
1 2 3 4 5 |
[root@study normal]# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- 192.168.0.2 anywhere tcp dpt:ssh DROP tcp -- anywhere anywhere tcp dpt:ssh |
禁止主机被ping
另一个常见的行为是,禁止主机被别人进行ping测试。我们都知道,ping命令使用的协议是icmp,如果要禁ping,就是在规则中限制icmp的请求。
一个错误的例子:
1 |
iptables -t filter -A INPUT -i ens33 -p icmp -j DROP |
添加了这个规则之后,主机是无法被别人ping了,但是你会发现,自己也不能ping别人了,为什么呢?原因是,icmp有两种回显报文,一种是回显请求(echo-request),一种是回显响应(echo-reply),而禁止被别人ping属于回显请求,如果不指定回显类型,当DROP的时候会DROP掉所有的回显,因此,造成既不能被别人ping,也不能ping别人的现象。
正确的例子:
知道原因之后,也就可以修改上面的错误例子了
1 |
iptables -t filter -R INPUT 3 -i ens33 -p icmp --icmp-type echo-request -j DROP |
-R参数用于替换规则,上面的命令指定了禁止的回显类型,并替换掉上面的错误规则。
设置指定回显信息类型
前面说过,REJECT类型的target可以指定返回的回显信息,它是通过参数–reject-with进行设置的,例如:
1 |
iptables -t filter -A INPUT -i ens33 -p icmp --icmp-type echo-request -j REJECT --reject-with icmp-host-unreachable |
创建自定义Chain
把所有规则写到同一个Chain里面并不是一个好的办法,规则太多,管理起来并不方便,把规则归类是一个好办法。通过创建自定义Chain,可以方便地通过名称进行规则归类。
例如,有多个ssh的规则,就可以创建一个名为SSH的Chain,然后把规则添加到这个Chain下面。创建自定义Chain的命令是iptables -N
1 2 3 4 5 6 7 8 9 10 11 12 |
[root@localhost ginotang]# iptables -N SSH #添加自定义Chain [root@localhost ginotang]# iptables -L #查看所有规则 Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- 192.168.0.2 anywhere tcp dpt:ssh DROP tcp -- anywhere anywhere tcp dpt:ssh DROP icmp -- anywhere anywhere icmp echo-request # 省略部分输出 Chain SSH (0 references) #这是一个自定义Chain target prot opt source destination |
添加好后,iptables -L命令就可以显示这个新添加的Chain。下一步就可以往这个Chain里面添加规则,规则的添加和系统内置的Chain使用方法一样,例如:
1 2 3 4 5 6 7 |
[root@localhost ginotang]# iptables -t filter -A SSH -i ens33 -p tcp --dport 22 -s 192.168.0.3 -j ACCEPT [root@localhost ginotang]# iptables -t filter -A SSH -i ens33 -p tcp --dport 22 -s 192.168.0.5 -j DROP [root@localhost ginotang]# iptables -L SSH Chain SSH (0 references) #表示没有引用 target prot opt source destination ACCEPT tcp -- 192.168.0.3 anywhere tcp dpt:ssh DROP tcp -- 192.168.0.5 anywhere tcp dpt:ssh |
默认,自定义规则并不会生效,因为它没有引用,上面的(0 references)已经说明,如果自定义规则要生效,它必须通过内置规则链的跳转。
设置自定义链的跳转
1 |
[root@localhost ginotang]# iptables -t filter -A INPUT -p tcp --dport 22 -j SSH |
意思是,所有访问端口22的tcp协议全部跳转到自定义的SSH链,设置好后再通过iptables -L命令观察
1 2 3 4 5 |
[root@localhost ginotang]# iptables -L SSH Chain SSH (1 references) target prot opt source destination ACCEPT tcp -- 192.168.0.3 anywhere tcp dpt:ssh DROP tcp -- 192.168.0.5 anywhere tcp dpt:ssh |
发现0 references已经变成1 references,这个时候自定义链才正式工作。
相关命令
查看iptables规则
除了-L参数外,iptables还可以有更多的显示格式,例如-n -v参数,-n参数以ip的方式显示源地址和目标地址,而-v参数用于显示更详细的输出,例如已经拦截到的数据量。
1 2 3 4 5 6 7 |
[root@localhost ginotang]# iptables -L -nv Chain INPUT (policy ACCEPT 26 packets, 2168 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- ens33 * 192.168.0.2 0.0.0.0/0 tcp dpt:22 0 0 DROP tcp -- ens33 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 0 0 REJECT icmp -- ens33 * 0.0.0.0/0 0.0.0.0/0 icmptype 8 reject-with icmp-host-unreachable 0 0 SSH tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 |
删除iptables设置
iptables -F
不带参数的iptables -F命令用于删除所有的规则,也可以传入指定的链行删除
iptables -Z
用于清除规则中已经捕获的数据,可以清除整个链,也可以清除链中的指定规则
iptables -X
用于删除自定义链,命令使用前必须清空链中的引用,如果不传入指定的链,则删除所有用户自定义链。
保存表和还原表
iptables命令设置的规则在系统关闭的时候就会失效,也即是说它不是永久的,如果希望在系统重启的时候重新应用规则,就要把这些规则先保存起来,然后在系统下次启动的时候进行还原
表的保存可以通过iptables-save命令:
1 |
[root@localhost ginotang]# iptables-save >> /etc/iptables.rule |
然后就可以在系统下一次登录的时候使用iptables-restore命令还原
1 |
[root@localhost ginotang]# iptables-restore < /etc/iptables.rule |
获取帮助
想知道某些参数如何设置,可以通过下面的方式,例如,查看 –reject-with可以设置的参数
1 |
[root@localhost ginotang]# iptables -j REJECT --help |
又如,获取有关icmp协议的设置信息
1 |
[root@localhost ginotang]# iptables -p icmp --help |
转载请注明:Pure nonsense » iptables基础