Windows Azure 安全最佳实践 – 第 7 部分:提示、工具和编码最佳实践


在撰写这一系列文章的过程中,我总结出了很多最佳实践。在这篇文章中,我介绍了在保护您的 Windows Azure 应用程序时,需要考虑的更多事项。

下面是一些工具和编码提示与最佳实践:

  • 在操作系统上运行
    • 获取最新的安全补丁
    • 尽量以部分信任模式运行
  • 错误处理
    • 如何实施重试逻辑
    • 记录 Windows Azure 中的错误
  • Azure 存储的访问权限
    • Blob 的访问权限
    • 存储连接字符串
    • 门卫模式
    • 旋转存储密钥
    • 用于确保数据安全的加密服务

在操作系统上运行

获取最新的安全补丁

当使用 Visual Studio 创建新的应用程序时,默认行为是按如下方式在 ServiceConfiguration.cscfg 文件中设置来宾操作系统版本:

osFamily="1"
osVersion="*"

这很好,因为您将自动获得更新,这也是 PaaS 的主要优点之一。但这并非最佳做法,因为您使用的操作系统不是最新版本。为了使用最新的操作系统版本 (Windows Server 2012 R2),应按如下方式进行设置:

osFamily="4" osVersion="*"

遗憾的是,许多客户决定固定使用某个特定的操作系统版本,希望通过避免来宾操作系统更新来增加正常运行时间。这种做法仅适用于企业客户:他们系统地测试staging 部署中的每次更新,然后计划对在生产部署中运行的关键业务应用程序进行 VIP 交换。对于其他不会测试每个来宾操作系统更新的客户来说,不配置自动更新会将 Windows Azure 应用程序置于危险的处境。

-- 来源:开发Windows Azure 应用程序的故障排除最佳实践

尽量以部分信任模式运行

Cloud Service默认情况下,部署到 Windows Azure 的角色将以完全信任模式运行。如果要调用非 .NET 代码或使用需要完全信任的 .NET 库,或任何需要管理员权限的代码或库,则需要完全信任。将您的代码限制为以部分信任模式运行意味着,任何有权访问您代码的人可执行的操作更加有限。

使用部分信任可以在您的 Web 应用程序受到威胁时,限制攻击者的破坏范围内。例如,默认情况下,恶意的攻击者无法修改磁盘上的任何 ASP.NET 页面,也无法更改任何系统二进制文件。

由于用户帐户不是虚拟机上的管理员,使用部分信任会增加更多的限制,多于 Windows 自动施加的限制。此信任级别通过 .NET 的代码访问安全性(CAS) 支持强制执行。

部分信任与 .NET 中的“中等信任”级别类似。仅授予对某些资源和操作的访问权限。通常,您的代码仅能通过 TCP 连接到外部 IP 地址,并且仅能访问其“本地存储”中的文件和文件夹(而非系统上的任何位置)。您的代码使用的任何库必须以部分信任模式运行,或特别标记为“允许部分信任的调用方”属性。

您可以在服务定义文件中明确配置角色的信任级别。服务定义架构提供了 WebRole 元素和 WorkerRole 元素的 enableNativeCodeExecution 属性。要以部分信任模式运行您的角色,必须在 WebRoleWorkerRole 元素上添加 enableNativeCodeExecution 属性,并将其设置为 false

但是,部分信任限制了应用程序的功能。由于一些微不足道的原因,一些有用的库(如用于访问注册表或访问众所周知的文件位置的库)无法在此类环境中运行。即使 Microsoft 自己的一些框架也不会在此环境中运行,因为它们没有设置“partially trusted caller”属性。

有关以部分信任模式运行的限制,请参阅 Windows Azure 部分信任策略参考

处理错误

Windows Azure 能够自我修复,您的应用程序可以吗?

重试逻辑

瞬态故障错误是由于一些临时情况(如网络连接或服务不可用等问题)导致的。通常,如果您很快重试导致瞬态错误的操作,将会发现错误已消失。

不同的服务可能会有不同的瞬态故障,并且不同的应用程序所需的故障处理策略也不同。

虽然它看上去似乎与安全无关,但将重试逻辑嵌入应用程序是一个最佳做法。

Azure 存储

使用随附 SDK 的 Windows Azure Storage Client Library 已经具备所需的重试行为。您可以通过设置 RetryPolicy 属性在任何存储客户端上设置重试行为。

SQLService Bus、缓存和 Azure 存储

但是 SQL Azure 不会提供现成的默认重试机制,因为它使用的是 SQL Server 客户端库。Service Bus 也不会提供重试机制。

因此,Microsoft 模式与实践团队和 Windows Azure 客户咨询团队开发了瞬态故障处理应用程序块。该块提供处理特定 SQL Azure、存储、Service Bus 和缓存情况的多种方式。

