linux下iptables学习
iptables的结构
iptables由上而下,由tables、chains、rules组成
四表
iptables有filter、nat、mangle、raw四种内置表
Filter表
filter是iptables的默认表,有一下三种内建链:
INPUT链 - 处理来自外部的数据
OUTPUT链 - 处理向外发送的数据
FORWARD链 - 将数据转发到本机的其他网卡设备上
NAT表
nat表有三种内建链
PREROUTING链 - 处理刚达到本机并在路由转发前的数据包。它会转换数据包种的目标IP地址,通常用于DNAT
POSTROUTING链 - 处理即将离开本机的数据包。它会转换数据包种的源IP地址,通常用于SNAT。
OUTPUT链 - 处理本机产生的数据包。
Mangle表
mangle表用于指定如何处理数据包。它能改变TCP头中的QoS位。Mangle表具有5个内建链。
PREROUTINE
OUTPUT
FORWARD
INPUT
POSTROUTIN
Raw表
raw表用于处理异常,它具有2个内建链
PREROUTING
OUTPUT
Rules规则
Rules包括一个条件和一个目标
如果满足条件就执行目标中的规则或特定值
如果不满足条件,就判断下一条Rules
目标值
ACCEPT - 允许防火墙接受数据包
DROP - 防火墙丢弃包
QUEUE - 防火墙将数据包移交到用户空间
RETURN - 防火墙停止执行当前链中的后续Rules,并返回到调用链中。
命令
// 可以使用下面的命令查看每个表中的规则:
iptables -t [filter|nat|mangle|raw] --list
/* 输出内容包含:
target - 前面提到的target的特殊值
prot - 协议:tcp、udp、icmp等
source - 数据包的源IP地址
destination - 数据包的目标IP地址
*/
// 清空所有iptables规则
iptables --flush
或者
iptables -F
// iptables永久保存
service iptables save
// 查看当前持久化的规则
cat /etc/sysconfig/iptables
// 设置默认策略
iptables -P INPUT DROP
iptables -P OUTPUT DROP
// NAT端口转发
iptables -t nat -I PREROUTING -p tcp --dport 3389 -j DNAT --to 192.168.0.20:22
iptables -t nat -I POSTROUTING -p tcp --dport 3389 -j MASQUERADE
// 规则操作
iptables -t [table] -[A|D|R|I|L|N] [route] [args...]
其他
模块
-
multiport模块
使用:连续匹配多个端口
// 只开发22\80\443端口,其他的拒绝 iptables -t filter -A INPUT -p tcp -m multiport -dports 22.80.443 -j ACCEPT iptables -t filter -p tcp -j DROP // 只开发1000-2000端口,其他的拒绝 iptables -t filter -p tcp -j DROP iptables -t filter -A INPUT -p tcp -m multiport -dports 1000-2000 -j ACCEPT
-
iprange模块
使用:连续匹配多个IP
参数:
--src-range 源地址范围
--dst-range 目标地址范围
// 只有192.168.15.7到192.168.15.66能够通过22端口登录,其他的拒绝 iptables -t filter -A INPUT -p tcp -m iprange --src-range 192.168.15.7-192.168.15.66 -j ACCEPT
-
string模块
使用:按照内容进行匹配
参数:
--string pattern 指定要匹配的字符串
--algo {bm|kmp} 匹配算法
// 要求访问的内容中包含HelloWrold的内容不允许访问 iptables -f filter -A OUTPUT -p tcp -m string --string "hello" --algo kmp -j DROP
-
time模块
使用:根据时间来控制访问(UTC)
参数:
--timestart hh:mm[:ss] 开始时间
--timestop hh:mm[:ss] 结束时间
--monthdays day[,day...] 指定一个月的某天
--weekdays day[,day...] 指定周还是周天
// 要求上午的08:00到上午的10:22不允许访问,其他时间可以 iptables -t filter -A INPUT -p tcp -m time --timestart 00:00 --timestop 02:22 -j DROP
-
icmp模块
使用:控制icmp协议
参数:
--icmp-type {type[/code]|typename}
echo-request 请求(我可以ping别人,别人休想ping我)
echo-reply 回应(别人可以ping我,我不想ping别人)
// 禁止别人ping我,我可以ping别人 iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j DROP
-
connlimit模块
使用:限制连接数,控制并发数
参数:
--connlimit-upto n 如果现有连接数小于或等于n则匹配
--connlimit-above n 如果现有连接数大于n则匹配
// 要求ssh的登录窗口最多只有2个 iptables -t filter -A INPUT -p ALL -dport 22 -m connlimit --connlimit-above 2 -j REJECT
-
limit模块
使用:针对报文速率进行限制。秒、分钟、小时、天
参数:
--limit rate[/second|/minute|/hour|/day]
--limit-burst number
// 允许1-个数据报文快速通过,超过的报文1/m iptables -t filter -A INPUT -p icmp m limit --limit 1/m --limit-burst 10 -j ACCEPT iptables -t filter -A INPUT -p icmp -j DROP // 带宽限速:限制传输的带宽不可以超过500k(500*1000/1500=333包) iptables -t filter -A INPUT -p tcp -m limit --limit 333/s -j ACCEPT iptables -t filter -A INPUT -p tcp -j DROP
-
mac模块
使用:根据源mac地址做条件
参数:
--mac-source 源mac地址
iptables -t filter -A INPUT -m mac --mac-source 00:50:56:12:34:56 -j ACCEPT
-
state模块
使用:通过state状态跟踪模块,判断新旧用户发起的请求,从而进行访问控制
参数:
状态类型:
NEW:新发出请求;链接追踪信息库中不存在此连接的相关信息条目,因此,将其识别位第一次发出的请求,即NEW位一次连接的第一个请求;如断开连接后,重新建立连接,再次发送请求,此请求也为NEW;
ESTABLISHED:NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态,即第一次连接第一次请求之后的请求都为ESTABLISHED;
RELATED:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系;
INVALID:无效的连接,如flag标记为不正确,如TCP6个标记为都为0或者都为1;
UNTRACKED:未进行追踪的连接,如raw表中关闭追踪;
// 拒绝新用户连接22端口 iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -j REJECT
-
conntrack模块
使用:连接追踪功能
相关文件:
/proc/net/nf_conntrack #此文件为跟踪库,记录了连接过本机的IP,但是记录在内存中,终究是有极限的
/proc/sys/net/nf_conntrack_max #此文件记录了最大跟踪连接的数量,超过此文件数量的连接将会被拒绝;连接跟踪会占用较多内存,加大系统负载
/proc/sys/net/netfilter/ #此目录下的文件记录了各个协议的连接超时时长 -
recent模块
使用:用于限制一段时间内的连接数,是防止大量请求攻击的必杀手段
参数:
--name 设定列表名称
--resource 源地址,此为默认。只进行数据库中信息的匹配,并不会对已存在的数据做任何变更操作。
--rdest 目的地址;
--seconds 指定时间内。当事件发生时,只会匹配数据库中前X秒内的记录,--seconds必须与--rcheck或--update参数公用;
--hitcount 命中次数。hits匹配重复发生次数,必须与--rcheck或--update参数共用;
--set 将地址添加进列表,并更新信息,包含地址加入的时间戳。即将符合条件的来源数据添加到数据库中,单如果来源段数据已经存在,则更新数据库中的记录信息;
--rcheck 检查地址是否在列表,以第一个匹配开始计算时间;
--update 和rcheck类似,以最后一个匹配计算时间。如果来源端的数据已存在,则将其更新;若不存在,则不做任何处理;
--remove 在列表里删除相应地址,后跟列表名称及地址。如果来源端数据已存在,则将其删除;若不存在,则不做任何处理;
// 抵御简单的DOS攻击, 利用recent和state模块限制单IP在300s内只能与本机建立3个新连接。被限制一分钟后即可恢复访问。 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 DROP // 限制每ip在一分钟内最多对服务器只能有8个http连接 iptables -I INPUT -p tcp --dport 80 -d 192.168.10.10 -m state --state NEW -m recent --name httpuser --set iptables -A INPUT -m recent --update --name httpuser --seconds 60 --hitcount 9 -j LOG --log-prefix 'HTTP attack: ' iptables -A INPUT -m recent --update --name httpuser --seconds 60 --hitcount 9 -j DROP // 限制80端口60秒内每个IP只能发起10个新连接,超过记录日记及丢失数据包,可防CC及非伪造IP的syn flood iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j LOG --log-prefix 'DDOS:' --log-ip-options iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT // 默认封闭SSH端口,为您的SSH服务器设置开门暗语 iptables -A INPUT -p tcp --dport 50001 --syn -j LOG --log-prefix "SSHOPEN: " #记录日志,前缀SSHOPEN: iptables -A INPUT -p tcp --dport 50001 --syn -m recent --set --name sshopen --rsource -j REJECT --reject-with tcp-reset #目标端口tcp 50001的新数据设定列表为sshopen返回TCP重置,并记录源地址。 iptables -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 15 --name sshopen --rsource -j ACCEPT #开启SSH端口,15秒内允许记录的源地址登录SSH。 // 指定端口容易被破解密钥,可以使用ping指定数据包大小为开门钥匙 iptables -F iptables -X iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -p icmp --icmp-type 8 -m length --length 78 -j LOG --log-prefix 'SSH_OPEN_KEY' iptables -A INPUT -p icmp --icmp-type 8 -m length --length 78 -m recent --name openssh --set --rsource -j ACCEPT iptables -A INPUT -p tcp --dport 22 --syn -m state --name openssh --rcheck --seconds 60 --rsource -j ACCEPT iptables -P INPUT DROP