点赞
评论
收藏
分享
举报
借助 NGINX Unit 在零信任环境中运行 Spring Boot 应用
发表于2022-04-12 10:43

浏览 1.5k

原文作者:Timo Stark of F5
原文链接:借助 NGINX Unit 在零信任环境中运行 Spring Boot 应用 - NGINX
转载来源:NGINX 官方网站


(首次发布于2021.8.18)  

近来,好像人人都在讨论“安全性”。保护应用安全历来挑战重重,上云之后更是难上加难。而一种看起来比较靠谱的解决方案是“零信任”。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
生成的文件是 build/libs/rootProject‑Version.war,其中:
3. 在名为 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" } } }
4. 激活配置(有关详细信息,请参阅文档):
# 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 天免费试用版,或与我们联系以讨论您的用例


更多资源

想要更及时全面地获取NGINX相关的技术干货、互动问答、系列课程、活动资源?

请前往NGINX开源社区:


已修改于2023-03-08 23:12
本作品系原创
创作不易,留下一份鼓励
NGINX官方账号

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
NGINX官方账号
这家伙很懒还未留下介绍~
239
文章
21
问答
198
粉丝
相关文章
介绍NGINXUnit是一个多语言动态应用服务器,同样支持代理和静态文件。是由NGINX作者IgorSysoev亲自设计带领团队从零实现的高性能纯C服务器。Unit的使用对开发者和运维非常友好。 关键特性:灵活用HTTP协议的RESTfulJSONAPI更新任意粒度配置极其强大和易用的路由管理请求支持所有主流语言:GO,Python,JAVA,Perl,PHP,NodeJS,Ruby支持负载均衡的代理支持静态资源服务 性能高并发:使用异步事件处理模型低内存:使用连接和内存复用每个应用语言的进程管理支持动态和静态分配对Java,Perl,Python,Ruby支持原生多线程处理 安全和稳定性处理请求的进程以非特权方式运行进程间完全独立不同的应用完全相互隔离支持用容器化方式对应用程序进行namespace和filesystem隔离支持SSL/TLS 社区和文档容易上手保持一直活跃的开发状态:https://github.com/nginx/unit/官方一直更新使用文档:https://unit.nginx.org/ 完整示例:{ "cer
点赞 7
浏览 1.7k
感谢您参加> Ø3月11日用Unit实现应用的动态配置Ø 3月18日Unit的负载均衡配置Ø 3月25日Unit架构设计Ø 4月01日Unit源代码解读
点赞 1
浏览 1.3k
Unit,已经出道好几年Unit是NGINX作者IgorSysoev亲自设计,NGINX团队核心人员开发的,首次开源发布于2017年。有着活跃的社区和专业的开发能力,我有幸成为其中正式一员。Changes with Unit 1.24.0   27 May 2021......Changes with Unit 0.1      06 Sep 2017*)Firstpublicrelease.Unit现代应用服务器软件结合此图看Unit,以下是它的核心功能。配置:完全动态,包括进程数、服务监听端口、证书等。路由:灵活并且强大的路由功能,它会成为微服务的杀器功能。语言:支持各种主流语言和版本,这对DevOps太友好了。文件:支持静态资源服务,并且更好用。代理:目前只有简单的轮循,成为完整的负载均衡只是时间问题。容器:目前拥有隔离功能,一直在挑战做容器的事情。NGINX,全球头号Web
点赞 0
浏览 1.3k