1 个不稳定版本

0.1.0 2024年3月3日

#1095网络编程

Apache-2.0

6KB
112 代码行

knock:Rust 中的端口敲门实现

中文文档

什么是端口敲门?

端口敲门是一种通过在一系列预先指定的关闭端口上生成连接尝试,在防火墙外部打开端口的机制。一旦接收到正确的连接尝试序列,防火墙规则将动态修改,以允许发送连接尝试的主机通过特定的端口(s)连接。

knock 仅检测 SYN 数据包,并不监听已打开的端口,它使用 pnet crate 来捕获原始数据包。

此技术的常见用途是通过执行成功的端口敲门序列后,仅允许访问 SSH 端口,从而保护 SSH 服务器免受未经授权的访问。

该项目受到了另一个 knock 项目的启发,该项目是用 C 语言编写的,但本项目是用 Rust 编写的,并且具有不同的配置格式。

为什么使用端口敲门?

端口敲门是一种简单而有效的方法,可以保护您的服务器免受未经授权的访问。这是一种轻量级且安全的方法,可以保护您的服务器免受未经授权的访问。

常见用例

  • 保护您的 SSH 服务器免受暴力破解攻击
  • 根据需要动态打开和关闭防火墙上的任何端口

下载

您可以从 发布页面 下载预构建的二进制文件。

构建

cargo build --release

配置

服务器配置

knockd 二进制文件的同一目录下创建一个名为 config.yaml 的配置文件。

interface: "eth0"
timeout: 5
rules:
  - name: "enable_ssh"
    command: "/usr/sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT"
    sequence:
      - 15523
      - 17767
      - 32768
      - 28977
      - 51234
  - name: "disable_ssh"
    command: "/usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT"
    sequence:
      - 51234
      - 28977
      - 32768
      - 17767
      - 15523
  • interface:要监听的网络接口
  • timeout:等待客户端发送完整序列的秒数超时
  • rules:接收到正确序列时应用的规则
    • name:规则的名称
    • command:接收到正确序列时执行的命令。 %IP% 将替换为客户端的 IP 地址
    • sequence:客户端应敲打的端口序列

客户端配置

在knock-cli二进制文件所在的目录下创建一个名为 config.yaml 的配置文件。

确保客户端的序列与服务器相同。

rules:
  - name: "enable_ssh"
    host: "example.com"
    sequence:
      - 12345
      - 54321
      - 32768
      - 18933
  - name: "disable_ssh"
    host: "example.com"
    sequence:
      - 18933
      - 32768
      - 54321
      - 12345
  • rules:发送正确序列时应用的规则
    • name:规则的名称,名称不需要与服务器规则名称匹配,但序列必须匹配。此外,名称在客户端配置文件中应该是唯一的
    • host:要发送序列到的主机
    • sequence:要敲击的端口号序列

用法

服务器

./knockd -c config.yaml

默认配置路径为 config.yaml,您也可以使用 -c 选项指定配置文件路径。

客户端

./knock-cli -c config.yaml -r enable_ssh

默认配置路径为 config.yaml,您也可以使用 -c 选项指定配置文件路径。

使用 -r 选项指定要敲击的规则名称。

以Docker容器运行服务器

docker run --network host --cap-add=NET_RAW --cap-add=NET_BIND_SERVICE --cap-add=NET_ADMIN -d --restart=always --name=knockd -v ./config.yaml:/config.yaml:ro ghcr.io/timothyye/knockd:latest

由于服务器需要监听原始数据包,您需要向容器添加 NET_RAWNET_BIND_SERVICENET_ADMIN 功能。

示例

假设您已经添加了一个防火墙规则来阻止所有指向SSH端口的入站连接。例如。

iptables -A INPUT -p tcp --dport 22 -j DROP

使用以下命令在服务器上启用SSH端口

./knock-cli -r enable_ssh

发送正确的序列后,将为客户端的IP地址打开SSH端口。现在您可以连接到SSH服务器。

要关闭SSH端口,请使用以下命令

./knock-cli -r disable_ssh

依赖项

~2.8–3.5MB
~73K SLoC