-
-
Save bzed/e1e6c76e98225f997062c57aacecd2fd to your computer and use it in GitHub Desktop.
require("base64") | |
core.register_fetches("ssl_c_pem", function(txn) | |
local der = txn.f:ssl_c_der() | |
local wrap = ('.'):rep(64); | |
local envelope = "-----BEGIN %s-----\n%s\n-----END %s-----\n" | |
local typ = "CERTIFICATE"; | |
der = base64.encode(data); | |
return string.format(envelope, typ, der:gsub(wrap, '%0\n', (#der-1)/64), typ); | |
end) |
That basically means that it can't find the base64 functions.
Maybe try
local base64 = require'base64'
somewhere. probably in the function?
That basically means that it can't find the base64 functions.
Maybe try
local base64 = require'base64'
somewhere. probably in the function?
I forgot to mention that I installed base64 from luarocks:
https://luarocks.org/modules/iskolbin/base64
Before that I had this error message:
[ALERT] 108/233244 (20196) : parsing [/etc/haproxy/haproxy.conf:14] : lua runtime error: /etc/haproxy/ssl_c_der.lua:1: module 'base64' not found:
no field package.preload['base64']
no file '/usr/share/lua/5.3/base64.lua'
no file '/usr/share/lua/5.3/base64/init.lua'
no file '/usr/lib64/lua/5.3/base64.lua'
no file '/usr/lib64/lua/5.3/base64/init.lua'
no file './base64.lua'
no file './base64/init.lua'
no file '/usr/lib64/lua/5.3/base64.so'
no file '/usr/lib64/lua/5.3/loadall.so'
no file './base64.so'
Where does the 'data' variable on line 9 get defined?
For folks finding this many years later, here is a working example
function client_cert(txn, t)
local der = txn.f:ssl_c_der()
local chain_der = txn.f:ssl_c_chain_der()
if type(der) == 'nil' then
return
end
local pem_w_chain = "-----BEGIN CERTIFICATE-----"
pem_w_chain = pem_w_chain .. "\n"
pem_w_chain = pem_w_chain .. txn.c:base64(der)
pem_w_chain = pem_w_chain .. "\n"
pem_w_chain = pem_w_chain .. "-----END CERTIFICATE-----"
pem_w_chain = txn.c:url_enc(pem_w_chain, "query")
if t == "req" then
txn.http:req_add_header("X-SSL-Client-Cert", pem_w_chain)
end
if t == "res" then
txn.http:res_add_header("X-SSL-Client-Cert", pem_w_chain)
end
if type(chain_der) ~= 'nil' then
local pem_w_chain = "-----BEGIN CERTIFICATE-----"
pem_w_chain = pem_w_chain .. "\n"
pem_w_chain = pem_w_chain .. txn.c:base64(chain_der)
pem_w_chain = pem_w_chain .. "\n"
pem_w_chain = pem_w_chain .. "-----END CERTIFICATE-----"
pem_w_chain = txn.c:url_enc(pem_w_chain, "query")
if t == "req" then
txn.http:req_add_header("X-SSL-Client-Cert", pem_w_chain)
end
if t == "res" then
txn.http:res_add_header("X-SSL-Client-Cert", pem_w_chain)
end
end
end
core.register_action("clientcert", { "http-req", "http-res" }, client_cert, 1)
This will add the X-SSL-Client-Cert
header to the request or response with the contents of the header being URL encoded PEM of the client certificate and chain.
You can use it in your haproxy config under a frontend like so
http-request lua.clientcert "req"
http-response lua.clientcert "res"
If you are using this header in hashicorp vault for example you'll want this config on the listener
x_forwarded_for_client_cert_header = "X-SSL-Client-Cert"
x_forwarded_for_client_cert_header_decoders = "URL,DER"
For folks finding this many years later, here is a working example
nice, thank you very much! Can't even remember which haproxy version we used back then :)
Hi. What are dependencies besides 'base64' package for this script? When I try to use it I get following in HAProxy error log.
haproxy[2263]: Lua sample-fetch 'ssl_c_pem': runtime error: /etc/haproxy/ssl_c_pem.lua:9: attempt to index a nil value (global 'base64') /etc/haproxy/ssl_c_pem.lua:9 C function line 3.