#sequence #firewall #port #connection #ssh #attempt #port-knocking

app knockd

使用Rust编写的端口敲击服务器

1 个不稳定版本

0.1.0 2024年3月3日

#1501 in 网络编程

Apache-2.0

16KB
369

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:客户端应敲击的端口序列

客户端配置

config.yaml 文件中创建配置文件,与 knock-cli 二进制文件位于同一目录。

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

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

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

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

./knock-cli -r disable_ssh

依赖关系

~5.5–7.5MB
~137K SLoC