]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEV: add a Lua helper script for SSL keys logging
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 24 May 2023 14:02:17 +0000 (16:02 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 24 May 2023 14:08:23 +0000 (16:08 +0200)
This script can be used through a http-request rules to log SSL keys for
traffic on a dedicated frontend. The resulting file can then be injected
into wireshark to decipher the corresponding network capture.

dev/sslkeylogger/sslkeylogger.lua [new file with mode: 0644]

diff --git a/dev/sslkeylogger/sslkeylogger.lua b/dev/sslkeylogger/sslkeylogger.lua
new file mode 100644 (file)
index 0000000..432fe65
--- /dev/null
@@ -0,0 +1,43 @@
+--[[
+    This script can be used to decipher SSL traffic coming through haproxy. It
+    must first be loaded in the global section of haproxy configuration with
+    TLS keys logging activated :
+
+      tune.ssl.keylog on
+      lua-load sslkeylogger.lua
+
+    Then a http-request rule can be inserted for the desired frontend :
+      http-request lua.sslkeylog <path_to_keylog_file>
+
+    The generated keylog file can then be injected into wireshark to decipher a
+    network capture.
+]]
+
+local function sslkeylog(txn, filename)
+       local fields = {
+               CLIENT_EARLY_TRAFFIC_SECRET     = function() return txn.f:ssl_fc_client_early_traffic_secret()     end,
+               CLIENT_HANDSHAKE_TRAFFIC_SECRET = function() return txn.f:ssl_fc_client_handshake_traffic_secret() end,
+               SERVER_HANDSHAKE_TRAFFIC_SECRET = function() return txn.f:ssl_fc_server_handshake_traffic_secret() end,
+               CLIENT_TRAFFIC_SECRET_0         = function() return txn.f:ssl_fc_client_traffic_secret_0()         end,
+               SERVER_TRAFFIC_SECRET_0         = function() return txn.f:ssl_fc_server_traffic_secret_0()         end,
+               EXPORTER_SECRET                 = function() return txn.f:ssl_fc_exporter_secret()                 end,
+               EARLY_EXPORTER_SECRET           = function() return txn.f:ssl_fc_early_exporter_secret()           end
+       }
+
+       local client_random = txn.c:hex(txn.f:ssl_fc_client_random())
+
+       -- ensure that a key is written only once by using a session variable
+       if not txn:get_var('sess.sslkeylogdone') then
+               file = io.open(filename, 'a')
+               for fieldname, fetch in pairs(fields) do
+                       if fetch() then
+                               file:write(string.format('%s %s %s\n', fieldname, client_random, fetch()))
+                       end
+               end
+
+               file:close()
+               txn:set_var('sess.sslkeylogdone', true)
+       end
+end
+
+core.register_action('sslkeylog', { 'http-req' }, sslkeylog, 1)