无需重启 NGINX 开源版即可实现 SSL/TLS 证书轮换
原文作者:Maxim Ivanitskiy of F5
原文链接:无需重启 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 {
…
# Sets an njs function for the variable. Returns a value of cert/key
js_set $dynamic_ssl_cert main.js_cert;
js_set $dynamic_ssl_key main.js_key;
# use variable's data
ssl_certificate data:$dynamic_ssl_cert;
ssl_certificate_key data:$dynamic_ssl_key;
# a location to clear cache
location = /clear {
js_content main.clear_cache;
# allow 127.0.0.1;
# deny all;
}
...
}
下面是使用 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 '';
}
}
/**
* Retrieves the key/cert value from Shared memory or fallback to disk
*/
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
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
开源医疗大模型排行榜: 健康领域大模型基准测试
多年来,大型语言模型 (LLMs) 已经发展成为一项具有巨大潜力,能够彻底改变医疗行业各个方面的开创性技术。这些模型,如 GPT-3,GPT-4 和 Med-PaLM 2,在理解和生成类人文本方面表现出了卓越的能力,使它们成为处理复杂医疗任务和改善病人护理的宝贵工具。它们在多种医疗应用中显示出巨大的前景,如医疗问答 (QA) 、对话系统和文本生成。此外,随着电子健康记录 (EHRs) 、医学文献和病人生成数据的指数级增长,LLMs 可以帮助医疗专业人员提取宝贵见解并做出明智的决策。 然而,尽管大型语言模型 (LLMs) 在医疗领域具有巨大的潜力,但仍存在一些重要且具体的挑战需要解决。 当模型用于娱乐对话方面时,错误的影响很小; 然而,在医疗领域使用时,情况并非如此,错误的解释和答案可能会对病人的护理和结果产生严重后果。语言模型提供的信息的准确性和可靠性可能是生死攸关的问题,因为它可能影响医疗决策、诊断和治疗计划。 例如,当有人问 GPT-3 关于孕妇可以用什么药的问题时,GPT-3 错误地建议使用四环素,尽管它也正确地说明了四环素对胎儿有害,孕妇不应该用。如果真按照这个错误的建议去给孕...
-
下一篇
GreatSQL的sp中添加新的sp_instr引入的bug解析
GreatSQL的sp中添加新的sp_instr引入的bug解析 一、问题发现 在一次开发中用到的sp需要添加新的sp_instr以满足需求,但是添加了数个sp_instr以后发现执行新的sp会发生core。 注:本次使用的GreatSQL 8.0.32-25 1、sp_head.cc的init_sp_psi_keys()代码里面添加10个新的sp_instr: void init_sp_psi_keys() { mysql_statement_register(category, &sp_instr_stmt1::psi_info, 1); mysql_statement_register(category, &sp_instr_stmt2::psi_info, 1); mysql_statement_register(category, &sp_instr_stmt3::psi_info, 1); ...... mysql_statement_register(category, &sp_instr_stmt10::psi_info, 1); } 2...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2全家桶,快速入门学习开发网站教程
- MySQL数据库在高并发下的优化方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Hadoop3单机部署,实现最简伪集群


微信收款码
支付宝收款码