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

2022-08-30 23:47:27

首先,请注意,我是配置SSL的新手。过去,我一直很幸运有一个IT部门提前为我设置了它。因此,请准备好我可能需要要求澄清您的一些答案的可能性。=)

我想做什么

我正在为员工建立一个公司内部网网站。例如,将有一个浏览器起始页,显示为每个员工自定义的内容。因此,我需要能够识别所述员工,而无需任何用户名/密码或其他提示(一次性设置是可以的;我只是不希望他们每次都得到提示)。当然,SSL似乎是执行此操作的最佳方法。

我将设置一个MySQL数据库,将“用户”帐户与SSL_CLIENT_M_SERIAL和SSL_CLIENT_I_DN相关联,我假设每个客户端证书(?)都是唯一的。我从这篇文章中得到了这个想法:http://cweiske.de/tagebuch/ssl-client-certificates.htm

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

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

到目前为止,什么有效

我已安装服务器端证书。是的,它们是自签名的(出于明显的原因)。Apache已经安装了mod_ssl,所有这些似乎都运行良好。我创建了一个 PHP 脚本,该脚本仅转储 $_SERVER 数组,并且所有 SSL_SERVER_* 键值都与我为其创建的证书匹配。

问题

我无法让客户端证书正常工作!在同一个PHP脚本中,无论我做什么,SSL_CLIENT_VERIFY==“NONE”,其他SSL_CLIENT_*键都丢失了。如果我在ssl.conf中将SSLVerifyClient设置为可选,就会发生这种情况。根据我读过的每个教程,他们都说Web服务器应该向浏览器询问客户端证书。问题是,我不能让它这样做!它只是直接进入PHP脚本,并假设我根本没有客户端证书。这发生在Firefox,Chrome和IE中。

因此,我尝试将SSLVerifyClient设置为必需并重新启动Web服务器。有了这个选项,我甚至无法建立SSL连接。Firefox只是说连接已被重置(其他浏览器也显示该错误自己的版本)。奇怪的是,日志没有显示这些连接尝试的任何活动!即access_log,error_log,ssl_access_log,ssl_error_log和ssl_request_log都不显示任何内容;就好像这种尝试从未发生过一样。这很令人沮丧,因为这意味着我甚至没有要处理的错误消息。只是一个网络服务器被动地主动告诉我下地狱。

我尝试使用PHP的OpenSSL扩展手动生成/安装我自己的客户端证书。证书安装得很好,尽管我找不到有关如何将该证书与服务器证书相关联的任何信息(假设我甚至需要这样做?)。此外,这似乎并不重要,因为如果设置了可选选项,Apache甚至不会请求客户端证书。如果设置了要求,它就会在没有解释的情况下爆炸。无论如何,我需要将其设置为可选,以使此架构正常工作。

环境

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

Apache: 2.2.3

菲律宾比索: 5.3.10

我猜你可能需要更多的信息来帮助我,所以请问!我会为你提供你需要的任何东西。

总而言之,我需要知道如何让Apache在满足上述条件的情况下请求SSL客户端证书。此外,如果必须执行任何特殊的签名/等才能使客户端证书与服务器证书“兼容”(同样,无需通过shell为每个客户端证书手动执行此操作!),我还需要知道这一点。

到目前为止,我100%坚持这一点。在谷歌上找不到任何有用的东西。您可以为此提供的任何帮助将不胜感激!谢谢!=)


答案 1

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

