kcilnk/fn-knock

By kcilnk

Updated about 2 hours ago

高性能的渐进式的自托管网关

Image
Networking
Security
Web servers
0

10K+

kcilnk/fn-knock repository overview

fn-knock

官网 · 使用文档 · Docker 部署文档

fn-knock 是一款鉴权网关,可帮助您便捷地对外提供服务,支持 SSL、DDNS、反向代理鉴权和内网穿透。

当前镜像使用内置 SQLite 存储,只需运行一个 fn-knock 容器,不需要 Redis。

镜像源

镜像源镜像地址适用网络
Docker Hubkcilnk/fn-knock:latest可稳定访问 Docker Hub 的网络
官方镜像源hub.fnknock.cn/kcilnk/fn-knock:latest中国大陆网络;latest 每 30 分钟同步一次

本文是 Docker Hub 页面,因此默认使用 kcilnk/fn-knock:latest。切换镜像源时,只需同时修改拉取命令和 .env 中的 FN_KNOCK_IMAGE

如需锁定版本,可将 latest 改为已发布的固定版本标签。

环境要求

需要 Linux 主机或基于 Linux 的 NAS,并已安装 Docker Engine 和 Docker Compose 插件:

docker version
docker compose version

网络模式

网络模式推荐程度说明
HOST 网络推荐、默认容器直接使用宿主机网络,可识别真实网卡与 IPv6
桥接网络可选使用隔离的双栈 bridge 并映射端口,但 DDNS 可能找不到宿主机网卡或 IPv6

需要使用 DDNS“从网卡获取”或依赖宿主机 IPv6 时,请使用 HOST 网络。

推荐部署:HOST 网络

1. 准备运行目录
mkdir -p /opt/fn-knock-docker
cd /opt/fn-knock-docker
2. 拉取镜像
docker pull kcilnk/fn-knock:latest
3. 创建 .env

将以下内容保存为 /opt/fn-knock-docker/.env

FN_KNOCK_IMAGE=kcilnk/fn-knock:latest
TZ=Asia/Shanghai
ADMIN_VIEW_PORT=7991
BACKEND_PORT=7998
AUTH_PORT=7997
GO_BACKEND_PORT=7996
GO_REPROXY_PORT=7999
DOCKER_ADMIN_TRUSTED_PROXY_CIDRS=
DOCKER_DISCOVER_LAN_IP=

关键配置:

配置项默认值说明
FN_KNOCK_IMAGEkcilnk/fn-knock:latest可改为官方镜像源地址或固定版本标签
ADMIN_VIEW_PORT7991管理面板的宿主机端口
GO_REPROXY_PORT7999网关对外服务端口
DOCKER_ADMIN_TRUSTED_PROXY_CIDRS留空仅当管理面板位于可信反向代理后时,填写代理出口 IP 或 CIDR
DOCKER_DISCOVER_LAN_IP留空仅在第三方反代无法自动识别宿主机局域网地址时填写

BACKEND_PORTAUTH_PORTGO_BACKEND_PORT 是内部组件端口,通常保持默认值。

4. 创建 docker-compose.yml

将以下内容保存为 /opt/fn-knock-docker/docker-compose.yml

services:
  fn-knock:
    image: ${FN_KNOCK_IMAGE}
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: ${TZ:-Asia/Shanghai}
      FN_KNOCK_RUNTIME_TARGET: docker
      FN_KNOCK_DATA_DIR: /var/lib/fn-knock
      FN_KNOCK_GATEWAY_CONFIG_DIR: /usr/local/etc/fn-knock
      ADMIN_VIEW_PORT: ${ADMIN_VIEW_PORT:-7991}
      BACKEND_PORT: ${BACKEND_PORT:-7998}
      AUTH_PORT: ${AUTH_PORT:-7997}
      GO_BACKEND_PORT: ${GO_BACKEND_PORT:-7996}
      GO_REPROXY_PORT: ${GO_REPROXY_PORT:-7999}
      DOCKER_ADMIN_TRUSTED_PROXY_CIDRS: ${DOCKER_ADMIN_TRUSTED_PROXY_CIDRS:-}
      DOCKER_DISCOVER_LAN_IP: ${DOCKER_DISCOVER_LAN_IP:-}
      ADMIN_VIEW_HOST: 0.0.0.0
      BACKEND_HOST: 127.0.0.1
    volumes:
      - fn_knock_data:/var/lib/fn-knock
      - fn_knock_gateway:/usr/local/etc/fn-knock
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -fsS http://127.0.0.1:${ADMIN_VIEW_PORT:-7991}/api/admin/healthz || exit 1",
        ]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s

volumes:
  fn_knock_data:
  fn_knock_gateway:

HOST 网络下不需要声明 ports 或自定义 bridge,服务会直接监听宿主机端口。

5. 启动并检查状态
docker compose up -d
docker compose ps
docker compose logs -f fn-knock

日志命令会持续运行,可按 Ctrl+C 退出。

可选:桥接网络

桥接网络适合更看重网络隔离,并且不依赖宿主机网卡识别的部署。

桥接网络可能导致 DDNS 找不到宿主机网卡或 IPv6。需要使用 DDNS“从网卡获取”时,请优先使用 HOST 网络。

.env 中增加:

FN_KNOCK_DOCKER_IPV4_SUBNET=172.30.0.0/16
FN_KNOCK_DOCKER_IPV6_SUBNET=fd42:fb33:7f7a:100::/64

