周末想用最近学的 Rust 来练手一下,于是参考一个很古老的 C 语言实现的端口敲门程序 knock,用 Rust 实现了一个版本。
Port Knocking 是一种网络安全技术,通过对服务器上的一系列预定义端口进行特定顺序的“敲门”(即发送数据包)来触发服务器上的一种反应,通常是打开一个原本关闭的端口,从而允许发起敲门序列的客户端建立连接。这种方法的优点在于,对外界而言,受保护的服务端口在没有接收到正确的敲门序列之前都是不可见的,从而增加了系统的安全性。
这个工具分为客户端和服务器端两部分:
服务器端 (knockd): 在服务器上运行,负责监听预设的一系列端口上的敲门尝试。当它检测到来自同一 IP 的特定序列时,会执行配置文件中定义的命令,如修改防火墙规则来允许来自该 IP 的连接。
客户端 (knock-cli): 用于发起敲门序列。用户可以通过客户端配置文件指定目标服务器地址和敲门的端口序列。执行敲门动作后,如果服务器端正确识别了敲门序列,客户端的 IP 地址将被允许访问原本隐藏或受限的服务。
项目地址: https://github.com/TimothyYe/knock
欢迎 Star 和贡献 Pull Request.
1
Autonomous 263 天前
支持一下,如果能用 docker 部署就更好了
|
2
timothyye OP @Autonomous 因为这个程序需要监听系统的网络接口,容器里面应该也是可以的,我还没试过。可以的话我打包一个镜像。
|
3
HiramWong 262 天前
零信任的概念
|
4
oneisall8955 262 天前 via Android
有意思
|
5
8520ccc 262 天前 via iPhone
感谢分享,另外有个小意见
实现一个密钥加密是不是更好? 防止重放攻击? |
6
timothyye OP @Autonomous 已经支持 docker 部署了,具体方法在 README 文件里面
|
7
ETiV 262 天前 via iPhone 1
这图感觉像是在竖中指…然后中指前面肿了
|
8
lovestudykid 262 天前
有点意思,但是为什么一定要用客户端呢?
|
9
Geo200 262 天前
本地运行是否一定要容器呢?只是学习的话有没有更快本地运行的方法?
|
10
timothyye OP @lovestudykid 不用也可以的,可以按照端口顺序连续用 telnet 去连接,用客户端方便的地方是可以配置多个规则,只要记住常用的规则名称就可以使用了。
|
13
a1210968738 262 天前 via Android
是不是也可以考虑通过 HTTPS 协议搞个简单的管理页面( basic 鉴权保证安全性),支持列出当前白名单列表,支持单个添加和移除,以及批量移除。
|
14
timothyye OP @a1210968738 你说的这个白名单是直接添加到 iptables 的客户端 IP 的白名单?
|
15
Autonomous 262 天前 via iPhone
@timothyye 应该是没问题的,我的 fail2ban 也是在 docker 容器内,用的 host 模式
|
16
fenglangjuxu 262 天前 via iPhone
类似对暗号
|
17
timothyye OP @Autonomous #15 嗯,是这样的,host 模式,然后启动的时候需要给容器一些特殊的权限。
|
18
timothyye OP @fenglangjuxu 是这样的,这个概念 Wikipedia 上有详细的介绍 https://en.wikipedia.org/wiki/Port_knocking
|
19
ZnductR0MjHvjRQ3 262 天前
有意思 好奇实现逻辑是什么样的
敲门是走 80/443 然后通过对应的密码 然后系统再去打开对应的端口吗 |
20
timothyye OP @Motorola3 实现逻辑就是服务端程序监听网卡的原始流量包,根据配置文件中被配置为敲门的端口,过滤出客户端 IP ,当一个客户端连续按照顺序连接这些敲门端口的时候,就可以匹配到对应的规则了,然后后端程序会去执行规则配置好的操作 iptables 的命令,打开被保护的 SSH ,或者其他端口。并且这个端口通过 iptables 命令设置成只允许这个敲门的客户端的 IP 去连接。由于服务端是过滤网卡的数据包,所以不需要监听任何端口,也不占用任何端口。
敲门不是走 80/443 ,是服务端程序直接监听网卡的数据包。 |
21
ZnductR0MjHvjRQ3 262 天前
@timothyye 那这样的话是不是 vps 没法用这个呀 vps 似乎不像是 ECS 有独立的网卡
|
23
a1210968738 262 天前 via Android
@timothyye 是的
|
24
timothyye OP @a1210968738 这样的话相当于封装了个 iptables 的网页版的功能?
|
25
xianzhe 261 天前 via Android
感觉五楼的疑问有道理,怎么防止流量重放攻击?
|
26
timothyye OP |
27
iqoo 261 天前
命令行版的用在特定用户的场合可以,如果是给公共用户使用就有些麻烦,得下载一个敲门工具。
之前做了个网页版的演示,直接用 JS 发 UDP 包敲门: https://www.etherdream.com/port-knocking/ |
28
iqoo 261 天前
可以在这个基础上加强一下,前后端都用 rust 实现。前端编译成 wasm 生成敲门认证串,后端用同一套算法解串,成功后把 ip 加到 ipset 白名单里。
|
29
a1210968738 261 天前 via Android
@timothyye 对,这样不需要额外的客户端,实用性和易用性都好很多
|
33
matate 261 天前
server 端用 nftables 可以直接实现 https://wiki.nftables.org/wiki-nftables/index.php/Port_knocking_example
|