4

I have an Apache 2.4 server configured as a reverse proxy to accept incoming HTTPS requests and reverse-proxy them to another server over HTTP with custom HTTP headers containing any provided client certificate information.

A simplified version of my configuration:

<VirtualHost _default_:443>
  SSLCertificateFile "/path/to/server.crt"
  SSLCertificateKeyFile "/path/to/server.key"
  SSLCACertificateFile "/path/to/client-ca-chain.pem"
  SSLVerifyClient optional

  ProxyRequests Off
  ProxyPreserveHost On
  ProxyPass / http://remote-server/
  ProxyPassReverse / http://remote-server/
  RequestHeader add X-Forwarded-Proto https
  RequestHeader add X-Forwarded-Port 443
  RequestHeader set Client-Cert-Subject "%{SSL_CLIENT_S_DN}s"
</VirtualHost>

For the most part, this is fine, but things get a little weird because Certificate Authentication is optional.

When a user provides their certificate, the remote system sees the Client-Cert-Subject header just as I'd expect:

Client-Cert-Subject: CN=USER.NAME.0123456789,OU=BLAH,O=WHATEVER,C=STUFF

When a user doesn't provide their certificate, e.g. by clicking "Cancel" instead of their certificate when prompted by the browser, the header is still included but contains the text string (null):

Client-Cert-Subject: (null)

This makes the remote server very angry.

What I'd like to do is include the header, complete with the certificate subject retrieved using %{SSL_CLIENT_S_DN}s, when the user provides one, but just not include the header at all if the user didn't provide a certificate. It would also be acceptable, although weird?, if the header was provided as an empty string when is no certificate information.

I've tried various iterations of using an If directive, e.g.

<If "-n %{SSL_CLIENT_S_DN}s">
  RequestHeader set Client-Cert-Subject "%{SSL_CLIENT_S_DN}s"
</If>

and of using an expression on the RequestHeader directive, e.g.

  RequestHeader set Client-Cert-Subject "%{SSL_CLIENT_S_DN}s" expr="-n %{SSL_CLIENT_S_DN}s"

but always get either a syntax error, always the header, or never the header.

How can I coerce apache to conditionally include my Client-Cert-Subject only when there's actually a client certificate?

1 Answer 1

2

The example of Header expression shows that the entire parameter has to be quoted ("expr=..." instead of expr="..."). I ended up with

 RequestHeader set X-SSL-CLIENT-CERT "%{SSL_CLIENT_CERT}s" "expr=-n %{SSL_CLIENT_CERT}"

and this worked, the "null" string didn't occur anymore (Apache 2.4.6).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .