我在生产环境中看到的7个Azure安全缺口(以及如何修复它们)

发布: (2025年12月15日 GMT+8 08:59)
7 min read
原文: Dev.to

Source: Dev.to

1. 网络安全组(NSG)规则不足

问题

网络安全组(NSG)是 Azure 虚拟机的主要网络层控制。生产环境中常出现过于宽松的入站规则,例如:

  • Allow * from 0.0.0.0/0
  • SSH(22)或 RDP(3389)对公网开放

实际案例

在一次安全审计中,发现 12 台生产 VM 的 SSH 对互联网开放。NSG 流日志显示 30 天内超过 50,000 次登录失败

检测方法

Azure 门户

  • 网络安全组 → 入站规则 – 查找:
    • 源:Any0.0.0.0/0
    • 端口:22338914335432
  • 查看每台 VM 的有效安全规则

KQL(NSG 流日志)

AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog"
| where SrcIP_s !startswith "10."
  and SrcIP_s !startswith "172."
  and SrcIP_s !startswith "192.168."
| where DestPort_d in (22, 3389)
| summarize Attempts = count() by SrcIP_s, DestPort_d
| order by Attempts desc

解决方案

立即措施

  • 删除 SSH/RDP 的 0.0.0.0/0 访问
  • 将可信的办公或 VPN IP 加入白名单
  • 使用 Azure Bastion 实现安全远程访问
  • 通过 Microsoft Defender for Cloud 启用 Just‑In‑Time (JIT) VM 访问

长期措施

  • 采用 应用安全组 (ASG)
  • 部署 Azure 防火墙 进行集中过滤
  • 使用 Azure Policy 强制执行 NSG 标准

2. 缺失 Azure 备份策略

问题

许多团队误以为 Azure 会自动备份 VM,实际上并不会。生产工作负载中常发现没有恢复服务保管库或任何备份计划。

检测方法

Azure 门户

  • 恢复服务保管库 → 备份项 – 与 VM 清单进行对比。

KQL 查询

Resources
| where type == "microsoft.compute/virtualmachines"
| project name, resourceGroup
| join kind=leftouter (
    RecoveryServicesResources
    | where type contains "protectedItems"
    | extend vmName = tostring(split(properties.sourceResourceId, "/")[8])
    | project vmName
) on $left.name == $right.vmName
| where isnull(vmName)

解决方案

  • 按区域创建 恢复服务保管库
  • 定义符合 RPO/RTO 的备份策略。
  • 启用 软删除
  • 季度 测试一次恢复。
  • 通过 Azure Monitor 配置备份警报。

3. 认证方式薄弱

问题

基于密码的 SSH 与 RDP 访问仍然普遍。部分环境在多个管理员账户之间复用相同密码,形成单点故障。

检测方法

Linux

grep -i PasswordAuthentication /etc/ssh/sshd_config
grep -i PubkeyAuthentication /etc/ssh/sshd_config

Windows

  • 检查 Azure AD 条件访问 策略。
  • 查看 Azure AD 登录日志 中基于密码的登录记录。

解决方案

Linux

  • 禁用密码认证:PasswordAuthentication no
  • 强制 基于 SSH 密钥的认证
  • 将私钥存放在 Azure Key Vault 中。
  • 为 Linux VM 启用 Azure AD 登录

Windows

  • 强制 多因素认证 (MFA)
  • 最小化本地管理员使用。
  • 部署 特权访问工作站 (PAW)

4. 传输中的数据未加密

问题

生产环境仍存在 HTTP 接口、未使用 TLS 的数据库以及 FTP 传输,即使涉及敏感数据。

检测方法

应用网关 / WAF 日志

AzureDiagnostics
| where ResourceType == "APPLICATIONGATEWAYS"
| where requestUri_s startswith "http://"
| summarize Count = count() by requestUri_s, clientIP_s
| order by Count desc

解决方案

  • 强制 HTTPS 端到端
  • http:// 重定向到 https://
  • 为所有数据库连接启用 TLS 1.2+
  • SFTP/FTPS 替代 FTP。
  • 通过 Azure Key Vault 管理证书。

5. 角色‑基于访问控制 (RBAC) 不当

问题

开发人员常拥有 ContributorOwner 权限,且作用域为订阅级别,违背最小特权原则。

检测方法

authorizationresources
| where type == "microsoft.authorization/roleassignments"
| where properties.roleDefinitionId contains "Owner"
   or properties.roleDefinitionId contains "Contributor"
| project principalId, scope = tostring(properties.scope)

解决方案

  • 定期进行 RBAC 审计
  • 移除不必要的订阅级别角色。
  • 创建 自定义角色,仅保留最小权限。
  • 使用 Azure AD 特权身份管理 (PIM)
  • 为高特权账户启用 访问审查

6. 缺失活动日志警报

问题

关键变更(如 NSG 规则更新、VM 删除)未触发任何警报,导致团队无法及时获知。

检测方法

  • Azure Monitor → 警报 – 按 活动日志 过滤,确认相关类别已被监控。

解决方案

为以下事件创建警报:

  • NSG 规则变更
  • VM 创建/删除
  • RBAC 修改
  • Defender for Cloud 策略更新
  • Key Vault 访问变更

7. 管理和数据库端口暴露

问题

除 SSH/RDP 外,数据库端口和管理界面也常对互联网开放(如 SQL、MySQL、PostgreSQL、MongoDB、Redis)。

检测方法

AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog"
| where DestPort_d in (1433, 3306, 5432, 8080, 8443, 27017, 6379)
| where SrcIP_s !startswith "10."
  and SrcIP_s !startswith "172."
  and SrcIP_s !startswith "192.168."
| summarize Count = count() by DestPort_d, DestIP_s
| order by Count desc

解决方案

  • 关闭非必要端口。
  • 为数据库访问使用 私有端点 / Private Link
  • 为基于 Web 的管理界面部署 带 WAF 的应用网关
  • 利用 Azure Bastion 实现安全远程管理。
  • 参考 Defender for Cloud 的建议进行配置。

结论

Azure 安全是一个持续的过程,需要不断监控、定期审计和主动修复。大多数安全缺口来源于缺少防护措施,而非缺少工具。充分利用 Azure PolicyDefender for Cloud基础设施即代码,可以在问题进入生产前将其拦截。

快速安全检查清单(≈ 85 分钟)

  • 审计 NSG 规则中 0.0.0.0/05 分钟
  • 验证 VM 备份 – 10 分钟
  • 检查 RBAC 分配 – 15 分钟
  • 检查 SSH 密码认证 – 10 分钟
  • 启用活动日志警报 – 20 分钟
  • 扫描暴露的数据库端口 – 10 分钟
  • 识别 HTTP 流量 – 15 分钟

讨论

你在生产环境中遇到过类似的 Azure 安全问题吗?你使用了哪些防护措施来防止它们?

Back to Blog

相关文章

阅读更多 »