Linux下的防火墙

嵌入式技术

1332人已加入

描述

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。当使用setenforce0这个命令后,再执行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 ACCEPT     tcp --  *      *      0.0.0.0/0           0.0.0.0/0            state NEW tcp dpt:22
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服务后还会加载已经保存的规则,所以需要使用serviceiptables 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

 

上例和-tfilter打印的信息是一样的。关于清除规则的命令中,阿铭用得最多就是下面两个:

 

# 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  #写入如下内容
#! /bin/bash
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选项要跟-picmp一起使用,后面指定类型编号。这个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

 

这样防火墙就失效了,但是一旦重新设定规则(哪怕只有一条),防火墙服务会自动开启。下面阿铭介绍一个用来备份防火墙规则的命令,如下所示:

 

# sh /usr/local/sbin/iptables.sh
# iptables-save > myipt.rule
# cat myipt.rule
# Generated by
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
# Completed on Fri Jun 26 1541 2020
# Generated by xtables-save v1.8.2 on Fri Jun 26 1541 2020
*raw
:PREROUTING ACCEPT [133:10536]
:OUTPUT ACCEPT [111:20700]
COMMIT
# Completed on Fri Jun 26 1541 2020
# Generated by xtables-save v1.8.2 on Fri Jun 26 1541 2020
*mangle
:PREROUTING ACCEPT [133:10536]
:INPUT ACCEPT [133:10536]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [111:20700]
:POSTROUTING ACCEPT [111:20700]
COMMIT
# Completed on Fri Jun 26 1541 2020
# Generated by xtables-save v1.8.2 on Fri Jun 26 1541 2020
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Fri Jun 26 1541 2020
# Generated by xtables-save v1.8.2 on Fri Jun 26 1541 2020
*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
# Completed on Fri Jun 26 1541 2020

 

先执行一下刚才的iptables脚本,使用iptables-save命令重定向到一个文件里。若想要恢复这些规则,使用下面的命令即可:

 

# iptables-restore < myipt.rule

 

 审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分