Linux防火墙

整理Linux下网络数据包流向及防火墙相关功能和操作

路由表

路由表规定了网络数据包的流向,使用命令route查看路由表,结果如下

route.png

Destination 目标地址(主机地址或网络地址)
Gateway 目标网关
Genmask 地址掩码
Iface 使用的网卡接口

路由表项根据地址类型可以分为:主机地址(具体IP地址)、网络地址(某个网段)、默认地址(0.0.0.0)
当需要路由数据包时,按照从小到大的顺序匹配路由表:首先匹配具体主机地址,没有匹配项再匹配网络地址,都没有的话使用默认路由
使用route命令可以对路由表进行设置(添加、删除等)

数据包流向

当数据包到达主机时,按照以下流向传递:

  1. 防火墙:默认防火墙有两个独立的机制,NetFilterTCPWrappers
  2. 服务设置:通过防火墙后进入服务进程,通常服务进场会控制其权限(例如httpd服务可以通过配置httpd.conf文件来控制某些ip的权限)
  3. 在第二步的基础上,SELinux可以对网络服务设置一些规则,限制服务的权限(例如将httpd服务的权限设置局限在一定范围内,防止当服务出现漏洞时威胁主机安全)
  4. 文件权限:最终,网络服务需要获取某些资源(文件)时,还是需要具有相应文件的权限,否则也是无法访问的

防火墙

防火墙也有硬件防火墙和软件防火墙之分;硬件防火墙就是一些处理包过滤的硬件设备,其搭建在网络节点上作为专门的过滤设备来使用,往往是去除了一些其他不必要功能的专门化硬件;软件防火墙则是一些可以过滤数据包的应用程序,本篇还是关注软件防火墙
Linux默认的防火墙机制包括NetFilterTCPWrappers;这是两个独立的机制,其中,NetFilter是数据包过滤式的,TCPWrappers是服务管理式的;通过这两个机制,Linux可以过滤掉绝大部分的恶意数据包,以及其他一些不希望收到的数据包(某些多进程服务在多主机环境下组网时可能需要过滤一些特定的数据包)

Netfilter

数据包到达主机后,首先要经过第一道门Netfilter
这是一个数据包过滤机制,它将数据包的头部数据提取出来进行分析,来决定对这个包索要采取的行为;这是Linux上的内建机制,同时提供了iptables这个软件来管理数据包过滤规则

虽然刚刚说Linux的防火墙机制包括NetFilterTCPWrappers,但实际上TCPWrappers平常只用来管理特定服务的访问源,并不作为防火墙使用;所以,平常说防火墙主要还是指NetFilter这个机制
在2.4以上的内核版本,使用iptabls来作为防火墙软件,iptabls指定了一些规则,当一个规则到达主机时,首先按照顺序匹配一个个规则,如果有相匹配的则执行相应动作,对这个数据包的处理也就完成了;可见,规则的顺序是很重要的,当匹配到某条规则后,就不会再继续匹配别的规则了

为了方便管理这些规则,iptabls提供了两个概念:表和链;表用于管理不同的功能项;表里分为不同的链,用来管理处理路径上的规则
默认情况下,iptabls至少拥有3个表,每个表的功能用途和包含的链如下:

  • Filter:主要用于进出本机的数据包
    1. INPUT链:进入路径
    2. OUTPUT链:送出路径
    3. FORWARD链:转发路径
  • NAT:主要用于ip和port的转换,跟本机关系不大,多是用于管理主机后的局域网
    1. PREROUTING:在进行路由判断之前的路径
    2. POSTROUTING:在进行路由判断之后的路径
    3. OUTPUT:送出路径
  • Mangle:主要是与特殊的数据包路由有关系
    1. INPUT链:进入路径
    2. OUTPUT链:送出路径
    3. FORWARD链:转发路径
    4. PREROUTING:在进行路由判断之前的路径

当有数据包需要处理时,会按照预定的顺序流转,经过各表中的链,在链中去匹配规则;内建各个表和链的关系(流转地图)如下

iptables-route.png

Mangle表很少使用,而NAT用于路由,对于单机来说通常只使用Filter就够了;本篇也只以Filter表来举例说明相关用法,不同的表原理也是一样

查看规则

iptables [-t table] -L [-n][-v]
选项:
-t 后面接表名,例如filter等,没有指定的话,默认指定filter
-L 列出当前规则
-n 不进行ip和host的反查
-v 列出更多信息

举例:
查看nat表当前的规则:iptables -t nat -L

输出(包括以下几个字段):
target         要执行的操作
prot           数据包协议
opt            额外选项
source         来源ip
destination    目标ip
复制代码

另外也可以通过iptables-save命令显示当前所有的规则,同时可以将其重定向到文件中,导出文件可以用iptables-restore命令导入

iptables-save [-t table]
选项:
-t 可以仅显示指定的表

举例:
将当前使用规则导出到文件:iptables-save > iptables.rule
复制代码

定义默认策略
当一个数据没有匹配到任何一条规则时(或者可能装机的时候没有启用防火墙则不定义任何规则),会采取默认策略动作(查看规则时,链名后的policy)

iptables [-t table] -P 链名 动作
选项:
-t 后面接表名,例如filter等,没有指定的话,默认指定filter
-P 指定默认策略
链名 包括INPUT,OUTPUT等
动作 接受ACCEPT 拒绝DROP

举例:
指定filter表的默认INPUT链策略为接受:iptables -P INPUT ACCEPT
复制代码

添加规则
添加规则,基本模式就是指定在什么情况下使用什么动作

