在Linux运维工作中,在涉及Linux安全时,我们第一时间想到的一般都是iptables这个工具。作为一个linux初学者来讲,在刚学习linux的过程中,有些实验总是总不成功。这时我们总会检查防火墙是否关闭,selinux是否关闭。在深入学习iptbales之后,这些以前知其然,不知其所以然的操作在内心就很敞亮了。想深入学习一个东西,总要问一下what is it?
本节学习目标
防火墙分类
Netfilter防火墙工作原理
iptables四表五链
iptables规则设定要点
iptables工具使用方法(熟练使用,包括主机防火墙配置,网络防火墙配置,以及nat配置)
防火墙是一种隔离工具。工作于主机或者网络的边缘,对于进出本主机或者本地网络的报文根据事先定义好的规则做匹配检测,对于能够被规则所匹配到的报文做出相应处理(允许,拒绝,丢弃等)。根据其管理的范围来分可以将其划分为主机防火墙和网络防火墙。根据其工作机制来区分又可分为包过滤型防火墙(netfilter)和代理服务器(Proxy)。有些人把tcp_warrpers也划分为防火墙的一种。这种是根据服务程序软件的名称来控制数据包的方法。
包过滤防火墙Netfilter是linux内核所支持的一个功能模块框架。Iptables是配置管理Netfilter的一个软件工具。所以Netfilter是工作与内核空间的。Netfilter是内核中一系列的钩子(hook),为内核模块在网络协议栈中的不同位置注册回调函数(callback)。在数据包经过网络协议栈中的不同位置时做相应的处理。
Netfilter中的五个钩子NF_IP_PRE_ROUTING,NF_IP_LOCAL_IN,NF_IP_FORWARD,NF_IP_POST_ROUTING,NF_IP_LOCAL_OUT。。其中网络数据包的流向图如下图所示
1网络数据包从网卡进来之后进入内核空间的TCP/IP协议栈进行层层解封装;
2 在数据包刚刚进入网络层的数据包通过NF_IP_PRE_FORWARD,在此店之后要进行一次路由选择,当目标地址为本机地址时,数据进入NF_IP_LOCAL_IN,非本地的目标地址进入NF_IP_FORWARD,所以目标地址转换通常在此点进行;
3 NF_IP_LOCAL_IN:经过路由之后送往本地的数据包经过此点,所以过滤INPUT包在此点进行。
4 NF_IP_FORWARD:经过路由选择之后要转发的数据包经过此点,所以网络防火墙通常在此点配置。
5 NF_IP_LOCAL_OUT:由本地用户空间应用进程产生的数据包过此检测点,所以OUTPUT包过滤在此点进行。
6 NF_IP_POST_ROUTING:刚刚通过NF_IP_FORWARD和NF_IP_LOCAL_OUT检测点的数据包要通过一次路由选择由哪个接口送往网络中,经过路由之后的数据包要通过NF_IP_POST_ROUTING此检测点,所以,源地址转换通常在此点进行。
iptables是工作在用户空间的一个管理netfilter的工具,该工具默认有五条链(chain), REROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING分别由netfilter的五个钩子函数来触发。Iptables设有四张表,用以实现Netfilter的不同功能。
filter表:iptables中使用最广泛的表,作用是进行包过滤,由此表来决定该数据包是否继续向它的目标地址前进。
Nat表:又此表的名称可以看出,该表用于网络地址转换用的,这也就是防火墙的另外一个功能,对源地址或者目标地址的修改。
mangle表:mangle表用于对ip报文的首部信息进行修改。
raw表:raw表的功能是为防火墙提供一种禁用连接状态追踪的机制,在大流量对外业务的服务器上使用这个表可以有效的避免连接追踪带来的性能问题,比如游戏服务器通常通过此表或者重新编译内核的方式禁用防火墙的连接追踪机制。
除此之外,在iptable的帮助文档中提到还有一张security表,用于在数据包总加入selinux特性功能,该表很少用到,这里不再详述。
Iptables的四张表有着不同的处理优先级,raw-->mangle-->nat -->filter,从左至右优先级依次降低。由于数据包进入协议栈中的钩子的位置不同以及表的优先级顺序不同,所以防火墙对于数据包的处理顺序特别容易混淆,这里引用一张胥峰前辈的处理顺序图(由于该图显示不清晰,可到附件下载):
想要配置一个较为安全的防火墙策略就需要了解其规则的组成以及设置规则时所需要思考的要点。
规则组成:报文的匹配条件,匹配到之后的处理动作
匹配条件:根据协议报文特征指定匹配条件,基本匹配条件和扩展匹配条件
处理动作:内建处理机制由iptables自身提供的一些处理动作
自定义处理机制:可自定义链来对匹配到的报文做处理。
注意:报文不会经过自定义链,只能在内置链上通过规则进行引用后生效,也就是所自定义链为规则的一个处理动作的集合。
设置iptables规则时需要考量的要点:
1、根据要实现哪种功能,判断添加在那张表上;
2、根据报文流经的路径,判断添加在那个链上
流入:PREROUTING--->INPUT
流出:OUTPUT--->POSTROUTING
转发:PREROUTING---->FORWARD--->POSTROUTING
链上其规则的次序,即为检查的次序,排列好检查次序能有效的提高性能,因此隐含一定的法则
1、同类规则(访问同一应用),匹配范围小的放上面
2、不同类规则(访问不同应用),匹配到报文频率大的放上面:
3、将那些可由一条规则描述的多个规则合并为一个
4、设置默认策略
远程连接主机配置防火墙时注意要点:
1,不要把链的默认策略修改为拒绝。因为有可能配置失败或者清除所有策略后无法远程到服务器。尽量使用规则条目配置默认策略
2,为防止配置失误策略把自己也拒掉,可在配置策略时设置计划任务定时清除策略。当确定无误后,关闭该计划任务。
磨刀不误砍柴工,当以上的东西在脑海中已经有一个框架之后,再学习iptables规则管理工具才会得心应手。
Man文档是学习工具的最好方法。这里不再详述,下面把我的学习笔记粘贴出来,以供读者参考如有错误敬请指正。
iptables命令: iptables [-t table] {-A|-C|-D} chain rule-specification ip6tables [-t table] {-A|-C|-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
iptables [-t table] SUBCOMMAND CHAIN CRETERIA -j TARGET
-t table: filter ,nat,mangle,raw 默认为filter
链管理: -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:exectly,显示计数器计数结果的精确值。
匹配条件: 基本匹配: [!] -s, --src,--source IP|Netaddr:检查报文中的源ip地址是否符合此处指定的地址范围 [!] -d,--dst,--destination IP|Netaddr:检查报文中的目标ip地址是否符合此处指定的地址范围 -p ,--protocal{tcp|udp|icmp}:检查报文中的协议,即ip首部中的protocol所标识的协议,8bit,6标识tcp.17表示udp -i,--in-inteface IFACE :数据报文的流入接口。仅能用于PREROUTING,INPUT,FORWARD链 -o,--out-inteface :数据报文的流出接口。仅能用于FORWARD,OUTPUT,POSTROUTING链上
扩展匹配:-m macth_name --spec_options eq: -m tcp --dport 22 表示使用tcp扩展的目标端口为22 隐式扩展:对-p protocal 指明的协议进行扩展,可省略-m选项: -p tcp --dport PORT[-PORT]:目标端口,可以是单个端口或者连续多个端口 --sport PORT[-PORT] --tcp-flags list1 list2 :检查list1所指明的所有标志位,且这其中,list2所表示出的所有标记必须为1,而余下的必须为0,没有list1中指明的,不做检查。 SYN,ACK,FIN,RST,PSH,URG, eq:--tcp-flags SYN,ACK,FIN,RST SYN ===== --syn: 检查三次握手的第一次握手 -p udp --dport --sport -p icmp --icmp-type 可用数字表示其类型: 0 echo-reply 8 echo-request
显示扩展:
目标: -j target:jump至指定的target ACCEPT:接收 DROP:丢弃 REJECT;拒绝 RETURN:返回调用链 REDIRECT:端口重定向 LOG:记录日志 MARK:做防火墙标记 DNAT:目标地址转换 SNAT:源地址转换 MASQUERADE:地址伪装 ... 自定义链:由自定义链上的规则进行匹配检查。
显示扩展:必须显示指明使用的扩展模块(rpm -ql iptables|grep "\.so") centos6 man iptables centos7 man iptbales-extensions
1、multiport扩展 以离散方式定义多端口匹配:最多匹配15个端口 [!] --source-ports,--sports port[,port|,port:port]... 指明多个源端口 [!] --destination-ports,--dports port[,port|,port:port]... 指明多个离散的目标端口 [!] --ports port[,port|,port:port]...
例子: # iptables -A INPUT -p tcp -m multiport --dports 22,80 -j ACCEPT # iptables -A OUTPUT -p tcp -m multiport --sports 22,80 -j ACCEPT
2、iprange扩展 指明连续的(但一般不能扩展为整个网络)ip地址范围
[!] --src-range from[-to] 匹配指明连续的源IP地址范围 [!] --dst-range from[-to] 指明连续的目标IP地址范围
# iptables -A INPUT -m iprange --src-range 172.18.11.0-172.18.11.100 -j DROP # iptables -A INPUT -p tcp -m multiport --dports 22,80 -m iprange --src-range 172.18.11.0-172.18.11.100 -j DROP
3、string扩展 检查报文中出现的字符串:
--algo {bm|kmp}:
[!] --string pattern [!] --hex-string pattern 16进制
iptables -I OUTPUT -m string --algo bm --string "movle" -j DROP
4、time扩展 根据报文到达的时间与指定的时间范围进行匹配 --datestart --datestop
--timestart --timestop
--monthdays --weekdays # iptables -I INPUT -d 172.18.11.7 -p tcp --dport 80 -m time --timestart 8:00 --timestop 10:00 -j DROP
# 注意 centos7 使用的是UTC时间
5、connlimit扩展 根据每客户端ip(也可以是地址块)做并发连接数数量匹配:
--connlimit-above n 连接数量大于n --connlimit-upto n 连接数量小于等于n # iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT # ssh连接大于3后链接被拒绝 6、limit扩展 基于收发报文速率做检查: 令牌桶过滤器:
--limit rate[/second|/minute|/hour|/day] --limit-burst number # iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 6/minute -j ACCEPT # iptables -A INPUT -p icmp -j REJECT
##跳过5个包,然后没10秒钟一个回应一个ping包
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... 例子: # iptables -I INPUT -d 172.18.11.7 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT # iptables -I OUTPUT -s 172.18.11.7 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 对新发起的http和ssh访问请求做控制, # iptables -A INPUT -d 172.16.100.10 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT # iptables -A OUTPUT -s 172.16.100.10 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT
如何开放被动模式的FTP服务?
(1) 装载ftp追踪时专用的模块 #modprobe nf_conntrack_ftp
路径 /lib/modules/3.10.0-514.el7.x86_64/kernel/net/netfilternf_conntrack_ftp.ko 模块信息 modinfo nf_conntrack_ftp.ko (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) 放行响应报文 ESTABLISHED #iptables -A OUTPUT -d localIP -p tcp -m state --state ESTABLISHED -j ACCEPT
如何保存及重载规则: 保存规则至指定文件: iptables-save > /path/to/somefile
从指定文件重载规则: iptables-restore < /path/from/somefile
centos6: service iptables save iptable-save >/etc/sysconfig/iptables service iptables restart iptables-restore < /etc/sysconfig/iptables 网络防火墙: 核心转发配置:/proc/sys/net/ipv4/ip_forward /etc/sysctl.conf net.ipv4.ip_forward=1 nat: SNAT:只修改请求报文的源地址 DNAT:只修改请求报文的目标地址
nat表: PREROUTING: DNAT OUTPUT POSTROUTING: SNAT
源地址转换 iptables -t nat -A POSTROUTING -s local_net ! -d local_net -j SNAT --to-source public_ip 公网ip固定 iptables -t nat -A POSTROUTING -s local_net ! -d local_net -j MASQUERADE 公网ip不固定
目标地址转换 iptables -t nat -A POSTROUTING -d public_ip -p tcp|udp --dport PORT -j DNAT --to-destination local_ip:port |
本文出自 “Keep simple keep stupid” 博客,请务必保留此出处http://yangzhiheng.blog.51cto.com/11586378/1976723
原文地址:http://yangzhiheng.blog.51cto.com/11586378/1976723