翻译自: ngx.ssl - Lua API for controlling NGINX downstream SSL handshakes

1. 概要

# 注意:如果你使用的是 OpenResty 1.9.7.2+,则不需要该行
lua_package_path "/path/to/lua-resty-core/lib/?.lua;;"; server {
listen 443 ssl;
server_name test.com; # useless placeholders: just to shut up NGINX configuration
# loder errors:
ssl_certificate /path/to/fallback.crt;
ssl_certificate_key /path/to/fallback.key; ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl" -- clear the fallback certificates and private keys
-- set by the ssl_certificate and ssl_certificate_key
-- directives above:
local ok, err = ssl.clear_certs()
if not ok then
ngx.log(ngx.ERR, "failed to clear existing (fallback) certificates")
return ngx.exit(ngx.ERROR)
end -- assuming the user already the my_load_certificate_chain()
-- herself.
local pem_cert_chain = assert(my_load_certifiate_chain()) local der_cert_chain, err = ssl.cert_pem_to_der(pem_cert_chain)
if not der_cert_chain then
ngx.log(ngx.ERR, "failed to convert certificate chain ",
"from PEM to DER: ", err)
return ngx.exit(ngx.ERROR)
end local ok, err = ssl.set_der_cert(der_cert_chain)
if not ok then
ngx.log(ngx.ERR, "failed to set DER cert: ", err)
return ngx.exit(ngx.ERROR)
end -- assuming the user already defined the my_load_private_key()
-- function herself.
local pem_pkey = assert(my_load_private_key()) local der_pkey, err = ssl.priv_key_pem_to_der(pem_pkey)
if not der_pkey then
ngx.log(ngx.ERR, "failed to convert private key ",
"from PEM to DER: ", err)
return ngx.exit(ngx.ERROR)
end local ok, err = ssl.ser_der_priv_key(der_pkey)
if not ok then
ngx.log(ngx.ERR, "failed to set DER private key: ", err)
return ngx.exit(ngx.ERROR)
end
} location / {
root html;
}
}

2. 描述

该 Lua 模块提供 API 函数来控制类似 ssl_certificate_by_lua*(ngx_lua 模块) 等上下文的 SSL 握手过程。

OpenSSL 允许我们动态地设置证书和私钥,因此期望可以在建立连接前才设置证书和私钥,这样,可以结合 SNI,针对不同的请求域名动态设置不同的证书和私钥,而无需事先把可能用到的证书和私钥都准备好。该 lua 模块提供的 API 以在 ssl_certificate_by_lua* 指令的上下文中支持此种情况。

在 Lua 中加载 ngx.ssl 模块,因如下:

local ssl = require "ngx.ssl"

3. 方法

3.1 clear_certs

语法:ok, err = ssl.clear_certs()
上下文:ssl_certificate_by_lua*
  • 清除在当前 SSL 连接中设置的任何已经存在的 SSL 证书和私钥。
  • 成功返回 true,失败返回一个 nil 值并且通过字符串描述错误。

3.2 cert_pem_to_der

语法:der_cert_chain, err = ssl.cert_pem_to_der(pem_cert_chain)
上下文:任意
  • 将 PEM 格式的 SSL 证书链数据转换为 DER 格式(转换后的 der 格式数据将用于 set_der_cert 函数)。
  • 失败,则返回 nil 值,并且通过字符串描述错误。
  • openssl 命令行工具可能无法正确将 SSL 证书链从 PEM 格式转换为 DER,因此总是使用该 Lua 函数进行转换。你可以总是使用类似 lua-resty-lrucache 或者 ngx_lua API(如 lua_shared_dict)等库来缓存 DER 格式的结果。
  • 该函数可以在任何上下文中使用。

3.3 set_der_cert

