跳到主要内容
版本:4.x

实践指南

安全性实践指南

写在前面,没有绝对的安全,如果环境允许的话尽量把 Spug 部署在内网且禁止公网访问,如果必须通过公网访问则尽可能通过防火墙等手段限制指定 IP 访问,并开启登录 MFA。

Spug 在登录安全方面提供了连续输错密码自动禁用账户的功能(同一账户累计 3 次失败后再次输错即被禁用,失败计数 24 小时后重置),尽可能的避免了被暴力破解登录的可能性。在 Token 安全方面提供了基于访问来源 IP 的 安全策略,当同一个 Token 访问来源 IP 发生变化时 Token 将自动失效,强制重新登录(可以通过 系统设置 / 安全设置 / 登录IP绑定 关闭该特性,不建议关闭)。

注意

Token 安全策略中的来源 IP 依赖 Nginx 转发请求时携带的 HTTP 头 X-Real-IPX-Forwarded-For, 所以请务必确保 Spug 能获取到用户的真实 IP 而不是上级的代理 IP,如果你使用的推荐的 Docker 部署方式,则这些工作默认已经做好了。 如果要在 Docker 容器暴露的 80 端口上再增加反向代理层,请正确配置 X-Forwarded-For,例如 Nginx 增加 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

在无法验证访问者的真实 IP 的情况下(Spug 获取到的 IP 是内网 IP),会在登录时弹出一个警告信息,如果 Spug 部署在内网且仅在内网使用(通过内网地址访问 Spug),则可以通过 系统管理 / 系统设置 / 安全设置 / 访问IP校验 来关闭这一特性。

发布过程中不同主机执行不同操作

假设一个应用需要发布到不同的三台主机上,但发布需要在主机上执行一些比如更新数据库等一次性且不能重复执行的操作,这时候可以考虑使用 Spug 的全局变量 SPUG_HOST_IDSPUG_HOST_NAME 来指定只在某个主机上执行这些操作,例如:

if [ "$SPUG_HOST_NAME" = "192.168.10.100" ]; then
echo "exec sql"
fi

默认PATH环境变量导致命令找不到问题

Spug 通过非交互式 SSH 会话执行命令,默认的 PATH 变量可能并不完整,如果出现一些命令找不到等报错情况可以使用类似如下写法来解决这个问题:

# 添加jdk至PATH变量
PATH=$PATH:/usr/local/jdk1.8.0_231/bin
java -jar xxx.jar

也可以在脚本开头执行 source /etc/profilesource ~/.bashrc 加载环境变量。

项目数据的持久存储

一些项目会在运行过程中生产需要持久存储的数据,例如用户上传的图片或需要留存的日志文件等。当使用常规发布时每个版本都是全新的目录,默认情况下这些文件会 在新版本中不可见。这种情况可以考虑把这些动态生成且需要持久存储的数据放在发布目录之外,通过软链接的形式链接至项目内,这样实际文件存储在一个公共的地 方每次更新时只需要额外做一个软链接的映射就可以解决问题了。

命令执行中的报错处理

从 v3 开始 Spug 移除了 set -e 特性,保持了与默认执行脚本行为一致。 如果你对执行中命令错误敏感,例如期望任何一个命令执行失败则中断 后续的命令,则可以在你编写的命令开头加上 set -e 即可。

使用 su 切换身份执行

默认情况下直接使用 su 命令将会导致执行到该命令时卡住无法继续执行,可通过如下方式使用 su 以使其正常工作:

su - ubuntu << EOF
echo '以ubuntu用户身份执行'
EOF

构建与发布分离

频繁发布的应用建议先在 构建仓库 中构建版本(或在测试环境发布时自动构建),验证通过后在生产环境的发布申请中选择 构建仓库 里同一个版本发布,保证测试与生产使用完全相同的产物,同时省去重复构建的时间。

用流水线串联外部 CI

如果代码构建在 Jenkins / GitLab CI 等外部系统完成,可以用 流水线数据上传 节点上传产物,再用 执行命令 节点解压、重启服务,最后用 推送 节点通知结果;需要人工确认的参数(版本号、是否重启)通过 参数化 节点在执行时填写。

监控告警自动恢复

任务计划 中创建触发器为 监控告警 的任务,执行对象选择 告警关联主机,例如进程检测异常时自动执行 systemctl restart nginx,实现简单的故障自愈。