目录

使用OpenResty mTLS认证

环境

为了支持mTLS功能,折腾的够呛,OpenResty官方又没支持,基于OpenResty的APISIX和Kong都有补丁,但两家公司的补丁又有点细微的差别。APISIX的定制OpenResty版本目前仅支持到1.19.3,而Kong的定制OpenResty跟官方版本是同步的。此处的方案就是用Kong的patch和APISIX的lua-resty-http(我稍微改了一丢丢兼容Kong的patch)。

功能

  • OpenResty作为客户端调用外部HTTP接口, 使用mTLS认证

Server配置

对应nginx配置

server {
  listen 443 ssl;
    server_name ssl.test.com;
  ssl_certificate ssl/mtls_server.crt;      #server公钥
  ssl_certificate_key ssl/mtls_server.key;  #server私钥
  ssl_client_certificate ssl/mtls_ca.crt;   #根级证书公钥,用于验证各个二级client
  ssl_verify_client on;
}

请求验证

  • curl命令行验证
curl --resolve ssl.test.com:443:127.0.0.1 --cacert ssl/mtls_ca.crt --cert ssl/mtls_client.crt --key mtls_client.key https://ssl.test.com
  • lua-resty-http验证
location /t {
    resolver local=on ipv6=off;
    resolver_timeout 5s;
    lua_ssl_verify_depth 1;
    lua_ssl_trusted_certificate /data/nginx/mtls/ca.pem;

    content_by_lua_block {
        local http = require "resty.http"
        local httpc = http.new()

        local res, err = httpc:request_uri("https://ssl.test.com/", {
            ssl_cert_path = "/data/nginx/mtls/client.pem",
            ssl_key_path = "/data/nginx/mtls/client.key",
        })
        if not res then
            ngx.log(ngx.ERR, err)
        else
            ngx.say(res.body)
            ngx.exit(res.status)
        end
    }
}

FAQ

1. 多CA证书如何使用

一个location下同时使用系统CA和自签名CA时,将CA合并成1个文件即可,参考系统的 /etc/pki/tls/certs/ca-bundle.crt

2. client证书兼容性测试结果

CA证书和Server证书都是ecdsa 256类型

系统版本客户端版本client证书类型能否使用
CentOS 7curl7.29.0ecdsa 256
CentOS 8curl7.61.1ecdsa 256
CentOS 7curl7.29.0rsa 2048
CentOS 8curl7.61.1rsa 2048
-lua-resty-http0.2.0ecdsa 256
-lua-resty-http0.2.0rsa 2048