语法:ok, err = ssl.set_der_cert(der_cert_chain)
上下文:ssl_certificate_by_lua*
  • 为当前的 SSL 连接设置 DER 格式的 SSL 证书链数据。注意,该 DER 数据是直接保存在 Lua 字符串参数中的。不需要外部文件支持。
  • 若成功返回 true,否则返回 nil 并且通过字符串描述错误。
  • 注意,SSL 证书链通常以 PEM 格式编码,因此首先需要使用 cert_perm_to_der 函数进行转换。

3.4 priv_key_pem_to_der

语法:der_priv_key, err = ssl.priv_key_perm_to_der(perm_priv_key)
上下文:任意
  • 将 PEM 格式的 SSL 私钥数据转换为 DER 格式(用于 set_der_priv_key 函数)。
  • 失败,返回 nil 并通过字符串描述错误。
  • 可选地,你可以使用 openssl 命令行工具脱机下执行 PEM 转换为 DER,如下:
openssl rsa -in key.pem -outform DER -out key.der
  • 该函数可以在任意上下文中调用。

3.5 set_der_priv_key

语法:ok, err = ssl.set_der_priv_key(der_priv_key)
上下文:ssl_certificate_by_lua*
  • 为当前 SSL 连接设置 DER 格式的私钥。
  • 成功返回 true,失败返回 nil 并通过字符串描述错误。
  • 通常,私钥是以 PEM 格式编码的。可以使用 priv_key_perm_to_der 函数或者使用 openssl 命令行工具脱机将 PEM 转换为 DER,如下:
openssl rsa -in key.pem -outform DER -out key.der

3.6 server_name

语法:name, err = ssl.server_name()
上下文:任意
  • 返回由客户端设置的 TLS SNI(Server Name Indication) 名。若客户端没有设置则返回 nil。
  • 失败,返回 nil 并通过字符串描述错误。
  • 通常我们使用 SNI 名作为域名(如 www.openresty.org)来标识当前的 web 站点,同时为当该网站加载相应的 SSL 证书链和私钥。
  • 注意,并不是所有的 https 客户端都设置 SNI 名,因此当从客户端握手请求中缺失 SNI 名时,我们可以使用客户端访问的服务器 IP 地址来标识该网站。有关更多详细信息,参阅 raw_server_addr 方法。
  • 可以在下游 https 的任何上下文中调用该函数。

3.7 raw_server_addr

语法:addr_data, addr_type, err = ssl.raw_server_addr()
上下文:任意
  • 返回当前 SSL 连接中客户端实际访问的原始服务器地址。
  • 前两个返回值分别表示地址数据和地址类型的字符串,根据地址类型值对地址值进行不同的解释:
    • unix: 地址数据是 UNIX 域套接字的文件路径。
    • inet:地址数据是 4 字节长的二进制 IPv4 地址。
    • inet6:地址数据时 16 字节长的二进制 IPv6 地址。
  • 失败返回 nil,并通过字符串描述错误。
  • 以下代码显示如何将 UNIX 域套接字和 IPv4 地址打印为人类可读的字符串:
local ssl = require "ngx.ssl"
local byte = string.byte local addr, addrtyp, err = ssl.raw_server_addr()
if not addr then
ngx.log(ngx.ERR, "failed to fetch raw server addr: ", err)
return
end if addrtyp == "inet" then -- IPv4
ip = string.format("%d.%d.%d.%d", byte(addr, 1), byte(addr, 2),
byte(addr, 3), byte(addr, 4))
print("Using IPv4 address: ", ip) elseif addrtyp == "unix" then -- UNIX
print("Using unix socket file ", addr) else -- IPv6
-- leave as an exercise for the readers
end
  • 可以在下游 https 的任何上下文中调用该函数。

3.8 raw_client_addr

语法:addr_data, addr_type, err = ssl.raw_client_addr()
上下文:任意

