iptables
iptables(linux防火墙)对于linux player来说都不是陌生,这是一款基于包过滤的4层防护软件,基于内核netfilter来过滤数据报文,在整个数据流经过程中,共设置了5个hooks,我们称之为链,基于不同的功能又形成了4个表,4表5链是iptables的核心功能。
iptables表
- filter:过滤功能,数据过滤,防火墙功能(核心功能)
- mangle:拆解报文,按需要重新修改报文
- nat:地址转换
- raw:关闭在nat表启用的追踪机制
iptables内置链
- prerouting:在数据报文进入内核未进行路由选择之前
- input:目标地址是本机主机,数据报文接受进入内核处理
- forward:目标是不是本机主机,数据报文到postrouting链上
- ouput:数据从用户空间出来的数据
- postrouting:数据进行路由选择之后
表与链的关系
从图中可知:
- prerouting可应用在raw,mangle,nat表中
- input可应用在mangle,filter表中
- forward可应用在mangle,filter表中
- output可应用在raw,mangle,nat,filter表中
- postrouting可应用在mangle,nat表中
还有如果在同一条链上同时应用了多个表的内容,优先级从高到低:
raw–>mangle–>nat–>filter
iptables tool
iptables就是一个书写表上链的规则的工具,它从2.0.X内核的ipfwadm到2.2.X内核的ipchains再到2.4.X内核的iptables,iptables这个工具经过了一遍遍的更新迭代,到目前为止已经是一个很完善及功能强大的工具。
链管理
- -N: new,新增一条自定义规则
- -X: delete,删除自定义的空链
- -P: policy,设置链的默认策略
- -E: rename, 重命名自定义的未被应用的链
规则管理
- -A: append,追加,默认为最后一条规则
- -I: insert,插入,默认为第一条规则
- -D: delete,删除
- (1)具体规则的内容
- (2)规则编号
- -R: replace,替换
- -F: flush,清洗
- -Z: zero,置零
- (1)由本规则匹配到的packets
- (2)由本规则匹配到的bytes
- -S: –list-rules,列出书写规则
查看规则
- -L: list,列出链上规则
- -n: numeric,以数字格式显示地址和端口
- -v: verbose,详细信息;-vv,-vvv
- –line-number: 显示链上的规则的编号
匹配条件
基本匹配
netfiter自带的匹配机制,属于最基本的匹配选项:
- [!] -s,–source address[/mask]:源地址匹配
- [!] -d,–destination address[/mask]:目标地址匹配
- [!] -i,–in-interface:限制报文流入的接口,只能用于prerouting,input,forward
- [!] -o,–out-interface:限制报文流出的接口,只能用于postrouting,output,forward
- [!] -p,{tcp|udp|icmp}:协议限制
扩展匹配
隐式扩展
[!] -p {tcp|udp|icmp}:限制协议
tcp
隐含指明了‘-m tcp’,由专用选项:
- [!] –source-port,–sport port[:port]: 匹配报文中的tcp首部的源端口,可以是端口范围
- [!] –destination-port,–dport port[:port]: 匹配报文中的tcp首部的目标端口,可以是端口范围
- [!] –tcp-flags mask comp: 检查报文中mask指明的tcp标志位,而要这些标志位comp中必须为1
- -tcp-flags syn,fin,ack,rst syn == –syn
- [!] –syn
udp
隐含指明了‘-m udp’,有专用选项
- [!] –source-port,–sport port[:port]: 匹配报文中的udp首部的源端口;可以是端口范围
- [!] –destination-port,–dport port[:port]: 匹配报文中的udp首部的目标端口,可以是端口范围
icmp
隐含指明了‘-m icmp’,有专用选项
- [!] –icmp-type {type[/code]|typename}
ping应答:0/0
ping请求:8/0
显示扩展
multiport
多端口匹配,以离散方式定义多端口匹配,最多可一次指定15个端口
- [!] –source-ports,–sports port[,port|,port:port]…
- [!] –destination-ports,–dports port[,port|,port:port]…
- [!] –ports port[,port|,port:port]…
eg:
默认规则是DROP,允许到达本机的22,23,80端口的报文通过
~]#iptables -A INPUT -p tcp -d 10.211.55.24 -m multiport –dports 23,22,80 -j ACCEPT
~]#iptables -A OUTPUT -p tcp -s 10.211.55.24 -m multiport –sports 23,22,80 -j ACCEPT
~]#iptables -P INPUT DROP
~]#iptables -P OUTPUT DROP
iprange
指明一段连续的ip地址范围作为源地址或目标地址匹配
- [!] –src-range from[-to]:源地址范围
- [!] –dst-range from[-to]:目标地址范围
eg:
限制地址范围访问
~]#iptables -A INPUT -p tcp -m iprange –src-range 10.211.55.35-10.211.55.36 -d 10.211.55.24 -m multiport –dports 22,23,80 -j ACCEPT
~]#iptables -A OUTPUT -p tcp -s 10.211.55.24 -m multiport –sports 22,23,80 -j ACCEPT
string
对报文中的应用层数据做字符串匹配检测
- –algo {bm|kmp} 算法 (bm=Boyer-Moore,kmp=Knuth-Pratt-Morris)必选
- [!] –string pattern: 给定要检查的字符串模式
- [!] –hex-string pattern: 给定要检查的字符串模式;16进制编码
eg:
对特定流经的字符串进行过滤
~]#iptables -I OUTPUT -m string –algo kmp –string ‘python’ -j REJECT
time
根据收到报文的时间/日期与指定的时间/日期范围进行匹配
- –datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]: 起始时间日期
- –datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]: 结束时间日期
- –timestart hh:mm[:ss]:起始时间
- –timestop hh:mm[:ss]:结束时间
- [!] –monthdays day[,day…]:匹配一个月中哪些天
- [!] –weekdays day[,day…]:匹配一周中的那些天
eg:
周末早上9:00到下午3:00不允许访问网站服务器
~]#iptables -I INPUT -p tcp -d 10.211.55.24 –dport 80 -m time –weekdays 6,7 –timestart 9:00 –timestop 15:00 -j DROP
connlimit
根据每客户端主机做并发连接数量限制,即每客户端最多可同时发起的连接数量
- –connlimit-upto n:连接数量小于等于n则匹配
- –connlimit-above n: 连接数量大于n则匹配
eg:
ssh并发连接到2个以上就拒绝连接
~]#iptables -I INPUT -p tcp -d 10.211.55.24 –dport 22 -m connlimit –connlimit-above 2 -j DROP
limit
基于令牌桶算法对报文的速率做匹配
- –limit rate[/second|/minute|/hour|/day] rate为报文个数
- –limit-burst number 峰值
eg:
限制网站的下载速率
~]#iptables -I OUTPUT -p tcp -s 10.211.55.24 –sport 80 -m limit –limit 100/second –limit-burst 200 -j ACCEPT
recent
利用iptables的recent模块来抵抗dos攻击
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 DROP
利用connlimit模块将单IP的并发设置为3;会误杀使用nat上网的用户,可以根据实际情况增大该值
利用recent和state模块限制单ip在300s内只能建立3个新连接,被限制五分钟即可恢复访问
下面对最后两句做一个说明
1.第二句是记录访问tcp 22端口的新连接,记录名称为ssh
-set 记录数据包的来源ip 如果ip已经存在将更新已经存在的条目
2.第三句是指在SSH记录中ip,300s内发起超过3次连接则拒绝ip的连接
–update 是指每次建立连接都更新列表
–seconds 必须与–rcheck或者–update同时使用
–hitcount 必须与 –rcheck或者–update同时使用
3.iptables的记录 /proc/net/ipt_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”
state
是conntract的子集,用于对报文的状态做状态追踪,state模块极大的扩展了iptables的应用,极大加强了安全防护。
- [!] –state state
- INVALID: 无法识别的连接
- ESTABLISHED:连接追踪模板当中存在记录的连接
- NEW: 连接追踪模版当中不存在的连接请求
- RELATED:相关联的连接
- UNTRACKED:未追踪的连接
ftp服务的特殊性,如何放行被动模式的ftp服务:
(1)内核加载nf_contract_ftp模块
modprode nf_contract_ftp
(2)放行命令连接
iptables -A INPUT -d 10.211.55.24 -p tcp –dport 21 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 10.211.55.24 -p tcp –sport 21 -m state –state ESTABLISHED -j ACCEPT
(3)放行数据连接
iptables -A INPUT -d 10.211.55.24 -p tcp -m state –state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 10.211.55.24 -p tcp -m state –state ESTABLISHED -j ACCEPT
已经追踪到的并记录下来的连接:
/proc/net/nf_conntrack
连接追踪功能所能够记录的最大连接数量(可调整)
/proc/sys/net/nf_conntract_max
conntrack所能够追踪的连接数量的最大值取决于/proc/sys/net/nf_conntract_max的设定;已经追踪到的并记录下来的连接位于/proc/net/nf_conntrack文件中,超时的连接将会被删除;当模版满载时,后续的新连接有可能会超时;解决方法:
(1)加大nf_conntrack_max的值
(2)降低nf_conntrack条目的超时时长:
不同协议的连接追踪时长:/proc/sys/net/netfilter/
处理动作
-j targetname [per-target-opotions]
- ACCEPT,DROP,REJECT
- RETURN: 返回调用的链
- LOG:记录日志
- REDIRECT: 端口重定向
- MARK:防火墙标记
- DNAT:目标地址转换
- SNAT:源地址转换
- MASQERADE: 地址伪装
LOG
- –log-level level
emerg, alert, crit, error, warning, notice, info or debug - –log-prefix prfix :日志前面添加前缀
eg:
记录下ssh的访问日志
~]#iptables -I INPUT -p tcp –dport 80 -j LOG –log-prefix ‘new http’
~]#tail /var/log/messages
Mar 25 16:27:42 localhost kernel: new httpIN=eth0 OUT= MAC=00:1c:42:59:56:3f:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.24 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=48501 PROTO=TCP SPT=50113 DPT=80 WINDOW=4102 RES=0x00 ACK URGP=0
Mar 25 16:27:46 localhost kernel: new httpIN=eth0 OUT= MAC=00:1c:42:59:56:3f:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.24 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=28281 DF PROTO=TCP SPT=50113 DPT=80 WINDOW=4102 RES=0x00 ACK URGP=0
Mar 25 16:27:46 localhost kernel: new httpIN=eth0 OUT= MAC=00:1c:42:59:56:3f:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.24 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=8743 DF PROTO=TCP SPT=50113 DPT=80 WINDOW=4102 RES=0x00 ACK FIN URGP=0
RETURN
返回调用者
eg:
创建一个自定义链,并调用和返回
~]#iptables -N deny_http
~]#iptables -I deny_http -s 10.211.55.37 -p tcp –dport 80 -j DROP
~]#iptables -I deny_http -s 10.211.55.38 -p tcp –dport 80 -j DROP
~]#iptables -A deny_http -j RETURN
~]#iptables -I INPUT -d 10.211.55.24 -j deny_http
REDIRECT
–to-ports port[-ports]
eg:
端口转发
~]#iptables -t nat -A PREROUTING -p tcp -s 10.211.55.35 –dport 80 -j REDIRECT –to-ports 8080
SNAT
常作用在 POSTROUTING链上
修改ip报文中的源ip地址,让本地网络中的主机可使用统一地址与外部主机通信,从而实现地址伪装
eg:
源地址转换
~]#iptables -t nat -A POSTROUTING -s 10.211.55.0/24 -j SNAT –to-source 192.168.31.1-192.168.31.4
DNAT
常作用在 PREROUTING链上
修改ip中的目标ip地址,让本地网络中服务器使用统一的地址向外提供服务(发布服务),但隐藏了自己的真实地址;
eg:
目的地址转换
~]#iptables -t nat -A PREROUTING -m iprange –dst-range 192.168.31.1-192.168.31.4 -j DNAT –to-destination 10.211.55.2
PNAT
~]#iptables -t nat -A PREROUTING -d 192.168.31.3:80 -j DNAT –to-destination 10.211.55.2:80
MASQERADE
常作用在 POSTROUTING链上
动态获取外网地址,用于替换SNAT
不建议在内网使用,开销太大
~]#iptables -t nat -A POSTROUTING -s 10.211.55.0/24 -j MASQERADE
总结:iptables为我们提供了多种多样的匹配的规则,但是规则是死的,人是活的,合理的搭配规则才是我们更需要关注的地方。