Compiling OpenResty (Nginx) with SSL extensions for LUA

The Lua SSL extensions for OpenResty enables you to use LUA to script SSL operations. For example, you can use this code to switch the SSL certificate depending on the servername.

Download and extract OpenResty:

$ cd /usr/local/src/
$ wget http://openresty.org/download/ngx_openresty-1.7.10.1.tar.gz
$ tar vxf ngx_openresty-1.7.10.1.tar.gz

Download and extract OpenSSL:

$ wget https://www.openssl.org/source/openssl-1.0.2a.tar.gz
$ tar vxf openssl-1.0.2a.tar.gz

Install the prerequisites:

$ apt-get install -y libpcre3-dev

Replace ngx_lua-0.9.15 with the latest one from Github and checkout the ssl-cert-by-lua branch. The SSL support hasn't been included in HEAD yet.

$ cd /usr/local/src/ngx_openresty-1.7.10.1/bundle
$ rm -rf ngx_lua-0.9.15
$ git clone https://github.com/openresty/lua-nginx-module/ ngx_lua-0.9.15
$ cd ngx_lua-0.9.15
$ git checkout ssl-cert-by-lua

Patch the Nginx code with support for the SSL context.

$ cd /usr/local/src/ngx_openresty-1.7.10.1/bundle/nginx-1.7.10/src/event
$ patch < ../../../ngx_lua-0.9.15/patches/nginx-ssl-cert.patch

Now we have prepared everything and we can build OpenResty:

$ cd /usr/local/src/ngx_openresty-1.7.10.1
$ ./configure --with-http_ssl_module --with-luajit --with-openssl=/usr/local/src/openssl-1.0.2a/ --add-module=bundle/lua-nginx-module && make && make install

Copy the SSL lua extension:

$ mkdir -p /usr/local/openresty/lualib/ngx
$ cp build/lua-nginx-module/lua/ngx/ssl.lua /usr/local/openresty/lualib/ngx/ssl.lua

If the build has been succesfull, we can check the configuration:

$ /usr/local/openresty/nginx/sbin/nginx -t

Now you can use both functions sslcertificatebylua and sslcertificatebylua_file.

Currently these functions are supported:

  • sslsetder_certificate
  • sslclearcerts
  • sslsetderprivatekey
  • sslrawserver_addr
  • sslservername
  • certpemto_der
  • sslgetocspresponderfromderchain
  • sslcreateocsp_request
  • sslvalidateocsp_response
  • sslsetocspstatusresp
  • sslgettls1_version

I've added some functions to create dynamic certificates on-the-fly depending on the request, which where used in a content filtering proxy. This solution has been tested under high load and outscales Squid (although I don't have actual numbers). The code will be opensourced soon, still have to clean it up.

Although you shouldn't do this, but if you are wondering how to prevent Nginx to verify proxied certificates, you can disable certificate verification by compiling with:

--with-openssl-opt=-DOPENSSL_NO_X509_VERIFY