点赞
评论
收藏
分享
举报
无需重启 NGINX 开源版即可实现 SSL/TLS 证书轮换
发表于2024-04-30 14:48

浏览 118

原文作者:Maxim Ivanitskiy - F5 NGINX 软件架构师
原文链接:无需重启 NGINX 开源版即可实现 SSL/TLS 证书轮换
转载来源:NGINX 中文官网

NGINX 唯一中文官方社区 ,尽在 nginx.org.cn



   

在高性能 Web 服务器领域,NGINX 是一个广受欢迎的选择,因为其轻便高效的架构支持它处理大量流量。通过在 NGINX JavaScript 模块(njs)中引入共享字典(shared dictionary)功能,NGINX 的性能更上一层楼。

在本文中,我们将探讨 njs 共享字典的功能和优势,并展示如何设置 NGINX 开源版,以无需重启即可轮换 SSL/TLS 证书。

   

共享字典简介及其优势

js_shared_dict_zone 指令允许 NGINX 开源版用户启用共享内存区,在 worker 进程之间高效交换数据。 这些共享内存区充当键值字典,存储着可实时访问和修改的动态配置设置。

共享字典的主要优势包括:

    • 开销极少且易于使用 – 直接内置在 njs 中,得益于直观的 API 和简单的实现,可轻松配置和使用。它还能够帮助您简化 worker 进程之间的数据管理和共享。
    • 轻量高效 – 与 NGINX 无缝集成,利用其事件驱动型非阻塞 I/O 模型。这种方法减少了内存占用,并提高了并发处理能力,支持 NGINX 高效处理大量并发连接。
    • 可扩展性 – 借助 NGINX 跨多个 worker 进程的横向扩展能力,您可以在这些进程之间共享和同步数据,而无需复杂的进程间通信机制。通过 time-to-live (TTL) 设置,您可以管理共享字典条目中的记录,将不活动的条目从区域中删除。evict 参数会删除最早的键值对,为新条目腾出空间。

 

使用共享字典进行 SSL 轮换

共享字典最有效的用例之一是 SSL/TLS 轮换。使用 js_shared_dict_zone 时,无需重启 NGINX 就可更新 SSL/TLS 证书或密钥。此外,它还提供了一个类似 REST 的 API,可用于管理 NGINX 上的证书。

下面是一个 NGINX 配置文件示例,该配置文件使用 js_set ssl_certificate 指令来设置 HTTPS 服务器。 JavaScript 处理程序使用 js_set 从文件中读取 SSL/TLS 证书或密钥。

此配置片段使用共享字典将证书和密钥作为缓存存储在共享内存中。如果没有密钥,则会从磁盘中读取证书或密钥,并将其放入缓存。

您还可以暴露一个位置,以便手动清除缓存。一旦磁盘上的文件更新(如证书和密钥更新),共享字典就会从磁盘中读取这些更新。该调整允许在不重启 NGINX 进程的情况下轮换证书/密钥。