瞬态故障处理应用程序块中包含有关当您使用应用程序中的以下 Windows Azure 服务时可能出现的瞬态故障的信息:

  • SQL Azure
  • Windows Azure Service Bus
  • Windows Azure 存储
  • Windows Azure 缓存服务

目前,该块包括增强的配置支持、对包装异步调用的增强支持,实现了块的重试策略与 Windows Azure 存储重试机制的集成,适用于企业库依赖注入容器。

捕捉错误

很遗憾,任何系统都不可避免地会出现故障,Windows Azure 也肯定会出现故障。即使使用重试逻辑,您偶尔也会遇到故障。您可以将自定义的错误处理添加到 ASP.NET Web 应用程序。自定义错误处理可以简化调试并提高客户满意度。

Eli Robillard 是 Microsoft MVP 计划的一员,他的文章 ASP.NET 的丰富自定义处理介绍了如何创建错误处理机制,该机制对用户非常友好并且仍提供了开发人员需要的详细技术信息。

如果显示错误页面,它应该在不牺牲美感的前提下为开发人员和最终用户提供服务。理想的错误页面会保持站点的外观和感觉,具备为内部开发人员(通过 IP 地址识别)提供详细错误信息的能力,同时确保不向最终用户提供任何详细信息。相反,它让用户轻松返回自己寻找的站点,而不会造成混乱。网站管理员应该能够通过电子邮件或在服务器日志中检查遇到的错误,(可选)并且能够接收来自遇到故障的用户的反馈。

记录 Windows Azure 中的错误

ELMAH(错误记录模块和处理程序)本身非常有用,只需进行简单修改即可提供非常有效的方式,用来处理整个 ASP.NET Web 应用程序的错误记录。我的同事 Wade Wegner 在他的文章在 Windows
Azure 中将 ELMAH 与表存储结合使用
中介绍了他建议的步骤。

当 ELMAH 开始运行 Web 应用程序并正确配置后,您即可获得以下功能,而无需更改任一代码行:

  • 记录几乎所有未处理的异常。
  • 可远程查看已记录异常完整记录的网页。
  • 有一个网页可以用来远程查看任何记录的异常的完整详细信息,包括色彩斑斓的 stack trace。
  • 在很多情况下,您可以检查 ASP.NET 为给定异常生成的原始黄屏死机,即使在关闭 customErrors 模式的情况下也是如此。
  • 在出现每个错误时会发出电子邮件通知。
  • 记录中最后 15 个错误的 RSS 订阅。

要了解有关 ELMAH 的更多信息,请参阅 MSDN 文章使用 HTTP 模块和处理程序创建可插入的 ASP.NET 组件,由 Scott MitchellAtif Aziz 共同撰写。另请参阅 ELMAH 项目页面

远程访问错误

有许多可用于远程管理 Windows Azure 存储帐户的方案。例如,在开发和测试期间,您可能要能够检查表、队列和 Blob 的内容,以验证您的应用程序是否如预期一样运行。您可能还需要将测试数据直接插入到存储中。

在生产环境中,您可能需要在故障排除期间检查应用程序存储的内容,或查看您保留的诊断数据。您可能还希望下载诊断数据进行离线分析,并能够删除存储的日志文件以降低存储成本。

通过Web 搜索可以发现越来越多可充当这些角色的第三方工具。请参阅 Windows Azure 存储管理工具获取一些有用的工具。

存储的访问权限

密钥

一个紧急注意事项是,任何应用程序都不应将 Windows Azure 提供的任何密钥用作加密数据的密钥。例如 Windows Azure 为存储服务提供的密钥。这些密钥已配置为允许出于安全性目的,或者当由于任何原因受到威胁时轻松旋转。换言之,它们将来可能不存在,并且可能分发范围太广泛。

旋转密钥

当您创建存储帐户时,您的帐户已分配两个 256 位帐户密钥。其中一个密钥必须作为 HTTP(S) 请求的一部分在头中指定。提供两个密钥,是为了进行密钥旋转,以保持数据的良好安全性。通常,您的应用程序会使用其中一个密钥来访问数据。然后在一段时间后(取决于您),您将应用程序切换为使用另外一个密钥。如果您知道您的全部应用程序都已经使用另一个密钥,您可以生成一个新秘钥, 这将自动作废第一个密钥。以这种方式使用两个密钥,您的应用程序就可以访问数据,而不会产生任何停机时间。

请参阅如何查看、复制和重新生成 Windows Azure 存储帐户的访问密钥,了解如何查看和复制 Windows Azure 存储帐户的访问密钥并执行主要和辅助访问密钥的滚动重新生成。