然后将 docker-compose.yml 替换为:

services:
  fn-knock:
    image: ${FN_KNOCK_IMAGE}
    restart: unless-stopped
    environment:
      TZ: ${TZ:-Asia/Shanghai}
      FN_KNOCK_RUNTIME_TARGET: docker
      FN_KNOCK_DATA_DIR: /var/lib/fn-knock
      FN_KNOCK_GATEWAY_CONFIG_DIR: /usr/local/etc/fn-knock
      ADMIN_VIEW_PORT: ${ADMIN_VIEW_PORT:-7991}
      BACKEND_PORT: ${BACKEND_PORT:-7998}
      AUTH_PORT: ${AUTH_PORT:-7997}
      GO_BACKEND_PORT: ${GO_BACKEND_PORT:-7996}
      GO_REPROXY_PORT: ${GO_REPROXY_PORT:-7999}
      DOCKER_ADMIN_TRUSTED_PROXY_CIDRS: ${DOCKER_ADMIN_TRUSTED_PROXY_CIDRS:-}
      DOCKER_DISCOVER_LAN_IP: ${DOCKER_DISCOVER_LAN_IP:-}
      ADMIN_VIEW_HOST: 0.0.0.0
      BACKEND_HOST: 127.0.0.1
    ports:
      - "${ADMIN_VIEW_PORT:-7991}:${ADMIN_VIEW_PORT:-7991}"
      - "${GO_REPROXY_PORT:-7999}:${GO_REPROXY_PORT:-7999}"
    networks:
      - fn_knock_net
    volumes:
      - fn_knock_data:/var/lib/fn-knock
      - fn_knock_gateway:/usr/local/etc/fn-knock
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -fsS http://127.0.0.1:${ADMIN_VIEW_PORT:-7991}/api/admin/healthz || exit 1",
        ]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s

volumes:
  fn_knock_data:
  fn_knock_gateway:

networks:
  fn_knock_net:
    enable_ipv6: true
    ipam:
      config:
        - subnet: ${FN_KNOCK_DOCKER_IPV4_SUBNET:-172.30.0.0/16}
        - subnet: ${FN_KNOCK_DOCKER_IPV6_SUBNET:-fd42:fb33:7f7a:100::/64}

如果 IPv4 子网与同机现有网络冲突,请将 FN_KNOCK_DOCKER_IPV4_SUBNET 改为其他私网 CIDR。IPv6 子网应保持为 ULA /64

默认端口

端口服务用途
7991管理后台入口首次访问时设置 Docker 管理面板密码
7999网关 / 代理入口外部用户访问代理服务时使用
7998Rust 后端仅供宿主机回环或容器内部访问
7997认证前端仅供宿主机回环或容器内部访问
7996Go 网关管理仅供宿主机回环或容器内部访问

首次访问与配置

  1. 打开 http://<宿主机IP>:7991
  2. 设置 Docker 管理面板密码并登录。
  3. 在管理后台完成反向代理、子域名、证书和鉴权配置。
  4. 让外部业务流量访问 7999 对应的网关入口。
  5. 如果 7991 位于可信反向代理后,在 .env 设置 DOCKER_ADMIN_TRUSTED_PROXY_CIDRS
  6. 仅当第三方反代无法自动识别宿主机局域网地址时,才设置 DOCKER_DISCOVER_LAN_IP

数据持久化

数据卷容器路径内容
fn_knock_data/var/lib/fn-knock密钥、备份以及 FRP、Cloudflared 等运行数据
fn_knock_gateway/usr/local/etc/fn-knock网关配置和默认 SQLite 数据库

重新创建容器或更新镜像不会删除具名数据卷。删除数据卷前请先完成备份。

更新镜像

如果 .env 使用 latest,可以执行:

cd /opt/fn-knock-docker
docker compose pull
docker compose up -d
docker compose ps

如果使用固定版本标签,请先修改 .env 中的 FN_KNOCK_IMAGE,然后执行相同命令。

使用 Watchtower 自动更新

.env 使用 latest 时,可以使用 Watchtower 自动检查和更新容器:

docker run -d \
  --name watchtower \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  nickfedor/watchtower --cleanup

默认情况下,Watchtower 每 24 小时检查所有运行中的容器。发现镜像摘要发生变化后,会拉取新镜像并按原配置重新创建容器,更新期间会有短暂重启。

--cleanup 会清理被替换的旧镜像,不会删除 fn-knock 的具名数据卷。

查看 Watchtower 状态:

docker ps --filter name=watchtower
docker logs watchtower

此基础配置会管理主机上的所有运行中容器,并通过 Docker Socket 获得较高权限。仅在可信主机上使用。如果其他容器不应自动更新,请参考 Watchtower 官方文档 限制更新范围。

重设管理面板密码

忘记密码时,在运行 Docker 的主机上执行:

cd /opt/fn-knock-docker
docker compose exec -T fn-knock fn-knock-reset-panel-password

再次访问 7991 时会重新进入首次设置密码流程。

该命令只会清除管理面板密码、登录会话和密码输错后的退避状态,不会删除业务配置、反代规则、证书、白名单、日志或数据卷。

Tag summary

Content type

Image

Digest

sha256:ff135d510

Size

36.3 MB

Last updated

about 2 hours ago

docker pull kcilnk/fn-knock