堡垒机Next-Terminal
以下是为你整理的 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 卡寿命,已进行极致优化:
- 日志级别降为
error,且关闭了运行日志文件和 Web 访问日志的写入,避免高频 I/O 导致卡顿或磁盘爆满。 - 数据库和组件连接均使用 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
五、 组件连通性排查流程
当网页可以成功打开,但需要确认后端与 pgsql 及 guacd 是否完全正常工作时,按以下步骤排查:
1. 验证 PostgreSQL 通信与初始化
由于主程序启动强制校验数据库,若成功进入登录页则代表基本握手成功。如需彻底确认,可检查 Next-Terminal 是否成功在 PG 库中完成建表:
podman exec -it pgsql psql -U nextterminal -d next_terminal_db -c "\dt"
- 正常状态:终端应输出
users、assets等系统级表结构列表。
2. 验证 guacd 编解码组件通信
- 登录 Next-Terminal 网页,创建一台香橙派本地 IP 的 SSH 资产并点击连接。
- 在香橙派宿主机终端死盯着 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. 容器应用内核心防线
- 启动 MFA 两步验证:成功登录 Next-Terminal 网页后,第一时间进入个人设置中心,绑定谷歌/微软身份验证器(OTP 动态口令)。
- 凭据安全:添加内部资产时,尽量避免直接存储 Root 明文密码,改用 SSH 密钥对(Key)形式或选择每次连接手动代填。