use std::env;
use tracing::{info, warn};
pub fn clear_system_aws_env() {
let aws_env_vars = [
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"AWS_SESSION_TOKEN",
"AWS_SECURITY_TOKEN",
"AWS_REGION",
"AWS_DEFAULT_REGION",
"AWS_PROFILE",
"AWS_CONFIG_FILE",
"AWS_SHARED_CREDENTIALS_FILE",
"AWS_ROLE_ARN",
"AWS_WEB_IDENTITY_TOKEN_FILE",
"AWS_ROLE_SESSION_NAME",
"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI",
"AWS_CONTAINER_CREDENTIALS_FULL_URI",
"AWS_EC2_METADATA_DISABLED",
"AWS_ACCESS_KEY",
"AWS_SECRET_KEY",
];
let mut cleared_count = 0;
for var in &aws_env_vars {
if env::var(var).is_ok() {
env::remove_var(var);
cleared_count += 1;
warn!("🔒 已清理系统环境变量: {}", var);
}
}
info!("🔒 安全检查完成,已清理 {} 个AWS环境变量,强制使用.env文件配置", cleared_count);
validate_env_cleanup();
}
fn validate_env_cleanup() {
let critical_vars = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"];
let mut found_vars = Vec::new();
for var in &critical_vars {
if env::var(var).is_ok() {
found_vars.push(*var);
}
}
if !found_vars.is_empty() {
warn!("⚠️ 警告: 以下关键AWS环境变量仍然存在: {:?}", found_vars);
warn!("⚠️ 这可能导致从不安全的来源读取凭证!");
} else {
info!("✅ 安全验证通过:关键AWS环境变量已清理");
}
}
pub fn validate_env_file() -> Result<(), Box<dyn std::error::Error>> {
dotenv::dotenv().ok();
let required_vars = [
("AWS_ACCESS_KEY_ID", "AWS访问密钥ID"),
("AWS_SECRET_ACCESS_KEY", "AWS秘密访问密钥"),
("AWS_REGION", "AWS区域"),
];
for (var_name, description) in &required_vars {
match env::var(var_name) {
Ok(value) if !value.trim().is_empty() => {
info!("✅ {} 已在.env文件中正确配置", description);
}
Ok(_) => {
return Err(format!("❌ {} 在.env文件中为空", description).into());
}
Err(_) => {
return Err(format!("❌ {} 未在.env文件中设置", description).into());
}
}
}
info!("✅ .env文件验证通过,包含所有必需的AWS配置");
Ok(())
}
pub fn create_secure_aws_env() -> Result<(), Box<dyn std::error::Error>> {
clear_system_aws_env();
dotenv::dotenv().ok();
validate_env_file()?;
info!("🔐 安全AWS环境已配置完成,凭证仅来自.env文件");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
#[test]
fn test_clear_system_aws_env() {
env::set_var("AWS_ACCESS_KEY_ID", "test_key");
env::set_var("AWS_SECRET_ACCESS_KEY", "test_secret");
env::set_var("AWS_REGION", "us-east-1");
clear_system_aws_env();
assert!(env::var("AWS_ACCESS_KEY_ID").is_err());
assert!(env::var("AWS_SECRET_ACCESS_KEY").is_err());
assert!(env::var("AWS_REGION").is_err());
}
#[test]
fn test_validate_env_file_missing_vars() {
clear_system_aws_env();
assert!(validate_env_file().is_err());
}
}