QAUP_Management/deploy/docker/secrets-manager.sh

318 lines
8.3 KiB
Bash
Executable File

#!/bin/bash
# QAUP 敏感信息管理脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
SECRETS_DIR="$PROJECT_ROOT/secrets"
ENV_FILE="$PROJECT_ROOT/.env"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_message() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}
# 生成随机密码
generate_password() {
local length=${1:-16}
openssl rand -base64 $length | tr -d "=+/" | cut -c1-$length
}
# 生成强密码
generate_strong_password() {
local length=${1:-20}
# 包含大小写字母、数字和特殊字符
LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*' < /dev/urandom | head -c $length
}
# 初始化密钥管理
init_secrets() {
print_message $BLUE "初始化密钥管理..."
mkdir -p "$SECRETS_DIR"
chmod 700 "$SECRETS_DIR"
# 生成主密钥
local master_key_file="$SECRETS_DIR/master.key"
if [ ! -f "$master_key_file" ]; then
openssl rand -hex 32 > "$master_key_file"
chmod 600 "$master_key_file"
print_message $GREEN "主密钥已生成: $master_key_file"
fi
# 创建密钥配置文件
local secrets_config="$SECRETS_DIR/secrets.conf"
if [ ! -f "$secrets_config" ]; then
cat > "$secrets_config" << EOF
# QAUP 密钥配置文件
# 此文件包含加密后的敏感信息
# 数据库密码
POSTGRES_PASSWORD_ENCRYPTED=
APP_DB_PASSWORD_ENCRYPTED=
# Redis 密码
REDIS_PASSWORD_ENCRYPTED=
# Token 密钥
TOKEN_SECRET_ENCRYPTED=
# API 密钥
AIRPORT_API_PASSWORD_ENCRYPTED=
EOF
chmod 600 "$secrets_config"
print_message $GREEN "密钥配置文件已创建: $secrets_config"
fi
print_message $GREEN "密钥管理初始化完成"
}
# 加密字符串
encrypt_string() {
local plaintext="$1"
local master_key_file="$SECRETS_DIR/master.key"
if [ ! -f "$master_key_file" ]; then
print_message $RED "错误: 主密钥文件不存在,请先运行 init 命令"
exit 1
fi
local master_key=$(cat "$master_key_file")
echo -n "$plaintext" | openssl enc -aes-256-cbc -a -salt -pass pass:"$master_key"
}
# 解密字符串
decrypt_string() {
local encrypted="$1"
local master_key_file="$SECRETS_DIR/master.key"
if [ ! -f "$master_key_file" ]; then
print_message $RED "错误: 主密钥文件不存在"
exit 1
fi
local master_key=$(cat "$master_key_file")
echo -n "$encrypted" | openssl enc -aes-256-cbc -d -a -pass pass:"$master_key"
}
# 生成所有密码
generate_all_passwords() {
print_message $BLUE "生成所有密码..."
# 生成数据库密码
local postgres_password=$(generate_strong_password 20)
local app_db_password=$(generate_strong_password 20)
# 生成 Redis 密码
local redis_password=$(generate_strong_password 16)
# 生成 Token 密钥
local token_secret=$(generate_password 32)
# 生成 API 密码
local airport_api_password=$(generate_strong_password 16)
print_message $GREEN "密码生成完成:"
echo "PostgreSQL 管理员密码: $postgres_password"
echo "应用数据库密码: $app_db_password"
echo "Redis 密码: $redis_password"
echo "Token 密钥: $token_secret"
echo "机场 API 密码: $airport_api_password"
# 询问是否保存到配置文件
read -p "是否将密码保存到环境配置文件? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
save_passwords_to_env "$postgres_password" "$app_db_password" "$redis_password" "$token_secret" "$airport_api_password"
fi
}
# 保存密码到环境文件
save_passwords_to_env() {
local postgres_password="$1"
local app_db_password="$2"
local redis_password="$3"
local token_secret="$4"
local airport_api_password="$5"
if [ ! -f "$ENV_FILE" ]; then
print_message $RED "错误: 环境文件不存在: $ENV_FILE"
exit 1
fi
# 备份原文件
cp "$ENV_FILE" "$ENV_FILE.backup.$(date +%Y%m%d_%H%M%S)"
# 更新密码
sed -i.tmp "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$postgres_password/" "$ENV_FILE"
sed -i.tmp "s/^APP_DB_PASSWORD=.*/APP_DB_PASSWORD=$app_db_password/" "$ENV_FILE"
sed -i.tmp "s/^REDIS_PASSWORD=.*/REDIS_PASSWORD=$redis_password/" "$ENV_FILE"
sed -i.tmp "s/^TOKEN_SECRET=.*/TOKEN_SECRET=$token_secret/" "$ENV_FILE"
sed -i.tmp "s/^AIRPORT_API_PASSWORD=.*/AIRPORT_API_PASSWORD=$airport_api_password/" "$ENV_FILE"
rm -f "$ENV_FILE.tmp"
print_message $GREEN "密码已保存到环境文件"
}
# 验证密码强度
validate_password_strength() {
local password="$1"
local min_length=8
local score=0
# 检查长度
if [ ${#password} -ge $min_length ]; then
score=$((score + 1))
fi
# 检查是否包含小写字母
if [[ "$password" =~ [a-z] ]]; then
score=$((score + 1))
fi
# 检查是否包含大写字母
if [[ "$password" =~ [A-Z] ]]; then
score=$((score + 1))
fi
# 检查是否包含数字
if [[ "$password" =~ [0-9] ]]; then
score=$((score + 1))
fi
# 检查是否包含特殊字符
if [[ "$password" =~ [^a-zA-Z0-9] ]]; then
score=$((score + 1))
fi
case $score in
0-2)
print_message $RED "密码强度: 弱"
return 1
;;
3)
print_message $YELLOW "密码强度: 中等"
return 0
;;
4-5)
print_message $GREEN "密码强度: 强"
return 0
;;
esac
}
# 检查环境文件中的密码
check_env_passwords() {
print_message $BLUE "检查环境文件中的密码强度..."
if [ ! -f "$ENV_FILE" ]; then
print_message $RED "错误: 环境文件不存在: $ENV_FILE"
exit 1
fi
source "$ENV_FILE"
local weak_passwords=0
# 检查各种密码
echo "检查 PostgreSQL 密码..."
if ! validate_password_strength "$POSTGRES_PASSWORD"; then
weak_passwords=$((weak_passwords + 1))
fi
echo "检查应用数据库密码..."
if ! validate_password_strength "$APP_DB_PASSWORD"; then
weak_passwords=$((weak_passwords + 1))
fi
if [ -n "$REDIS_PASSWORD" ]; then
echo "检查 Redis 密码..."
if ! validate_password_strength "$REDIS_PASSWORD"; then
weak_passwords=$((weak_passwords + 1))
fi
fi
if [ $weak_passwords -eq 0 ]; then
print_message $GREEN "所有密码强度检查通过"
else
print_message $YELLOW "发现 $weak_passwords 个弱密码,建议重新生成"
fi
}
# 显示帮助信息
show_help() {
echo "QAUP 敏感信息管理脚本"
echo ""
echo "用法: $0 [命令] [选项]"
echo ""
echo "命令:"
echo " init 初始化密钥管理"
echo " generate 生成所有密码"
echo " check 检查密码强度"
echo " encrypt <text> 加密文本"
echo " decrypt <text> 解密文本"
echo ""
echo "示例:"
echo " $0 init # 初始化密钥管理"
echo " $0 generate # 生成所有密码"
echo " $0 check # 检查密码强度"
echo " $0 encrypt 'mypassword' # 加密密码"
}
# 主函数
main() {
if [ $# -eq 0 ]; then
show_help
exit 0
fi
local command=$1
shift
case $command in
init)
init_secrets
;;
generate)
generate_all_passwords
;;
check)
check_env_passwords
;;
encrypt)
if [ $# -eq 0 ]; then
print_message $RED "错误: 请提供要加密的文本"
exit 1
fi
encrypt_string "$1"
;;
decrypt)
if [ $# -eq 0 ]; then
print_message $RED "错误: 请提供要解密的文本"
exit 1
fi
decrypt_string "$1"
;;
help|--help|-h)
show_help
;;
*)
print_message $RED "未知命令: $command"
show_help
exit 1
;;
esac
}
main "$@"