限制对 Blob 的访问

默认情况下,仅存储帐户的所有者可访问存储容器和其中的任何 Blob。如果要给匿名用户提供容器及其 Blob 的读取权限,您可以设置容器权限以允许公共访问。匿名用户可在可供公众访问的容器中读取 Blob,而无需对请求进行身份验证。请参阅限制对容器和Blob 的访问

共享访问签名是授予容器和 Blob 的访问权限的 URL。共享访问签名授予 URL 已授予权限指定的 Blob 服务资源的访问权限。当在某些具有 HTTP 请求的情况下使用共享访问签名时需要小心,因为 HTTP 请求会在互联网上以明文形式公开完整的 URL。

通过指定共享访问签名,您可以向用户授予权限,允许其在指定时间段内访问特定 Blob 或某个指定容器中任何 Blob 的 URL。您还可以指定可在通过共享访问签名访问的 Blob 上执行的操作。支持的操作包括:

  • 读取和写入 Blob 内容、块列表、属性和元数据
  • 删除 Blob
  • Leasing Blob
  • 创建 Blob 快照
  • 列出容器中的 Blob

块 Blob 和页面 Blob 都支持共享访问签名。

如果共享访问签名的某些权限不准备向公众开放,那么它的访问策略应使用所需的最小权限进行构建。此外,共享访问签名应通过 HTTPS 通信安全地分配给指定用户,应与容器级别的访问策略相关联以进行吊销,并且应为签名指定尽可能短的有效期。

请参阅创建共享访问签名使用共享访问签名 (REST API)

存储连接字符串

如果您有某个托管服务使用 Windows Azure Storage Client Library 访问 Windows Azure 存储帐户,建议您将连接字符串存储在服务配置文件中。通过将连接字符串存储在服务配置文件中,已部署服务可以响应配置更改,而无需重新部署应用程序。

在以下情况下,这样做会很有利:

  • 测试 – 在将应用程序部署到staging环境时使用测试帐户,并且当您将应用程序移到生产环境时必须将其切换为 Live 帐户。
  • 安全性 – 如果由于正在使用的密钥受到威胁导致您必须旋转存储帐户的密钥。

有关配置连接字符串的更多信息,请参阅配置连接字符串

有关使用连接字符串的更多信息,请参阅读取存储客户端库的配置设置和处理已更改的设置

门卫设计模式

门卫是一种设计模式,其中存储的访问权限需进行协商,以便通过限制特权角色在专用内部渠道上的通信交互并仅与其他 Web role/worker role 进行交互,以尽量减小特权角色的攻击面。

该模式在 Microsoft 下载中的文章开发 Windows Azure 应用程序的最佳安全做法中进行了说明。

这些角色应部署在单独的 VM 上。

即使 Web role 被成功攻击,也不会泄漏特权密钥材料。使用两个角色的以下示例是对该模式的最好诠释:

  • 门卫 – 为来自 Internet 的请求提供服务的 Web role。由于这些请求可能是恶意的,门卫不被信任用于任何其他职责,除非验证了其收到的输入。门卫在托管代码中实施并以 Windows Azure 部分信任模式运行。此角色的服务配置设置不包含用于 Windows Azure 存储的任何共享密钥信息。
  • KeyMaster – 特权后端 worker role,仅接收来自门卫的输入,并通过安全渠道进行接收(即,可通过 HTTPS 确保安全性的内部端点或队列存储)。KeyMaster 通过门卫处理其订阅的存储请求,并假设请求已进行某种程度的净化。顾名思义,KeyMaster 是使用服务配置中的 Windows Azure 存储帐户信息进行配置的,可从 Blob 或表存储中检索数据。然后数据可以反馈回请求客户端。此设计不需要完全信任或本机代码,但它可提供在需要时以较高权限级别运行 KeyMaster 的灵活性。

多密钥

如果无法将部分信任门卫放置在完全信任角色之前,则可使用多密钥设计模式保护受信任的存储数据。例如,当 PHP Web role 作为前端 Web role 并将部分信任门卫放置在 PHP Web role 前面时,可能会使性能降低得无法接受。

与门卫/KeyMaster 模式相比,多密钥设计模式具有以下优点:

· 将存储帐户的职责分离出来。如果 Web role A 泄露了,仅会丢失不受信任的存储帐户及关联密钥。

· 无需指定任何内部服务端点。相反,会使用多个存储帐户。

· 面向外部的不受信任的 Web role 无需 Windows Azure 部分信任。由于 PHP 不支持部分信任,PHP 托管不可进行门卫配置。

请参阅 Microsoft 下载中的开发 Windows Azure 应用程序的最佳安全做法

加密服务

