linux防火墙主要功能
Linux下的防火墙功能是非常丰富的,但阿铭在日常的运维工作中,使用它的情况并不多。所以阿铭打算把一些常用的知识点介绍给大家。
14.4.1 SELinux
SELinux是Linux系统特有的安全机制。因为这种机制的限制太多,配置也特别烦琐,所以几乎没有人真正应用它。安装完系统,我们一般都要把SELinux关闭,以免引起不必要的麻烦。临时关闭SELinux的方法为:
# setenforce 0
但这仅仅是临时的,要想永久关闭需要更改配置文件/etc/selinux/config,需要把SELINUX= enforcing改成SELINUX=disabled,更改后的内容如下所示:
# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
更改完该配置文件后,重启系统方可生效。可以使用getenforce命令获得当前SELinux的状态,如下所示:
# getenforce
Disabled
阿铭的SELinux早就关闭了,所以会显示为Disabled,如果还没有关闭默认会输出enforcing。当使用setenforce 0这个命令后,再执行getenforce命令会输出permissive。
14.4.2 netfilter
在之前的CentOS版本(比如CentOS6)的防火墙为netfilter,从CentOS7开始,防火墙为firewalld。很多朋友把Linux的防火墙叫作iptables,其实这样叫并不太恰当,iptables仅仅是一个工具。对于CentOS 7或者8上的firewalld,阿铭目前在工作中使用得并不多。当然,即使是firewalld,同样也支持之前版本的命令用法,也就是说它是向下兼容的。
关于这一节的内容,阿铭是这样安排的。首先要大概讲一下之前版本iptables的常用用法,然后再介绍一下firewalld的一些用法。下面阿铭先教你如何把firewalld关闭,然后开启之前版本的iptables。示例命令如下:
# systemctl stop firewalld #关闭firewalld服务
# systemctl disable firewalld #禁止firewalld服务开机启动,后面将会详细讲解
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
# yum install -y iptables-services #安装iptables-services,这样就可以使用之前版本的iptables了
# systemctl enable iptables #让它开机启动
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to
/usr/lib/systemd/system/iptables.service.
# systemctl start iptables #启动iptables服务
到此,咱们就可以使用之前版本的iptables了。CentOS上默认设有iptables规则,这个规则虽然很安全,但对于我们来说没有用,反而会造成某些影响,所以阿铭建议你先清除规则,然后把清除后的规则保存一下。示例命令如下:
# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot
opt in out source destination
21 1620 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 16 packets, 1536 bytes)
pkts bytes target prot opt in out source destination
# iptables –F
# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
上例中,-nvL选项表示查看规则,-F选项表示清除当前规则,但清除只是临时的,重启系统或者重启iptalbes服务后还会加载已经保存的规则,所以需要使用service iptables save保存一下规则。通过上面的命令输出,我们也可以看到,防火墙规则保存在/etc/sysconfig/iptables中,你可以查看一下这个文件。
1. netfilter的5个表
filter表主要用于过滤包,是系统预设的表,这个表也是阿铭用得最多的表。该表内建3个链:INPUT、OUTPUT以及FORWARD。INPUT链作用于进入本机的包,OUTPUT链作用于本机送出的包,FORWARD链作用于那些跟本机无关的包。
nat表主要用于网络地址转换,它也有3个链。PREROUTING链的作用是在包刚刚到达防火墙时改变它的目的地址(如果需要的话),OUTPUT链的作用是改变本地产生的包的目的地址,POSTROUTING链的作用是在包即将离开防火墙时改变其源地址。该表阿铭仅偶尔会用到。
mangle表主要用于给数据包做标记,然后根据标记去操作相应的包。这个表几乎不怎么用,除非你想成为一个高级网络工程师,否则就不需要太关注。
raw表可以实现不追踪某些数据包,默认系统的数据包都会被追踪,但追踪势必消耗一定的资源,所以可以用raw表来指定某些端口的包不被追踪。这个表,阿铭从来没用过。
security表在CentOS 6中是没有的,它用于强制访问控制(MAC)的网络规则。可以说这个表阿铭都没有深入研究过,更别说使用了。所以,你暂时不用理会它。
2. netfilter的5个链
5个链分别为PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。
-
PREROUTING:数据包进入路由表之前。
-
INPUT:通过路由表后目的地为本机。
-
FORWARDING:通过路由表后,目的地不为本机。
-
OUTPUT:由本机产生,向外转发。
-
POSTROUTIONG:发送到网卡接口之前。
具体的数据包流向,可以参考下面图:
表和链对应的关系图如下:
3. iptables基本语法
iptables是一个非常复杂和功能丰富的工具,所以它的语法也是很有特点的。下面阿铭就给大家介绍几种常用的语法。
(1) 查看规则以及清除规则,其用法如下:
# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 4 packets, 384 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 4 packets, 384 bytes)
pkts bytes target prot opt in out source destination
-t选项后面跟表名,-nvL表示查看该表的规则,其中-n表示不针对IP反解析主机名,-L表示列出,-v表示列出的信息更加详细。如果不加-t选项,则打印filter表的相关信息,如下所示:
# iptables -nvL
Chain INPUT
(policy ACCEPT 252 packets, 19329 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD
(policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT
(policy ACCEPT 222 packets, 24340 bytes)
pkts bytes target prot opt in out source destination
上例和-t filter打印的信息是一样的。关于清除规则的命令中,阿铭用得最多就是下面两个:
# iptables -F
# iptables -Z
这里-F表示把所有规则全部删除,如果不加-t指定表,默认只清除filter表的规则。-Z表示把包以及流量计数器置零(这个阿铭认为很有用)。
(2) 增加/删除一条规则,其用法如下:
# iptables -A INPUT -s 192.168.72.1 -p tcp --sport 1234 -d 192.168.72.128 --dport 80 -j DROP
这里没有加-t选项,所以针对的是filter表。这条规则中各个选项的作用如下。
-
-A/-D:表示增加/删除一条规则。
-
-I:表示插入一条规则,其实效果跟-A一样。
-
-p:表示指定协议,可以是tcp、udp或者icmp。
-
--dport:跟-p一起使用,表示指定目标端口。
-
--sport:跟-p一起使用,表示指定源端口。
-
-s:表示指定源IP(可以是一个IP段)。
-
-d:表示指定目的IP(可以是一个IP段)。
-
-j:后面跟动作,其中ACCEPT表示允许包,DROP表示丢掉包,REJECT表示拒绝包。
-
-i:表示指定网卡(不常用,但偶尔能用到)。
下面阿铭再多举几个例子来帮你理解这些概念:
# iptables -I INPUT -s1.1.1.1 -j DROP
上例表示插入一条规则,把来自1.1.1.1的所有数据包丢掉。下例表示删除刚刚插入的规则:
# iptables -D INPUT -s1.1.1.1 -j DROP
注意删除一条规则时,必须和插入的规则一致。也就是说,两条iptables命令,除了-I和-D不一样外,其他地方都一样。
下例表示把来自2.2.2.2并且是TCP协议到本机80端口的数据包丢掉:
# iptables -I INPUT -s2.2.2.2 -p tcp --dport 80 -j DROP
注意,--dport/--sport必须和-p选项一起使用,否则会出错。
下例表示把发送到10.0.1.14的22端口的数据包丢掉:
# iptables -I OUTPUT -p tcp --dport 22 -d10.0.1.14 -j DROP
下例表示把来自192.168.1.0/24这个网段且作用在ens33上的包放行:
# iptables -A INPUT -s 192.168.1.0/24 -i ens33 -j ACCEPT
# iptables -nvL |grep '192.168.1.0/24'
0 0 ACCEPT all -- ens33 * 192.168.1.0/24 0.0.0.0/0
有时候服务器上的iptables过多了,你想删除某一条规则,但又不容易掌握创建时的规则。其实有一种比较简单的方法,先查看iptables规则,示例命令如下:
# iptables -nvL --line-numbers
Chain INPUT (policy
ACCEPT 309 packets, 23689 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT all -- ens33 * 192.168.1.0/24 0.0.0.0/0
然后删除某一条规则,使用如下命令:
# iptables -D INPUT 1
这里-D后面依次跟链名、规则num。这个num就是查看iptables规则时第1列的值。随后查看刚才的规则时已经没有了,如下所示:
# iptables -nvL --line-numbers
iptables还有一个选项经常用到,即-P(大写)选项,它表示预设策略。其用法如下:
# iptables -P INPUT DROP
-P后面跟链名,策略内容或为DROP,或为ACCEPT,默认是ACCEPT。注意:如果你在连接远程服务器,千万不要随便执行这个命令,因为一旦输入命令并回车,远程连接就会被断开。
这个策略一旦设定后,只有使用命令iptables -P INPUT ACCEPT才能恢复成原始状态。下面阿铭针对一个小需求介绍一下如何设定iptables规则。
需求:只针对filter表,预设策略INPUT链DROP,其他两个链ACCEPT,然后针对192.168.72.0/24开通22端口,对所有网段开放80端口,对所有网段开放21端口。
这个需求不算复杂,但是因为有多条规则,所以最好写成脚本的形式。脚本内容如下:
# vi /usr/local/sbin/iptables.sh #写入如下内容
ipt="/usr/sbin/iptables"
$ipt -F
$ipt -P INPUT DROP
$ipt -P OUTPUT ACCEPT
$ipt -P FORWARD ACCEPT
$ipt -A INPUT -s 192.168.72.0/24 -p tcp --dport 22 -j ACCEPT
$ipt -A INPUT -p tcp --dport 80 -j ACCEPT
$ipt -A INPUT -p tcp --dport 21 -j ACCEPT
完成脚本的编写后,直接运行/bin/bash /usr/local/sbin/iptables.sh即可。如果想开机启动时初始化防火墙规则,则需要在/etc/rc.d/rc.local中添加一行/bin/bash /usr/local/sbin/iptables.sh。执行过程如下:
# sh /usr/local/sbin/iptables.sh
# iptables -nvL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
20 1580 ACCEPT tcp -- * * 192.168.72.0/24 0.0.0.0/0 tcp dpt:22
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:21
运行脚本后,查看规则就是这样的,这里可以看到阿铭的第一条规则中已经有20个包(第一列)被放行过了。
关于icmp的包有一个比较常见的应用,如下所示:
# iptables -I INPUT -p icmp --icmp-type 8 -j DROP
这里--icmp-type选项要跟-p icmp一起使用,后面指定类型编号。这个8指的是能在本机ping通其他机器,而其他机器不能ping通本机,请牢记。
4. nat表的应用
其实,Linux的iptables功能是十分强大的。阿铭的一位老师曾经这样形容Linux的网络功能:只有想不到,没有做不到!也就是说,只要你能够想到的关于网络的应用,Linux都能帮你实现。你在日常生活中应该接触过路由器,它的功能就是分享上网。本来一根网线过来(其实只有一个公网IP),通过路由器后,路由器分配一个网段(私网IP),这样连接路由器的多台PC都能连接因特网,而远端的设备认为你的IP就是那个连接路由器的公网IP。这个路由器的功能其实就是由Linux的iptables实现的,而iptables又是通过nat表作用而实现的。
在这里,阿铭举一个例子来说明iptables是如何实现这个功能的。假设你的机器上有两块网卡eth0和eth1,其中eth0的IP为10.0.2.68,eth1的IP为192.168.1.1。eth0连接了因特网,但eth1没有连接。现在有另一台机器(192.168.1.2)和eth1是互通的,那么如何设置才能让连接eth1的这台机器连接因特网,和10.0.2.68互通呢?方法很简单,如下所示:
# echo "1" > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
这里,第一个命令涉及内核参数相关的配置文件,它的目的是打开路由转发功能,否则无法实现我们的应用。第二个命令则是iptables对nat表做了一个IP转发的操作。-o选项后面跟设备名,表示出口的网卡;MASQUERADE表示伪装。关于nat表,阿铭不想多讲,你只要学会这个路由转发功能即可,其他的东西交给网络工程师去学习吧,毕竟你将来是要做Linux系统工程师的。
5. 保存和备份iptables规则
前面阿铭提到过,咱们设定的防火墙规则只保存在内存中,并没有保存到某一个文件中。也就是说,当系统重启后以前设定的规则就没有了,所以设定好规则后要先保存一下。命令如下:
# service iptables save
iptables: Saving
firewall rules to /etc/sysconfig/iptables:[ ok ]
它会提示你防火墙规则保存在/etc/sysconfig/iptables文件内,这个文件就是iptables的配置文件。所以日后如果你遇到备份防火墙规则的任务,只要复制一份这个文件的副本即可。
有时我们需要清除防火墙的所有规则,使用命令iptables -F固然可以,但最好的办法还是停止防火墙服务,如下所示:
# service iptables stop
Redirecting to /bin/systemctl stop iptables.service
这样防火墙就失效了,但是一旦重新设定规则(哪怕只有一条),防火墙服务会自动开启。下面阿铭介绍一个用来备份防火墙规则的命令,如下所示:
xtables-save v1.8.2 on Fri Jun 26 15:27:41 2020
*security
:INPUT ACCEPT [809:137209]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [682:88704]
COMMIT
*raw
:PREROUTING ACCEPT [133:10536]
:OUTPUT ACCEPT [111:20700]
COMMIT
*mangle
:PREROUTING ACCEPT [133:10536]
:INPUT ACCEPT [133:10536]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [111:20700]
:POSTROUTING ACCEPT [111:20700]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*filter
:INPUT DROP [108:8568]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [111:20700]
-A INPUT -s 192.168.72.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
COMMIT
先执行一下刚才的iptables脚本,使用iptables-save命令重定向到一个文件里。若想要恢复这些规则,使用下面的命令即可:
# iptables-restore < myipt.rule