首页 文章

Apache不会请求我的SSL客户端证书

提问于
浏览
13

首先,请注意我是配置SSL的新手 . 在过去,我一直很幸运有一个IT部门可以提前为我做好准备 . 因此,请准备好我可能需要澄清你的一些答案 . =)

What I'm Trying to Do

我正在为员工 Build 一个公司内联网网站 . 例如,将有一个浏览器起始页面,显示为每个员工定制的内容 . 因此,我需要能够识别所述员工而无需任何用户名/密码或其他提示(虽然一次性设置是可以的;我只是不希望每次都提示它们) . 当然,SSL似乎是实现这一目标的最佳方式 .

我假设每个客户端证书(?)都是唯一的'll have a MySQL database setup to associate 145502 accounts with SSL_CLIENT_M_SERIAL and SSL_CLIENT_I_DN, which I'm . 我从这篇文章中得到了这个想法:http://cweiske.de/tagebuch/ssl-client-certificates.htm

用户第一次访问内部网站时,他们将没有证书(我不想为客户手动生成证书!),在这种情况下$ _SERVER [“SSL_CLIENT_VERIFY”] ==“NONE” . 如果发生这种情况,它将转到用户帐户设置页面,其中包括PHP生成SSL客户端证书并将其发送到浏览器以供用户安装的步骤 . 很好,很简单 . 然后,用户安装证书, Build 关联,并在重新启动浏览器后(为了更好地衡量),用户返回内部网站 .

此时,Apache应该请求客户端证书,然后浏览器发送该证书 . PHP脚本然后解析必要的$ _SERVER变量,与MySQL数据库进行比较,并且所有人都有好的时间 . 再次,美好而简单 .

What's Working So Far

我安装了服务器端证书 . 是的,他们是自签名的(出于显而易见的原因) . Apache安装了mod_ssl,所有这些似乎都运行正常 . 我创建了一个只转储$ SERVER数组的PHP脚本,所有SSL_SERVER *键值都与我为它创建的证书相匹配 .

The Problem

我无法获得客户端证书!在同一个PHP脚本中,无论我做什么,都缺少SSL_CLIENT_VERIFY ==“NONE”和其他SSL_CLIENT_ *键 . 如果我在ssl.conf中将SSLVerifyClient设置为可选,则会发生这种情况 . 根据我读过的每个教程,他们都说网络服务器应该向浏览器询问客户端证书 . 事情是,我无法做到这一点!它只是直接进入PHP脚本,并假设我根本没有客户端证书 . 这种情况发生在Firefox,Chrome和IE中 .

所以我尝试将SSLVerifyClient设置为必需并重新启动网络服务器 . 有了这个选项,我可以't even establish an SSL connection. Firefox just says the connection has been reset (other browsers display their own versions of that error as well). What'奇怪的是日志不会显示任何东西;它's as if the attempt never even occurred. This is frustrating because it means I don'甚至有一个错误信息可供使用 . 只是一个网络服务器被动 - 积极地告诉我下地狱 .

我尝试使用PHP的OpenSSL扩展手动生成/安装我自己的客户端证书 . 证书安装得很好,虽然我找不到任何关于如何将该证书与服务器关联的信息(假设我甚至需要?) . 此外,它似乎无关紧要,因为如果设置了可选项,Apache仍然不会请求客户端证书 . 如果设置了需求,它只是爆炸而没有解释 . 我需要将它设置为可选,以使此模式起作用 .

The Environment

操作系统:CentOS 5.7 64位(VirtualBox)

Apache:2.2.3

PHP:5.3.10

我猜你可能需要更多的信息来帮助我,所以请问!我会为你提供你需要的一切 .

总而言之,我需要知道如何在给定上述条件的情况下让Apache请求SSL客户端证书 . 此外,如果有任何特殊的签名/等必须要使客户端证书与服务器证书“兼容”(再次,没有通过shell为每个客户端证书手动执行!),我需要知道好 .

截至目前,我100%坚持这一点 . 在Google上找不到任何远程帮助 . 您可以提供的任何帮助将是非常感谢!!谢谢! =)

