iptables防火墙可以用于创建过滤(filter)与NAT规则。所有Linux发行版都能使用iptables,因此理解如何配置iptables将会帮助你更有效地管理Linux防火墙。如果你是第一次接触iptables,你会觉得它很复杂,但是一旦你理解iptables的工作原理,你会发现其实它很简单,接下来我们从基础给大家解析iptables防火墙的应用:
第一部分:初识网络安全及防火墙原理
1、Linux网络安全模型
(1).防火墙:主要工作在主机或者网络边缘,对进出报文使用定义的规则进行检测过滤,并且由匹配的规则和策略进行处理的一组硬件或软件。也有可能是两者的结合。
1)通常使用的防火墙设备:
硬件防火墙:专门的一台防火墙硬件设备,工作在整个网络入口处。
软件防火墙:工作在主机中TCP/IP协议栈上面的软件(工作在系统内核中)。
2)防火墙工作位置
网络层:工作在网络层,类似路由器,主要拆除物理层和链路层协议,检测IP/TCP/UDP/ICMP网络层协议和传输层协议首部,来进行规制定制。
应用层:工作在应用层,拆除网络层和传输层首部,查看应用层内容。
2. IDS(Intrusion-detection system) 入侵检测系统
HIDS(主机入侵检测系统):OSSEC
NISC(网络入侵检测系统):snort(可以作为网络嗅探器)
Filesystem: 文件系统级别检测入侵检测
3. IPS(入侵防御系统): IDS + Firewall两者联动
4. honeypot:蜜罐系统,用于诱捕黑客,获取证据。
5. 系统安全漏洞扫描工具,进行系统安全评估:Nessus, nmap 等
6. rootkit:直接在系统层植入后门,将无法防护,只能重新安装系统 。
二、 iptables工作机制
1. iptables/netfilter:网络层防火墙,可以链接追踪状态(状态检测), 是一个规则编写工具。规则通过内核中netfilter框架产生作用。
2. 设置iptables防护的五个位置(hook_function 位置)以及允许规则(五链四表):
1) PREROUTING: 主机外报文进入位置,允许的表mangle, nat(目标地址转换,把本机地址转换为真正的目标机地址,通常指响应报文)
2) INPUT:报文进入本机用户空间位置,允许的表filter, mangle
3) OUTPUT:报文从本机用户空间出去的位置,允许filter, mangle, nat
4) FOWARD:报文经过路由并且发觉不是本机决定转发但还不知道从哪个网卡出去,允许filter, mangle
5) POSTROUTING:报文经过路由被转发出去,允许mangle,nat(源地址转换,把原始地址转换为转发主机出口网卡地址)
四表: filter, nat , mangle, raw
五链:PREROUNTING, INPUT, FORWARD, OUTPUT, POSTROUTING
3. 表与链的对应关系
1) filter: INPUT, FORWARD, OUTPUT
2) nat: PREROUTING, OUTPUT, POSTROUTING
3) mangle: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
4) raw:
4. 规则:匹配到后的处理机制
1) 通: 默认为堵, 只对规则匹配到的进行开放
2) 堵: 默认为通, 只对规则匹配到的堵
5. 网络层和传输层协议检查内容
1) IP:
SIP: 源IP
DIP: 目标IP
2) TCP:
SPORT: 源端口
DPORT:目标端口
Flags:标识位
3) ICMP: ICMP-TYPE (ping 命令协议)
6. 关于TCP协议标识位以及有限状态机图解
TCP协议通信时,伴随着标识位的相互传输,以及在各个状态之间的转换。这些标识位将成为规则检测的内容。
7. 扩展检测机制:
1)time(根据时间),
2)应用层协议(如qq)
3)string 敏感字符
4)state(connection-tracking) 连接追踪
8. 匹配到的报文处理机制:
1) DROP: 默默的丢弃
2) REJECT:拒绝,不建议使用,容易拉仇恨
3) ACCEPT:接受
4) SNAT: 源地址转换
5) DNAT:目标地址转换
6) REDIRECT: 端口映射
7) LOG:日志
8) RETURN: 返回
第二部分:iptables工具详解及应用
1.iptables:从这里开始:
1)删除现有规制
iptables [-t table] {-F|-L|-Z} [chain [runlenum]] [options…] :查看修改规则命令组
-F : 清空链中的规则,规则具有编号,从上到下,从1开始 -L: list,列出表中的所有规则 -n: 数字格式显示IP和Port -v: 详细格式显示 pkts bytes target prot opt in out source destination 每个字段的含义: pkts: packets, 被本规则所匹配到的报文的个数; bytes: 被本规则所匹配到的所有报文的大小之和,会执行单位换算; target: 目标,即处理机制; prot: 协议,一般为{TCP|UDP|ICMP}; opt: 可选项 in: 数据包的流入接口; out: 数据包的流出接口; source: 源地址; destination: 目标地址; -X: exactly, 精确值,不执行单位换算 --line-number: 显示各规则的行号 -Z: 匹配数量清零
举例:
[[email protected] ~]# iptables -F 或 [[email protected] ~]# iptables --flush [[email protected] ~]# iptables -L -n -v [[email protected] ~]# iptables -L -n -v --line-number
2)设置默认链策略(也可以说是设置控制机制策略)
iptables [-t table] -P chain target :为链指定默认策略,指定默认规则
iptables的filter表中有三种链:INPUT, FORWARD和OUTPUT。默认的链策略是ACCEPT,你可以将它们设置成DROP。
[[email protected] ~]# iptables -P INPUT DROP [[email protected] ~]# iptables -P FORWARD DROP [[email protected] ~]# iptables -P OUTPUT DROP 如果以上链没有任何规则,你需要明白,这样做会屏蔽所有输入、输出网卡的数据包,除非你明确指定哪些数据包可以通过网卡(默认指定的表是:filter)
3)iptables 查看链表,创建链表,类命令
(1)iptables [-t table] -N chain : 创建一条自定义规则的链
[[email protected] ~]# iptables -t filter -N clean_in 注:自定义链在没有被引用之前是不起作用的,必须引用才生效。
(2)iptables [-t filter] -X [chain] : 删除一个自定义链
[[email protected] ~]# iptables -t filter -X clean_in
(3)iptables [-t table] -E old-chain-name new-chain-name :为一个自定义链修改名字
[[email protected] ~]# iptables -t filter -E clean_in clean_in_httpd
4)iptables 添加和编辑规则相关命令
(1)iptables [-t table] {-A | -D} chain rule-specification
-A: append, 附加一条规则 -D chain [rulenum] rule-specification: 删除一条规则 -I chain [rulenum] rule-specification : 修改规则 -R chain [rulenum] rule-specification:替换指定规则 -S chain [rulenum] 只显示链上的规则添加 rule-specification格式 : 匹配条件 -j 处理机制 通用匹配条件: -s: 匹配原地址,可以IP,也可以是网络地址,可以使用!操作符取反,!192.168.0.0/16; -s 相当于 --src 或 --source -d: 匹配目标地址 -p: 匹配协议,通常只使用{TCP|UDP|ICMP}三者之一; -i:数据报文流入的接口:通常用于INPUT, FORWARD, PREROUTING -o:流出接口,通常只用于OUTPUT,FORWARD,和POSTROUTING -j target RETURN:返回调用链 ACCEPT: 放行 举例: 1. 允许172.16.0.0/16网段ping通,当前172.16.100.7主机 # iptables -t filter -A INPUT -i eth0 -s 172.16.0.0/16 -d 172.16.100.7/16 -p ICMP -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -p ICMP -j ACCEPT 结果; ICMP INPUT和OUTPUT链都有匹配到 Chain INPUT (policy ACCEPT 168 packets, 11348 bytes) pkts bytes target prot opt in out source destination 13 876 ACCEPT icmp -- eth0 * 172.16.0.0/16 172.16.0.0/16 Chain OUTPUT (policy ACCEPT 126 packets, 18488 bytes) pkts bytes target prot opt in out source destination 13 876 ACCEPT icmp -- * * 172.16.100.7 172.16.0.0/16
(2)iptables规则保存
# service iptables save: 默认会被保存在/etc/sysconfig/iptables文件中,start的时候也会从这里读取 下面两种方式也可以存取 # iptables-save > /path/to/some_rulefile # iptables-restore < /path/from/some_rulefile
5)iptables隐含扩展配置
(1)tcp协议的隐含扩展
-p tcp --dport m[-n]:匹配的目标端口,可以使连续的多个端口 --sport: 源端口 --tcp-flags rst,syn,ack,fin syn : 空格之前表示匹配哪些标识位,空格之后是哪些标识位为1 --syn:单独匹配某一项标识位 所有使用的值: URG, PSH, RST, SYN, ACK, FIN,ALL, NONE 举例: 释放所有172.16.0.0/16网段的ssh服务 # iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7/16 -p tcp --dport 22 -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7/16 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT # iptables -t filter -P INPUT DROP # iptables -t filter -P OUTPUT DROP 结果: ssh链接不会断开,可以看见进出都有报文匹配,而ping报文会被drop Chain INPUT (policy DROP 19 packets, 1464 bytes) pkts bytes target prot opt in out source destination 379 26864 ACCEPT tcp -- * * 172.16.0.0/16 172.16.0.0/16 tcp dpt:22 Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 113 10316 ACCEPT tcp -- * * 172.16.100.7 172.16.0.0/16 tcp spt:22
(2)udp协议的隐含扩展
-p udp : udp报文相关的拓展匹配 --dport --sport 放行本机的tftp服务 # iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7/16 -p udp --dport 69 -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7/16 -d 172.16.0.0/16 -p udp --sport 69 -j ACCEPT 放行本机DNS服务 # iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7/16 -p udp --dport 53 -j ACCEPT # iptables -t filter -A INPUT -s 172.16.100.7/16 -d 172.16.0.0/16 -p udp --sport 53 -j ACCEPT
(3)icmp 协议的隐含扩展
-P icmp : icmp协议相关拓展 --icmp-type 8: ping 请求 0:ping 响应 以上响应代码如不足,可参考我的博客:ICMP-type对应表 释放本机的ping请求 # iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7/16 -p icmp --icmp-type 8 # iptables -t filter -A INPUT -s 172.16.100.7/16 -d 1172.16.0.0/16 -p icmp --icmp-type 0
6)显示扩展:必须指定的扩展模块
-m 扩展模块名称 –专用选项1 –专用选项2
(1)multiport:多端口匹配模块,一次可以指定最多15离散端口。
-m multiport --source-ports,--sports port[,port|,port:port] : 指定源端口 --destination-port, --dports: 指定目标端口 --ports: 指定源端口和目标端口 举例: 开放本机所在网络,ssh和web服务。 # iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7/16 -p tcp -m multiport --dport 22,80 -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7/16 -d 172.16.0.0/16 -p tcp -m multiport --sport 22.80 -j ACCEPT
(2) iprange:匹配ip地址范围
-m iprange: [!] --src-range from[-to] [!] --dst-range from[-to] 举例: 开放本机ssh给172.16.100.1-172.16.100.120访问 # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 22 -m iprange --src-range 172.16.100.1-172.16.100.120 -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7 -p tcp --sport 22 -m iprange --dst-range 172.16.100.1-172.16.100.120 -j ACCEPT
(3)time:指定时间范围匹配
-m time --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]] --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]] --timestart hh:mm[:ss] --timestop hh:mm[:ss] [!] --weekdays day[,day...] 举例,在工作日时间开放samba(tcp, 901端口) 服务 # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 --timestop 18:00:00 -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7 -p tcp --sport 901 -j ACCEPT
(4)string:字符串过滤
-m string --algo {bm|kmp}:字符匹配查找时使用的算法 --string "STRING" : 要查找的字符串 --hex-string "HEX-STRING": 要查找的字符,先编码成16进制格式,可以提高查询效率 举例: 禁止本机的web报文,包含‘fuck’字符 # iptables -t filter -A OUTPUT -s 172.16.100.7 -p tcp --dport 80 -j ACCEPT # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --sport 80 -m string --algo bm --string "fuck" -j DROP
(5)connlimit:每个ip对指定服务的最大并发链接数
-m connlimit --connlimit-above [0]:此选项用于,坚定某个IP是正常访问还是发起攻击
(6)limit:报文速率控制
--limit #/[/second|/minute|/hour|/day] 限制速率 --limit-burst # 峰值速率 举例: 防御DDos攻击 # iptables -t filter -I INPUT -d 172.16.100.7 -p icmp --icmp-type 8 -m limit --limit 2/second --limit-burst 10 -j ACCEPT 在另一台主机上,使用hping3命令发起攻击 # hping -1 -c 10000 -i u1 172.16.100.7 结果: Chain INPUT (policy DROP 9727 packets, 272K bytes) pkts bytes target prot opt in out source destination 11 308 ACCEPT icmp -- * * 0.0.0.0/0 172.16.100.7 icmp type 8 limit: avg 2/sec burst 10 可以看到只有11个报文通过,其他的icmp请求全被drop了
(7)state:状态匹配
-m state --state NEW:新建连接 ESTABLISHED:已经建立的连接 RELATED:与现有连接有关联的连接 INVALID: 异常连接 状态匹配是由ip_conntrack, nf_conntrack两个模块实现的。 # cat /proc/sys/net/nf_conntrack_max 定义了连接追踪的最大值,因此,建议按需调大此值; # cat /proc/net/nf_conntrack 记录了当前追踪的所有连接 # cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established 记录建立的连接超时时间 法则: 1. 对于进入的状态为ESTABLISHED都应该放行; 2. 对于出去的状态为ESTABLISHED都应该放行; 3. 严格检查进入的状态为NEW的连接; 4. 所有状态为INVALIED都应该拒绝; 举例:放行工作于被动模式下的FTP服务 1. 确保iptables加载ftp协议支持的模块:ip_nat_ftp, ip_conntrack_ftp 编辑/etc/sysconfig/iptables-config文件,定义如下参数: IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp" 2. 开放命令连接端口,tcp 21号端口 # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT 3. 放行请求报文的RELATED和ESTABLISHED状态,放行响应报文的ESTABLISHED状态; # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7 -p tcp -m state --state ESTABLISHED -j ACCEPT 如果只开放命令连接的话,依然可以进行身份认证,但是无法下载,或者查看目录 启动服务时的最后一个服务通常是/etc/rc.d/rc.local (/etc/rc.local),这事实上是一个脚本,但凡写在此脚本中的命令或脚本调用都在系统运行至此服务被执行
7)实践应用:INPUT和OUTPUT默认策略为DROP的一些实例
1. 限制本地主机的web服务器在周一不允许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不允许访问;web服务器仅允许响应报文离开本机; # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m state --state NEW -m limit --limit 100/second -m time ! --weekdays Mon -j ACCEPT # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT # iptables -t filter -A OUTPUT-s 172.16.100.7 -p tcp --sport 80 -m state --state ESTABLISHED -m string --algo kmp ! --string "admin" -j ACCEPT 2. 在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给172.16.0.0网络中的主机访问;数据下载请求的次数每分钟不得超过5个 # iptables -t filter -R INPUT 2 -d 172.16.100.7 -s 172.16.0.0/16 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 --timestop 18:00:00 -j ACCEPT # iptables -t filter -R INPUT 3 -d 172.16.100.7 -s 172.16.0.0/16 -p tcp -m state --state RELATED -m limit --limit 5/min -j ACCEPT # iptables -t filter -A INPUT -d 172.16.100.7 -s 172.16.0.0/16 -p tcp -m state --state ESTABLISHED -j ACCEPT # iptables -t filter -A OUTPUT -d 172.16.0.0/16 -s 172.16.100.7 -p tcp -m state --state ESTABLISHED -j ACCEPT 3. 开放本机的ssh服务给172.16.100.1-172.16.100.100中的主机,新请求建立的速率一分钟不得超过2个;仅允许响应报文通过其服务端口离开本机; # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 22 -m state --state NEW -m iprange --src-range 172.16.100.1-172.16.100.100 -m limit --limit 2/min -j ACCEPT # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --dport 22 -m state --state ESTABLISHED -m iprange --src-range 172.16.100.1-172.16.100.100 -j ACCEPT # iptables -t filter -A OUTPUT -s 172.16.100.7 -p tcp --sport 22 -m iprange --dst-range 172.16.100.1-172.16.100.100 -m state --state ESTABLISHED -j ACCEPT 4. 拒绝TCP标志位全部为1及全部为0的报文访问本机; # iptables -t filter -A INPUT -d 172.16.100.7 -p tcp --tcp-flags ALL ALL -j DROP
第三部分:iptables实现网络防火墙配置解析
1)FORWARD 链限定本机路由功能
对于Linux主机来说,设定/proc/sys/net/ipv4/ip_forward的值为1,即为开启了路由功能;
设置方法:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# sysctl -w net.ipv4.ip_forward=1
如果对于转发进行限定,需要在FORWARD链上面进行限定规则。
举例: 四台主机,vm1,vm2,vm3 vm1: eth0:192.168.56.12(内网) GATEWAY:192.168.56.11 vm2: eth0:172.16.100.7 eth1:192.168.56.11(内网) vm3:eth0:172.16.100.8 GATEWAY:172.16.100.7 物理机:172.16.0.1 (1)允许vm1和vm3之间的ping 请求 (2)允许vm3访问vm1的web服务 (3)允许vm3访问vm1的ssh服务 ## 设置vm1主机 # ifconfig eth0 192.168.56.12/24 up # route add default gw 192.168.56.11 ## 设置vm3主机 # ifconfig eth0 172.16.100.8/16 up # route add default gw 172.16.100.7 ## 设置vm2主机 # ifconfig eth1 192.168.56.11/24 up # echo 1 /proc/sys/net/ipv4/ip_forward # iptables -P FORWARD DROP # iptables -t filter -A FORWARD -s 192.168.56.12 -d 172.16.100.8 -p icmp -j ACCEPT # iptables -t filter -A FORWARD -s 172.16.100.8 -d 192.168.56.12 -p icmp -j ACCEPT # iptables -t filter -A FORWARD -s 172.16.0.0/16 -d 192.168.56.12 -p tcp --dport 80 -j ACCEPT # iptables -t filter -A FORWARD -s 192.168.56.12 -d 172.16.0.0/16 -p tcp --sport 80 -j ACCEPT # iptables -t filter -A FORWARD -s 172.16.0.0/16 -d 192.168.56.12 -p tcp --dport 22 -j ACCEPT # iptables -t filter -A FORWARD -s 192.168.56.12 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT (优化web:80 ssh:22转发规则 # iptables -t filter -A FORWARD -m state --state ESTABLISHED -j ACCEPT # iptables -t filter -A FORWARD -d 192.168.56.12 -p tcp -m multiport --dport 22,80 -m state --state NEW -j ACCEPT ) 加入ssh转发规则后可以在物理机上添加路由表测试: # route add 192.168.56.0 mask 255.255.255.0 172.16.100.7 # ssh 192.168.56.12 --连接成功说明转发生效
2)NAT(过载技术)地址转换相关应用
Basic NAT: 静态NAT;地址端口池子
内部主机都需要外部主机地址池中的一个地址
NAPT:动态NAT,网络地址端口转换;外部主机端口使用一个地址,但是选择一个动态端口映射,建立一个会话表。
使用命令: iptables基于SNAT和DNAT这两个目标实现地址转换技术; -j SNAT --to-source SIP 规则添加:POSTROUTING链 -j MASQUERADE : 地址伪装,无需知道原地址是什么,自动找到可以使用的互联网地址,拨号上网连接时(或IP不固定情况下)可以使用。 -j DNAT --to-destination DIP[:PORT] 支持端口映射
所有nat地址转换,如果限定访问内容,可以在FORWARD链上面做过滤限定
(1)源地址转换SNAT:用于让内网主机访问互联网
例子: vm1:eth0:192.168.56.12 模拟内网 vm2:eth0:172.16.100.7 eht1:192.168.56.11 vm3:eth0172.16.100.8 模拟外网 开通使内网通过SNAT访问外网服务器。 ## 内网主机vm1设置路由 # route add default gw 192.168.56.11 ## 中间主机vm2 # iptables -P FORWARD ACCEPT # iptables -t nat -A POSTROUTING -d 192.168.56.0/24 -j SNAT --to-source 172.16.100.7 或 # # iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j SNAT --to-source 192.168.56.11
(3)目标地址转换DNAT:让互联网上主机访问本地内网中的某服务器上的服务(发布)
例子: vm1: eth0:192.168.56.12 模拟内网 vm2: eth0:172.16.100.7 eht1:192.168.56.11 vm3:eth0:172.16.100.8 模拟外网 开通使内网通过DNAT使得外网访问内网主机web服务器。 ## 内网vm1服务器需要路由指向vm2内网地址,否则请求无法返回 # route add default gw 192.168.56.11 ## 外网vm3需要可以向vm2外网地址通信 # route add default gw 172.25.100.7 ## vm2主机设置目标地址转换条目 # iptables -t nat -A PREROUTING -d 172.16.100.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.56.12 这样外网地址主机发出访问到中间主机,请求会被转发到内网主机。 使用外网直接访问 web服务。
2)FORWARD链上做内容过滤及相关限定:
案例1:限制172.16.100.8转发及主机所有请求:
# iptables -t filter -A FORWARD -s 172.16.100.8 -j REJECT
案例2:禁止访问带有"samlee"关键字的内容的请求
访问内容限制之前,如下图所示:
添加规则限制访问带有samlee关键字的内容:
# iptables -t filter -A FORWARD -d 172.16.0.0/16 -p tcp --sport 80 -m string --algo kmp --string "samlee" -j REJECT
规则生效就无法访问了:
访问不带限制关键字的内容,是可以正常访问的:
第四部分:iptables实现七层访问过滤
为了让iptables支持layer7识别应用层协议,我们需要对内核中的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行。它将两个文件的上下文,合并显示在一起,所以叫做"合并格式"。每一行最前面的标志位,空表示无变动,减号表示第一个文件删除的行,
加号表示第二个文件新增的行。
尽管并没有指定patch和diff的关系,但通常patch都使用diff的结果来完成打补丁的工作,这和patch本身支持多种diff输出文件格式有很大关系。patch通过读入patch命令文件(可以从标准输入),对目标文件进行修改。通常先用diff命令比较新老版本,patch命令文件则采用diff的输出文件,从而保持原版本与新版本一致。
patch的标准格式为
patch [options] [originalfile] [patchfile]
如果patchfile为空则从标准输入读取patchfile内容;如果originalfile也为空,则从patchfile(肯定来自标准输入)中读取需要打补丁的文件名。因此,如果需要修改的是目录,一般都必须在patchfile中记录目录下的各个文件名。绝大多数情况下,patch都用以下这种简单的方式使用:
patch -p[num] < patchfile
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的文件。
一、为单个文件进行补丁操作
1、建立测试文件oldfile、newfile
[[email protected] ~]# cat << EOF >oldfile
> 123456
> abcdef
> 123456
> abcdef
> EOF
[[email protected] ~]# cat << EOF >newfile
> 123456
> samlee
> 123456
> samlee
> EOF
2、使用diff创建补丁file20160418.patch
查询补丁内容:
[[email protected] ~]# diff -uN oldfile newfile
--- oldfile2016-04-18 09:22:13.298495248 +0800
+++ newfile2016-04-18 09:23:53.990500363 +0800
@@ -1,4 +1,4 @@
123456
-abcdef
+samlee
123456
-abcdef
+samlee
使用重定向创建补丁:
[[email protected] ~]# diff -uN oldfile newfile > file20160418.path
给oldfile打补丁:
[[email protected] ~]# patch -p0 < file20160418.path
patching file oldfile
3、可以去除补丁,恢复旧版本
[[email protected] ~]# patch -RE -p0 < file20160418.path
patching file oldfile
二、为多个文件进行补丁操作
1、创建测试文件夹
[[email protected] ~]# mkdir olddir newdir
[[email protected] ~]# echo "olddir" > olddir/file001
[[email protected] ~]# echo "newdir" > newdir/file001
[[email protected] ~]# echo "opensamlee" > olddir/file002
[[email protected] ~]# echo "opensamlee" > newdir/file002
[[email protected] ~]# echo "newdirsamlee" >> newdir/file002
[[email protected] ~]# echo "oldirsamlee" >> olddir/file002
2、创建补丁
[[email protected] ~]# diff -uNr olddir newdir > dir20160418.patch
3、打补丁
[[email protected] ~]# cp dir20160418.patch ./olddir/
[[email protected] ~]# cd olddir/
[[email protected] olddir]# patch -p1 < dir20160418.patch
patching file file001
patching file file002
4、撤销补丁
[[email protected] olddir]# patch -R -p1 < dir20160418.patch
patching file file001
patching file file002
准备好以上的知识之后,下面实现的是利用iptables/netfilter基于layer7实现应用层过滤:
前言
做为企业运维管理来说,对P2P、QQ、酷狗等软件是又爱又恨,大多数公司为了提高工作效率,禁止公司员工登陆QQ、看视频等,在市场上买专门的上网行为管理设备,随便一种都是价格不菲,而使用linux来做网关一样可以禁止qq、酷狗等软件,为实现此功能就需要为iptables/netfilter添加layer7模块,而iptables/netfilter是基于内核的,所以需要重新编译内核。
编译过程
环境介绍
系统环境:CentOS6.5
所需源码包:
iptables-1.4.20.tar.bz2
kernel-2.6.32-431.5.1.el6.src.rpm
l7-protocols-2009-05-28.tar.gz
netfilter-layer7-v2.23.tar.gz
源码包下载地址:
http://vault.centos.org/6.5/updates/Source/SPackages/kernel-2.6.32-431.5.1.el6.src.rpm
http://ftp.netfilter.org/pub/iptables/iptables-1.4.20.tar.bz2
编译内核
解决依赖关系
[[email protected] ~]# yum -y groupinstall "Development Tools" "Server Platform Development"
创建内容编译用户并安装内核
[[email protected] ~]# useradd mockbuild [[email protected] ~]# rpm -ivh kernel-2.6.32-431.5.1.el6.src.rpm warning: kernel-2.6.32-431.5.1.el6.src.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY 1:kernel ########################################### [100%]
将源码解压到指定目录:
为内核打补丁
开始编译
首先选择此项--Networking support
进入此项设定参数--Networking options --->
下拉,选择此项并进入Network packet filtering framework (Netfilter)
进入核心过滤设置Core Netfilter Configuration
启用layer7支持--"layer7" match support
返回第一层,进入此项 Enable loadable module support
取消模块签名校验
对内核的名称进行标记修改
General setup -> Local version - append to kernel release
改名-layer7
返回,进入API加密设置
取消内核签名校验,否则无法编译安装
编译安装
[[email protected] ~]# yum -y install screen #为了防止意外,我们在screen里编译安装 [[email protected] ~]# screen [[email protected] ~]# make [[email protected] ~]# make modules_install [[email protected] ~]# make install screen命令: screen:打开一个新的screen 隐藏:Ctrl+a, d 重新打开隐藏的screen: 显示各screen ID: screen -ls 重新打开: # screen -r Screen_ID
查看一下grub.conf文件,新内核的信息是否写入了:
以新内核启动
编译iptables
解压并打补丁
[[email protected] ~]# tar xf iptables-1.4.20.tar.bz2 [[email protected] ~]# cp netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* iptables-1.4.20/extensions/
备份脚本文件,卸载旧版本
[[email protected] ~]# cp /etc/rc.d/init.d/iptables{,.bak} [[email protected] ~]# cp /etc/sysconfig/iptables-config{,.bak} [[email protected] ~]# rpm -e iptables iptables-ipv6 --nodeps
编译安装iptables
[[email protected] ~]# cd iptables-1.4.20 [[email protected] iptables-1.4.20]# ./configure --prefix=/usr --with-ksource=/usr/src/linux [[email protected] iptables-1.4.20]# make && make install
还原iptables启动脚本及配置文件
[[email protected] ~]# mv /etc/rc.d/init.d/iptables.bak /etc/rc.d/init.d/iptables [[email protected] ~]# mv /etc/sysconfig/iptables-config.bak /etc/sysconfig/iptables-config
修改启动脚本
将所有/sbin/$IPTABLES替换为/usr/sbin/$IPTABLES
查看iptables版本
[[email protected] ~]# iptables -V iptables v1.4.20
为layer7模块提供其所识别的协议的特征码
[[email protected] ~]# tar xf l7-protocols-2009-05-28.tar.gz [[email protected] ~]# cd l7-protocols-2009-05-28 [[email protected] l7-protocols-2009-05-28]# make install mkdir -p /etc/l7-protocols cp -R * /etc/l7-protocols
装载模块
[[email protected] ~]# modprobe nf_conntrack [[email protected] ~]# modprobe xt_layer7 [[email protected] ~]# lsmod | grep xt_layer7 xt_layer7 12087 0 nf_conntrack 79822 5 xt_layer7,xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state
添加内核参数,使之永久有效
[[email protected] ~]# vim /etc/sysctl.conf net.ipv4.ip_forward = 1 net.netfilter.nf_conntrack_acct = 1 [[email protected] ~]# sysctl -p
应用层过滤测试
案例要求
假设内网主机由服务器代理上网,为提高工作效率,禁止内网用户登录QQ
代理服务器:172.16.100.7(可访问网络),192.168.56.11
内网客户端:192.168.56.12/24 gateway:192.168.56.11
网络设置
内网客户端主机网络设置:
设置代理服务器iptables规则,使用SNAT源地址转换,使192.168.56.0/24网段可以上网:
设置规则之前没有匹配到到数据包:
使用客户端访问:
客户端访问之后查询规则匹配到数据包大小及数量:
以上测试说明我们使用源地址转换代理上网配置已经OK了!
安装QQ客户端,试试是否可以登录QQ:
上图测试证明可以登录QQ,下面设置iptables规则禁止QQ登录:
重新登录QQ:
登录失败,看看有没有匹配到报文:
已经有报文被拒绝了,至此iptables基于layer7实现应用层过滤以实现,需要禁止其他程序,请自行添加相应规则
最后我们来说iptables日志选项(log)的使用,实现qq协议数据报文日志记录:
[[email protected] ~]# iptables -I FORWARD -m layer7 --l7proto qq -j LOG --log-prefix "From qq iptables" --给日志添加前缀 [[email protected] ~]# tail -f /var/log/messages
iptables日志使用总结如下:
通常情况下,iptables的默认政策为DROP,不匹配的数据包将被直接丢弃。但在丢弃之前建议把信息记录下来,以使你了解哪些信息没有通过规则,有时可依此判断是否有人在尝试攻击你的服务器。
下面给出一个用来详细记录未匹配规则的数据包的iptables规则:
#记录下未符合规则的udp数据包,然后丢弃之。
#iptables -A INPUT -i $IFACE -p udp -j LOG --log-prefix "IPTABLES UDP-IN: "
#iptables -A INPUT -i $IFACE -p udp -j DROP
#iptables -A OUTPUT -o $IFACE -p udp -j LOG --log-prefix "IPTABLES UDP-OUT: "
#iptables -A OUTPUT -o $IFACE -p udp -j DROP
# 记录下未符合规则的icmp数据包,然后丢弃之。
#iptables -A INPUT -i $IFACE -p icmp -j LOG --log-prefix "IPTABLES ICMP-IN: "
#iptables -A INPUT -i $IFACE -p icmp -j DROP
#iptables -A OUTPUT -o $IFACE -p icmp -j LOG --log-prefix "IPTABLES ICMP-OUT: "
#iptables -A OUTPUT -o $IFACE -p icmp -j DROP
# 记录下未符合规则的tcp数据包,然后丢弃之。
iptables -A INPUT -i $IFACE -p tcp -j LOG --log-prefix "IPTABLES TCP-IN: "
iptables -A INPUT -i $IFACE -p tcp -j DROP
iptables -A OUTPUT -o $IFACE -p tcp -j LOG --log-prefix "IPTABLES TCP-OUT: "
iptables -A OUTPUT -o $IFACE -p tcp -j DROP
# 记录下其他未符合规则的数据包,然后丢弃之。
iptables -A INPUT -i $IFACE -j LOG --log-prefix "IPTABLES PROTOCOL-X-IN: "
iptables -A INPUT -i $IFACE -j DROP
iptables -A OUTPUT -o $IFACE -j LOG --log-prefix "IPTABLES PROTOCOL-X-OUT: "
iptables -A OUTPUT -o $IFACE -j DROP
加上适当的记录日志前缀,可以方便对日志进行分析。 日志通常记录在/var/log/message文件中。如,可以使用 cat /var/log/message | grep "IPTABLES UDP-IN: " 查找出你需要的日志信息。
当然为了防止日志文件过大,你也可以对日志文件记录进行限制,如可以在-j LOG 命令 前加上-m limit --limit 6/h --limit-burst 5
以上就是iptables实践应用所有内容