如何使用在Apache 2.4上运行的PHP 5.6从SSL客户端证书中获取SSL_CLIENT_* 变量?

rnmwe5a2  于 2022-11-14  发布在  Apache
关注(0)|答案(2)|浏览(160)

Introduction

I'm using PHP 5.6 and Apache 2.4 in the back-end of my web site where I use SSL to authenticate clients as an optional form of entering the site. I want to get some SSL_CLIENT_* variables which are contained in the certificate but aren't being shown by Apache 2.4, therefore, I cannot access them using $_SERVER .

Description

I want to get the following environment variables from the client certificate:

  • SSL_CLIENT_S_DN_CN
  • SSL_CLIENT_SAN_OTHER_msUPN_0
  • SSL_CLIENT_SAN_Email_0

When I dump $_SERVER in PHP 5.6 I can see what is returned by the variable SSL_CLIENT_VERIFY . If it returns GENEROUS , all three variables are shown; if it is SUCCESS only the first on the list above, SSL_CLIENT_S_DN_CN , is shown; and, if SSL_CLIENT_VERIFY is NONE , there is no certificate supplied by the client.
I used XAMPP v3.2.2 on Windows 10 (Apache 2.4 and PHP 7.0) locally and I can access all the variables, but, somehow, I cannot do the same using a remote Debian 9 server running Apache 2.4 and PHP 5.6.
I tried unsuccessfully to set up the SSLRequire (which is deprecated according to the docs - mod_ssl) option and Require as well.
I resorted to StackOverflow and ServerFault search for similar questions, involving SSL client certificates, but all the questions I came across involve SSL basic configuration (HTTP to HTTPS, Proxy, etc.) and creating headers with existing environment variables, like SSLRequire that works this way, for what I understood by reading the docs.
In the default-ssl.conf I tried to set the headers using the variables, but when I do the following:
print_r(getallheaders());
PHP 5.6 returns NULL :
Array ( [...] [SSL_CLIENT_SAN_OTHER_msUPN_0] => (null) [SSL_CLIENT_SAN_Email_0] => (null) )
The question again is how to get the variables SSL_CLIENT_SAN_OTHER_msUPN_0 and SSL_CLIENT_SAN_Email_0 from the client certificate.

Attachments

    1. My Apache 2.4 SSL configuration file:*

default-ssl.conf

<VirtualHost *:443>
    ServerName myserver.name #Omitted
    RequestHeader set SSL_CLIENT_SAN_OTHER_msUPN_0 "%{SSL_CLIENT_SAN_OTHER_msUPN_0}s"
    RequestHeader set SSL_CLIENT_SAN_Email_0 "%{SSL_CLIENT_SAN_Email_0}s"
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
    # Configuracoes de cache    
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
    Header set Note "Cache desabilitado no servidor/host"

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    # Configuracao do SSL
    SSLEngine on
    # [...] Certificados AC e certificados da aplicacao: OMITTED
    SSLOptions +StdEnvVars +OptRenegotiate -StrictRequire +FakeBasicAuth -ExportCertData  
    # Solicita certificado SSL/TLS do cliente            
    SSLVerifyClient optional_no_ca 
    SSLVerifyDepth 3

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +OptRenegotiate -ExportCertData -StrictRequire +FakeBasicAuth +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
        SSLOptions +StdEnvVars
    </Directory>
    BrowserMatch "MSIE [2-6]" \
                 nokeepalive ssl-unclean-shutdown \
                 downgrade-1.0 force-response-1.0
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
    1. PHP 5.6 file*

index.php

<?php //index.php

// Get client certificate data
$cn = $_SERVER['SSL_CLIENT_S_DN_CN'];
$email = $_SERVER['SSL_CLIENT_SAN_Email_0'];
$id = $_SERVER['SSL_CLIENT_SAN_OTHER_msUPN_0'];

$client_certificate_data = [
    'cn' => $cn,
    'email' => $email,
    'id' => $id
];

echo json_encode(
    $client_certificate_data,
    JSON_NUMERIC_CHECK
);

// Output: {"cn":"EXAMPLE CN CONTENT HERE","email":null,"id":null}

ljo96ir5

ljo96ir51#

Apache指令SSLOptions +StdEnvVars将SSL信息作为环境变量传递给Php。更多信息请参见以下链接:
Using SSL Client Certificates with PHP和SSL选项指令

bvn4nwqk

bvn4nwqk2#

如果SSL_CLIENT_VERIFY被设置为NONE,则意味着客户端没有发送证书。在这种情况下,当然不能提供关于客户端证书的信息。
在所有其他情况下,您应该获得SSL_CLIENT_S_DN_CN。只有当客户端证书包含SAN条目时,您才会获得SSL_CLIENT_SAN_*,即您看到的差异可能是由于使用了不同的客户端证书。

相关问题