Firewall: 防火墙, 隔离工具; 工作于主机或网络的边缘, 对于进出本主机或网络的报文根据事先定义好的检查规则作匹配检测, 对于能够被规则所匹配到的报文做出相应处理的组件;
主机防火墙:
网络防火墙
- ipfw
- ipchains
- iptables/netfilter
- framework: netfilter
- hooks function
- rule utils: iptables
功能:(四表)
filter: 过滤, 防火墙;
nat: network address translation, 网络地址转换;
mangle: 拆解报文, 做出修改, 封装报文;
raw: 关闭 nat 表上启用的连接追踪机制;
链 (内置): (五链)
- PREROUTING
- INPUT
- FORWARD
- OUTPUT
- POSTROUTING
流入: PREROUTING --> INPUT
流出: OUTPUT --> POSTROUTING
转发: PREROUTING --> FORWARD --> POSTROUTING
各功能的分别实现:
- filter:INPUT, FORWARD, OUTPUT (iptables -t filter -L -n)
- nat: PREROUTING(DNAT), OUTPUT, POSTROUTING(SNAT) (iptables -t nat -L -n)
- mangle:PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING (iptables -t mangle -L -n)
- raw:PREROUTING, OUTPUT (iptables -t raw -L -n)
路由发生的时刻:
报文进入本机后:
判断目标主机;
报文发出之前:
判断经由哪个接口送往下一跳;
iptables: 四表五链
添加规则时的考量点:
(1) 要实现哪种功能: 判断添加在哪张表上;
(2) 报文流经的路径: 判断添加在哪个链上;
链: 链上规则的次序, 即为检查的次序; 因此隐含一定的法则
(1) 同类规则 (访问同一应用), 匹配范围小的放上面;
(2) 不同类规则 (访问不同应用), 匹配到报文频率较大的放上面;
(3) 将那些可由一条规则描述的多个规则合并为一个;
(4) 设置默认策略;
功能的优先级次序: raw --> mangle --> nat --> filter
规则:
组成部分: 报文的匹配条件, 匹配到之后处理动作
匹配条件: 根据协议报文特征指定
基本匹配条件
扩展匹配条件
处理动作:
内建处理机制
自定义处理机制
注意: 报文不会经过自定义链, 只能在内置链上通过规则进行引用后生效;
iptables: 规则管理工具
添加, 修改, 删除, 显示等;
规则和链有计数器:
pkts: 由规则或链所匹配到的报文的个数;
bytes: 由规则或链匹配到的所有报文大小之和;
iptables 命令:
- iptables [-t table] {-A|-D} chain rule-specification
- iptables [-t table] -I chain [rulenum] rule-specification
- iptables [-t table] -R chain rulenum rule-specification
- iptables [-t table] -D chain rulenum
- iptables [-t table] -S [chain [rulenum]]
- iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
- iptables [-t table] -N chain
- iptables [-t table] -X [chain]
- iptables [-t table] -P chain target
- iptables [-t table] -E old-chain-name new-chain-name
- -t table:
- filter, nat, mangle, raw
链管理:
-F:flush, 清空规则链; 省略链, 表示清空指定表上的所有的链;
-N:new, 创建新的自定义规则链;
-X:drop, 删除用户自定义的空的规则链;
-Z:zero, 清零, 置零规则计数器;
-P:Policy, 为指定链设置默认策略; 对 filter 表中的链而言, 默认策略通常有 ACCEPT, DROP, REJECT;
-E: rEname, 重命令自定义链; 引用计数不为 0 的自定义链, 无法改名, 也无法删除;
规则管理:
-A:append, 将新规则追加于指定链的尾部;
-I:insert, 将新规则插入至指定链的指定位置;
-D:delete, 删除指定链上的指定规则;
有两种指定方式:
(1) 指定匹配条件;
(2) 指定规则编号;
-R:replace, 替换指定链上的指定规则;
查看:
-L:list, 列出指定链上的所有规则;
-n: numberic, 以数字格式显示地址和端口号;
-v: verbose, 显示详细信息;
-vv, -vvv
--line-numbers: 显示规则编号;
-x: exactly, 显示计数器计数结果的精确值;
匹配条件:
基本匹配:
[!] -s, --src, --source IP|Netaddr: 检查报文中源 IP 地址是否符合此处指定的地址范围;
[!] -d, --dst, --destination IP|Netaddr: 检查报文中源 IP 地址是否符合此处指定的地址范围;
[!] -p, --protocol {tcp|udp|icmp}: 检查报文中的协议, 即 ip 首部中的 protocols 所标识的协议;
[!] -i, --in-interface IFACE: 数据报文的流入接口; 仅能用于 PREROUTING, INPUT 及 FORWARD 链上;
[!] -o, --out-interface IFACE: 数据报文的流出接口; 仅能用于 FORWARD, OUTPUT 及 POSTROUTING 链上;
扩展匹配:-m macth_name --spec_options
例如:-m tcp --dport 22
隐式扩展: 对 - p protocol 指明的协议进行的扩展, 可省略 - m 选项;
-p tcp
--dport PORT[-PORT]: 目标端口, 可以是单个端口或连续多个端口;
--sport PORT[-PORT]
--tcp-flags LIST1 LIST2: 检查 LIST1 所指明的所有标志位, 且这其中, LIST2 所表示出的所有标记位必须为 1, 而余下的必须为 0; 没有 LIST1 中指明的, 不作检查;
- SYN, ACK, FIN, RST, PSH, URG
- --tcp-flags SYN,ACK,FIN,RST SYN
- --syn:
- -p udp
- --dport
- --sport
- -p icmp
- --icmp-type
可用数字表示其类型:
- 0:echo-reply
- 8: echo-request
显式扩展: 必须使用 - m 选项指定使用的扩展;
目标:
-j TARGET:jump 至指定的 TARGET
ACCEPT: 接受
DROP: 丢弃
REJECT: 拒绝
RETURN: 返回调用链
REDIRECT: 端口重定向
LOG: 记录日志
MARK: 做防火墙标记
DNAT: 目标地址转换
SNAT: 源地址转换
MASQUERADE: 地址伪装
...
自定义链: 由自定义链上的规则进行匹配检查
四表: filter, nat, mangle, raw
五链: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
- -j TARGET:
- ACCEPT, DROP, REJECT, RETURN, LOG, MARK, DNAT, SNAT, MASQUEARDE, ...
匹配标准:
通用匹配:-s, -d, -p, -i, -o
扩展匹配
隐含扩展:
- -p tcp: --dport, --sport, --tcp-flags, --syn (--tcp-flags SYN,ACK,FIN,RST SYN)
- -p udp: --dport, --sport
- -p icmp: --icmp-type
显式扩展: -m
iptables:
显式扩展: 必须显式指明使用的扩展模块 (rpm -ql iptables | grep "\.so")
- CentOS 6: man iptables
- CentOS 7: man iptables-extensions
1,multiport 扩展
以离散方式定义多端口匹配; 最多指定 15 个端口;
[!] --source-ports,--sports port[,port|,port:port]...: 指明多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]...: 指明多个离散的目标端口;
- [!] --ports port[,port|,port:port]...
- ~]# iptables -I INPUT -s 172.16.0.0/16 -d 172.16.100.9 -p tcp -m multiport --dports 22,80 -j ACCEPT
- ~]# iptables -I OUTPUT -d 172.16.0.0/16 -s 172.16.100.9 -p tcp -m multiport --sports 22,80 -j ACCEPT
2,iprange 扩展
指明连续的 (但一般是不能扩展为整个网络)ip 地址范围时使用;
[!] --src-range from[-to]: 指明连续的源 IP 地址范围;
[!] --dst-range from[-to]: 指明连续的目标 IP 地址范围;
- ~~]# iptables -I INPUT -d 172.16.100.9 -p tcp -m multiport --dports 22:23,80 -m iprange --src-range 172.16.100.1-172.16.100.120 -j ACCEPT
- ~]# iptables -I OUTPUT -s 172.16.100.9 -p tcp -m multiport --sports 22:23,80 -m iprange --dst-range 172.16.100.1-172.16.100.120 -j ACCEPT
3,string 扩展
检查报文中出现的字符串;
- --algo {bm|kmp}
- bm = Boyer-Moore
- kmp = Knuth-Pratt-Morris
- [!] --string pattern
- ~]# iptables -I OUTPUT -m string --algo bm --string 'movie' -j REJECT
4,time 扩展
根据报文到达的时间与指定的时间范围进行匹配;
- --datestart
- --datestop
- --timestart
- --timestop
- --monthdays
- --weekdays
5,connlimit 扩展
根据每客户端 IP(也可以是地址块) 做并发连接数数量匹配;
--connlimit-above n: 连接的数量大于 n
--connlimit-upto n: 连接的数量小于等于 n
6,limit 扩展
基于收发报文的速率做检查;
令牌桶过滤器
- --limit rate[/second|/minute|/hour|/day]
- --limit-burst number
7,state 扩展
根据连接追踪机制检查连接的状态;
调整连接追踪功能所能够容纳的最大连接数量:
/proc/sys.NET/nf_conntrack_max
已经追踪到并记录下的连接:
/proc.NET/nf_conntrack
不同协议或连接类型追的时长:
/proc/sys.NET/netfilter/
可追踪的连接状态:
NEW: 新发出的请求; 连接追踪模板中不存此连接相关的信息条目, 因此, 将其识别为第一次发出的请求;
ESTABLISHED:NEW 状态之后, 连接追踪模板中为其建立的条目失效之前期间内所进行的通信的状态;
RELATED: 相关的连接; 如 ftp 协议的命令连接与数据连接之间的关系;
INVALIED: 无法识别的连接;
--state STATE1,STATE2,...
问题: 如何开放被动模式的 ftp 服务?
(1) 装载 ftp 追踪时的专用的模块:
# modprobe nf_conntrack_ftp
(2) 放行请求报文:
命令连接: NEW, ESTABLISHED
数据连接: RELATED, ESTABLISHED
- # iptables -A INPUT -d LocalIP -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
- # iptables -A INPUT -d LocalIP -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
(3) 放行响应报文:
- ESTABLISEHD
- # iptables -A OUTPUT -s LocalIP -p tcp -m state --state ESTABLISHED -j ACCEPT
如何保存及重载规则:
保存规则至指定文件:
iptables-save> /PATH/TO/SOMEFILE
从指定文件重载规则:
- iptables-restore </PATH/FROM/SOMEFILE
- CentOS 6:
- service iptables save
- iptables-save> /etc/sysconfig/iptables
- service iptables restart
- iptables-restore < /etc/sysconfig/iptables
- CentOS 7:
引入了新的 iptables 前端管理服务工具: firewalld
- firewalld-cmd
- firewalld-config
关于 firewalld:
http://www.ibm.com/developerworks/cn/linux/1507_caojh/index.html
核心转发:/proc/sys.NET/ipv4/ip_forward
- /etc/sysct.conf
- net.ipv4.ip_forward = 1
- iptables:
显式扩展, 网络防火墙
显式扩展: multiport, iprange, string, time, connlimit, limit, state
- state:
- /proc.NET/nf_conntrack
- /proc/sys.NET/nf_conntrack_max
- NEW, ESTABLISHED, RELATED, INVALID
- iptables:
nat:Network Address Translation, 安全性, 网络层 + 传输层
proxy: 代理, 应用层
nat:
SNAT: 只修改请求报文的源地址;
DNAT: 只修改请求报文的目标地址;
nat 表:
- PREROUTING:DNAT
- OUTPUT
- POSTROUTING:SNAT
源地址转换: iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE
目标地址转换: iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]
iptables 的链接跟踪表最大容量为 / proc/sys.NET/ipv4/ip_conntrack_max, 链接碰到各种状态的超时后就会从表中删除.
所以解決方法一般有两个:
(1) 加大 ip_conntrack_max 值
- vi /etc/sysctl.conf
- net.ipv4.ip_conntrack_max = 393216
- net.ipv4.netfilter.ip_conntrack_max = 393216
(2): 降低 ip_conntrack timeout 时间
- vi /etc/sysctl.conf
- net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
- net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
- net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
- net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120
- iptables -t nat -L -n
补充: 利用 iptables 的 recent 模块来抵御 DOS***: 22, 建立一个列表, 保存有所有访问过指定的服务的客户端 IP
SSH: 远程连接,
- iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
- iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
- iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach:"
- iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
1. 利用 connlimit 模块将单 IP 的并发设置为 3; 会误杀使用 NAT 上网的用户, 可以根据实际情况增大该值;
2. 利用 recent 和 state 模块限制单 IP 在 300s 内只能与本机建立 2 个新连接. 被限制五分钟后即可恢复访问.
下面对最后两句做一个说明:
1. 第二句是记录访问 tcp 22 端口的新连接, 记录名称为 SSH
--set 记录数据包的来源 IP, 如果 IP 已经存在将更新已经存在的条目
2. 第三句是指 SSH 记录中的 IP,300s 内发起超过 3 次连接则拒绝此 IP 的连接.
--update 是指每次建立连接都更新列表;
--seconds 必须与 --rcheck 或者 --update 同时使用
--hitcount 必须与 --rcheck 或者 --update 同时使用
3.iptables 的记录:/proc.NET/xt_recent/SSH
也可以使用下面的这句记录日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"
iptables 实现七层访问过滤:
模块: layer7
识别应用层协议
- iptables/netfilter
- iptables -m state,
- netfilter state
对内核中的 netfilter, 打补丁 layer7, 重新编译内核
对 iptables 打补丁, 补上 layer7 模块, 重新 iptables
来源: http://www.bubuko.com/infodetail-2898944.html