
Ghostwriter
用 Docker 与 Ghostwriter CLI 部署 Ghostwriter 服务端
Ghostwriter 采用数据库、应用、界面三层容器架构。本文按前置条件、Docker 版本校验、CLI 下载解包、install 命令、登录与常见定制(日期格式、自有证书、域名与 IP 白名单、代理信任、新增用户、TOTP 迁移)的顺序,讲清一次可跑通的部署流程,并给出配置改动后重启容器的方法。
Ghostwriter 是一套面向红队与渗透测试团队的报告与项目管理平台,采用数据库、应用、界面分层的多容器架构。它把客户与项目管理、发现库、观察记录库、基础设施管理、操作日志、报告生成以及 BloodHound 集成等功能放在同一个 Web 界面里,适合需要多人协作撰写报告的安全团队。本文要讲的是最基础也最关键的一步:用 Docker 和 Ghostwriter CLI 在一台机器上把 Ghostwriter 服务端装起来、登录进去,并完成常见的安装后定制。如果你只是想先看看界面长什么样,也可以借助 Ghostwriter 这个工具条目了解它的定位,再回到本文按步骤操作。
整个流程可以概括为:确认机器规格与 Docker 版本 → 下载对应平台的 Ghostwriter CLI → 解包 → 执行 install → 用随机生成的 admin 密码登录 → 按需修改配置并重启容器。下面逐段展开。
准备工作
确认硬件规格
Ghostwriter 的容器化部署对资源有明确要求,官方给出的最低规格与较大团队(超过 5 名用户)的推荐规格如下:
| 资源项 | 最低规格 | 较大团队(>5 用户) |
|---|---|---|
| 内存 | 2GB RAM | 16GB RAM |
| 处理器 | 2 个核心 | 4 个核心 |
| 硬盘 | 10GB | 60GB |
之所以推荐规格明显高于最低值,是因为 Ghostwriter 包含完整的协作编辑功能,同时在线用户越多,占用的资源越多。用于生产环境时,建议直接按较高规格准备。按素材的说法,较高规格大致相当于 AWS 上的 t3.xlarge 实例。具体机型与价格请以云厂商官网当前信息为准。
安装并校验 Docker
最省事的方式是安装 Docker Desktop,在本地机器上运行 Ghostwriter 容器。版本上有两条硬性要求:
- Docker 版本需大于等于 20,因为 Ghostwriter 使用的是 Alpine Linux 镜像。
- Docker Compose 版本需大于等于 1.26,才能正确解析 compose 文件。
先检查版本:
docker compose version
# 例如输出 Docker Compose version v2.23.3,即满足 >= 1.26.x
docker version
# 查看 Client 与 Server 两处的 Version 值,需 >= 20
Compose 版本这条限制不是可有可无的。低于 v1.26 的版本会尝试自行构建容器,并在解析配置文件时出错,问题集中在引号处理上:旧版 DotEnv 解析器会把带引号的端口号当成字面量,于是 Docker 尝试绑定 "8000" 这种带引号的值时报错。从 v1.26 起 Compose 改用 Python 的 DotEnv 解析器,能正确理解引号。
另外注意命令形式:旧版安装的 Compose 命令是 docker-compose(带连字符)。如果你的 PATH 里只有 docker-compose 而没有 docker compose,建议升级到最新版本,后续命令统一使用 docker compose 形式。
操作步骤
第一步:下载 Ghostwriter CLI
Ghostwriter CLI 是一个用于安装和管理 Ghostwriter 及其容器的命令行工具。到发布页下载与你的操作系统(macOS、Linux、Windows)和架构(AMD64 或 ARM)匹配的最新版本。也可以直接用命令行下载,各平台示例:
# Linux
wget <ghostwriter-cli-linux-amd64.tar.gz 的下载地址>
# Windows PowerShell
curl.exe -L -o "$env:USERPROFILE\Downloads\ghostwriter-cli-windows-amd64.zip" <下载地址>
# macOS(ARM)
curl -L -o ghostwriter-cli-darwin-arm64.tar.gz <下载地址>
下载地址请以发布页当前提供的链接为准,注意区分 amd64 与 arm64 两种架构包,选错架构会导致解包后的可执行文件无法运行。
第二步:解包
切换到下载目录,解压文件:
# Linux
tar -xvzf ghostwriter-cli-linux-amd64.tar.gz
# Windows PowerShell
cd "$env:USERPROFILE\Downloads"; tar -xf ghostwriter-cli-windows-amd64.zip
# macOS
tar -xvzf ghostwriter-cli-darwin-arm64.tar.gz
第三步:执行 install 命令
在终端或 PowerShell 中进入解包后的目录,运行安装命令。三个平台的调用方式略有差别:
# Linux / macOS
./ghostwriter-cli install
# Windows PowerShell
.\ghostwriter-cli install
安装过程中,Ghostwriter 会生成 TLS 证书并下载最新的 Docker 文件。这些文件会落在操作系统的 XDG 数据目录下:
- Linux:
~/.local/share/ghostwriter/ - macOS:
~/Library/Application Support/ghostwriter/ - Windows:
%LOCALAPPDATA%/ghostwriter/
install 命令实际上完成了一整套生产环境搭建动作:写入默认服务器配置、生成服务器 TLS 证书、拉取最新的预构建容器镜像、创建一个带随机密码的默认 admin 用户。也就是说,正常情况下你不需要再手工准备数据库或应用容器。
第四步:等待安装完成并保存密码
保持终端窗口打开,直到看到随机生成的密码输出:
[+] Ghostwriter is ready to go!
[+] You can log in as `admin` with this password: <Password>
把这个密码记下来,下一步登录要用。如果弄丢了,可以用下面的命令从配置里取回:
# Linux / macOS
./ghostwriter-cli config get ADMIN_PASSWORD
# Windows PowerShell
.\ghostwriter-cli config get ADMIN_PASSWORD
关于这个密码有两点需要理解清楚。第一,它只用于创建账号;登录 Ghostwriter 后可以在管理面板里修改密码,用户资料的其他部分也可以改。第二,在配置里修改密码不会影响已安装的系统——配置中保留它只是为了方便你随时取回初始密码。
第五步:登录 Ghostwriter
在浏览器中打开服务器地址,用 admin 用户名和刚才的随机密码登录。生产模式下 Ghostwriter 监听 443 端口。
如果只是开发或测试用途,可以在安装时加上 --mode local-dev:
./ghostwriter-cli install --mode local-dev
开发模式下 Ghostwriter 监听 localhost(127.0.0.1)的 8000 端口,并启用调试日志,排查问题更方便。开发模式不使用 TLS,因此会跳过证书生成。如果你打算修改 Ghostwriter 的代码库或测试功能,开发环境更合适。
第六步:按需定制并重启
安装完成后可以调整配置。任何配置改动都需要重启 Ghostwriter 才能生效,重启方式是先停容器再起容器:
./ghostwriter-cli containers down
./ghostwriter-cli containers up
下面几项是最常见的定制内容。
修改日期格式
默认格式是 d M Y,渲染出来类似 3 Jun 2022,界面部分区域和报告中都使用这个格式。修改命令:
./ghostwriter-cli config set date_format "d M Y"
设置 DATE_FORMAT 时要使用 Django 的格式字符串取值,不要写成其他日期库的占位符。
使用自有 TLS 证书
Ghostwriter 默认生成自签名证书。如果想换成自己的签名证书,按以下命名与位置放置文件:
- 密钥对文件命名为
ghostwriter.key与ghostwriter.crt - Diffie-Helman 参数文件命名为
dhparam.pem - 三个文件都放进安装时创建的
ssl目录,例如~/.local/share/ghostwriter/ssl、~/Library/Application Support/ghostwriter/ssl或%LOCALAPPDATA%/ghostwriter/ssl
换证书通常意味着主机名也变了,所以接着要做下一项域名配置。证书如果暂时没准备好,也可以先装完再换。
配置域名或 IP 地址
Ghostwriter 会显式校验主机名是否在允许列表内,以防止 HTTP Host 头攻击。因此用自定义域名或服务器 IP 访问时,必须先把新地址加入允许列表:
./ghostwriter-cli config allowhost <你的域名或 IP>
如果新域名同时配了 TLS 证书,还要把 Nginx 的主机名改成与新证书、新域名一致:
./ghostwriter-cli config set NGINX_HOST <你的域名>
要移除已添加的主机,用 config disallowhost。这里有一个容易踩的坑:通配符 * 可以使用,但只接受单独的 *,它会放行任意主机名或 IP。像 *.myserver.local 或 192.168.10.* 这样的部分通配写法不起作用,无法放行主机。虽然通配符可用,但并不推荐。
通过 Web 代理访问
与 Host 头保护类似,Ghostwriter 还会校验 Origin 和 Referer 头。如果通过代理访问 Ghostwriter,需要把代理配置为受信任来源:
./ghostwriter-cli config trustorigin <你的代理>
要撤销信任,用 config distrustorigin。
添加更多用户
用户可以通过管理面板创建,也可以让用户自行访问 /accounts/signup 注册。建议要求用户填写完整资料,因为 Ghostwriter 会用全名来显示用户操作记录、填充报告模板。另外 Django 的用户名区分大小写,为避免后续混淆,建议统一使用小写。
迁移旧版安装的 TOTP 密钥
如果是从使用 allauth-2fa 做双因素认证的旧版本升级,需要把 TOTP 密钥迁移到新格式:
./ghostwriter-cli migrate_totp
一个完整示例
下面以一台 Linux AMD64 机器为例,走一遍从零到登录的最小流程。假设机器已满足 2GB 内存、2 核、10GB 磁盘的最低要求,且 Docker 与 Compose 版本已通过上面的校验。
# 1. 下载 CLI 包
wget <ghostwriter-cli-linux-amd64.tar.gz 的下载地址>
# 2. 解包
tar -xvzf ghostwriter-cli-linux-amd64.tar.gz
# 3. 进入解包目录并安装
cd ghostwriter-cli-linux-amd64
./ghostwriter-cli install
# 4. 终端会输出随机密码,例如:
# [+] Ghostwriter is ready to go!
# [+] You can log in as `admin` with this password: <Password>
# 5. 若忘记密码,随时取回
./ghostwriter-cli config get ADMIN_PASSWORD
# 6. 浏览器访问服务器地址(生产模式监听 443),用 admin + 上述密码登录
# 7. 假设要把访问地址改为 gw.example.internal,先放行主机
./ghostwriter-cli config allowhost gw.example.internal
./ghostwriter-cli config set NGINX_HOST gw.example.internal
# 8. 重启容器让配置生效
./ghostwriter-cli containers down
./ghostwriter-cli containers up
如果只是本地试跑,把第 3 步换成 ./ghostwriter-cli install --mode local-dev,然后访问 http://127.0.0.1:8000 即可,不需要处理证书与 443 端口。
注意事项
- 版本门槛:Docker 需 >= 20,Docker Compose 需 >= 1.26。低于 1.26 的 Compose 会在解析带引号的配置值时出错,导致端口绑定失败。
- 命令形式:如果系统里只有
docker-compose而没有docker compose,说明 Compose 版本偏旧,建议升级。 - 架构匹配:下载 CLI 时务必选对 AMD64 或 ARM,选错会导致可执行文件无法运行。
- 密码语义:初始随机密码只用于创建账号;在配置里改密码不会改变已安装系统的登录密码,登录后应在管理面板中修改。
- 配置生效:任何配置改动后都要执行
containers down再containers up,否则改动不生效。 - 主机白名单:只支持完整域名、IP 或单独的
*,不支持*.domain、192.168.10.*这类部分通配。 - 代理场景:通过代理访问时,除了放行主机,还要用
trustorigin信任代理,否则 Origin 与 Referer 校验会拦截请求。 - 用户名大小写:Django 用户名区分大小写,建议统一小写。
- 资源随人数增长:协作编辑功能会随同时在线人数增加而占用更多资源,生产环境按较高规格准备。
- 易变信息:镜像版本、实例规格、云厂商价格等请以官网当前信息为准。