unix功能:iptables And ipfw
ipfw介绍
功能
根据文档可知, iptables实际上就是一个ip包过滤管理器
, 结合之前做过的防火墙经验(modsecurity), 实际上就是一个本地防火墙, 认真研究iptables命令文档, 你会发现它的实际逻辑和防火墙是真的非常像.
- 通过定义一系列的规则链条来进行数据的防护, 每一种类型的链条处理不同的数据
- input(入包), forword(通过包), output(本地生成包), 类似waf上请求响应的规则处理
- 在完成基本包过滤基础上增加一个额外的包修改, 包转发等功能
iptables本身仅仅是一个客户端代理, 一个命令行工具, 只有将一些安全设置指定到对应的安全框架
中, 此时其和安全框架
共同组成了防火墙, 这个安全框架叫netfilter
. netfilter算是主机防火墙
或者软件防火墙
, 而waf等是网络防火墙
或硬件防火墙
, 前者主要实现下面三个功能:
- 网络地址转发
- 数据包内容修改
- 数据包过滤
iptables通过链概念
, 表分类
, 规则
等概念, 并结合前两者实现了数据的处理, 这些概念会在后面提及, 这里先简单的介绍下表, 链, 规则的关系:
- 每一个表包含内部链, 也可以包含用户自定义链
- 每一个链是一个规则列表, 对相应包进行pattern(模式匹配)和action
- 每条规则定义了如何处理相匹配的包, 这被称为target(action)
- 每一条链可以被多个表关联.
让我们将功能和上面术语结合在一起:
- 涉及包内容过滤时: 使用INPUT/OUTPUT 链来进行ACCEPT, REJEST, DROP.
- 涉及包转发时: 使用PREROUTING, FORWARD, POSTROUTING链来进行包转发
注意, 并非所有的链组合成一个串行结构, 可能是条件结构, 并行结构等, 例如:
- 进入本机报文经过链: PREROUTING->INPUT
- 经由本机转发报文: PREROUTING -> FORWARD -> POSTROUTING
- 本机发出的报文: OUTPUT -> POSTROUTING
命令
iptables命令格式如下:
1 | iptables -[ACD] chain rule-specification [options], [A-append D-删除 C-check] |
整体命令格式可以总结如下: iptables [CMD] rulenum [options]
, 其中CMD
就是上面所述, 其本身也归属于options, 下面简单的介绍一下options.
options
- commands: 这些选项指定执行明确的动作, 一般而言, 只能指定一个选项
- paramater: 使用参数指定一个特定的规则, 常常用于add, delete, replace, append, check等命令中.
- other: 其他特殊选项信息
这里简单的介绍下参数选项信息:
1 | -p [!] protocol 指定规则或包检查准备处理的协议类型, 可以是协议号或者协议名, !表示相反规则, 0 表示所有 |
其他选项信息:
1 | -v 详细输出 |
安装配置
- 重启, 停止, 打开防火墙:
/etc/init.d/iptables start/stop/restart
- 永久性关闭/打开防火墙
1 | # 关闭 |
- centos下iptables操作
1 | # 1. 启动和关闭 |
开启端口: vim /etc/sysconfig/iptables
, 之后增加端口到相应文件中
链和表
链
链包含内部定义链和用户自定义链, 每个链都是一系列的规则, 不同的链在不同的关卡中进行着不同的包过滤
检查机制, 内部定义链:
- prerouting (经由路由, 公网进入当前内网时)
- input
- output
- forward
- postrouting (经由路由, 内网通往外网时)
自定义链条不能单独使用, 其需要被某个默认的链条当做target调用之后才能作为默认链的某一个补充来进行包处理.
表
将具有相同功能的规则聚集在一起, 形成table
, 这是一个逻辑概念, 从而高效的进行表的管理, 实际进行包过滤的时候还是基于链来完成, 当然链中的每一条规则则归属于不同的table. 目前有四种功能的表:
- filter表: 负责包过滤, 实现防护墙机制
- nat表: 网络地址转发
- mangle表: 包修改和重新封装
- raw表: 关闭nat表上启用的连接追踪机制
其中过滤功能有:
- 哪些 IP 可访问
- 哪些 IP 不能访问
- 允许哪些端口
- 禁止访问特定端口
一般而言, 用户自定义链中的规则在特定的table
中
- prerouting: raw, mangle, nat表, 路由上也一般不做包过滤, 仅做包转发
- input: mangle, filter, nat表
- output: mangle, filter, nat, raw表
- forward: mangle, filter表
- postrouting: mangle, nat表
另外, 默认情况下, 每一个链中的不同表规则存在优先级问题, 一般来说: raw > mangle > nat > filter
. 默认情况下, 查询规则时都是基于表去查找当前拥有的链路和规则信息的, 即上面信息的相反对应关系.
数据流
数据经过防火墙的数据流图如下:
1 |
|
另外, 如果在 LINUX 上想要主机支持转发功能, 需要内核开启IP_FORWARD 功能.
规则结构
类似modsecurity
防护策略一样, 链表内的规则也是由pattern
和action
组成.
- 匹配条件: 分为基本匹配条件和扩展匹配条件
- 基本匹配条件: 源地址Source IP, 目标地址Destination IP
- 扩展匹配条件: 例如源端口, 目的端口等
- 处理动作: 在iptables中称为target, 动作称为基本动作和扩展动作
- ACCEPT: 允许数据包通过
- DROP: 丢包
- REJECT: 拒绝
- SNAT: 源地址转换, 解决内网用户用同一个公网地址上网的问题
- MASQUERADE: SNAT的一种特殊形式, 用于动态,临时 IP 上
- DNAT: 目标地址转换
- REDIRECT: 本地端口映射
- LOG: 记录日志并传递给下一条规则
3. 命令
查询命令
1 | # 指定表信息, 获取表中所有链路 |
输出项
当命令中包含-v
时会输出详细的规则信息:
- pkts: 该规则匹配到的包数量
- bytes: 该规则匹配到的报文总大小
- target: 规则对应的动作
- prot: 规则对应的协议
- opt: 规则对应的选项
- in: 数据包由哪个网卡流入
- out: 数据包由哪个网卡流
- source: 规则对应的源地址, 例如 IP, 网段, 默认显示anywhere, 名称解析
- destination: 规则对应的目的地址, 例如 IP, 网段, 默认为anywhere
处理这些输出信息之外, 在头部还有一些计数信息, 表示策略, 所有包统计信息
- policy ACCEPT: 当前链的默认策略, 这里表示通过
- packets: 当前链默认策略匹配到的包的数量
- bytes: 当前链默认策略匹配到的所有包的大小总和
工作场景 1: 禁止某个IP地址访问我们的主机
配置: 需要在 INPUT 链上定义规则, 根据 2.3 的数据流可以知道进入本机的数据
包流量会经过 PREROUTING和INPUT 链处理, 但是PREROUTING链不存在filter表中的
规则, 即天生不支持过滤, 所以只能在 INPUT 中定义.
规则操作
- 增加规则命令, 具体例子可见4.1节中的ping命令规则添加
1 | # 1. 链首插入一条 ACCEPT 命令 |
- 删除规则命令, 指定序号或者根据匹配条件/动作进行删除
1 | # 1. 根据序号删除 |
- 更改规则
1 | # 1. 根据序号进行更改(规则原本的匹配条件也必须填写) |
- 保存规则, 默认情况下上面的命令在重启iptables或者重启服务器之后都会重置
1 | # 1. centos6保存iptables规则, 默认保存到/etc/sysconfig/iptables |
匹配条件
上面规则命令中都涉及到包的匹配逻辑, 那么匹配条件都有哪些呢? 除了源地址还有哪些匹配条件?
- 指定源地址(单个或者多个)
1 | # 1. 单 IP |
- 目标地址(适用于多网卡, 多 IP 情况)
1 | # 1. 指定入口网卡 IP |
- 协议类型
1 | # 1. tcp所有端口(该操作会将所有连接关闭) |
- 网卡接口
1 | # 1. 指定网卡而非 IP, -i 仅仅判断包流入, 仅仅用于INPUT, FORWARD, PREROUTING |
- 指定源端口和目的端口(扩展匹配条件)
1 | # 1. 使用扩展匹配条件需要指定扩展模块名称, -m指定扩展模块名称 |
扩展模块
除了上面讲解的基本扩展模块
用于扩展匹配条件
, 还有很多其他扩展模块极大的丰富了iptables的功能.
- iprange: 一段连续的ip地址范围, 用于匹配源地址, 目标地址
1 | # 1. 源匹配条件(--src-range) |
- string: 指定匹配的字符串, 用于报文全文匹配, 需要指定匹配算法
1 | # 1. 对 HTTP 请求内容的过滤 |
- time: 根据时间段匹配报文, 报文如果在该时间段内达到或者发出, 则设置规则
1 | # 1. 例如, 约束指定时间不能浏览网页 |
- connlimit: 限制每一个 IP地址同时连接到server端的数量, 默认所有客户端 IP, 单 IP 连接限制
1 | # 1. 限制ssh连接 |
- limit: 类似connlimit, 对报文到达速率进行限制, 限制单位时间内流入包数量
1 | # 1. 每分钟限制数量为10(限制ping), 通过两条规则达到条件 |
配置和实例
阻止ping
有如下两台机器:
1 | # 1. 其中, 通过mac ping Ubuntu |
现在, 如果希望仅仅mac所在 IP 访问当前机器, 可以在ubuntu上设置如下信息:
1 | # 1. 增加规则(指定规则类型-表, 指定链-INPUT) |
输出如下:
1 | Chain INPUT (policy ACCEPT 92 packets, 6584 bytes) |
链顺序
在 4.1 中我们增加了一个DROP
动作的规则, 那么如果我们在该规则的后面再添加一条ACCEPT
的规则, 那么是否可以ping
通目标主机呢?
1 | # 1. 默认情况下表类型都是filter, -A表示append |
输出如下:
1 | Chain INPUT (policy ACCEPT 62 packets, 4483 bytes) |
让我们再次增加一条新规则, 现在将规则插入到链首部
1 | # 1. -I 表示insert |
输出如下:
1 | Chain INPUT (policy ACCEPT 102 packets, 6504 bytes) |
所以规则的顺序非常重要, 可以使用--line-number
查看链上各个规则的顺序, 如果希望新增加的
规则在中间插入, 只需要指定序号即可:
1 | # 1. 新增加一个规则, 指定序号为 1(类似 -I INPUT) |
白名单机制
默认情况下, 所有链的策略都是ACCEPT
, 新增加的链规则都是 DROP, REJECT, 这就是黑名单机制,这导致上面的频率限制等会出现问题, 未匹配的规则实际上默认还是走了 ACCEPT, 所以上面所有命令的!
操作都有点怪.
我们可以设置白名单
方式, 将所有链的默认规则设置为DROP
, 在一个个增加相应规则, 确保所有流量都在自己的控制范围之内, 但是如果直接将所有链规则设置为DROP
, 有时候可能导致一个问题, 当不小心清除所有链规则时, 好了, 管理员自己无法连接远程服务器了, 所以最好的白名单方式:
- 最好在每一个链的末尾增加一个REJECT 规则即可
业务场景
1 | # 1. 限制指定的IP可以访问, ip段,此时其他IP无法访问 |
查看当前防火墙允许接受的所有协议(或者端口号)
1 | # 命令 |
临时打开指定的端口: iptables -A INPUT -p tcp --dport 21 -j ACCEPT