Files
TrueGrowth/scripts/SECURITY.md

4.9 KiB
Raw Permalink Blame History

部署脚本安全指南

⚠️ 安全风险说明

如果将这些脚本开源,需要注意以下安全风险:

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
  • 中风险:如果用户使用密码认证,密码可能泄露

建议

  1. 在脚本顶部添加安全警告
  2. 在 README 中强调使用 SSH 密钥认证
  3. 提供 .env.example 文件
  4. 考虑添加更严格的输入验证