http {
     ...
    js_shared_dict_zone zone=kv:1m;
   
    server {
    …
     # 为变量设置一个 njs 函数。返回证书/密钥的值
      js_set $dynamic_ssl_cert main.js_cert;
      js_set $dynamic_ssl_key main.js_key;
   
      # 使用变量的数据
      ssl_certificate data:$dynamic_ssl_cert;
      ssl_certificate_key data:$dynamic_ssl_key;
     
     # 清除缓存的位置 
   location = /clear {
      js_content main.clear_cache;
      # 允许 127.0.0.1;
      # 全部拒绝;
    }
  ...
  }

下面是使用 js_shared_dict_zone 轮换 SSL/TLS 证书和密钥的 JavaScript 实现:

function js_cert(r) {
  if (r.variables['ssl_server_name']) {
    return read_cert_or_key(r, '.cert.pem');
  } else {
    return '';
  }
}

function js_key(r) {
  if (r.variables['ssl_server_name']) {
    return read_cert_or_key(r, '.key.pem');
  } else {
    return '';
  }
}
/** 
   * 从共享内存或磁盘读取密钥/证书值
   */
  function read_cert_or_key(r, fileExtension) {
    let data = '';
    let path = '';
    const zone = 'kv';
    let certName = r.variables.ssl_server_name;
    let prefix =  '/etc/nginx/certs/';
    path = prefix + certName + fileExtension;
    r.log('Resolving ${path}');
    const key = ['certs', path].join(':');
    const cache = zone && ngx.shared && ngx.shared[zone];
   
    if (cache) {
    data = cache.get(key) || '';
    if (data) {
      r.log(`Read ${key} from cache`);
      return data;
    }
  }
  try {
    data = fs.readFileSync(path, 'utf8');
    r.log('Read from cache');
  } catch (e) {
    data = '';
    r.log(`Error reading from file:${path}. Error=${e}`);
  }
  if (cache && data) {
    try {
      cache.set(key, data);
      r.log('Persisted in cache');
    } catch (e) {
      const errMsg = `Error writing to shared dict zone: ${zone}. Error=${e}`;
      r.log(errMsg);
    }
  }
  return data
}

可通过发送 /clear 请求让缓存失效,这样 NGINX 在下一次 SSL/TLS 握手时就会从磁盘加载 SSL/TLS 证书或密钥。此外,您还可以使用 js_content 从请求中获取 SSL/TLS 证书或密钥,同时持久化和更新缓存。

本例的完整代码可在 njs GitHub 代码库中找到。

 

立即开始

共享字典功能是一款强大的应用可编程性工具,在简化和可扩展性方面具有显著优势。利用 js_shared_dict_zone 的功能,您可以发掘新的增长机遇,并高效处理不断增长的流量需求。

准备好使用 js_shared_dict_zone 来加速 NGINX 部署了吗?您可以使用 js_shared_dict_zone 升级 NGINX 部署,解锁新的用例。有关此功能的更多信息,请参阅我们的文档。此外,您还可以在最近推出的 njs-acme 项目(支持 njs 模块运行时与 ACME 提供程序协同工作)中看到共享字典功能的完整示例。

如果您对 NGINX 开源版感兴趣或有任何问题,欢迎微信添加小 N 助手(微信号:nginxoss)加入 NGINX 官方微信群,以了解更多信息、提出问题并获得有关 NGINX 开源版的反馈。

 


 

NGINX 唯一中文官方社区 ,尽在 nginx.org.cn

更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源: 开源社区官网 | 微信公众号 | B 站

已修改于2024-04-30 14:48
本作品系原创
创作不易,留下一份鼓励
NGINX官方账号

暂无个人介绍

关注



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

按点赞数排序

按时间排序

关于作者
NGINX官方账号
这家伙很懒还未留下介绍~
244
文章
21
问答
198
粉丝
相关文章
NGINX开源版本和商用版本的差异化对比 先从官方的对比图讲起: 其中NGINXPLUS一栏代表当前商用版本的功能/场景支持列表,NGINXOSS一栏代表社区开源版本的功能支持列表。 再从NGINX模块增强角度的对比图讲起: 其中新增的商业版本模块,是在原来开源模块基础上额外具备的,简单地说是商业版本独有的;其次,开源模块的增强部分,在商业版本里相比传统的开源模块,又做了些许优化与提升。 出处引用:https://www.nginx.com/products/nginx/#compare-versions 最后从NGINXController角度和社区开源版本的行业定制的对比图说起: 某行业基于开源版本的定制化视图: NGINX官方部分摘录: 从这一系列的结构介绍里可以看出,NGINXController对部署的要求及NGINX服务的纳管情况,简单地说提供一个平台工具来定位用了哪些NGINX服务,NGINX服务的进程情况如何,NGINX相关监控指标运行情况等,相比某行业基于开源版的定制,一个是追求原味的呈现,另一个是更贴近客
点赞 1
浏览 1.5k
基于作者、开发理念、生产就绪性、安全和支持等方面来了解哪个 NGINX Ingress controller 最适合您。访问 NGINX 中文官方开源社区(nginx.org.cn)了解详情。
点赞 0
浏览 1.9k
我们比较了社区版 Ingresser Controller、NGINX 开源版 Ingress Controller 和 NGINX Plus Ingress Controller 在动态 Kubernetes 云环境中的性能。经过测试,我们得出:只有 NGINX Plus Ingress Controller 不会随着 Pod 副本数量的增加和减少而产生高延迟。访问 NGINX 中文官方开源社区(nginx.org.cn)了解详情。
点赞 1
浏览 1.5k