zoukankan      html  css  js  c++  java
  • OpenResty之ngx.ssl

    翻译自: 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()
    上下文:任意
    
  • 相关阅读:
    读取ClassPath下resource文件的正确姿势
    动画展现十大经典排序算法(附Java代码)
    定量度量程序复杂度的McCabe方法
    从一个例子入门Mysql储存过程
    从源码看Spring Security之采坑笔记(Spring Boot篇)
    函数传递参数的本质
    main函数是必须的吗
    变量存储与长度
    C语言与汇编衔接1
    关于function和task的说明
  • 原文地址:https://www.cnblogs.com/jimodetiantang/p/9260698.html
Copyright © 2011-2022 走看看