1

I have a configuration where I have nginx terminating https as reverse proxy, behind that an apache server that serves a perl application (openxpki).

That apache server needs to inject the client certificate into ENV:SSL_CLIENT_CERT in order for openxpki to work.

nginx is configured to pass client certificate to apache via an http header X-SSL-CERT

    proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

Important to note that the certificate gets url encoded here by nginx. (otherwise it cannot be transferred in a header line)

Now apache needs to read the header and set it in ENV:SSL_CLIENT_CERT

Just using

    SetEnvIfNoCase X-SSL-CERT "(.*)" SSL_CLIENT_CERT=$1

wont work, as then you get the url encoded version in ENV:SSL_CLIENT_CERT

Using unescape is required here, to un-escape the url encoded cert. I managed to get that working with

    # Cannot use unescape directly in SetEnvIfNoCase  as it only allows $1,$2, ..
    RequestHeader set X-SSL-CERT-UNESCAPED "expr=%{unescape:%{HTTP:X-SSL-CERT}}" early
    SetEnvIfNoCase X-SSL-CERT-UNESCAPED "(.*)" SSL_CLIENT_CERT=$1

This kinda works... however....

This unescaped everything, but forward slashes (%2F = '/'). As a certificate is base64 stuff, this does often contain forward slashes -> leaving in %2F snippets, resulting in a broken cert in ENV:SSL_CLIENT_CERT

How can I get the certificate ('-----BEGIN CERTIFICATE...') in my perl application? How can I get apache to fully unescape this?

I tried all settings of AllowEncodedSlashes, but that didn't change anything

harmv
  • 1,905
  • 22
  • 22

1 Answers1

0

Ok, I have found the answer (workaround?) myself.

The following apache config makes it work

        RequestHeader set X-SSL-CERT-UNESCAPED "expr=%{unescape:%{HTTP:X-SSL-CERT}}" early
        # Fixing broken unescape() in apache config....
        # Replace the encoded forward slashes
        RequestHeader edit* X-SSL-CERT-UNESCAPED "%2F"  "/" early
        SetEnvIfNoCase X-SSL-CERT-UNESCAPED "(.*)" SSL_CLIENT_CERT=$1

Feels like working around apache bugs in config language though... (eg: using early is not recommended by apache: Early mode is designed as a test/debugging aid for developers)

Using apache behind a reverse proxy seems common enough that there should be cleaner way to do this.

Does anyone know a clean(er) way to propagate a client certifcite from apache into your perl application?

harmv
  • 1,905
  • 22
  • 22