以下是为你整理的 Next-Terminal 在 Podman 环境下的完整部署与安全加固笔记。已将排坑过程、最终配置及技术原理系统化整合,方便后续维护或迁移时直接复制使用。


一、 部署环境与架构说明

  • 宿主机环境:香橙派(ARM64 架构,2核2G 内存)
  • 容器引擎:Podman + podman-compose(Rootless 免 Root 模式)
  • 数据库:外部独立运行的 PostgreSQL 容器(容器名为 pgsql
  • 核心组件关系
  • Next-Terminal:Web 服务端(Go 语言开发),负责前端展示、鉴权和资产管理。最新版强制要求必须存在配置文件,且不支持 SQLite 驱动。
  • guacd:Guacamole 协议代理守护进程(C 语言开发)。Next-Terminal 的最新版已内置 Go 版 SSH 客户端,但连接 Windows 远程桌面(RDP)或 VNC 时,仍必须依赖 guacd 组件进行图形编解码

二、 配置文件(config.yaml)

最新版 Next-Terminal 的配置采用了深层嵌套结构。为了适应香橙派 2G 内存和 TF 卡寿命,已进行极致优化:

  1. 日志级别降为 error,且关闭了运行日志文件和 Web 访问日志的写入,避免高频 I/O 导致卡顿或磁盘爆满。
  2. 数据库和组件连接均使用 Podman 内部容器名直连。

在宿主机项目目录下创建 nt-config 文件夹,并在内部新建 config.yaml

Database:
  Enabled: true
  Type: postgres
  Postgres:
    Hostname: pgsql            # 纯内网直连 PostgreSQL 容器名
    Port: 5432
    Username: nextterminal     # 替换为真实的 PG 用户名
    Password: YourSecurePassword # 替换为真实的 PG 密码
    Database: next_terminal_db # 替换为真实的 PG 数据库名
  ShowSql: false

log:
  Level: error                 # 仅记录致命错误,降低内存和 CPU 开销
  Filename: ""                 # 关闭日志写盘,保护 TF 卡寿命

Server:
  Addr: "0.0.0.0:8088"

App:
  Website:
    AccessLog: ""              # 关闭网页端访问日志
  Recording:
    Type: "local"
    Path: "/usr/local/next-terminal/data/recordings"
  Guacd:
    Drive: "/usr/local/next-terminal/data/drive"
    Hosts:
      - Hostname: guacd        # 指向同一 Compose 网络下的 guacd 服务名
        Port: 4822
        Weight: 1
  ReverseProxy:
    Enabled: false             # 保持关闭,外部使用 Caddy 代理
# 反向代理核心配置
  ReverseProxy:
    Enabled: false              # 必须为 false。反向代理和证书由外部 Caddy 负责,不需要内置服务重复监听。
    HttpEnabled: true 
    HttpAddr: ":80" 
    HttpRedirectToHttps: false  
    HttpsEnabled: true 
    HttpsAddr: ":443" 
    SelfProxyEnabled: false     # 必须改为 false。关闭内置的自代理功能,避免证书申请与外部 Caddy 冲突。
    SelfDomain: "zter.baidaoya.site" 
    Root: "https://zter.baidaoya.site" # 当 SelfProxyEnabled 为 false 时必须填写。指定外网访问的完整绝对路径,用于前端 WebSocket 握手及资源拼接。
    IpExtractor: "x-forwarded-for"    # 必须改为 x-forwarded-for 或 x-real-ip。否则系统审计日志中记录的登录 IP 全为 FRP 或 Caddy 的内网 IP。
    IpTrustList: 
      - "10.89.0.0/24"             # 信任前置代理传递过来的 IP 头信息。

三、 容器编排配置(docker-compose.yml)

Podman Rootless 避坑设计

  • 挂载单个文件易触发 Podman 的 UID 隔离 Bug,导致容器内无权读取。此处采用挂载整个配置文件夹,并配合 :Z 标签修复 SELinux 和安全上下文权限。
  • 通过 networks 显式引入外部 pgsql 容器所在的 Podman 网络(通常默认网络名为 podman),实现容器名 DNS 互访,去除冗余的 extra_hosts 中转。
  • 严格限制 deploy.resources.limits 内存为 400M,防止 RDP 大图传输时突发高负载冲垮香橙派系统。
version: '3.8'

services:
  # 1. Next-Terminal 主程序
  next-terminal:
    image: dushixiang/next-terminal:latest
    container_name: next-terminal
    restart: always
    ports:
      - "8088:8088"
    volumes:
      # 挂载宿主机配置文件夹到容器内,:Z 是 Podman 环境下保障权限必加的后缀
      - ./nt-config:/etc/next-terminal:Z
    deploy:
      resources:
        limits:
          memory: 400M
    networks:
      - default
      - pg_network   # 关联外部现有的 PostgreSQL 容器网络
    depends_on:
      - guacd

  # 2. Guacamole 核心组件(Windows RDP 编解码)
  guacd:
    image: docker.io/guacamole/guacd:1.6.0
    container_name: next-terminal-guacd
    restart: always
    environment:
      - TZ=Asia/Shanghai
    deploy:
      resources:
        limits:
          memory: 400M
    networks:
      - default

# 声明并引入外部已存在的 PostgreSQL 网络
networks:
  pg_network:
    name: podman     # 此处填写实际 pgsql 容器所在的 Podman 网络名
    external: true

四、 部署与重置命令

在执行启动前,务必放开宿主机配置文件夹的读取权限,并清理 Podman 的幽灵缓存:

# 1. 赋予本地目录及文件规范的读取权限,规避 Rootless 权限拒绝问题
chmod -R 755 ./nt-config

# 2. 彻底停止并移除旧的错误容器缓存
podman-compose down
podman rm -f next-terminal next-terminal-guacd 2>/dev/null
podman container prune -f

# 3. 启动全套服务
podman-compose up -d

# 4. 跟踪实时启动日志
podman logs -f next-terminal

五、 组件连通性排查流程

当网页可以成功打开,但需要确认后端与 pgsqlguacd 是否完全正常工作时,按以下步骤排查:

1. 验证 PostgreSQL 通信与初始化

由于主程序启动强制校验数据库,若成功进入登录页则代表基本握手成功。如需彻底确认,可检查 Next-Terminal 是否成功在 PG 库中完成建表:

podman exec -it pgsql psql -U nextterminal -d next_terminal_db -c "\dt"
  • 正常状态:终端应输出 usersassets 等系统级表结构列表。

2. 验证 guacd 编解码组件通信

  1. 登录 Next-Terminal 网页,创建一台香橙派本地 IP 的 SSH 资产并点击连接。
  2. 在香橙派宿主机终端死盯着 guacd 的容器日志:
podman logs -f next-terminal-guacd
  • 正常状态:点击连接的瞬间,日志会高频滚动并提示 INFO: Creating new client for protocol "ssh" 以及 Connection from container...

3. 容器内网络盲测(当出现不通时使用)

若连接报错,可直接钻入主程序容器内部,利用网络工具反向探测目标网络:

# 测试 next-terminal 容器内部能否解析并 ping 通 pgsql 容器
podman exec -it next-terminal ping pgsql -c 2

# 测试 next-terminal 容器内部能否成功连通 guacd 容器的 4822 端口
podman exec -it next-terminal nc -zv guacd 4822

六、 腾讯云外网穿透安全加固

将香橙派上的 Next-Terminal 经由 FRP 穿透,并通过腾讯云上的 Caddy 暴露到公网时,该容器转变为全权凭据管理器,具备较高的安全风险。必须配合以下架构进行立体防御:

1. 腾讯云 Caddy 端安全配置(Caddyfile)

严禁将登录页直接无保护裸露在公网上。利用 Caddy 的 basic_auth(基础身份认证)在最外层加一把隐形锁,阻断全网自动扫描器。

(注:密码密文需在腾讯云上执行 caddy hash-password --plaintext 你的外层密码 来生成)

nt.yourdomain.com {
    # 第一道防线:浏览器原生弹窗认证
    basic_auth {
        admin $2a$10$EbtF... # 替换为你生成的密文
    }
    
    # 转发至本地的 frps 监听端口
    reverse_proxy 127.0.0.1:8088
}

2. 香橙派端 FRP 传输加密(frpc.toml)

确保腾讯云到香橙派之间的物理链路流量处于加密状态,防止数据在传输中途被监听:

[[proxies]]
name = "next-terminal"
type = "tcp"
local_ip = "127.0.0.1"
local_port = 8088
remote_port = 8088
# 核心安全防护:强制开启 TLS 传输加密
transport.tls.enable = true

3. 容器应用内核心防线

  1. 启动 MFA 两步验证:成功登录 Next-Terminal 网页后,第一时间进入个人设置中心,绑定谷歌/微软身份验证器(OTP 动态口令)。
  2. 凭据安全:添加内部资产时,尽量避免直接存储 Root 明文密码,改用 SSH 密钥对(Key)形式或选择每次连接手动代填。

标签: none

添加新评论