3 回答

  • 0

    如果没有完成,您可以查看apache doc .

    一般原则是您创建自签名证书并在尝试使用之前进行检查 .

    然后看起来客户端通过http连接到您的Intranet站点 . 从那里,有许多不同的方法可以使用您的ssl证书切换到https . 最简单的方法是使用apache重写模块 . 但在您的情况下,当您进行php / mysql检查时,您可以将客户端从http重定向到https,这不是简单的方法 .

    在任何两种情况下(apache通过mod_rewrite自动重定向,或通过级联测试重定向(php / javascript / html)),你需要以正确的方式设置你的2个虚拟主机(一个用于http,一个用于https),但这假定一些假设 .

    例如(debian - apache 2.2),这是一个自动重定向,由Apache完成(例如上面描述的第一种情况):

    cat / etc / apache2 / sites-available / test

    # VHOST test
    
    <VirtualHost *:80>
    
        DocumentRoot /home/www/test
        ServerName www.test.dev
    
        # ######################
        # Redirect commons
        # ######################
        RewriteEngine on
        # Case of vhosts
        RewriteOptions Inherit
    
        # ######################
        # Redirect (empty index)
        # ######################
    
        # Condition 1 to redirect : request matching with the server
        RewriteCond %{HTTP_HOST}   ^www\.test\.dev [NC]
    
        # Condition 2 to redirect : non empty HOST
        RewriteCond %{HTTP_HOST}   !^$
    
        # Automatic Empty requests Redirect
        RewriteRule ^(.*)/$ /index.php
    
    
        # ######################
        # Redirect to SSL
        # ######################
        RewriteCond %{HTTP_HOST}   ^www\.test\.dev [NC]
        RewriteCond %{HTTP_HOST}   !^$
        RewriteCond %{SERVER_PORT} ^80$
        RewriteCond %{REQUEST_URI} /
    
        # Redirection
        RewriteRule ^/(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
    
    </VirtualHost>
    

    SSL的第二个虚拟主机:cat在/ etc / apache2的/网站可用/测试SSL

    # VHOST for ssl
    
    DocumentRoot "/home/www/test"
    ServerName www.test.dev
    
        # SSL
        SSLEngine on
        SSLCACertificateFile /etc/apache2/ssl/cur_cert/ca.pem
        SSLCertificateFile /etc/apache2/ssl/cur_cert/serveur.pem
        SSLCertificateKeyFile /etc/apache2/ssl/cur_cert/serveur.key
    
    
        <Directory "/home/www/test">
            Options FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            Allow from 127.0.0.1 192.168.0.0/16
        </Directory>
    
    
        <Directory "/home/www/test/cgi-bin">
            Options FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            Allow from 127.0.0.1 192.168.0.0/16
            Options +ExecCGI
            AddHandler cgi-script .cgi
        </Directory>
    
    </VirtualHost>
    

    你的情况可能会稍微推迟,例如你不会在第一个虚拟主机中有重定向部分,而只有一个简单的虚拟主机,第二个用于https(ssl) . 一旦你完成了mysql检查,重定向将通过php / javascript完成 .

    这是一个php类的示例摘要,用于将交换机从http级联到https,使用php,然后是javascript,然后是html:

    public function Redirect($url){
    
        if (TRUE !== Validator::isValidURL($url))
            die ("FATAL ERR: url not valid");
    
        // PHP ABSOLUTE URL REDIRECT (HTTP1.1)
        if (!headers_sent()) {
    
            header("Status: 200");
            header("Cache-Control: no-cache, must-revalidate"); // required for HTTP/1.1
            header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // past Date
            header("Pragma: no-cache");
            header('Location: '.$url); // note: 302 code return by default with "Location"
            flush();
            exit();
    
            // if headers are already sent... do javascript redirect... if javascript is disabled, do html redirect.
        } else {
    
            // Js redirect
            echo '<script type="text/javascript">';
            //echo "<!--";
            echo 'document.location="'. $url .'";';
            //echo "//-->";
            echo '</script>';
    
            // HTML redirect if js disabled
            echo '<noscript>';
            echo '<meta http-equiv="refresh" content="0;url="'.$url.'" />';
            echo '</noscript>';
    
            exit();
        }
    
        return FALSE;
    
    } /* end of method (redirect) */
    

    希望它能帮助您更好地了解如何继续并根据您的具体情况调整此方法 .

  • 4

    首先,您需要配置Apache Httpd以请求客户端证书 . 为此,您至少需要在要使用此方法进行身份验证的位置/目录上使用 SSLVerifyClient optional .

    其次,Apache Httpd也需要信任客户端发送的证书 . (你原则上可以使用 SSLVerifyClient optional_no_ca ,让任何客户端证书通过Apache Httpd SSL / TLS堆栈,然后才在PHP中验证证书,但是's quite a bit of work, for which you need be a bit more careful since that'不一定是简单的代码;更重要的是,这在这里是没用的上下文,因为你're in a scenario where you'控制你的CA.)

    据我所知, SSL_CLIENT_VERIFY (一个我自己没有用过的变量)似乎只对 SSLVerifyClient optional_no_ca 非常有用 . 它可能适用于 SSLVerifyClient optional ,但我对此表示怀疑 . SSLVerifyClient require 将使用不受信任的客户端证书(由 SSLCACertificateFile / SSLCACertificatePath 中的某个CA)拒绝连接,或者如果没有证书 . 据我所知, SSLVerifyClient optional 将允许客户端通过没有证书或可信证书,但如果证书不受信任,也将拒绝连接 .

    在这里,通过拒绝连接,我的意思是突然关闭SSL / TLS连接并发出警报 . 没有机会生成HTTP(S)错误页面 . 所有你都会遇到标准浏览器错误,这与 ssl_error_unknown_certificate_... 一致 . (您应该在可用性方面考虑这一点 . )

    从那时起,您需要的是在同一网站内 Build 自己的CA,可能是基于Web的浏览器密钥生成 . 您不希望 SSLVerifyClient require ,因为您需要让尚未拥有证书的用户(使用 optional 代替) . 话虽这么说,这些指令不需要适用于整个主机,但可以特定于某些位置/目录 .

    集成您自己的基于Web的CA(或更一般地,创建您自己的CA)并不是所有这些的新手 . 存在现成的工具(例如OpenCA),或者您可以使用JavaScript/ActiveX的各个位来构建自己的工具,并且您需要服务器端代码来处理SPKAC或PKCS#10请求(以及颁发实际证书) . (为了使这样的CA有用,您希望申请新证书的用户在申请时提供一些ID证明,也许是密码 . )

    设置此项后,您应配置 SSLCACertificateFile (或 ...Path )以指向内部CA的CA证书(无论是否需要了解它 . )浏览器仅建议由这些CA或中间人颁发的证书(除非您还配置了 SSLCADNRequestFile ,用于发送已接受的CA列表 .

    请注意,这两个步骤(设置CA并设置网站以使用客户端证书)实际上是独立的 . 两者都可以成为同一站点的一部分这一事实可能很方便,但是,即使它正在进入,也不建议这样做 . 有许多工具可以创建您自己的小CA,可以使用少量证书进行管理:例如OpenSSL's CA.plTinyCA . 你也可以使用这些test certificates(如果你想使用CRL, localhosttestclienttestclient_r 被撤销,可能最初没有必要):所有密码都是 testtest .

    当您需要管理您颁发的证书并将其映射到用户时 . 但是, SSL_CLIENT_M_SERIALSSL_CLIENT_I_DN 不是正确的变量 . SSL_CLIENT_I_DN 是颁发者DN(即CA 's Subject DN). What you'正在寻找的是 SSL_CLIENT_S_DN :客户端证书主题DN . SSL_CLIENT_M_SERIAL 是证书序列号:每个证书都是唯一的:一个用户可以拥有多个具有相同主题DN的证书(例如,如果一个人过期或被撤销) .


    尽管如此,我还不确定客户端证书是否是实现目标的最佳方式(让公司员工在没有密码的情况下登录) .

    • 首先,用户应该使用密码保护自己的证书 . 我猜你真正追求的是单点登录(SSO) .

    • 其次,根据用户的计算机知识程度,证书实际上很难管理 .

    严格来说,单词"certificate"根本不包括私钥,但有时暗示私钥的使用可能会让一些人感到困惑 . 一方面,你有时会听到"Import your certificate into your browser"和"Use your certificate to log in";另一方面,你也可以听到"send me your certificate" . 前者意味着私钥的使用和可用性("certificate"可能仅意味着这些表达式中的 .p12 ) . 后者绝对不应该涉及私钥 .

    浏览器用户界面往往很差或者很难用于管理证书或注销 . 同样,如果无法识别证书,则不会 Build SSL / TLS连接,因此Web服务器无法显示任何类型的HTML错误页面 .

    也许你也可以考虑其他形式的SSO(例如CAS,基于SAML或Kerberos / SPNEGO . )

  • 0

    我有一个类似的问题:

    • CentOS 6.3

    • Apache 2.2.15

    经过一些尝试,我认出了我的问题 .

    如果我设置了 SSLVerifyClient optionalSSLVerifyClient optional_no_ca 并且我还指定了 SSLCACertificateFileSSLCACertificatePath ,则只有在从配置中指定的CA参考文件/路径中找到的CA发布时,Apache才会获取客户端证书 .

相关问题