Port knocking 详解
Port knocking 会让服务保持不可见,直到有人证明自己知道秘密。本指南介绍其工作原理、两种常见实现方式 — knockd 和 fwknop — 以及实际使用中敲门失败的原因。
Port knocking 的工作原理
防火墙会丢弃所有通往受保护端口的连接,因此扫描器不会发现任何内容。一个小型守护进程会监测到达防火墙的流量。当某个源地址产生预期模式时,守护进程会添加一条防火墙规则,允许该地址访问,通常仅持续较短时间。
这个模式就是敲门。使用 knockd 时,它是按特定顺序、在时间限制内对特定端口发起的一系列连接尝试。使用 fwknop 时,它是单个加密数据包。
knockd:敲门序列
knockd 会监听一个网络接口,并将连接尝试与 /etc/knockd.conf 中的序列进行匹配。一个序列可混合 TCP 和 UDP 端口。匹配成功时,knockd 会运行一条命令 — 通常是针对敲门地址 (%IP%) 的 iptables 或 nftables 规则。
此示例会为敲门地址打开 SSH,并在 10 秒后再次关闭。如果防火墙接受已建立的连接,现有 SSH 会话会继续正常运行。
[options]
UseSyslog
[openSSH]
sequence = 7311:tcp,8822:tcp,9133:udp
seq_timeout = 10
tcpflags = syn
start_command = /usr/sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
cmd_timeout = 10
stop_command = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT 请自行选择端口;切勿重复使用公开示例中的端口。tcpflags = syn 使 knockd 仅统计带有 SYN 标志的数据包 — 即连接尝试的第一个数据包。
fwknop:单包授权
fwknop 使用一个经加密 (AES) 和认证 (HMAC) 的 UDP 数据包替代序列。服务器端的 fwknopd 会被动捕获该数据包、验证它、检查其并非重放,然后为数据包内的地址打开所请求的端口。
使用 fwknop --key-gen 生成密钥,并将其放入服务器的 access.conf。Secret Knock 会从您的 .fwknoprc 导入客户端配置。
SOURCE ANY
OPEN_PORTS tcp/22
KEY_BASE64 <output of fwknop --key-gen>
HMAC_KEY_BASE64 <output of fwknop --key-gen>
FW_ACCESS_TIMEOUT 30 由于允许访问的地址位于加密数据包内,SPA 可为不同于发包地址的地址打开端口 — 当您通过使用移动数据的手机为其他地点的笔记本电脑敲门时非常实用。
敲门失败的原因
- IPv4 与 IPv6:敲门通过一种地址族发出,而 SSH 通过另一种地址族连接。防火墙为您未使用的地址打开了门。
- 不同的公网地址:使用移动数据、运营商 NAT 或 VPN 时,服务器看到的 IP 可能不同于您的预期。请检查敲门来源地址。
- 重传的 SYN:若 TCP 敲门未收到响应,客户端操作系统会再次发送相同的 SYN。在我们的测试中,knockd 0.8 会因重复的 SYN 重置序列,因此客户端每次敲门都必须只发送一次,并迅速停止连接尝试。
- 时序:在 seq_timeout 之外到达的敲门,或顺序错误的敲门,会重新开始序列。
- 中间设备:某些网络会阻止或改写通往非常用端口的流量,因此在家可用的敲门可能会在酒店或办公网络中失败。
安全吗?
knockd 序列以未加密形式发送;任何能监视您流量的人都可重放它。请将其用于向扫描器隐藏服务,并置于 SSH 密钥之前 — 不要用它替代 SSH 密钥。fwknop SPA 通过加密、HMAC 和重放保护弥补了这一缺口,在流量可能被观察时是更好的选择。
通过 iPhone、Mac 和 Apple Watch 敲门
Secret Knock 可从 iPhone、iPad 和 Mac 发送 knockd 序列及 fwknop SPA 数据包,检查端口是否响应,并打开您的 SSH App。Apple Watch 会通过已配对的 iPhone 敲门,因为 watchOS 不允许 App 发送原始 TCP 或 UDP 数据包;远离 iPhone 时,它可通过 HTTP 向启用该功能的服务器发送 SPA。