您可以使用加密来确保应用程序层数据的安全。加密服务提供程序 (CSP) 是系统程序接口中显示的加密标准、算法和函数的实施。

Jonathan Wiggs 在 MSDN 杂志中发表了一篇文章 Windows Azure 中的加密服务和数据安全,这篇文章生动地说明了如何在应用程序中提供这类服务。他解释说:“一致的建议是永远不要创建您自己的加密算法或使用专有加密算法。.NET CSP 中提供的算法已经过证明和测试并具有多年的公众支持。”

您可以选择下面的多种选项。Microsoft 提供了:

Microsoft Base Cryptographic Provider。一组可导出到其他国家或地区的广泛的基本加密功能。

Microsoft Strong Cryptographic Provider。Microsoft Base Cryptographic Provider 的扩展,在 Windows 2000 及更高版本中提供。

Microsoft Enhanced Cryptographic Provider。Microsoft Base Cryptographic Provider 通过更长的密钥和其他算法得出的结果。

Microsoft AES Cryptographic Provider。Microsoft Enhanced Cryptographic Provider 支持 AES 加密算法。

Microsoft DSS Cryptographic Provider。通过安全哈希算法 (SHA)和数字签名标准 (DSS) 算法提供哈希、数据签名和签名验证功能。

Microsoft Base DSS and Diffie-Hellman Cryptographic Provider。DSS Cryptographic Provider 的超集,同时支持使用安全哈希算法 (SHA) 和数字签名标准 (DSS) 算法进行 Diffie-Hellman 密钥交换、哈希、数据签名和签名验证。

Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider。支持 Diffie-Hellman 密钥交换(40 位的 DES 衍生品)、SHA哈希、DSS 数据签名和 DSS 签名验证。

Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider。支持哈希、使用 DSS 进行数据签名、生成 Diffie-Hellman (D-H) 密钥、交换 D-H 密钥以及导出 D-H 密钥。此 CSP 支持 SSL3 和 TLS1 协议的密钥派生。

Microsoft RSA/Schannel Cryptographic Provider。支持哈希、数据签名和签名验证。算法标识符 CALG_SSL3_SHAMD5 用于 SSL 3.0 和 TLS 1.0 客户端身份验证。此 CSP 支持 SSL2、PCT1、SSL3 和 TLS1 协议的密钥派生。

Microsoft RSA Signature Cryptographic Provider。提供数据签名和签名验证。

密钥存储

通过加密数据提供的数据安全性仅与使用的密钥的安全性相同,并且此问题要比人们起初预想的难度要高得多。您不应该使用 Azure 存储密钥,而可以使用上一节中的提供程序创建您自己的密钥。

在 Windows Azure 存储服务内部存储您自己的密钥库是保存一些机密信息的不错选择,因为您可以相信这些数据在多租户环境中的安全性并通过您自己的存储密钥确保其安全性。这与将存储密钥用作加密密钥有所不同。相反,您可以使用存储服务密钥随意访问密钥库, 就像任何其他存储文件一样。

密钥管理

首先,要始终假设您用来解密、加密和保护数据的流程为任何攻击者所熟知。请牢记这一点,确保定期循环您的密钥以保证其安全性。仅将密钥提供给需要的用户,避免将密钥暴露得过于广泛而不受您控制。

清理

当您使用密钥时应进行清理,建议将此类数据存储在缓冲区,如字节数组。这样一来,清理完信息后,您就可以用零或任何其他数据(确保该数据已不在该内存中)覆盖缓冲区。

您仍然可以从 Jonathan 的文章 Windows Azure 中的加密服务和数据安全中研究和学习如何组合所有的组件。

总结

安全性绝非开发流程的最后一步。恰恰相反,它应该始终是开发流程的一部分,您应该根据您自己的应用程序的需求制定安全性决策。

您所使用的方法应确保您的应用程序开发周期中的每个环节都考虑到安全性。检查您的体系结构和代码中可能允许其他用户访问您的数据的地方。

Windows Azure 使安全性成为成为一项共同责任。通过平台即服务,您可以更加专注于您的应用程序和您自己的安全性需求。

在这一系列博客文章中,我介绍了在 Windows Azure 中如何确保应用程序的安全。这一系列文章分为七个部分,介绍了威胁、如何响应、在应用程序生命周期中可采取哪些流程,并规定了根据应用程序的需求实施最佳实践的方式。

我还介绍了一些集成用户标识的方法,以及 Azure 提供的一些使用户能够以新方式访问云应用程序的服务。

以下是本系列中的文章的链接:

本文翻译自:

http://blogs.msdn.com/b/usisvde/archive/2012/03/15/windows-azure-security-best-practices-part-7-tips-tools-coding-best-practices.aspx

Comments (0)

Skip to main content