burncloud-aws 0.1.1

burncloud-aws
Documentation
//! 安全模块 - 确保AWS凭证只能从.env文件读取

use std::env;
use tracing::{info, warn};

/// 🔒 强制清理所有AWS相关的系统环境变量,确保只能从.env文件读取凭证
///
/// 这是一个安全函数,用于防止程序从系统环境变量读取AWS凭证,
/// 强制要求用户在.env文件中配置凭证,避免凭证泄露风险。
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",

        // 容器和IAM相关变量
        "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环境变量已清理");
    }
}

/// 强制验证.env文件包含必需的AWS凭证
pub fn validate_env_file() -> Result<(), Box<dyn std::error::Error>> {
    // 确保dotenv加载
    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(())
}

/// 创建安全的AWS凭证加载器,仅从.env文件读取
pub fn create_secure_aws_env() -> Result<(), Box<dyn std::error::Error>> {
    // 第一步:清理系统环境变量
    clear_system_aws_env();

    // 第二步:加载.env文件
    dotenv::dotenv().ok();

    // 第三步:验证.env文件配置
    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());
    }
}