nginxluaopenresty

Which directive I can run before ssl_certificate_by_lua_block to get user-agent information in openresty


I am using OpenResty to generate SSL certificates dynamically. I am trying to find out the user-agent of request before running ssl_certificate_by_lua_block and decide If I want to continue with the request or not.

I found out that ssl_client_hello_by_lua_block directive runs before ssl_certificate_by_lua_block but if I try to execute ngx.req.get_headers()["user-agent"] inside ssl_client_hello_by_lua_block I get the following error

2022/06/13 09:20:58 [error] 31918#31918: *18 lua entry thread aborted: runtime error: ssl_client_hello_by_lua:6: API disabled in the current context
stack traceback:
coroutine 0:
    [C]: in function 'error'
    /usr/local/openresty/lualib/resty/core/request.lua:140: in function 'get_headers'
    ssl_client_hello_by_lua:6: in main chunk, context: ssl_client_hello_by_lua*, client: 1.2.3.4, server: 0.0.0.0:443

I tried rewrite_by_lua_block but it runs after ssl_certificate_by_lua_block

Are there any directive that can let me access ngx.req.get_headers()["user-agent"] and run before ssl_certificate_by_lua_block as well?

My Nginx conf for reference.

nginx.conf

# HTTPS server
server {
    listen 443 ssl;

    rewrite_by_lua_block {
        local user_agent = ngx.req.get_headers()["user-agent"]
        ngx.log(ngx.ERR, "rewrite_by_lua_block user_agent -- > ", user_agent)
    }

    ssl_client_hello_by_lua_block {
        ngx.log(ngx.ERR, "I am from ssl_client_hello_by_lua_block")
        local ssl_clt = require "ngx.ssl.clienthello"
        local host, err = ssl_clt.get_client_hello_server_name()
        ngx.log(ngx.ERR, "hosts -- > ", host)
        -- local user_agent = ngx.req.get_headers()["user-agent"]
        -- ngx.log(ngx.ERR, "user_agent -- > ", user_agent)
    }

    ssl_certificate_by_lua_block {
      auto_ssl:ssl_certificate()
    }
    ssl_certificate /etc/ssl/resty-auto-ssl-fallback.crt;
    ssl_certificate_key /etc/ssl/resty-auto-ssl-fallback.key;
    location / {
    proxy_pass http://backend_proxy$request_uri;
  }
}

Solution

  • If someone is facing the same issue. Here is the email group of OpenResty that helped me.

    I was not thinking correctly. The certificate negotiation happens before a client send user-agent data(that comes in after the SYNACK reaches the client). So you cant save issuing the certificate in the process. Hard luck.

    Once the handshake and the Client/Server Hello happens then the server has the user-agent, you can do the blocking under access_by_lua_block.