一、详述iptables五链
1.简介
iptables是Linux系统上的防火墙,是一个包过滤型的防火墙,能够根据事先定义好的检查规则对进出本机或者本地网络的报文进行匹配检查,并对于能够被规则匹配的报文作出相应的处理动作。
Linux系统上的防火墙是由iptables/nethilter组成,其中iptables是规则的制定工具,netfilter在内核协议框架中定义了5个卡点位置,并在这5个位置通过钩子函数对进出的数据包进行过滤,从而达到防火墙的功能。iptables工具工作在用户控件,他可以制定一些规则然后送到内核空间,然后结合netfilter的钩子函数及处理方法对数据包进行放行或者拒绝处理。
五链:
netfilter五个钩子对应的图解如下:- prerouting: 流入的数据包进入路由表之前
- input:通过 路由表判断后目的是本机,然后进入本机内部资源
- forward:通过路由表判断后目的地不是本机,然后通过路由转发到其他地方
- output:由本机产生的书记向外部转发
- postrouting:传出的数据包到达网卡出口之前
报文流向:
流入本机:prerouting --> input ==> 用户空间进程;
流出本机:用户空间进程==> output --> postrouting;
转发:prerouting --> forward --> postrouting;
四表:
当这些内置链中拥有着大量的规则,其中肯定包含着不同类型的规则,如过滤Ip或端口的规则、修改报文的规则等等,而iptables把这些具有相同功能的规则作为表而管理存放。不同的规则链中所能包含的规则类型是不一样的,有些链可能可以有地址转换规则,有些链却不能设置。那么就iptables自身内置的四种功能表其所包含的规则能被哪些链所使用,其分类如下:
filter:过滤表,能被INPUT、FORWARD、OUTPUT这三个规则链使用。
nat:网络地址转换表,能被PREROUTING、OUT、POSTROUTING(centos7中还包含着INPUT)使用。
mangle:报文修改表,能被PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING使用。
raw:一般是为了不再让iptables对数据包进行跟踪,提高性能,能被PREROUTING,OUTPUT使用。
除此之外规则链中的规则是链式结构,按理来说执行的时候是有一定的顺序的,但是不同的规则属于不同的表,那么表之间的优先顺序是怎么区分的呢?其实当一个规则链当中包含了四个表filter,nat,mangle,raw时,那么当要执行这个规则链中的规则时,其执行的顺序是raw>mangle>nat>filter的,也就意味着同一个规则链中,表的优先级为:raw>mangle>nat>filter。
二、举例实现iptables多端口匹配、连接追踪、字符串匹配、时间匹配、并发连接限制、速率匹配、报文状态匹配等应用
对于iptables的规则来说,其基本的功能就是根据匹配条件来尝试匹配报文,一旦匹配成功,就按照规则定义的处理动作来处理报文,其命令的使用语法为:
iptables [-t table] COMMAND [chain] [PARAMETERS] [-m matchname [per-match-options]] [-j targetname [per-target-options]]
下面分析其各个字段:
- -t table:raw, mangle, nat, filter(默认)
- COMMAND:
链管理:(PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING)
-N:new, 自定义一条新的规则链(默认链通过引用来生效自定义链)
-X: delete,删除自定义的规则空链,非空自定义链和内置链无法删除
-P:Policy,设置默认策略;无法匹配是做出的处理机制,对filter表中的链而言,
其默认策略有:
ACCEPT:接受
DROP:丢弃
REJECT:拒绝
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
-F:flush,清空指定的规则链,忽略链名时,清空表中所有的链
-Z:zero,置零,将计数器置零
iptables的每条规则都有两个计数器:
(1) 匹配到的报文的个数
(2) 匹配到的所有报文的大小之和
规则管理:
-A:append,追加
-I:insert, 插入,要指明位置,省略时表示第一条
-D:delete,删除;(1) 指明规则序号 (2) 指明规则本身
-R:replace,替换指定链上的指定规则
查看:
-L:list, 列出指定鏈上的所有规则
-n:numberic,以数字格式显示地址和端口号
-v:verbose,详细信息;-vv, -vvv: 更详细的消息
-x:exactly,显示计数器结果的精确值;--line-numbers:显示规则的序号
- chain:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
- 匹配条件:
一、基本匹配条件:无需加载任何模块,由iptables/netfilter自行提供.
[!] -s, --source address[/mask][,...]:检查报文中的源IP地址是否符合此处指定的地址或范围
[!] -d, --destination address[/mask][,...]:检查报文中的目标IP地址是否符合此处指定的地址或范围
[!] -p, --protocol protocol,检查报文中的相关协议
protocol: tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh or "all"{tcp|udp|icmp}
[!] -i, --in-interface name:数据报文流入的接口;只能应用于数据报文流入的环节,只能应用于PREROUTING,INPUT和FORWARD链
[!] -o, --out-interface name:数据报文流出的接口;只能应用于数据报文流出的环节,只能应用于FORWARD、OUTPUT和POSTROUTING链
二、扩展匹配条件: 需要加载扩展模块,方可生效
1.隐式扩展:不需要手动加载扩展模块;因为它们是对协议的扩展,所以,只使用-p指明了协议,就表示已经指明了要扩展的模块,对应的扩展模块如下:
(1)tcp:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围
[!] --tcp-flags mask comp
mask is the flags which we should examine, written as a comma-separated list,例如 SYN,ACK,FIN,RST
comp is a comma-separated list of flags which must be set,例如SYN
例如:“--tcp-flags SYN,ACK,FIN,RST SYN”表示,要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0
[!] --syn:用于匹配第一次握手,相当于”--tcp-flags SYN,ACK,FIN,RST SYN“;
(2)udp
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围
(3)icmp
[!] --icmp-type {type[/code]|typename}
echo-request:8
echo-reply:0
2.显式扩展:必须要手动加载扩展模块, [-m matchname [per-match-options]]
(1)multiport扩展:以离散方式定义多端口匹配;最多指定15个端口
[!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口
[!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口
[!] --ports port[,port|,port:port]...:指明多个端口
(2) iprange扩展:指明连续的ip地址范围(但一般不覆盖整个网络)
[!] --src-range from[-to]:源IP地址
[!] --dst-range from[-to]:目标IP地址
(3)string扩展:对报文中的应用层数据做字符串模式匹配检测
[!] --algo {bm|kmp}:字符串匹配检测算法,bm|kmp是两种字符串检测算法
[!] --string pattern:要检测的字符串模式
[!] --hex-string pattern:以16进制格式检测的字符串模式,
(4)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...]
[!]--kerneltz:使用内核上的时区,而非默认的UTC
(5)connlimit扩展:根据每客户端IP做并发连接数数量匹配
[!]--connlimit-upto n:匹配连接的数量小于等于n的
[!]--connlimit-above n:匹配连接的数量大于n的
(6)limit扩展:基于收发报文的速率做匹配
[!] --limit rate[/second|/minute|/hour|/day] 速率
[!] --limit-burst number 限制连接的数量
(7)state扩展:根据”连接追踪机制“去检查连接的状态
[!] --state state
conntrack机制:追踪本机上的请求和响应之间的关系;状态有如下几种:
NEW:新发出请求,连接追踪模板中不存在此连接的相关信息而将其识别为第一次发出的请求
ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信状态
RELATED:相关联的连接;如ftp协议中的数据连接与命令连接之间的关系
INVALID:无效的连接
UNTRACKED:未进行追踪的连接
- 处理动作:-j targetname [per-target-options]
ACCEPT:接受
DROP:丢弃,不返回数据
REJECT:拒绝,返回相应数据
RETURN:返回调用链
REDIRECT:端口重定向
LOG:记录日志
MARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装
...
自定义链名:调用自定义链作为处理动作
例子:
##查看iptable配置
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 39 packets, 2602 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 23 packets, 2171 bytes)
pkts bytes target prot opt in out source destination
##多端口匹配
[root@wujunjie ~]# iptables -I INPUT 1 -d 192.168.32.128 -p tcp -m multiport --dports 21,22,80,8080,443 -j ACCEPT
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 428 ACCEPT tcp -- * * 0.0.0.0/0 192.168.32.128 multiport dports 21,22,80,8080,443
#在INPUT链中第一条位置插入一条规则:
目标地址为192.168.32.128的协议为tcp;并且目标端口号分别为:21,22,80,8080,443选择接受
##连接追踪
[root@wujunjie ~]# iptables -A INPUT -d 192.168.32.128 -p tcp -m multiport --dports 21,22,80 -m state --state INVALID -j REJECT
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 6 packets, 428 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 0.0.0.0/0 192.168.32.128 multiport dports 21,22,80 state INVALID reject-with icmp-port-unreachable
#在INPUT链中新增一条规则:
目标IP为192.168.32.128,tcp协议,端口为21,22,80
连接状态为无效的连接时选择拒绝.
##字符串匹配
[root@wujunjie ~]# iptables -A OUTPUT -s 192.168.32.128 -d 192.168.32.0/16 -p tcp --sport 80 -m string --algo bm --string "sex" -j REJECT
[root@wujunjie ~]# iptables -L -nv
Chain OUTPUT (policy ACCEPT 4 packets, 464 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 192.168.32.128 192.168.32.0/24 tcp spt:80 STRING match "sex" ALGO name bm TO 65535 reject-with icmp-port-unreachable
#在OUTPUT链中新增一条规则:
来源IP为192.168.32.128,目标IP为192.168.32.0/24网段.tcp协议,80端口
匹配的字符串包含"sex"则选择拒绝
##时间匹配
[root@wujunjie ~]# iptables -A INPUT -s 192.168.32.0/24 -d 192.168.32.128 -p tcp --dport 80 -m time --timestart 00:30 --timestop 12:30 --weekdays Mon,Sun -j DROP
[root@wujunjie ~]# iptables -L -nv
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP tcp -- * * 192.168.32.0/24 192.168.32.128 tcp dpt:80 TIME from 00:30:00 to 12:30:00 on Mon,Sun UTC
#在INPUT链中新增一条规则:
来源IP为192.168.32.0/24网段,目标IP为192.168.32.128,tcp协议80端口
星期一和星期日的00:30-12:30时间段内选择丢弃
##并发连接限制
[root@wujunjie ~]# iptables -A INPUT -d 192.168.32.128 -p tcp --dport 21 -m connlimit --connlimit-above 2 -j REJECT
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 0.0.0.0/0 192.168.32.128 tcp dpt:21 #conn src/32 > 2 reject-with icmp-port-unreachable
#在INPUT新增一条规则:
目标IP为192.168.32.128,tcp协议,端口21
并发连接数大于2时选择拒绝
##速率匹配
[root@wujunjie ~]# iptables -I INPUT -d 192.168.32.128 -p icmp --icmp-type 8 -m limit --limit 5/minute --limit-burst 3 -j ACCEPT
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT icmp -- * * 0.0.0.0/0 192.168.32.128 icmptype 8 limit: avg 5/min burst 3
#在INPUT链插入一条规则:
目标IP为192.168.32.128 ICMP协议,类型是8,
链接速率5/min,最大连接数(在5/min速率下的连接数)为3,选择接受
##报文状态匹配
[root@wujunjie ~]# iptables -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
[root@wujunjie ~]# iptables -L -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 flags:0x3F/0x02 reject-with icmp-port-unreachable
# -m tcp使用tcp扩展模块,
--tcp-flags:要匹配的报文
SYN,ACK,FIN,RST,URG,PSH:报文状态的列表,可以写成ALL.
SYN :列表中的SYN标志必须为1其余的必须全部为0
三、举例实现iptables之SNAT源地址修改及DNAT目标地址修改和PNAT端口修改等应用
SNAT:源地址转换,代理内部客户端访问外部网络
修改ip报文中的源IP地址;只能用在POSTROUTING、INPUT链上、自定义链(但也只能被POSTROUTING、INPUT链调用)上;
- 使用场景:
让本地网络中的主机可使用统一地址与外部通信,从而实现地址伪装;即转换客户端地址,一般代理本地私网主机到互联网;
请求:由内网主机发起,修改源IP,如果修改则由管理员定义;
响应:修改目标IP,由nat自动根据会话表中追踪机制实现相应修改; - 原地址转换:
本地内网用户访问外网服务器时,在本地网关上进行原地址转换,把内网用户请求报文中原地址转换为网关的公网地址与外界通信,外网服务器响应内网用户时,进行目标地址转换,只不过响应报文中不需要用户参与,网关根据追踪会话表自动完成目标地址转换,转发给内网用户;
DNAT:目标地址转换,将内部服务器发布至外部网络
修改ip报文中的目标IP地址;仅用在PREROUTING和OUTPUT链上;
- 使用场景:让本地网络中的服务器使用统一的地址向外提供服务,但隐藏了自己的真实地址,还可实现负载均衡;即转换服务器端地址,把本地私网主机放在互联网上当服务器;
请求:由外网主机发起,修改其目标地址,由管理员定义;
响应:修改原地址,但有nat自动根据会话表中的追踪机制实现对应修改; - 目标地址转换:
外网用户访问本地内网中向外提供服务的主机时,本地网关会进行目标地址转换,把目标地址改为内网的服务器地址,内网服务器响应外网用户时,在本地网关上完成源地址转换,只不过响应报文中不需要用户参与,根据追踪会话表自动完成源地址转换;
PNAT:端口地址转换
实现端口转换,而REDIRECT能专门实现端口转换机制,而DNAT完成目标端口转换,响应报文时能自动进行源端口转换;
实验:按下图配置网关主机实现客户端访问服务器,演示网络防火墙功能
1.按上图配置好三台虚拟机,并按图中ip配置好,开启网关主机的核心转发功能
[root@www ~]# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
##客户端添加默认路由,网关指向192.168.0.128
[root@wujunjie6 ~]# route add default gw 192.168.0.128
[root@wujunjie6 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 * 255.255.255.0 U 1 0 0 eth0
default 192.168.0.128 0.0.0.0 UG 0 0 0 eth0
##服务端添加路由,去往192.168.0.0/24网段的网关指向192.168.32.132
[root@wujunjie ~]# route add -net 192.168.0.0/24 gw 192.168.32.132
[root@wujunjie ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 100 0 0 ens33
192.168.0.0 192.168.32.132 255.255.255.0 UG 0 0 0 ens33
192.168.32.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
##测试客户端可以访问服务端web服务
[root@wujunjie6 ~]# curl 192.168.32.128
1231312
2.实现SNAT
#NAT主机清空防火墙
[root@www ~]# iptables -F
#客户端隐藏ip地址访问服务端(SNAT),在NAT主机添加以下规则
[root@www ~]# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 192.168.32.132
#测试客户端访问服务端
[root@wujunjie6 ~]# curl 192.168.32.128
1231312
#在NAT主机抓包分析看出客户端ip被隐藏,转换成192.168.32.132
[root@www ~]# tcpdump -i ens33 -nn tcp port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 65535 bytes
15:16:12.084982 IP 192.168.32.132.35944 > 192.168.32.128.80: Flags [S], seq 1164040495, win 14600, options [mss 1460,sackOK,TS val 3334227 ecr 0,nop,wscale 6], length 0
15:16:12.085625 IP 192.168.32.128.80 > 192.168.32.132.35944: Flags [S.], seq 1545332595, ack 1164040496, win 28960, options [mss 1460,sackOK,TS val 3491777 ecr 3334227,nop,wscale 7], length 0
15:16:12.086207 IP 192.168.32.132.35944 > 192.168.32.128.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 3334228 ecr 3491777], length 0
#在服务端抓包分析,显示原地址为192.168.32.132
[root@wujunjie ~]# tcpdump -i ens33 -nn tcp port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 65535 bytes
15:17:12.161234 IP 192.168.32.132.35946 > 192.168.32.128.80: Flags [S], seq 2466142336, win 14600, options [mss 1460,sackOK,TS val 3373289 ecr 0,nop,wscale 6], length 0
15:17:12.161360 IP 192.168.32.128.80 > 192.168.32.132.35946: Flags [S.], seq 3318338433, ack 2466142337, win 28960, options [mss 1460,sackOK,TS val 3530840 ecr 3373289,nop,wscale 7], length 0
15:17:12.163915 IP 192.168.32.132.35946 > 192.168.32.128.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 3373292 ecr 3530840], length 0
3.实现DNAT
#在nat主机上清空nat表上所有规则
[root@www ~]# iptables -t nat -F
#使用DNAT目标地址转换实现服务端地址隐藏,在nat主机添加以下规则
[root@www ~]# iptables -t nat -A PREROUTING -d 192.168.0.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.32.128
#检查NAT主机未开放80端口
[root@www ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:111 *:*
LISTEN 0 5 192.168.122.1:53 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 128 127.0.0.1:6011 *:*
LISTEN 0 128 :::111 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 128 ::1:6010 :::*
LISTEN 0 128 ::1:6011 :::*
#测试客户端访问服务端
[root@wujunjie6 ~]# curl 192.168.0.128
1231312
##在NAT主机抓包分析看出目的ip转换成192.168.32.128
[root@www ~]# tcpdump -i ens33 -nn tcp port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 65535 bytes
16:46:40.017036 IP 192.168.0.129.52202 > 192.168.32.128.80: Flags [S], seq 545915071, win 14600, options [mss 1460,sackOK,TS val 8747652 ecr 0,nop,wscale 6], length 0
16:46:40.017522 IP 192.168.32.128.80 > 192.168.0.129.52202: Flags [S.], seq 3578174836, ack 545915072, win 28960, options [mss 1460,sackOK,TS val 8905188 ecr 8747652,nop,wscale 7], length 0
16:46:40.018382 IP 192.168.0.129.52202 > 192.168.32.128.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 8747653 ecr 8905188], length 0
16:46:40.018577 IP 192.168.0.129.52202 > 192.168.32.128.80: Flags [P.], seq 1:175, ack 1, win 229, options [nop,nop,TS val 8747654 ecr 8905188], length 174
16:46:40.019309 IP 192.168.32.128.80 > 192.168.0.129.52202: Flags [.], ack 175, win 235, options [nop,nop,TS val 8905189 ecr 8747654], length 0
#在客户端抓包分析,显示响应地址来自192.168.0.128,而非192.168.32.128,隐藏了服务端地址
[root@wujunjie6 ~]# tcpdump -i eth0 -nn tcp port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:51:30.171203 IP 192.168.0.129.52204 > 192.168.0.128.80: Flags [S], seq 390783522, win 14600, options [mss 1460,sackOK,TS val 9029300 ecr 0,nop,wscale 6], length 0
16:51:30.174714 IP 192.168.0.128.80 > 192.168.0.129.52204: Flags [S.], seq 157251816, ack 390783523, win 28960, options [mss 1460,sackOK,TS val 9186835 ecr 9029300,nop,wscale 7], length 0
16:51:30.174767 IP 192.168.0.129.52204 > 192.168.0.128.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 9029304 ecr 9186835], length 0
4.实现PNAT
#将服务器端口监听8080端口确保客户端通过端口转换能被访问
[root@wujunjie ~]# vim /etc/httpd/conf/httpd.conf
Listen 8080
[root@wujunjie ~]# systemctl restart httpd
#修改NAT主机第一条PREROUTING规则
[root@www ~]# iptables -t nat -R PREROUTING 1 -d 192.168.0.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.32.128:8080
#客户端仍然访问192.168.0.128的80端口,结果仍可以服务端
[root@wujunjie6 ~]# curl 192.168.0.128
1231312
#在NAT主机抓包分析,看出目标地址端口被转换成192.168.32.128:8080
[root@www ~]# tcpdump -i ens33 -nn tcp port 8080
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 65535 bytes
08:43:07.345164 IP 192.168.0.129.56696 > 192.168.32.128.8080: Flags [S], seq 2887035108, win 14600, options [mss 1460,sackOK,TS val 996761 ecr 0,nop,wscale 6], length 0
08:43:07.345521 IP 192.168.32.128.8080 > 192.168.0.129.56696: Flags [S.], seq 3239447526, ack 2887035109, win 28960, options [mss 1460,sackOK,TS val 997210 ecr 996761,nop,wscale 7], length 0
08:43:07.346180 IP 192.168.0.129.56696 > 192.168.32.128.8080: Flags [.], ack 1, win 229, options [nop,nop,TS val 996762 ecr 997210], length 0
四、简述sudo安全切换工具,及详细讲解visudoer
1.简介
sudo命令Linux系统管理指令,是允许系统管理员让普通用户执行一些或全部的root命令的一个工具。sudo命令提供了丰富的日志,详细记录了每个用户干了什么,并且使用时间戳来对用户通过了sudo执行认证的有效期进行限制。sudo命令相关信息存放在/etc/sudoers文件中,执行sudo命令的用户需提前将自己用户名及可执行命令等相关信息添加到该文件当中。sudo命令的执行无需知道超级管理员密码,因此部分系统甚至利用sudo来使得一般用户取代root作为管理账号使用。
2.sudo命令
sudo [options] COMMAND
-u username:以指定用户的身份运行命令;
-l:列出用户能以sudo方式执行的所有命令;
-k:清除(密码)此前缓存用户成功认证的结果;
3.visudo命令
sudo命令的配置文件为/etc/sudoers文件,里面记录了sudo用户的权限信息即分组信息。/etc/sudoers文件只能通过visudo命令进行编辑修改,为的是防止有多个用户同时修改此文件,并且进行相应的语法检查。默认情况下,visudoers是不会保存有语法错误的配置文件,但它会提示相应的错误,并询问如何处理。
- 授权文件有两类内容:
(1)别名的定义,即为变量;
(2)授权项,可使用别名进行授权,要先定义别名; - 授权项(每一行一个授权项)格式:
who where=(runas) commands
#谁 通过哪些主机=(以谁的身份) 运行什么命令
who:用户
username:单个用户;
#uid:单个用户的ID号;
%groupname:组内的所有用户;
%#gid:组内的所有用户;
user_alias:用户别名;
where:主机地址
ip或hostname:单个主机;
NetAddr:网络地址;支持多种表示格式;
host_alias:主机别名;
whom(ranas):以指定用户身份运行
username:单个用户;
#uid:单个用户的ID号;
runas_alias:以指定用户身份运行;
commands:命令
command:单个命令;
directory:指定目录内的所有应用程序;
sudoedit:特殊权限,可编辑sudoers文件,可用于向其它用户授予sudo权限;
示例:
fedora ALL=(root) /usr/sbin/useradd, /usr/sbin/usermod
#fedora:定义的用户
#ALL=(root):指定用户,不写表示所有用户;
#/usr/sbin/useradd, /usr/sbin/usermod 可运行的命令;
- 定义别名的方法:
ALIAS_TYPE NAME=item1,item2,...
ALIAS_TYPE:4种,注意书写格式大小写
User_Alias:授权用户别名类型
Host_Alias:主机别名类型
Runas_Alias:作为哪些用户执行的别名类型
Cmnd_Alias:命令别名类型
示例:
User_Alias NETADMIN=jeck,magedu
#用NETADMIN来表示jeck,magedu这些用户
Cmnd_Alias NETCMND=ip, ifconfig, route
#用NETCMND这个别名去代表ip, ifconfig, route
NETADMIN localhost=(root) NETCMND
#这个NETADMIN用户别名里的用户在本地主机中可以root的身份执行NETCMND这个命令别名里面的命令
4.综合示例
[root@wujunjie ~]# visudo
##添加以下命令
Cmnd_Alias ADMINCOMMANDS1=/usr/bin/passwd,!/usr/bin/passwd root
#定义命令别名组2
Cmnd_Alias ADMINCOMMANDS2=/usr/sbin/shutdown,/usr/sbin/reboot
#定义用户别名组
User_Alias ADMINUSERS=wujunjie
#定义sudo命令授权规则
ADMINUSERS ALL=(root) NOPASSWD:ADMINCOMMANDS1,PASSWD:ADMINCOMMANDS2
##验证
[wujunjie@wujunjie ~]$ sudo -l #列出用户能以sudo方式执行的所有命令;
Matching Defaults entries for wujunjie on this host: #匹配此主机上 wujunjie的默认条目:
!visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2
QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET
XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User wujunjie may run the following commands on this host: #用户 wujunjie 可以在该主机上运行以下命令:
(root) NOPASSWD: /usr/bin/passwd, !/usr/bin/passwd root, (root) PASSWD: /usr/sbin/shutdown, /usr/sbin/reboot
[root@wujunjie ~]# su - wujunjie
Last login: Fri Nov 2 09:00:39 CST 2018 on pts/0
[wujunjie@wujunjie ~]$ sudo passwd root
Sorry, user wujunjie is not allowed to execute '/bin/passwd root' as root on wujunjie.
#提示无法以wujunjie用户无法以root用户的身份执行/bin/passwd root
[wujunjie@wujunjie ~]$ sudo passwd www
Changing password for user www.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
#更改www密码用户成功
[wujunjie@wujunjie ~]$ sudo shutdown -r now
[sudo] password for wujunjie:
#以root身份重启提示需要密码