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:地址伪装
...
自定义链:由自定义链上的规则进行匹配检查
回顾:
iptables/netfilter
netfilter: kernel framework,
iptables
四表:filter, nat, mangle, raw
五链:PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
回顾:
子命令:
链:-F, -X, -N, -E, -Z, -P, -L
规则:-A, -I, -D, -R
-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
练习:
主机防火墙:
放行telnet, ftp, web服务;
放行samba服务;
放行dns服务(查询和区域传送);
网络防火墙:
放行telnet, ftp, web服务;
放行samba服务;
放行dns服务(查询和区域传送);
回顾:
telnet: 23/tcp
samba: 137/udp, 138/udp, 139/tcp, 445/tcp
dns: INPUT: 53/udp, OUTPUT: 53/udp
核心转发:/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
练习:INPUT和OUTPUT默认策略为DROP;
1、限制本地主机的web服务器在周一不允许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不允许访问;web服务器仅允许响应报文离开本机;
2、在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给172.16.0.0网络中的主机访问;数据下载请求的次数每分钟不得超过5个;
3、开放本机的ssh服务给172.16.x.1-172.16.x.100中的主机,x为你的座位号,新请求建立的速率一分钟不得超过2个;仅允许响应报文通过其服务端口离开本机;
4、拒绝TCP标志位全部为1及全部为0的报文访问本机;
5、允许本机ping别的主机;但不开放别的主机ping本机;
练习:判断下述规则的意义:
# iptables -N clean_in
# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
# iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A clean_in -d 172.16.100.7 -j RETURN
# iptables -A INPUT -d 172.16.100.7 -j clean_in
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A OUTPUT -o lo -j ACCEPT
# iptables -A INPUT -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP
# iptables -A INPUT -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP
# iptables -A INPUT -i eth0 -p udp --dport 1026 -j DROP
# iptables -A INPUT -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP
# iptables -A INPUT -p icmp -m limit --limit 10/second -j ACCEPT
补充:利用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
diff/patch:文本操作工具
diff是Unix系统的一个很重要的工具程序。它用来比较两个文本文件的差异,是代码版本管理的核心工具之一。其用法非常简单:
# diff <变动前的文件> <变动后的文件>
由于历史原因,diff有三种格式:
* 正常格式(normal diff)
* 上下文格式(context diff)
* 合并格式(unified diff)
1、正常格式的diff
例如,对file1(变动前的文件)和file2(变动后的文件)进行比较可使用如下命令:
# diff file1 file2
显示结果中,第一行是一个提示,用来说明变动位置。它分成三个部分:前面的数字,表示file1的第n行有变化;中间的"c"表示变动的模式是内容改变(change),其他模式还有"增加"(a,代表addition)和"删除"(d,代表deletion);
2、上下文格式的diff
上个世纪80年代初,加州大学伯克利分校推出BSD版本的Unix时,觉得diff的显示结果太简单,最好加入上下文,便于了解发生的变动。因此,推出了上下文格式的diff。它的使用方法是加入-c选项(即context)。
# diff -c f1 f2
结果分成四个部分。第一部分的两行,显示两个文件的基本情况:文件名和时间信息,"***"表示变动前的文件,"---"表示变动后的文件。第二部分是15个星号,将文件的基本情况与变动内容分割开。第三部分显示变动前的文件,即file1。
另外,文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。
第四部分显示变动后的文件,即file2。
3、合并格式的diff
如果两个文件相似度很高,那么上下文格式的diff,将显示大量重复的内容,很浪费空间。1990年,GNU diff率先推出了"合并格式"的diff,将f1和f2的上下文合并在一起显示。
它的使用方法是加入u参数(代表unified)。
# diff -u f1 f2
其结果的第一部分,也是文件的基本信息。"---"表示变动前的文件,"+++"表示变动后的文件。第二部分,变动的位置用两个@作为起首和结束。第三部分是变动的具体内容。
除了有变动的那些行以外,也是上下文各显示3行。它将两个文件的上下文,合并显示在一起,所以叫做"合并格式"。每一行最前面的标志位,空表示无变动,减号表示第一个文件删除的行,加号表示第二个文件新增的行。
diff
-u
patch
尽管并没有指定patch和diff的关系,但通常patch都使用diff的结果来完成打补丁的工作,这和patch本身支持多种diff输出文件格式有很大关系。patch通过读入patch命令文件(可以从标准输入),对目标文件进行修改。通常先用diff命令比较新老版本,patch命令文件则采用diff的输出文件,从而保持原版本与新版本一致。
patch的标准格式为
patch [options] [originalfile] [patchfile]
如果patchfile为空则从标准输入读取patchfile内容;如果originalfile也为空,则从patchfile(肯定来自标准输入)中读取需要打补丁的文件名。因此,如果需要修改的是目录,一般都必须在patchfile中记录目录下的各个文件名。绝大多数情况下,patch都用以下这种简单的方式使用:
patch命令可以忽略文件中的冗余信息,从中取出diff的格式以及所需要patch的文件名,文件名按照diff参数中的"源文件"、"目标文件"以及冗余信息中的"Index:"行中所指定的文件的顺序来决定。
-p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略所有目录信息,-p0(或者-p 0)表示使用全部的路径信息,-p1将忽略第一个"/"以前的目录,依此类推。如/usr/src/linux-2.4.15/Makefile这样的文件名,在提供-p3参数时将使用linux-2.4.15/Makefile作为所要patch的文件。
patch
-p
-R
mockbuild
总结:操作步骤
1、获取并编译内核
# useradd mockbuild
# rpm -ivh kernel-2.6.32-431.5.1.x86_64.el6.src.rpm
# cd rpmbuild/SOURCES
# tar linux-2.6.32-*.tar.gz -C /usr/src
# cd /usr/src
# ln -sv
2、给内核打补丁
# tar xf netfilter-layer7-v2.23.tar.bz2
# cd /usr/src/linux
# patch -p1 < /root/netfilter-layer7-v2.23/kernel-2.6.32-layer7-2.23.patch
# cp /boot/config-* .config
# make menuconfig
按如下步骤启用layer7模块
Networking support → Networking Options →Network packet filtering framework → Core Netfilter Configuration
<M> “layer7” match support
3、编译并安装内核
# make
# make modules_install
# make install
4、重启系统,启用新内核
5、编译iptables
# tar xf iptables-1.4.20.tar.gz
# cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* /root/iptables-1.4.20/extensions/
# cp /etc/rc.d/init.d/iptales /root
# cp /etc/sysconfig/iptables-config /root
# rpm -e iptables iptables-ipv6 --nodeps
# ./configure --prefix=/usr --with-ksource=/usr/src/linux
# make && make install
# cp /root/iptables /etc/rc.d/init.d
# cp /root/iptables-config /etc/sysconfig
6、为layer7模块提供其所识别的协议的特征码
# tar zxvf l7-protocols-2009-05-28.tar.gz
# cd l7-protocols-2009-05-28
# make install
7、如何使用layer7模块
ACCT的功能已经可以在内核参数中按需启用或禁用。此参数需要装载nf_conntrack模块后方能生效。
net.netfilter.nf_conntrack_acct = 1
l7-filter uses the standard iptables extension syntax
# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]
# iptables -A FORWARD -m layer7 --l7proto qq -j REJECT
编译内核:
make menuconfig
make -j #
make modules_install
make install
清理内核源码树:
提示:xt_layer7.ko依赖于nf_conntrack.ko模块
博客:iptables所有应用,包括layer7的实现;
课外扩展:recent模块,layer7模块;
tcp_wrapper:tcp包装器
对基于tcp协议开发并提供服务的应用程序,提供的一层访问控制工具;
基于库调用实现其功能:
libwrap
判断服务是否能够由tcp_wrapper进行访问控制:
(1) 动态编译:ldd命令;
(2) 静态编译:strings命令查看应用程序文件,其结果中如果出现
hosts.allow
hosts.deny
在配置文件在为各服务分别定义访问控制规则实现访问控制:
/etc/hosts.allow
/etc/hosts.deny
配置文件语法:
daemon_list: client_list [:options]
daemon_list:
应用程序的文件名称,而非服务名;
应用程序文件名称列表,彼此间使用逗号分隔;
例如:sshd, vsftpd:
ALL表示所有服务;
client_list:
IP地址;
主机名;
网络地址:必须使用完整格式的掩码,不使用前缀格式掩码;所以类似于172.16.0.0/16不合法;
简短格式的网络地址:例如172.16. 表示 172.16.0.0/255.255.0.0;
ALL:所有主机;
KNOWN:
UNKNOWN
PARANOID
例如:vsftpd服务不允许172.16.100.1访问
EXCEPT: 除了
hosts.allow
vsftpd: 172.16. EXCEPT 172.16.100.0/255.255.255.0 EXCEPT 172.16.100.1
[:options]
deny: 拒绝,主要用于hosts.allow文件中
allow:允许,用于hosts.deny文件,实现allow的功能
spawn: 启动额外应用程序:
vsftpd: ALL :spawn /bin/echo `date` login attempt from %c to %s, %d >> /var/log/vsftpd.deny.log
%c: client ip
%s: server ip
%d: daemon name
练习:控制telnet服务仅允许172.16.0.0网络中的主机访问,但不包括172.16.100.0/255.255.255.0中的主机;
对所有正常登录的主机都记录于/var/log/telnet.allow.log中;
所有未授权访问尝试都记录于/var/log/telnet.deny.log中;
博客作业:iptables