单包授权认证(SPA,Single Packet Authorization)技术的前身是端口敲门(PK,Port Knocking)技术,SPA相较于后者增加了认证加密技术。
现在,为了更好地了解SPA,我们利用liunx系统的iptables工具,来实现端口敲门服务。
1、配置环境
1、CentOS 7系统(服务器)(172.16.7.7)
2、CentOS 8系统(客户端)(172.16.8.8)
(因为手头上没有两个相同系统所以混着用了,建议使用相同的系统。)
3、在CentOS7中设置了Squid反向代理,访问CentOS7系统的80端口就能打开内网Web服务器。
2、配置流程
首先对服务器端iptables进行配置:
#!/bin/bash
# PacketKnocking.sh
# 首先将防火墙设置为完全开放
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
# 添加将要使用的链
iptables -N KNOCKING
iptables -N GATE1
iptables -N GATE2
iptables -N GATE3
iptables -N PASSED
# 接受目前存在的所有连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 允许本地连接
iptables -A INPUT -i lo -j ACCEPT
# 允许用于部分服务的端口开启,如80
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 将上述规则中未处理的数据包传输到KNOCKING链
iptables -A INPUT -j KNOCKING
## 配置第一个敲门端口
# 命名IP地址
iptables -A GATE1 -p tcp --dport 1111 -m recent --name AUTH1 --set -j DROP
# 丢弃其他所有数据包
iptables -A GATE1 -j DROP
## 配置第二个敲门端口
# 清除名称
iptables -A GATE2 -m recent --name AUTH1 --remove
# 命名IP地址
iptables -A GATE2 -p tcp --dport 2222 -m recent --name AUTH2 --set -j DROP
# 将不符合第二个端口要求的数据发送到第一个端口进行重新匹配
iptables -A GATE2 -j GATE1
## 配置第三个敲门端口
# 清除名称
iptables -A GATE3 -m recent --name AUTH2 --remove
# 命名IP地址
iptables -A GATE3 -p tcp --dport 3333 -m recent --name AUTH3 --set -j DROP
# 将不符合第三个端口要求的数据发送到第一个端口进行重新匹配
iptables -A GATE3 -j GATE1
# 允许加入此链接的用户连接80端口
iptables -A PASSED -p tcp --dport 80 -j ACCEPT
# 将不符合该连接的端口发送到第一个端口进行重新匹配
iptables -A PASSED -j GATE1
# 配置允许连接时长
iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH3 -j PASSED
# 配置敲门操作允许间隔
iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH2 -j GATE3
iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH1 -j GATE2
# 将不符合该连接的端口发送到第一个端口进行重新匹配
iptables -A KNOCKING -j GATE1
配置完成后检查iptables流量表
[root@bogon xiahuai]# iptables -v -L
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any any anywhere anywhere ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 KNOCKING all -- any any anywhere anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain GATE1 (4 references)
pkts bytes target prot opt in out source destination
0 0 DROP tcp -- any any anywhere anywhere tcp dpt:lmsocialserver recent: SET name: AUTH1 side: source mask: 255.255.255.255
0 0 DROP all -- any any anywhere anywhere
Chain GATE2 (1 references)
pkts bytes target prot opt in out source destination
0 0 all -- any any anywhere anywhere recent: REMOVE name: AUTH1 side: source mask: 255.255.255.255
0 0 DROP tcp -- any any anywhere anywhere tcp dpt:EtherNet/IP-1 recent: SET name: AUTH2 side: source mask: 255.255.255.255
0 0 GATE1 all -- any any anywhere anywhere
Chain GATE3 (1 references)
pkts bytes target prot opt in out source destination
0 0 all -- any any anywhere anywhere recent: REMOVE name: AUTH2 side: source mask: 255.255.255.255
0 0 DROP tcp -- any any anywhere anywhere tcp dpt:dec-notes recent: SET name: AUTH3 side: source mask: 255.255.255.255
0 0 GATE1 all -- any any anywhere anywhere
Chain KNOCKING (1 references)
pkts bytes target prot opt in out source destination
0 0 PASSED all -- any any anywhere anywhere recent: CHECK seconds: 30 name: AUTH3 side: source mask: 255.255.255.255
0 0 GATE3 all -- any any anywhere anywhere recent: CHECK seconds: 10 name: AUTH2 side: source mask: 255.255.255.255
0 0 GATE2 all -- any any anywhere anywhere recent: CHECK seconds: 10 name: AUTH1 side: source mask: 255.255.255.255
0 0 GATE1 all -- any any anywhere anywhere
Chain PASSED (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:http
0 0 GATE1 all -- any any anywhere anywhere
所有连接均未收到包。
然后在客户端发起nmap扫描端口。
nmap -Pn --host-timeout 201-max-retries 0 172.16.7.7 -p 1111
sleep 1s
nmap -Pn --host-timeout 201-max-retries 0 172.16.7.7 -p 2222
sleep 1s
nmap -Pn --host-timeout 201-max-retries 0 172.16.7.7 -p 3333
访问172.16.7.7的80端口。
访问成功!
PS:扫描重点是nmap设置必须为-Pn和max retries设置为0。
nmap -sU设定不进行端口扫描,只进行主机扫描,-Pn设定是不进行主机扫描,默认主机存在,只进行端口扫描。如果不选择-Pn,nmap会一次性发送多个包同时进行主机扫描he端口扫描,干扰端口敲门进程,导致测试失败。
同时,max retries参数也需要设置为0,否则在端口filter的情况下,nmap会默认发送两个包重复进行端口扫描,干扰端口敲门进程,导致测试失败。