前言
最近在工作中听到一个概念Single Packet Authorization
(spa, 单包认证)。代码看的无聊的时候,来捯饬下这个概念。这个不在我工作范围内,所以只能自己查查资料。
书籍这块,可以参考:
- 《软件定义边界(SDP) 安全架构技术指南》2.7 SDP连接安全 单包授权(这本书我快速翻了一遍,没看懂)
- 《Linux 防火墙》Michael Rash著 第12章 端口碰撞与单数据包授权、第13章 fwknop简介
书没咋看懂,看博客快些,虽然不够成体系:
- 连钥匙孔都藏起来的ssh 完全防御: SPA – 挺不错,一篇可以搞懂spa这个概念
- 零信任实践之单包认证(SPA) – 一般般,演示了fwknop的使用
spa简介
这部分来自上面参考链接的拼拼凑凑。
通俗些的解释
首先是通俗些的解释,来自 连钥匙孔都藏起来的ssh 完全防御: SPA。
如果说ssh 服务是进入伺服器的锁头, 那么帐号密码就是开锁的钥匙。你可以用 密不透水的设定 来保护锁头, 或是用 fail2ban把企图开锁但履试履败的可疑份子挡在庭院之外一阵子, 让他连试钥匙的机会都没有。但其实另外还有一个中文世界鲜少人知道的终极绝招: 把锁头/钥匙孔整个藏起来, 只当懂门路的人(你自己) 用特定暗号敲门时, 才让锁头/钥匙孔短暂出现一两分钟。今天要介绍的伺服器完全防御机制叫做 Single Packet Authorization (SPA)。
这要先从port knocking说起。这个机制的运作方式是: 先用防火墙预设把所有的ports (或至少重要的ports, 例如22) 通通封掉, 这就像是在门锁之外再盖上一层 没有锁头、 没有钥匙孔的门 一样。然后跟客户端约好按照某个特定顺序敲几个ports (例如先敲23815、 次敲62408、 再敲59174) 伺服器侦测到这个特定顺序, 外门才会像芝麻开门一样地短暂打开一两分钟, 这时才看得见钥匙孔(port 22, ssh)。客户端必须趁这短短的空隙下ssh 指令连线、 输入帐号密码。过了这个时间, 外门又关上、 任何人又看不见port 22, 也就是只看见一片铜墙铁壁,连钥匙孔都看不见; 但已连线的工作阶段则可维持连线不受影响。
2005 年时, Michael Rash 发明了SPA 并以fwknop 实作。简单地说, 它只用一个封包来敲门。这个封包的内容包含了一串乱码(以便防止replay 攻击)、 用户id、 时间戳记、 fwknop 版本、 欲开启的埠号资讯或是shell 指令、 以及上述所有资讯的digest。这所有的内容并非直接放入封包, 而是经过对称或非对称方式加密。除了解决了上述传统port forwarding 的问题之外, fwknop 比一般的port knocking 软体还多了其他很多优点。
不通俗的解释
我们再来看下不通俗的解释,这个层次会高点,站在SDP的角度,看SPA,来自《软件定义边界(SDP) 安全架构技术指南》2.7 SDP连接安全 单包授权
SDP技术最关键的组成部分之一是要求并强制实施“先认证后连接” 模型,该模型弥补了TCP/IP开放且不安全性质的不足。 SDP通过单包授权(SPA) 实现这一点。 SPA是一种轻量级安全协议, 在允许访问控制器或网关等相关系统组件所在的网络之前先检查设备或用户身份。
SPA的目的是允许服务被防火墙隐藏起来并被默认丢弃。该防火墙系统应该丢弃所有TCP和UDP数据包, 不回复那些连接尝试, 从而不为潜在的攻击者提供任何关于该端口是否正被监听的信息。 在认证和授权后, 用户被允许访问该服务。
尽管各种SPA的实现可能有轻微差别, 这些实现都应该能满足以下原则:
- 数据包必须被加密和认证
- 数据包必须自行包含所有必要的信息; 单独的数据包头不被信任
- 生成和发送数据包必须不依赖于管理员或底层访问权限; 不允许篡改原始数据包
- 服务器必须尽可能无声地接收和处理数据包; 不发送回应或确认
SPA在SDP中起很大作用。 SDP的目标之一是克服TCP/IP开放和不安全的基本特性。 TCP/IP的这个特性允许“先连接后认证” 。 鉴于今天的网络安全威胁形势, 允许恶意行为人员扫描并连接到我们的企业系统是不可被接受的。 与SDP组合的SPA通过两种方式应对这个弱点。 使用SDP架构的应用被隐藏在SDP网关/AH后面, 从而只有被授权的用户才能访问。 另外, SDP组件自身, 如控制器和网关也被SPA保护。 这允许它们被安全地面向互联网部署, 确保合法用户可以高效可靠地访问, 而未授权用户则看不到这些服务。 SPA提供的关键好处是服务隐藏。 防火墙的Default-drop(默认丢弃)规则缓解了端口扫描和相关侦查技术带来的威胁。 这种防火墙使得SPA组件对未授权用户不可见, 显著减小了整个SDP的攻击面。 相比与VPN的开放端口以及在很多实现中都存在的已知弱点, SPA更安全。
安装fwknop-来实践一把
我不乐意去看fwknop-官方文档,参考上前言中的链接。
两个机器的ip如下所示。一台作为客户端,一台作为服务端。给服务端安装ssh服务。
# 网络结构
# client:192.168.10.105/24
# server:192.168.10.107/24
# 服务端
➜ sudo apt install openssh-server
➜ systemctl status sshd
# 测试下连通性:使用客户端登录服务端
➜ ssh dacao@192.168.10.107
dacao@192.168.10.107's password:
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.13.0-44-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
122 updates can be applied immediately.
To see these additional updates run: apt list --upgradable
Your Hardware Enablement Stack (HWE) is supported until April 2025.
Last login: Thu Jun 16 22:03:06 2022 from 192.168.10.105
接下来我们使用iptables
,禁止连接服务端的22号端口。
# 大胆操作,重启后iptables的设置会失效
➜ sudo iptables --list --line-numbers
➜ sudo iptables -A INPUT -i enp0s3 -p tcp --dport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
➜ sudo iptables -A INPUT -i enp0s3 -p tcp --dport 22 -j DROP
设置之后,无法使用ssh登录服务端。并且我们使用wireshark
抓包查看。
或者我们使用nmap
查看端口。
➜ ~ nmap 192.168.10.107 -p 22
Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-17 08:04 CST
Nmap scan report for 192.168.10.107
Host is up (0.00079s latency).
PORT STATE SERVICE
22/tcp filtered ssh
Nmap done: 1 IP address (1 host up) scanned in 0.37 seconds
客户端安装fwknop-client
,并生成KEY_BASE64 跟HMAC_KEY_BASE64。看名字,可能一个是对密钥做了base64,一个是对密钥做hmac,以确认身份。
# 客户端
➜ sudo apt install fwknop-client
➜ fwknop -A tcp/22 -a 192.168.10.105 -D 192.168.10.107 --key-gen --use-hmac --save-rc-stanza
➜ cat ~/.fwknoprc
[default]
[192.168.10.107]
ALLOW_IP 192.168.10.105
ACCESS tcp/22
SPA_SERVER 192.168.10.107
KEY_BASE64 FW4I26jOgbxN8P/3G4s3sShDvtT3SMsgi+0ce3BNbw0=
HMAC_KEY_BASE64 lGvcpGkCrBj07sV9TCTMWVnvuAb/bGQiAvP+R1a3NNhGCBfioc1LQV1e+JLw5hpNaHrit1AumZA9QeIqa2+AgA==
USE_HMAC Y
KEY_BASE64 aeIy3aqVjhl40nLgC7Vt40ZKGp+AqdFSLdu/xpts5ZU=
HMAC_KEY_BASE64 XxUoP8NgRJlUSyj8+ObdPj5mukvWtpciiJ67hf3ssVo879PNis4hlCBl0cif1pNAuEzUNnBTNgZPO17Z+rnF0g==
服务端安装fwknop-server
。把客户端的~/.fwknoprc 里面对应的那两句copy 过去。编辑/etc/fwknop/fwknopd.conf 找到PCAP_INTF 那一句, 把eth0 改成伺服器对外网卡名称。
➜ sudo apt install fwknop-server
# systemctl status fwknop-server.service
# sudo systemctl start fwknop-server.service # 会失败
# 添加到access.conf
➜ sudo cp -a /etc/fwknop/access.conf /etc/fwknop/access.conf.bak
# ➜ echo "REQUIRE_SOURCE_ADDRESS Y\n\
KEY_BASE64 FW4I26jOgbxN8P/3G4s3sShDvtT3SMsgi+0ce3BNbw0=\n\
HMAC_KEY_BASE64 lGvcpGkCrBj07sV9TCTMWVnvuAb/bGQiAvP+R1a3NNhGCBfioc1LQV1e+JLw5hpNaHrit1AumZA9QeIqa2+AgA==" | sudo tee -a /etc/fwknop/access.conf
# 编辑/etc/fwknop/fwknopd.conf 找到PCAP_INTF 那一句, 把eth0 改成伺服器对外网卡名称。
# sudo fwknopd --interface enp0s3
# 前台运行
➜ sudo fwknopd -f
客户端先敲门,再连接。ssh连接成功。
➜ fwknop -n 192.168.10.107
➜ ssh dacao@192.168.10.107
dacao@192.168.10.107's password:
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.13.0-44-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
122 updates can be applied immediately.
To see these additional updates run: apt list --upgradable
Your Hardware Enablement Stack (HWE) is supported until April 2025.
Last login: Fri Jun 17 07:49:21 2022 from 192.168.10.105
抓包信息如下。
其他
从表面来看,spa概念上的内容似乎不是很复杂,主要包含两个方面:加密与认证、动态修改防火墙策略。
没到源码层面去看,说简单就是扯淡。
以后遇到spa再说吧。