安装防火墙并正确设置是网络安全的重要组成部分,CentOS附带了一个已经内置的功能强大的iptables,特别是CentOS 7,默认情况下附带有firewalld——动态防火墙守护程序(我们将在本教程的稍后部分将其禁用)。首先,让我们探讨iptables如何实际管理网络流量。
表,链和规则
iptables使用IP地址、协议(tcp,udp,icmp)和端口的概念,这意味着我们可以为这三者的特定组合设置单独的规则。这些规则中的每一个都包含潜在的匹配项和相应的动作(目标),如果数据包与规则匹配,则执行该动作。
iptables中有5个表:raw,filter,nat,mangle和security。通常,我们只需要使用过filter表,这是防火墙大部分工作的地方。Nat表用于端口转发,其他三个表通常用于涉及多个路由器的复杂配置。
这些表由链(chains)组成,链是按顺序排列的规则列表。默认filter表包含三个内置链:
- INPUT –所有发往主机的数据包
- OUTPUT –来自主机的所有数据包
- FORWARD –所有既不是发往主机的数据包,也不是发自主机的数据包,而是通过它的。如果将机器用作路由器,通常会使用此链。
默认情况下,所有链都不包含任何规则,因此由我们来设置它们。但是,链确实具有默认策略,该策略通常设置为ACCEPT,因此允许所有传入和传出连接。可以将此默认策略更改为DROP,并且它始终适用于链的末尾,这意味着在应用该默认策略之前,数据包必须通过链中的所有现有规则(并且不匹配任何规则)。
默认策略的概念提出了两种在决定如何设置防火墙规则之前要考虑的可能性。
- 我们可以将默认策略设置为ACCEPT,然后添加规则以专门阻止或丢弃来自特定IP地址或特定端口的所有数据包。
- 或者,我们可以设置默认策略为DROP所有数据包,然后为来自受信任IP或特定端口的特定ACCEPT数据包添加规则。
通常,我们将前者用于我们的OUTPUT链(出站流量),在这里我们信任离开我们机器的流量,而后者则用于我们的INPUT链,以便我们控制谁或什么人被允许访问它。
实际的数据包过滤基于规则,该规则由一个或多个match指定,即,数据包必须满足的条件才能应用该规则,以及一个目标——如果数据包与所有条件都匹配,则应采取的措施。
在这里,我们还需要提及其他几件事。iptables会将任何网络接口上出现的每个数据包都视为相同,因此由我们来定义规则以区别对待接口是我们的责任。通常,iptables仅适用于IPv4流量——对于IPv6,有一个单独的名为ip6tables的用户实用程序,其语法与iptables相同,但是其中某些选项特定于其中一个。
安装,启用和配置IPTABLE
管理iptables需要root级访问权限,因此最好直接以root用户身份登录或提升为root shell。
禁用firewalld
如果要在CentOS 7上使用iptables,我们需要做的第一件事就是禁用 firewalld 。我们可以使用以下命令来做到这一点:
[root@myvps ~]# systemctl stop firewalld [root@myvps ~]# systemctl mask firewalld
为了检测它是否被禁用,我们可以使用:
[root@myvps ~]# systemctl status firewalld firewalld.service Loaded: masked (/dev/null) Active: inactive (dead) Jul 29 13:57:47 myvps systemd[1]: Stopped firewalld - dynamic firewall daemon.
安装iptables
如果你的系统上未安装iptables,可以使用yum进行安装:
[root@myvps ~]# yum install iptables-services -y
在安装之后,我们将其设置为在启动时启动,并启动服务:
[root@myvps ~]# systemctl enable iptables [root@myvps ~]# systemctl start iptables
现在,要检查规则和默认策略,我们可以使用 iptables -L
:
[root@myvps ~]# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT icmp -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) target prot opt source destination
我们可以在这里看到我们所有三个链的默认策略都设置为ACCEPT,并且我们确实有一些规则,主要是针对INPUT链。
从这里开始,我们将介绍基本的iptables设置,但是强烈建议你熟悉iptables的所有各种选项。我们不会详细介绍各种选项的功能,但是下面的命令将为你提供一个很好的起点,然后你可以进一步调整以适应你的特定需求。
设置iptables
首先,我们将INPUT链的默认策略设置为ACCEPT,以致我们不会被锁定在服务器之外,因为我们将刷新(清除)默认规则集:
[root@myvps ~]# iptables -P INPUT ACCEPT
接下来,我们将使用以下规则刷新规则集:
[root@myvps ~]# iptables -F
本机接口允许所有连接
我们将为本地主机接口(-i lo)附加(-A)规则到INPUT链上,以允许所有连接(-j ACCEPT),因为许多应用程序通常需要正常运行:
[root@myvps ~]# iptables -A INPUT -i lo -j ACCEPT
然后,我们可以添加一条规则,该规则将加载conntrack模块(-m conntrack),该规则将检查数据包的状态并确定其是新的,已建立的还是相关的。NEW表示传入的数据包是主机系统未启动的新传入的连接。建立和相关是指进入的数据包,这些数据包是已经建立的连接的一部分,或者与已经建立的连接有关。
该规则将仅允许后者2:
[root@myvps ~]# iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
另外,我们可以使用状态模块:
[root@myvps ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
允许ssh,http和https端口上的所有流量
然后,我们将允许ssh,http和https端口上的所有流量:
[root@myvps ~]# iptables -A INPUT -p tcp --dport ssh -j ACCEPT [root@myvps ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT [root@myvps ~]# iptables -A INPUT -p tcp --dport 443 -j ACCEPT
参照上面这个写法,随意为你需要的任何其他端口添加任何其他规则。
现在我们有了基本规则,该规则将允许localhost接口上的所有流量以及ssh和http/s流量。我们可以将INPUT链的默认策略设置为DROP:
[root@myvps ~]# iptables -P INPUT DROP
禁止转发,允许所有出站流量
由于我们通常不希望服务器充当代理,因此我们将丢弃FORWARD链上的所有流量,并且由于我们相信其来源,因此将允许所有出站流量:
[root@myvps ~]# iptables -P FORWARD DROP [root@myvps ~]# iptables -P OUTPUT ACCEPT
为了安全起见,现在我们可以检查我们的新规则,并附带一些额外的详细信息:
[root@myvps ~]# iptables -L -v
保存规则,重启防火墙
最后要做的是保存这些规则,以便在每次重新启动时加载它们。我们可以通过以下两种方式实现:
[root@myvps ~]# /sbin/service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
要么:
[root@myvps ~]# service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
当然,我们应该在此时重启防火墙:
[root@myvps ~]# systemctl restart iptables.service
每次修改规则集时,都应执行以上两个步骤!
允许特定规则
至此,我们已经有了一个非常基本但可行的防火墙设置。由于我们现在将INPUT链上的默认策略设置为DROP,因此,如果我们要允许(或列入白名单)特定IP,则可以使用类似以下内容:
[root@myvps ~]# iptables -A INPUT -s 1.2.3.4 -j ACCEPT
当然,如果你的默认策略设置为ACCEPT,并且你想阻止IP,只需在该规则中将ACCEPT替换为DROP。
请记住,规则是按顺序处理的。如果你的规则集中某处有DROP规则,并且你想接受一些本应与DROP规则相匹配的连接,则必须在该规则之前添加它,这样,-A(附加)将不起作用。在这种情况下,我们可以使用-I(插入)选项,如下所示:
[root@myvps ~]# iptables -I INPUT 1 -i lo -j ACCEPT
如果我们之前未添加此特定规则,则必须插入它。注意-I
选项是如何需要两个参数的,第一个用于链(INPUT),另一个是插入规则的位置(在这个例子中,是第一条规则)。
结论
希望本文能够说明iptables提供的功能和灵活性。你可以混合并匹配所有各种标志,以根据需要进行设置。