4.9 KiB
4.9 KiB
部署脚本安全指南
⚠️ 安全风险说明
如果将这些脚本开源,需要注意以下安全风险:
1. 密码泄露风险
风险等级:高
- 问题:脚本从
.env文件读取密码,如果.env文件被意外提交到 Git,密码会泄露 - 缓解措施:
- ✅
.env已在.gitignore中(已确认) - ✅ 脚本中不包含硬编码的密码
- ⚠️ 建议添加
.env.example文件作为模板(不包含真实密码)
- ✅
2. 密码在进程列表中可见
风险等级:中
- 问题:使用
sshpass -p "password"时,密码会出现在进程列表中(ps aux) - 缓解措施:
- ✅ 优先使用 SSH 密钥认证(推荐)
- ⚠️ 如果必须使用密码,考虑使用环境变量或
sshpass -e(从环境变量读取)
3. Sudo 密码传递方式不安全
风险等级:中
- 问题:使用
echo 'password' | sudo -S时,密码可能出现在命令历史或进程列表中 - 缓解措施:
- ⚠️ 建议配置免密 sudo(更安全)
- ⚠️ 或者使用
expect脚本(但增加了复杂性)
4. 命令注入风险
风险等级:中
- 问题:如果配置值包含特殊字符(如
;、|、&),可能导致命令注入 - 当前保护:
- ✅ 使用双引号包裹变量
- ✅ 密码转义单引号
- ⚠️ 但路径变量(如
tempPath)未完全转义
5. SSH 安全选项
风险等级:低
- 问题:
StrictHostKeyChecking=no禁用了主机密钥验证 - 说明:这是为了自动化部署的便利性,但降低了安全性
- 建议:在生产环境首次连接后,应该使用已知主机文件
🔒 安全建议
1. 使用 SSH 密钥认证(强烈推荐)
# 生成 SSH 密钥对
ssh-keygen -t ed25519 -C "deploy@aitu"
# 将公钥添加到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# 在 .env 中配置
DEPLOY_SSH_KEY=~/.ssh/id_ed25519
2. 配置免密 Sudo(推荐)
在服务器上配置:
# 编辑 sudoers 文件
sudo visudo
# 添加以下行(将 username 替换为实际用户名)
username ALL=(ALL) NOPASSWD: /bin/cp, /bin/rm, /usr/sbin/nginx, /bin/systemctl, /usr/sbin/service
3. 使用环境变量传递密码(如果必须)
修改脚本使用环境变量:
# 在 .env 中不存储密码,而是使用环境变量
export DEPLOY_SSH_PASSWORD="your-password"
export DEPLOY_SUDO_PASSWORD="your-sudo-password"
# 使用 sshpass -e(从环境变量读取)
sshpass -e ssh ...
4. 限制 SSH 密钥权限
# 使用受限的 SSH 密钥(只能执行特定命令)
# 在服务器的 ~/.ssh/authorized_keys 中添加:
command="/usr/bin/sudo /bin/cp /tmp/*.conf /etc/nginx/sites-enabled/",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAAC3...
5. 使用专用部署用户
- 创建专门的部署用户(如
deploy) - 限制该用户的权限
- 只允许执行必要的命令
6. 添加 .env.example 文件
创建示例配置文件,不包含真实密码:
# .env.example
DEPLOY_HOST=your-server.com
DEPLOY_USER=username
DEPLOY_PORT=22
DEPLOY_SSH_KEY=~/.ssh/id_rsa
# DEPLOY_SSH_PASSWORD= # 不推荐,使用 SSH 密钥
# DEPLOY_SUDO_PASSWORD= # 建议配置免密 sudo
📋 开源前检查清单
- 确认
.env在.gitignore中 - 创建
.env.example文件(不包含真实密码) - 检查脚本中是否有硬编码的服务器地址、密码等
- 添加安全警告注释到脚本顶部
- 在 README 中添加安全使用说明
- 考虑添加命令注入防护(更严格的输入验证)
🛡️ 改进建议
1. 增强命令注入防护
// 转义 shell 特殊字符
function escapeShellArg(str) {
return "'" + str.replace(/'/g, "'\\''") + "'";
}
// 使用转义函数
const safePath = escapeShellArg(tempPath);
const safeRemotePath = escapeShellArg(remotePath);
2. 使用更安全的密码传递方式
// 使用环境变量而不是命令行参数
if (config.DEPLOY_SSH_PASSWORD) {
process.env.SSHPASS = config.DEPLOY_SSH_PASSWORD;
scpCommand = 'sshpass -e scp';
}
3. 添加输入验证
// 验证服务器地址格式
function validateHost(host) {
const hostPattern = /^[a-zA-Z0-9.-]+$/;
if (!hostPattern.test(host)) {
throw new Error('Invalid host format');
}
}
📝 总结
当前安全状态:
- ✅ 基本安全措施已到位(
.env在.gitignore中) - ⚠️ 密码传递方式可以改进
- ⚠️ 建议优先使用 SSH 密钥和免密 sudo
开源风险评估:
- 低风险:如果用户遵循最佳实践(使用 SSH 密钥、免密 sudo)
- 中风险:如果用户使用密码认证,密码可能泄露
建议:
- 在脚本顶部添加安全警告
- 在 README 中强调使用 SSH 密钥认证
- 提供
.env.example文件 - 考虑添加更严格的输入验证