OpenResty之ngx.ssl的更多相关文章

  1. openresty的ngx.timer.at

    openresty的ngx.timer.at真是个强大的方法. 例如某些函数不可以在一些NGINX的执行阶段使用时,可以ngx.timer.at API 创建一个零延迟的timer,在timer中去处 ...

  2. OpenResty之ngx.var.VARIABLE

    1. ngx.var.VARIABLE syntax: ngx.var.VAR_NAME context: set_by_lua*, rewrite_by_lua*, access_by_lua*, ...

  3. OpenResty之ngx.shared.DICT

    参考链接: resty.core.shdict ngx_shared.DICT 源码正文: dict.lua 部分源码如下: local ffi = require 'ffi' local base ...

  4. centos yum 安装openresty

    yum 安装openresty sudo yum install yum-utils -y sudo yum-config-manager --add-repo https://openresty.o ...

  5. OpenResty之指令与常用API

    1. 指令 通过 Lua 编写 Nginx 脚本的基本构建块是指令.指令常用于指定 Lua 代码是几时执行的以及如何使用运行的结果.下图展示了指令执行的顺序. lua_capture_error_lo ...

  6. openresty HTTP status constants nginx api for lua

    https://github.com/openresty/lua-nginx-module context: init_by_lua, set_by_lua, rewrite_by_lua, acce ...

  7. Nginx+lua+openresty精简系列

    1. CentOS系统安装openresty 你可以在你的 CentOS 系统中添加 openresty 仓库,这样就可以便于未来安装或更新我们的软件包(通过 yum update 命令).运行下面的 ...

  8. 打破基于OpenResty的WEB安全防护(CVE-2018-9230)

    原文首发于安全客,原文链接:https://www.anquanke.com/post/id/103771 0x00 前言 ​ OpenResty® 是一个基于 Nginx 与 Lua 的高性能 We ...

  9. 用 letsencrypt 生成 SSL 证书

    letsencrypt 生成 SSL 证书 事先配置好访问域名解析 在nginx 对应虚拟主机添加一个验证区域: 配置 nginx server { listen 80; ... location ~ ...

随机推荐

  1. SVN配置使用及移植

    使用svn作为配置管理工具及其普遍的用于项目开发中,网上有很多关于svn的原理介绍及命令行管理教程.这里仅仅分享下个人配置及使用的过程,不通过命令行,可简单的上手操作.如有遗漏欢迎留言交流. 配置及使 ...

  2. 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句

    salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...

  3. sudo命令 sudoers文件

    超级用户权限 # Host alias specification Host_Alias HA = 192.168.1.1, 192.168.1.2 # User alias specificatio ...

  4. jdk在window系统中的配置

    其实配置很简单,百度上很多配置的复杂化了,今天办公室的某小白百度了半天也没有配置好.   我使用的是Linux ,就很多简单了很多编译器都是集成的,尤其是现在kali linux 系统觉得做得越来也好 ...

  5. python3使用ConfigParser从配置文件中获取列表

    使用python3使用ConfigParser从配置文件中获取列表 testConfig.py #!/usr/bin/env python # coding=utf- __author__ = 'St ...

  6. JS Array.reverse 将数组元素颠倒顺序

    <pre><script type="text/javascript"> //JS Array.reverse 将数组元素颠倒顺序//在JavaScript ...

  7. python | 不可变数据类型

    目录 第1节 分类 第2节 不可变数据类型 2.1 布尔型(bool) 2.2 数字型(number) 2.3 字符串(string) 2.4 元组(tuple) 第1节 分类 python中有7种标 ...

  8. HTML5游戏2D开发引擎

    1.PixiJS(基于webGl和canvas) 官网:http://www.pixijs.com/ github(star:20672):https://github.com/pixijs/pixi ...

  9. 纯css实现树形结构

    纯css实现属性结构 **css实现属性结构的思路是利用伪类实现树形结构连接线,如果想实现点击展开和收 缩以及复选框效果还得配合js来实现.其实展开和收缩就是一个点击元素其子元素隐藏 和显示的切换.* ...

  10. linux命令集合(二)

    yum源的配置 yum  得配置yum源,配置阿里云的 两个 yum源  ,阿里云的yum源中,会有 mariadb的软件包   阿里云的yum仓库中,mariadb版本如下 mariadb      ...