NGINX.COM
Web Server Load Balancing with NGINX Plus

近来,好像人人都在讨论“安全性”。保护应用安全历来挑战重重,上云之后更是难上加难。而一种看起来比较靠谱的解决方案是“零信任”。Gartner 将“零信任”定义为:

……一种在所有计算基础架构中消除绝对信任的方法,“零信任”意味着会有意地且持续地计算和调整信任级别,使得“适时、适度地访问企业资源”得以实现。

但“零信任”究竟是如何在云环境中工作的,有哪些技术可以帮助您实现“零信任”?本文将在一个常见用例的背景下介绍零信任:

假设您是一家拥有各种由 Java 提供支持的 API 和服务的保险公司。现在您已迁移到云端,生产级工作负载由 CI/CD 流水线自动构建,并部署在公有云服务提供商的 Kubernetes 集群中。在处理敏感的客户信息时,一个主要要求就是使用 TLS 加密所有的流量。

您已在边缘负载均衡器和 Ingress Controller 上启用了加密,但对 Ingress Controller 和应用本身之间的流量进行加密的最佳方法是什么?答案就包括了需要启用应用服务器来处理 TLS。

许多 Java 商店使用 Apache Tomcat 作为首选的应用服务器,并将 Spring Boot 作为框架来构建独立的生产就绪型 Spring 应用(比使用 Java 本身更容易)。针对可以处理 HTTPS 流量的应用,本文详细展示了如何为其配置内置 Apache Tomcat 的 Spring Boot(以及 NGINX Unit)。

Spring Boot:HTTPS 流量通信

在撰写本文时,Spring Boot 已在 GitHub 上获得了近 6万个赞,它是 Java 框架领域一颗耀眼的巨星:好上手、轻量级且功能强大。Spring Boot 项目可以通过内置的应用服务器(例如 Apache Tomcat)编译成自包含的 .jar 文件。要启动 Java 服务,只需执行 .jar 文件并开始向暴露的端口(默认为 8080)发送流量即可,非常简单!

为了正确处理 TLS 连接(HTTPS 流量),您还需要为 Java 服务执行以下几个步骤。有关这些步骤的更多详细信息,请参阅 Spring 文档

这些说明适用于自签名证书和密钥,但对于生产环境,我们强烈建议替换来自官方证书颁发机构 (CA) 的证书密钥对。

  1. 创建包含证书和密钥的密钥存储器:

    # keytool -genkey -alias tomcat -keyalg RSA -keystore certstore
  2. 将密钥存储器放在 Tomcat 肯定能访问的容器镜像中。

  3. 将这些属性添加到 application.properties 文件中,并使用适当的密码替换 secret

    server.port = 8443
    server.ssl.key-store = classpath:keystore.jks
    server.ssl.key-store-password = secret

配置完成后,Spring Boot 应用将监听端口 8443 的 HTTPS 连接情况。但如果您还想接受 HTTP 连接怎么办?一旦在 application.properties 文件中配置了 HTTPS,您就不能再配置 HTTP;您必须在 Java 代码中实现 HTTP 处理。如需了解典型示例,请参阅 GitHub 上的 spring-projects 仓库。

事实证明,将 4 层 TLS 加密委托给应用框架(例如 Spring Boot)是可行的,但却不方便操作。如果您还使用其他语言和框架(例如 Ruby 和 Rails,或 Python 和 Flask)编写应用,则情况会更加复杂,因为每个框架都拥有自己的配置监听器以及处理密钥和证书的方式。但幸运的是,有一些工具可以让事情变得简单得多!

NGINX Unit 前来救场!

NGINX Unit 是一个开源的多语言应用服务器、反向代理和静态文件服务器,由 NGINX 核心工程团队为类 Unix 系统编写。借助 NGINX Unit,您可以使用标准化的 API 同时运行和管理用多种不同语言编写而成的应用,在撰写本文时,它支持除 Java 之外的七种语言:汇编、Go、JavaScript (Node.js®)、Perl、PHP、Python 及 Ruby。

Unit 还允许您单独配置 HTTP 和 HTTPS 接口,而不必再受使用它们的应用的限制。我们来通过 Spring Boot API 示例探索这个强大的功能。首先,我们必须为 Unit 服务器构建 Spring Boot 应用。在 Unit 实现 Java Servlet API 版本 3 时,唯一的变化是在 GradleMaven 构建定义中增加了一行。我们使用 Gradle 进行测试。

  1. war 插件添加到 build.gradle 文件:

    plugins {
      id 'org.springframework.boot' version '2.4.4'
      id 'io.spring.dependency-management' version '1.0.11.RELEASE'
      id 'java'
      id 'war'
    }
  2. 构建 .war 文件:

    # ./gradlew build
  3. 生成的文件是 build/libs/rootProject‑Version.war,其中:

  4. 在名为 config.json 的文件中定义 Unit 配置:

    {
        "listeners": {
            "*:8080": {
                "pass": "applications/java"
            }
        },
        "applications": {
            "java": {
                "user": "unit",
                "group": "unit",
                "type": "java",
                "environment": {
                    "Deployment": "0.0.1"
                },
                "classpath": [],
                "webapp": "/path/to/build/libs/demo-0.0.1-SNAPSHOT.war"
            }
        }
    }
  5. 激活配置(有关详细信息,参阅文档):

    # curl -X PUT --data-binary @config.json --unix-socket \
           /path/to/control.unit.sock http://localhost/config/applications/java-app

好了,就是这样!Spring Boot 应用现在正在 Unit 上运行,并且不需要 Tomcat 或其他 Java 应用服务器。

启用 HTTPS

您可能会问,“但如何启用 HTTPS 呢?”问得好,开干吧!您可以通过以下步骤轻松启用 HTTPS。(如上文所述,我们使用的是自签名证书。在生产环境中,请您确保使用 CA 签名证书。)

  1. 创建自签名证书包:

    # cat cert.pem ca.pem key.pem > bundle.pem
  2. 将证书包上传到 Unit:

    # curl -X PUT --data-binary @bundle.pem --unix-socket \
           /path/to/control.unit.sock http://localhost/certificates/bundle
  3. 在一个名为 listener.json 的文件中定义 HTTPS 监听器的配置:

    "127.0.0.1:443": {
        "pass": "applications/java-app",
        "tls": {
            "certificate": "bundle"
        }
    }
  4. 激活新的监听器:

    # curl -X PUT --data-binary @listener.json --unix-socket \ 
    /path/to/control.unit.sock http://localhost/config/listeners

应用现在接受了 TLS 加密连接 — 无需重新启动应用或 Unit。但其最强大之处在于,上述过程同样适用于使用 Unit 支持的任何语言和框架编写的应用。因此,无需深入了解特定语言的详细信息即可配置 HTTPS。

结语

强大的 NGINX Unit 监听器功能使得对于 HTTP 和 HTTPS 的支持变得更简单,并且这种支持完全不受应用的限制,因为加密是应用于监听器层而非应用层的。如要了解服务器名称指示 (SNI) 和自定义 OpenSSL 配置命令等其他 TLS 功能,请参阅 NGINX Unit 文档

如要开始使用 NGINX Unit,请参阅安装说明

NGINX Plus 用户可免费获得 NGINX Unit 支持。立即下载 30 天免费试用版,或与我们联系以讨论您的用例。

Hero image
免费白皮书:
NGINX 企阅版全解析

助力企业用户规避开源治理风险,应对开源使用挑战

关于作者

Timo Stark

Professional Services Engineer

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。