Linux的软件防火墙iptables
一、iptables基础
1.1、iptables简介和组成
iptables是Linux系统内嵌的一个防火墙软件(封包过滤防火墙),它集成在Linux系统的内核中,因此执行效率十分高效;iptables通过设置一些封包过滤规则,用来定义什么数据可以接收,什么数据需要剔除,因此,用户通过iptables可以对进出计算机的数据包进行IP过滤,以此来达到保护主机的目的。
iptables是由最基本的多个表格(tables)组成的,并且每个表格的用途都不一样,在每个表格中又定义了多个链(chain),通过这些链可以设置相应的规则和策略。
iptables的基础表 | 表包含的链 | 说明 |
filter表 | filter表主要是用于数据包的信息过滤 | |
INPUT链 | 主要是将外部数据包进入到Linux系统内部进行信息过滤【重点关注这个】 | |
OUTPUT链 | 将Linux服务器内部数据包发送到外部进行的信息过滤 | |
FORWARD链 | 将外部的数据包传递到内部计算机中 | |
NAT表 | NAT(Network Address Translation)表主要是用于网络地址转换 | |
PREROUTING链 | 是在数据包刚刚到达防火墙时,根据需要改变它的目的地址 (如:DNAT操作,就是通过一个合法的公网IP地址,通过对防火墙的访问,重定向到防火墙内的其它计算机(DMZ区域),也就是说通过防火墙改变了访问的目的地址,以使数据包能重定向到指定的主机) | |
POSTROUTING链 | 在数据包就要离开防火墙之前改变其源地址 (如SNAT操作,屏蔽了本地局域网主机的信息,本地主机通过防火墙连接到internet,这样在internet上看到的本地主机的来源地址都是同一个IP,屏蔽了来源主机地址信息) | |
OUTPUT链 | 改变了本地产生数据包的目的地址 | |
mangle表 | 改变不同数据包及数据包头内容 | |
PREROUTING链 | 在数据包刚刚到达防火墙时,根据需要改变它的目的地址 | |
POSTROUTING链 | 在数据包就要离开防火墙之前改变其源地址 | |
OUTPUT链 | 将外部的数据包传递到内部计算机中 | |
INPUT链 | 主要是将外部数据包进入到Linux系统内部进行信息过滤 | |
FORWARD链 | 将外部的数据包传递到内部计算机中 | |
自定义表 | 可以根据需要自定义规则策略 |
数据包从进入iptables到流出的完整流程是:外部流量先经PREROUTING链(可做DNAT),再经路由决策,目标为本机的流量走INPUT链(filter表过滤),转发流量走FORWARD链,最后经POSTROUTING链(可做SNAT)流出。
1.2、防火墙规则的执行流程
1.2.1、防火墙规则的执行流程
总体来说就是数据包会首先执行我们配置的规则,如果匹配到我们的规则就执行对应的规则动作,否则就继续向下查找规则匹配;若都不满足我们配置的规则,则会进入到最初的预设规则执行。详细的防火墙规则执行流程如下图所示:
1.2.2、查看与清除防火墙规则
序号 | 命令 | 说明 |
1 | iptables -L -n | 列出当前Linux系统【filter表】的所有链规则内容 |
2 | iptables -t nat -L -n | 列出【Nat表】的所有链规则内容 |
1 | iptables -F | 【清除iptables规则】清除防火墙的所有已定义的规则链 |
2 | iptables -X | 【删除自定义规则链】清除防火墙所有用户自定义的规则链 |
3 | iptables -Z | 【重置计数器】清除所有规则链的包和字节计数器归零 |
注意:上面三条指令可以清除防火墙的所有规则,但是不能清除预设的默认规则(policy) |
1.3、防火墙规则设置语法
序号 | 防火墙命令 | 说明 |
1 | -t | 用于指定表;常见的表有【filter表】、【NAT表】、【mangle表】、【自定义表】等,如果没有用“-t”指定表,则默认使用filter表。 |
2 | -P | 表示Policy(策略),可指定策略,其中针对【filter表】有INPUT链、OUTPUT链、FORWARD链这三个选项。 |
iptables设置语法: iptables [-t tables] [-AI 链] [-io 网络接口] [-p 协议] [-s 来源IP/网络] [-d 目标IP/网络] -j [ACCEPT|DROP|REJECT|REDIRECT] | ||
序号 | 选项 | 说明 |
1 | -A | (Add)新增加一条规则,放到已有规则的最后面 |
2 | -I | (Insert)插入一条规则,如果没有制定插入规则的顺序,则新插入的变成第一条规则 |
3 | -i | (in)指定数据包进入的网络接口。linux下常见的有eth0、eth1、lo等等。此参数一般与INPUT链配合使用 |
4 | -o | (out)指定数据包传出的网络接口。经常与OUTPUT链配合使用 |
5 | -p | (protocol)指定此规则适用的协议,常用的协议有tcp、udp、icmp以及all |
6 | -s | (source)指定来源IP或者网络,也就是限定数据包来源的IP或者网络,可以单独指定某个IP,也可以指定某段网络 |
7 | -d | 指定目标IP或者网络,跟参数“-s”类似 |
8 | -j | 此参数后面指定要执行的动作,主要的动作有接受(ACCEPT)、抛弃(DROP)及记录(LOG); 《1》ACCEPT 接受该数据包; 《2》DROP 直接丢弃该数据包,不给客户端任何回应; 《3》REJECT 拒绝接受数据包; |
9 | -m | 指定iptables使用的扩展模块,常用的有tcp模块等 |
10 | --sport | 限制来源的端口号,端口号可以是连续的,如 1024:65535 |
11 | --dport | 限制目标的端口号码,端口号可以是连续的,如 1024:65535 |
二、防火墙规则设置
2.1、针对IP/网络、网络接口与协议的过滤规则实操
这是主要是针对ip/网络、网络接口、tcp,udp协议的过滤规则(以filter表为主):
#查看当前iptables的所有规则内容(默认查看【filter表】的状态,如果需要查看其他表的状态加上 -t 表名)
iptables -nL#查看全局允许访问该Linux服务器的信息(访问白名单)
more /etc/hosts.allow#查看全局禁止访问该Linux服务器的信息(访问黑名单)
more /etc/hosts.deny#示例1:只允许让192.168.1.2主机访问Linux服务器的22端口,其他所有主机都无法访问
iptables -A INPUT -s 192.168.1.2 -p tcp -m tcp --dport 22 -j ACCEPT#预设 filter表 的INPUT链丢弃所有主机发来的数据包(即:拒绝所有访问)
iptables -P INPUT DROP#示例2:只允许让192.168.1.2主机访问Linux服务器的111端口,其他所有主机都无法访问
iptables -A INPUT -s 192.168.1.2 -p tcp -m tcp --dport 111 -j ACCEPT#示例3:允许任意主机都可以访问Linux服务器的80端口(端口开放需要指明具体的协议,如:这里指定tcp协议)
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT#示例4:只允许192.168.1.2主机访问Linux服务器的任意资源【即:服务器完全信任192.168.1.2主机】,其他主机无法访问
iptables -A INPUT -s 192.168.1.2 -j ACCEPT#示例5:将来自网络接口lo【回环地址】的数据包,全部接受
iptables -A INPUT -i lo -j ACCEPT#示例6:允许任意主机都可以ping该Linux服务器进行ping通(针对协议进行开放)
iptables -A INPUT -i ens33 -p icmp -j ACCEPT#查看当前Linux服务器上运行的所有tcp接口内容
netstat -atnlp#查看规则链内容(默认查看【filter表】查看其他表的状态加上 -t 表名,这里可以列出序号,在插入或者删除的时候就不用自己去数编号)
iptables -nL --line-numbers#示例1:允许局域网内192.168.1.0/24的所有主机访问我们这个服务器,除了192.168.1.66这台主机
iptables -A INPUT -i ens33 -s 192.168.1.66 -j DROP
iptables -A INPUT -i ens33 -s 192.168.1.0/24 -j ACCEPT#示例2:允许任意主机访问都可以访问Linux服务器的443端口且将该链插入到第4行(在 INPUT 后不指明在第几行插入,那默认就是在第一条插入)(端口开放需要指明具体的协议,如:这里指定tcp协议)
iptables -I INPUT 4 -p tcp -m tcp --dport 443 -j ACCEPT#示例3:允许来自192.168.3.0/28的1024:65535端口范围的主机可以通过22端口连接linux服务器(端口开放需要指明具体的协议,如:这里指定tcp协议)
iptables -A INPUT -i ens33 -s 192.168.3.0/28 -p tcp -m tcp --sport 1024:65535 --dport 22 -j ACCEPT
在线网络计算器 | TCP/IP子网掩码计算换算 —在线工具https://www.sojson.com/convert/subnetmask.html
2.2、针对数据状态模块的过滤规则
数据状态模块机制是iptables中特殊的一部分(严格来说不应该叫状态机制),因为它只是一种连接跟踪机制。连接跟踪可以让【filter表】知道某个特定连接的状态。
数据状态模块的过滤规则语法: iptables -A INPUT -m state/mac --state NEW/ESTABLISHED/RELATED/INVALID | ||
序号 | 参数 | 说明 |
1 | -m | iptables的几个模块选项,常见的有: 《1》state:状态模块; 《2》mac:网卡硬件地址(hardware address); |
2 | --state | 一些数据封包的状态,主要有: 《1》NEW:某个连接的第一个包; 《2》ESTABLISHED:表示该封包属于某个已经建立的链接; 《3》RELATED:当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了; 《4》INVALID:表示数据包不能被识别属于哪个连接或没有任何状态; |
#针对数据包状态过滤示例(只要是已建立的连接或者相关数据包就予以通过,不能识别或者没有任何状态的数据包全部丢弃)
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
2.3、制定防火墙规则
业务场景:我们现在的内网环境中有一台服务器(如:172.16.213.78)没有外网的IP地址没法上网,想要实现给这台内网服务器实现上网功能。我们现在拥有可上外网的服务器(172.16.213.51,这台服务器对应的外网ip是172.84.4.131)如下图所示:
#1-查看该内网服务器(172.16.213.78)的路由情况和ping百度确定是没网的
route -n
ping www.baidu.com#2-在可上网的服务器(172.16.213.51)上配置一条NAT路由转发到外网(外网地址是:172.84.4.131)
iptables -t nat -A POSTROUTING -s 172.16.213.78/32 -j SNAT --to-source 172.84.4.131#3-在该内网服务器(172.16.213.78)上配置一条指向可上网服务器(172.16.213.51)的路由
route add default gw 172.16.213.51#4-还需检查该内网服务器(172.16.213.78)的DNS是否配置(没有的话需要手动编辑【/etc/resolv.conf】文件配置上)
more /etc/resolv.conf
三、iptables常用命令清单
序号 | 命令分类 | 命令 | 说明 |
1 | 查看当前 iptables 状态 | iptables -nL | 这里没有使用【-t 表名】指定其他表名称,就默认查看的是【filter表】的所有链规则内容 |
iptables -nL --line-numbers | 默认查看【filter表】的所有链规则内容,且可以显示序号,方便插入或删除的时候数编号了 | ||
iptables -nL --line-numbers --verbose | 默认查看【filter表】的所有链规则内容,除了可以显示编号还可以查看到数据包过滤的流量统计,访问次数等信息 | ||
2 | 插入一条规则 | iptables -I INPUT -i lo -j ACCEPT | 这里没有在INPUT后面指定需插入的行号,表示默认在第一行插入规则 (接受所有来自lo回环地址的访问) |
iptables -I INPUT 3 -s 192.168.3.0/24 -j ACCPET | 表示在第3行插入规则 (接受192.168.3网段的主机到该Linux的所有数据包,全部接受) | ||
3 | 追加一条规则 | iptables -A INPUT -i ens33 -s 192.168.1.0/24 -j ACCEPT | 在【filter表】的INPUT链最后追加一条规则 (允许192.168.1网段的所有主机访问该Linux的ens33网口,且这些主机的数据包,全部接受) |
4 | 删除一条记录 | iptables -D INPUT 8 | 删除【filter表】INPUT链中的第8条数据 |
5 | 针对协议开放 | iptables -I INPUT -p icmp -j ACCEPT | 允许任意主机都可以ping通该Linux服务器 |
6 | 针对端口开放 (必须指定协议) | iptables -A INPUT -p tcp --dport 22 -j ACCEPT | 允许任意主机都可以通过22端口远程访问该Linux服务器 |
7 | 限制ip端口访问 | iptables -A INPUT -s 192.168.3.0/24 -p tcp --dport 22 -j ACCPET | 允许192.168.3网段的所有主机都可以通过22端口访问该Linux服务器 |
8 | 拒绝所有访问 | iptables -P INPUT -j DROP | 设置【filter表】的INPUT链预设拒绝所有访问 |
9 | 根据时段 限制访问 | iptables -A INPUT -p tcp -m time --timestart 16:00 --timestop 22:00 -j DROP | 设置所有的tcp协议数据包在北京时间凌晨0点到凌晨6点传递到该Linux服务器时全部拒绝 注意:这里的时间是指 UTC 时间,需要进行转换(UTC时间比北京时间慢8个小时) 时间转换工具 | GPS/UTC/北京时间转换器 |
10 | 限制单个 IP 一分钟内建立 的连接数 | iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 25 -j REJECT | 限制单个IP对该Linux服务器的80端口发起过多的连接请求,单个IP连接数超过25个就拒绝连接 |
11 | 保存iptables 规则 | iptables-save > /etc/sysconfig/iptables | 将现有的iptables规则保存到指定文件中 |
12 | 从文件恢复 iptables 规则 | iptables-restore < /etc/sysconfig/iptables | 从/etc/sysconfig/iptables文件恢复iptables的规则 |
13 | 对外建立的连接经过 INPUT 不拦截 | iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
| 只要是已建立的连接或者相关数据包就予以通过,不能识别或者没有任何状态的数据包全部丢弃 |