本文目录导读:

- 使用环境变量(基础方案)
- 使用密钥文件
- 加密存储与解密
- Docker Secrets(Docker Swarm模式)
- HashiCorp Vault集成
- AWS Secrets Manager集成
- Kubernetes Secrets
- 安全的配置文件管理
- 最佳实践脚本模板
- 安全建议
在Shell脚本中配置容器密钥管理,主要有以下几种安全实践方案:
使用环境变量(基础方案)
#!/bin/bash # 设置密钥环境变量 export DB_PASSWORD="your_secure_password" export API_KEY="your_api_key_here" # 运行容器时注入 docker run -e DB_PASSWORD -e API_KEY your_image
使用密钥文件
#!/bin/bash # 创建安全的密钥文件 SECRETS_DIR="/run/secrets" mkdir -p $SECRETS_DIR chmod 700 $SECRETS_DIR # 写入密钥 echo "your_secure_password" > $SECRETS_DIR/db_password chmod 600 $SECRETS_DIR/db_password # Docker使用密钥文件 docker run -v $SECRETS_DIR/db_password:/run/secrets/db_password your_image
加密存储与解密
#!/bin/bash
# 使用GPG加密密钥文件
gpg --symmetric --cipher-algo AES256 secrets.txt
# 脚本中解密使用
decrypt_secret() {
local secret_file=$1
gpg --decrypt --quiet "${secret_file}.gpg" 2>/dev/null
}
# 使用示例
DB_PASSWORD=$(decrypt_secret "db_password")
Docker Secrets(Docker Swarm模式)
#!/bin/bash # 创建Docker secret echo "my_secret_password" | docker secret create db_password - # 在服务中使用 docker service create \ --secret db_password \ --name my_service \ your_image
HashiCorp Vault集成
#!/bin/bash
# Vault认证
vault_login() {
local role_id=$1
local secret_id=$2
vault write auth/approle/login \
role_id="$role_id" \
secret_id="$secret_id" \
-format=json | jq -r '.auth.client_token'
}
# 获取密钥
get_secret() {
local path=$1
local token=$2
vault kv get \
-token="$token" \
-format=json "$path" | jq -r '.data.data'
}
# 使用示例
TOKEN=$(vault_login "role_id" "secret_id")
DB_PASSWORD=$(get_secret "secret/data/database" "$TOKEN" | jq -r '.password')
AWS Secrets Manager集成
#!/bin/bash
# 需要安装AWS CLI
get_aws_secret() {
local secret_name=$1
local region=${2:-us-east-1}
aws secretsmanager get-secret-value \
--secret-id "$secret_name" \
--region "$region" \
--query SecretString \
--output text
}
# 使用示例
DB_PASSWORD=$(get_aws_secret "prod/db/password")
Kubernetes Secrets
#!/bin/bash
# 创建K8s Secret
kubectl create secret generic db-secret \
--from-literal=password='your_password'
# 脚本中读取
get_k8s_secret() {
local secret_name=$1
local namespace=${2:-default}
kubectl get secret "$secret_name" \
-n "$namespace" \
-o jsonpath="{.data.password}" | base64 --decode
}
DB_PASSWORD=$(get_k8s_secret "db-secret")
安全的配置文件管理
#!/bin/bash
# 使用模板和envsubst
cat > config.template << EOF
DATABASE_URL=postgresql://user:${DB_PASSWORD}@localhost/db
API_KEY=${API_KEY}
EOF
# 应用配置
envsubst < config.template > config.prod
# 清理敏感文件
secure_cleanup() {
local files=("$@")
for file in "${files[@]}"; do
if [ -f "$file" ]; then
# 使用shred安全删除
shred -z -u "$file"
fi
done
}
trap 'secure_cleanup config.prod secrets.txt' EXIT
最佳实践脚本模板
#!/bin/bash
set -euo pipefail
# 配置
SECRETS_DIR="/run/secrets"
ENCRYPTION_KEY_FILE="/etc/secrets/key"
# 安全清理
cleanup() {
unset DB_PASSWORD API_KEY SECRET_TOKEN
if [ -d "$SECRETS_DIR" ]; then
find "$SECRETS_DIR" -type f -exec shred -z -u {} \;
fi
}
trap cleanup EXIT ERR SIGINT SIGTERM
# 加载密钥函数
load_secrets() {
local source=$1
case $source in
file)
if [ -f "$SECRETS_DIR/db_password" ]; then
DB_PASSWORD=$(cat "$SECRETS_DIR/db_password")
export DB_PASSWORD
fi
;;
env)
# 从环境变量读取
DB_PASSWORD=${DB_PASSWORD:-}
;;
vault)
# 从Vault读取
DB_PASSWORD=$(vault kv get -field=password secret/database)
;;
*)
echo "Unknown secret source: $source"
exit 1
;;
esac
# 验证密钥存在
if [ -z "${DB_PASSWORD:-}" ]; then
echo "ERROR: Database password not set"
exit 1
fi
}
# 主逻辑
main() {
# 加载密钥
load_secrets "${SECRET_SOURCE:-file}"
# 使用密钥启动容器
docker run -d \
--name my_app \
-e DB_PASSWORD \
your_image:latest
}
# 执行主函数
main "$@"
安全建议
- 最小权限原则:只给脚本必要的密钥访问权限
- 密钥轮换:定期更换密钥,脚本应支持动态更新
- 审计日志:记录密钥访问行为
- 传输加密:所有密钥传输使用TLS
- 内存保护:避免密钥持久化到磁盘或日志
- 时间限制:为临时密钥设置过期时间
选择哪种方案取决于你的基础设施和应用需求,对于生产环境,推荐使用专门的密钥管理服务(如Vault、AWS Secrets Manager)。