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?
Best Answer
The example of Header expression shows that the entire parameter has to be quoted ("expr=..." instead of expr="..."). I ended up with
and this worked, the "null" string didn't occur anymore (Apache 2.4.6).