其次,客户端发送的证书也需要被Apache Httpd信任。(原则上你可以使用,让任何客户端证书通过Apache Httpd SSL / TLS堆栈,然后才在PHP中验证证书,但这是相当多的工作,为此你需要更加小心,因为这不一定是容易的代码;更重要的是,这在这种情况下是相当无用的, 因为您处于控制 CA 的场景中。SSLVerifyClient optional_no_ca

据我所知,(我自己没有用过的变量)似乎只对.它可能适用于 ,但我怀疑是这样。 将使用不受信任的客户端证书(由 / 中的某个 CA)或没有证书时拒绝连接。据我所知,会让客户端在没有证书或受信任证书的情况下通过,但如果证书不可信,也会拒绝连接。SSL_CLIENT_VERIFYSSLVerifyClient optional_no_caSSLVerifyClient optionalSSLVerifyClient requireSSLCACertificateFileSSLCACertificatePathSSLVerifyClient optional

在这里,通过拒绝连接,我的意思是突然关闭SSL / TLS连接并发出警报。没有机会生成 HTTP(S) 错误页。您将在标准浏览器错误中得到的所有内容,类似于.(您应该从可用性的角度考虑这一点。ssl_error_unknown_certificate_...

从那时起,您需要的是设置自己的CA,可能是基于Web的浏览器内密钥生成和同一网站。你不会想要这样,因为你需要让还没有证书的用户进入(使用)。话虽如此,这些指令不需要适用于整个主机,但可以特定于某些位置/目录。SSLVerifyClient requireoptional

如果您不熟悉所有这些,那么集成您自己的基于Web的CA(或者更一般地说,创建自己的CA)不一定容易。现成的工具是存在的(例如OpenCA),或者您可以使用各种JavaScript / ActiveX构建自己的工具,并且您需要服务器端代码来处理SPKAC或PKCS#10请求(并颁发实际的证书)。(要使此类 CA 有用,您希望申请新证书的用户在申请时提供一些 ID 证明,可能是密码。

设置此设置后,应将 (或) 配置为指向内部 CA 的 CA 证书(无论它是否是基于 Web 的 CA,是否在同一站点上)。(当然,保持CA的私钥是私有的,可能是在基于CA Web的应用程序内配置的,但Apache Httpd本身不需要知道它。浏览器只会建议由这些 CA 或中间人颁发的证书(除非您还配置了 ,这将用于发送接受的 CA 列表)。SSLCACertificateFile...PathSSLCADNRequestFile

请注意,这两个步骤(设置CA和设置您的网站以使用客户端证书)实际上确实是独立的。两者都可以是同一站点的一部分这一事实可能很方便,但不是必需的。你可以尝试Apache Httpd设置,而无需先在网站上部署整个CA(我建议这样做,即使只是为了看看你要进入什么)。有许多工具可以创建自己的小CA,这些工具可以通过少量证书进行管理:例如OpenSSL的 CA.plTinyCA。您也可以使用这些测试证书(如果要使用 CRL,则会吊销 ,一开始可能不需要):所有密码都是 。localhosttestclienttestclient_rtesttest

正如您已经预料到的那样(使用MySQL数据库),您需要管理您颁发的证书并将其映射到用户。 但是,它们不是要使用的正确变量。 是发行人 DN(即 CA 的主题 DN)。您要寻找的是:客户端证书主题DN。 是证书序列号:不要使用它,因为它在每个证书中是唯一的:一个用户可以拥有具有相同主题 DN 的多个证书(例如,如果一个证书过期或被吊销)。SSL_CLIENT_M_SERIALSSL_CLIENT_I_DNSSL_CLIENT_I_DNSSL_CLIENT_S_DNSSL_CLIENT_M_SERIAL


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

  • 首先,用户无论如何都应该使用密码保护自己的证书。我猜,你真正想要的是某种形式的单点登录(SSO)。

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

    严格来说,“证书”这个词根本不包括私钥,但有时意味着私钥的使用,这可能会让一些人感到困惑。一方面,您有时会听到“将证书导入浏览器”和“使用证书登录”;另一方面,您还可以听到“将您的证书发送给我”。前者意味着私钥的使用和可用性(“证书”可能只是这些表达式中的意思)。后者绝对不应该涉及私钥。.p12

    浏览器用户界面往往很差或令人困惑,无法管理证书或注销。同样,如果证书未被识别,则不会建立 SSL/TLS 连接,因此 Web 服务器没有机会显示任何类型的 HTML 错误页面。

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


答案 2

我有类似的问题:

  • CentOS 6.3
  • 阿帕奇 2.2.15

经过一些尝试,我意识到我的问题。

如果我设置了 or 并且我还指定了 或 ,则 Apache 仅在从配置中指定的 CA 引用文件/路径中找到的 CA 发布客户端证书时才会获取客户端证书。SSLVerifyClient optionalSSLVerifyClient optional_no_caSSLCACertificateFileSSLCACertificatePath


推荐