在 Apache 中有条件地设置 SSL 证书请求标头

在 Apache 中有条件地设置 SSL 证书请求标头

我有一个配置为反向代理的 Apache 2.4 服务器,用于接受传入的 HTTPS 请求并通过 HTTP 将它们反向代理到另一台服务器,并使用包含任何提供的客户端证书信息的自定义 HTTP 标头。

我的配置的简化版本:

<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>

在大多数情况下,这是没问题的,但是事情变得有点奇怪,因为证书认证是可选的。

当用户提供他们的证书时,远程系统会看到Client-Cert-Subject如我预期的标头:

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

当用户不提供其证书时(例如,在浏览器提示时单击“取消”而不是其证书),标头仍然包含在内,但包含文本字符串(null)

Client-Cert-Subject: (null)

这让远程服务器非常生气。

我想做的是,%{SSL_CLIENT_S_DN}s当用户提供证书时,包含使用 检索到的证书主题的标头,但如果用户未提供证书,则根本不包含标头。如果在没有证书信息时将标头作为空字符串提供,这也是可以接受的,尽管很奇怪?

我尝试过多次使用If指令,例如

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

并在 RequestHeader 指令上使用表达式,例如

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

但总是出现语法错误、总是出现标题或从不出现标题。

Client-Cert-Subject当实际存在客户端证书时,如何强制 apache 有条件地包含我?

答案1

例如标头表达式表明整个参数必须用引号引起来(“expr=...”而不是 expr="...”)。我最终得到了

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

并且这有效,“null”字符串不再出现(Apache 2.4.6)。

相关内容