Cloud-init 与机器镜像
跳过手动安装的两种方式:在创建 VPS 时粘贴一份 cloud-init 模板, 或者构建一个已经装好一切的 机器镜像。
Cloud-init(一次一台服务器)
panel/deploy/cloud-init.yaml 是一个 user-data 模板。编辑
顶部那几项设置,在创建服务器时把它粘贴进你服务商的 “user data” 框,
服务器启动完成时面板就已就绪。进度和任何失败都会记录到
/var/log/nimbopanel-provision.log。
不要把 user data 当作机密存储
这是值得读两遍的部分。在每一家主流服务商上,user data 都可以
从运行中的实例内部 通过 169.254.169.254 上的 HTTP 取回——
而该地址可被机器上的 任何 进程访问,包括一个主机
客户的 PHP 脚本。
因此,粘贴进 user data 的一个许可证密钥,会被你托管的每一个客户读到, 除非有东西阻止它。模板分两步阻止它,按此顺序:
- 它在密钥落盘 之前 把元数据服务对除 root 以外的所有人 关闭;
- 在安装器把密钥存入仅 root 可读的配置之后,它会粉碎 user data 在磁盘上的副本。
如果你宁愿根本不把密钥放在那里,就把它留空,稍后从 面板输入。在你输入之前服务器以未授权状态运行,这是一种受支持的 状态。
机器镜像(一次构建,多台服务器)
panel/deploy/packer/nimbopanel.pkr.hcl 构建一个已装好整套栈的
镜像。时间就花在那里——软件包、PHP、邮件、DNS、数据库——
而这一切在各台服务器之间毫无差别。
那个会让每个克隆都变成同一台服务器的错误
镜像必须 不含任何身份。如果它含有,那么由它构建出的每一台服务器都会共享 那个身份:
| 被错误地烘焙进去的东西 | 在每个克隆上会发生什么 |
|---|---|
| SSH 主机密钥 | 它们全都出示相同的密钥。任何处于客户与其服务器之间的人都能冒充它,在所有克隆上,且不显示任何警告 |
| Nimbopanel 的 instance-id | 许可证指纹 由它派生,而安装器绝不会重新播种一个已存在的 id——于是一千台服务器看上去像一次激活 |
/etc/machine-id |
systemd、DHCP 租约和 journald 身份会发生冲突 |
| 面板数据库和配置 | 管理员密码、许可证密钥和每一个账户都装在一个陌生人下载的文件里 |
| DKIM 密钥、TLS 证书 | 是为构建机器签发的;在克隆上毫无意义,且泄露给拿到该镜像的每一个人 |
这些都不会自己声张。它们是后来被别人发现的。
panel/deploy/image-deidentify.sh 会把这一切全部移除,Packer 构建把它作为
最后 一步运行,然后再以 --check 重跑一次,因此构建会失败,
而不是产出一个只是看起来干净的快照。被移除的一切都会在
克隆首次启动时被重建:sshd 生成新的主机密钥,systemd 写入新的
machine-id,安装器播种一个全新的 instance-id。
/etc/machine-id 被留为 空,而不是删除——systemd 把一个空文件读作
“启动时生成一个”,而缺失的文件会让某些镜像根本无法启动。
发布之前先验证
sudo ./image-deidentify.sh # remove
sudo ./image-deidentify.sh --check # confirm, exits non-zero if anything survives
也要在一个已启动的克隆上运行这项检查,而不只是在构建时。如果它报告了任何东西, 就不要发布该镜像。
应用市场上架
服务商的 “一键应用” 项目(Vultr、DigitalOcean、Linode、Contabo)各自有 各自的提交格式和审核。上面的镜像正是他们所要的 产物;那些文书工作是各服务商特有的,不是这套工具能替你完成的。