Skip to main content

burncloud_aws/
security.rs

1//! 安全模块 - 确保AWS凭证只能从.env文件读取
2
3use std::env;
4use tracing::{info, warn};
5
6/// 🔒 强制清理所有AWS相关的系统环境变量,确保只能从.env文件读取凭证
7///
8/// 这是一个安全函数,用于防止程序从系统环境变量读取AWS凭证,
9/// 强制要求用户在.env文件中配置凭证,避免凭证泄露风险。
10pub fn clear_system_aws_env() {
11    let aws_env_vars = [
12        // 基础凭证变量
13        "AWS_ACCESS_KEY_ID",
14        "AWS_SECRET_ACCESS_KEY",
15        "AWS_SESSION_TOKEN",
16        "AWS_SECURITY_TOKEN",
17
18        // 区域配置变量
19        "AWS_REGION",
20        "AWS_DEFAULT_REGION",
21
22        // 配置文件变量
23        "AWS_PROFILE",
24        "AWS_CONFIG_FILE",
25        "AWS_SHARED_CREDENTIALS_FILE",
26
27        // 角色和临时凭证变量
28        "AWS_ROLE_ARN",
29        "AWS_WEB_IDENTITY_TOKEN_FILE",
30        "AWS_ROLE_SESSION_NAME",
31
32        // 容器和IAM相关变量
33        "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI",
34        "AWS_CONTAINER_CREDENTIALS_FULL_URI",
35        "AWS_EC2_METADATA_DISABLED",
36
37        // 其他可能的凭证变量
38        "AWS_ACCESS_KEY",
39        "AWS_SECRET_KEY",
40    ];
41
42    let mut cleared_count = 0;
43    for var in &aws_env_vars {
44        if env::var(var).is_ok() {
45            env::remove_var(var);
46            cleared_count += 1;
47            warn!("🔒 已清理系统环境变量: {}", var);
48        }
49    }
50
51    info!("🔒 安全检查完成,已清理 {} 个AWS环境变量,强制使用.env文件配置", cleared_count);
52
53    // 验证清理是否成功
54    validate_env_cleanup();
55}
56
57/// 验证环境变量清理是否成功
58fn validate_env_cleanup() {
59    let critical_vars = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"];
60    let mut found_vars = Vec::new();
61
62    for var in &critical_vars {
63        if env::var(var).is_ok() {
64            found_vars.push(*var);
65        }
66    }
67
68    if !found_vars.is_empty() {
69        warn!("⚠️ 警告: 以下关键AWS环境变量仍然存在: {:?}", found_vars);
70        warn!("⚠️ 这可能导致从不安全的来源读取凭证!");
71    } else {
72        info!("✅ 安全验证通过:关键AWS环境变量已清理");
73    }
74}
75
76/// 强制验证.env文件包含必需的AWS凭证
77pub fn validate_env_file() -> Result<(), Box<dyn std::error::Error>> {
78    // 确保dotenv加载
79    dotenv::dotenv().ok();
80
81    let required_vars = [
82        ("AWS_ACCESS_KEY_ID", "AWS访问密钥ID"),
83        ("AWS_SECRET_ACCESS_KEY", "AWS秘密访问密钥"),
84        ("AWS_REGION", "AWS区域"),
85    ];
86
87    for (var_name, description) in &required_vars {
88        match env::var(var_name) {
89            Ok(value) if !value.trim().is_empty() => {
90                info!("✅ {} 已在.env文件中正确配置", description);
91            }
92            Ok(_) => {
93                return Err(format!("❌ {} 在.env文件中为空", description).into());
94            }
95            Err(_) => {
96                return Err(format!("❌ {} 未在.env文件中设置", description).into());
97            }
98        }
99    }
100
101    info!("✅ .env文件验证通过,包含所有必需的AWS配置");
102    Ok(())
103}
104
105/// 创建安全的AWS凭证加载器,仅从.env文件读取
106pub fn create_secure_aws_env() -> Result<(), Box<dyn std::error::Error>> {
107    // 第一步:清理系统环境变量
108    clear_system_aws_env();
109
110    // 第二步:加载.env文件
111    dotenv::dotenv().ok();
112
113    // 第三步:验证.env文件配置
114    validate_env_file()?;
115
116    info!("🔐 安全AWS环境已配置完成,凭证仅来自.env文件");
117    Ok(())
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use std::env;
124
125    #[test]
126    fn test_clear_system_aws_env() {
127        // 设置一些测试环境变量
128        env::set_var("AWS_ACCESS_KEY_ID", "test_key");
129        env::set_var("AWS_SECRET_ACCESS_KEY", "test_secret");
130        env::set_var("AWS_REGION", "us-east-1");
131
132        // 执行清理
133        clear_system_aws_env();
134
135        // 验证清理
136        assert!(env::var("AWS_ACCESS_KEY_ID").is_err());
137        assert!(env::var("AWS_SECRET_ACCESS_KEY").is_err());
138        assert!(env::var("AWS_REGION").is_err());
139    }
140
141    #[test]
142    fn test_validate_env_file_missing_vars() {
143        // 清理所有环境变量
144        clear_system_aws_env();
145
146        // 验证应该失败
147        assert!(validate_env_file().is_err());
148    }
149}