iptables [-t table] [相关选项] [-j 动作]
选项:
-t 后面接表名,例如filter等,没有指定的话,默认指定filter
-j 当匹配到时采用的动作,包括 接受ACCEPT 丢弃DROP 拒绝REJECT 记录LOG

-A 在指定链最后加一条规则
-I 在指定链最首加一条规则

-i 进入的网络接口名(如eth0等)
-o 送出的网络接口名

-p 使用的协议,包括 tcp udp icmp all
-s 来源,可以是具体ip或者某个网段(子网掩码表示)
-d 同上,表示目标
可以使用 [!] 来取反

--sport 来源端口,可以指定范围使用 [:] 隔开收尾
--dport 同上,表示目标
使用这两个选项时,要同时指定协议才行(-p tcp 或者 -p udp)

-m 外挂模块,例如 状态模块state 硬件模块mac
--state 数据包状态,包括 无效INVALID 已建立连接ESTABLISHED 新建立连接NEW 与发送出去数据包相关RELATED
--mac-source 源mac地址
配合使用

--icmp-type icmp数据包类型
需要指定 [-p icmp]

举例:
所有从网卡lo进来的数据包都接受:iptables -A INPUT -i lo -j ACCEPT
所有来自192.168.17.178的数据包都接受:iptables -A INPUT -s 192.168.17.178 -j ACCEPT
所有发到5000到6000端口的数据包都记录:iptables -A OUTPUT -p tcp --dport 5000:6000 -j LOG
丢弃所有无效状态的数据包:iptables -A INPUT -m state --state INVALID -j DROP
接受来源为指定mac地址的包:iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -j ACCEPT
丢弃icmp类型为8的数据包:iptables -A INPUT -p icmp --icmp-type 8 -j DROP
复制代码

删除规则
上面说过,规则的顺序是很重要的,因为匹配到一条规则之后,这条链里的其他规则就不再判断了(要么丢弃了,要么进入后面的链),所以,当不清楚当前的规则或是当前规则太多时,先删除规则再重新定义可能会比较好

iptables [-t table] [-FXZ]
选项:
-t 后面接表名,例如filter等,没有指定的话,默认指定filter
-F 清除所有已制定规则
-X 清除所有自定义链规则
-Z 重置所有链的计数和流量统计

举例:
清除NAT表的所有规则:iptables -t nat -F
复制代码

添加自定义链
当规则非常多时还可以利用自定义链来分别处理,方便管理

iptables [-t table] [-N 链名] [-j 链名]
选项:
-t 后面接表名,例如filter等,没有指定的话,默认指定filter
-N 创建自定义链
-j 指定链名而非动作时,将使用指定链的规则来处理

举例:
创建新链:iptables -N NEW_CHAIN
添加规则:iptables -I NEW_CHAIN -s 127.0.0.1 -j ACCEPT
引用新链:iptables -I INPUT -p tcp -j NEW_CHAIN
复制代码

TCPWrappers

通过第一道门后,紧接着就是第二道门TCPWrappers
这是一个服务管理机制,它主要对服务程序进行管理,决定哪个来源可以访问哪个服务;Linux也提供了两个配置文件/etc/hosts.allowetc/hosts.deny来实现对服务管理的控制
这个规则相对比较简单,但是,并非所有的服务都支持TCPWrappers,可以通过以下方式查看是否支持(因为需要支持动态库libwrap,如果没有查询到动态库那就是不支持啦):

$ ldd /usr/sbin/sshd | grep libwrap
    libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007eff072ec000)
复制代码

处理过程
首先匹配/etc/hosts.allow,若有匹配项则放行
其次匹配/etc/hosts.deny,若有匹配项则丢弃
若都没有匹配项,则默认放行

匹配规则
两个规则文件格式都是一样的:服务列表:主机列表:选项
其中,服务列表是要指定的服务名字,使用逗号分隔;主机列表是允许的请求来源,可以是具体的主机地址,也可以是带掩码的某个网段,还可以是域名,同样使用逗号分隔;选项是可以额外执行的操作

常用宏
ALL 所有主机
LOCAL 本地主机
KNOWN 所有在DNS中可以解析到的主机
UNKNOWN 所有在DNS不可以解析到的主机
PARANOID 所有在DNS中正向解析与反向解析不匹配的主机
EXCEPT 除了(用于在主机列表中排除一部分)

常用选项
allow 用于在/etc/hosts.deny配置中允许某些主机访问
deny 用于在/etc/hosts.allow配置中拒绝某些主机访问
spawn 用于使用一些额外的命令(通常是写一些日志)

举几个例子:
sshd:ALL EXCEPT 192.168.17.0/24 在deny配置中配置这一条规则,指定除了192.168.17.0/24以外,所有的主机都不能访问ssh服务
sshd:192.168.17.178:deny 在allow配置中配置这一条规则,指定192.168.17.178的主机不能访问ssh服务
sshd:192.168.17.178:spawn echo 'xxx' >> /var/log/example.log 在allow配置中配置这一条规则,当有来自192.168.17.178主机对ssh服务的访问时,写出一条日志

以上就是本篇全部内容

参考资料、博文:
《鸟哥的Linux私房菜——服务器架设篇》
Linux ❀ TcpWrappers-Mariadb-linux访问控制顺序_香蕉味儿的安慕希酸奶°-CSDN博客
Linux tcp_wrappers 详解 - Dus - 博客园 (cnblogs.com)
Linux 防火墙之TCP Wrappers - ArongH - 博客园 (cnblogs.com)
linux 路由表详解 - 远洪 - 博客园 (cnblogs.com)
iptables详解(10):iptables自定义链 - wanstack - 博客园 (cnblogs.com)