我如何告诉 Apache 强制客户端身份验证,但根据受信任的证书列表而不是 CA 进行授权?

我如何告诉 Apache 强制客户端身份验证,但根据受信任的证书列表而不是 CA 进行授权?

我正在尝试创建一个 Apache SSL 服务器,用于预生产测试,即使在生产中也只有不到 5 个左右的用户访问。由于用户群较小,我认为管理证书的最简单方法就是自行签名,然后明确告诉 Apache 只信任我们创建的少数证书。据我所知,Apache 似乎需要一个 CA,但我希望有办法解决这个问题。

此外,就开发而言,我倾向于了解我的东西,但作为系统管理员,我还是个新手,所以解决方案越简单越好。

顺便说一句,我还看到了这篇文章:这里我认为这与我所问的问题类似,但不是我想要的解决方案。理想情况下,我可以使用 openSSL 动态生成自签名证书,并将它们副本添加到目录中,这样当它们用于访问服务器时,Apache 就会创建连接。

答案1

你需要做两件事。

首先,您需要为要连接的浏览器生成证书。

然后,您需要设置 Apache 以要求某些文件夹使用这些证书。

apache 部分很简单 - 只需将其添加到您的 /etc/apache2/sites-enabled/your_apache_file.conf:

<Location /path/to/folder>
SSLVerifyClient require
SSLVerifyDepth 1
</Location>

现在假设您已经像这样设置了 apache SSL:

SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCACertificateFile /etc/apache2/ssl/ca.crt

SSLVerifyClient optional
SSLOptions +StdEnvVars +ExportCertData

您还需要将自己设置为 CA。

这是我们用于生成客户端证书的一段 Python 代码 - 这应该可以让您很好地了解从这里需要做什么:

commonname = "name_of_client_machine"


serial_file = open('/usr/local/my/web/certs/ca.srl','r')
serial = serial_file.read().strip()

cert_folder = '/usr/local/my/web/certs/clients/%s_%s' % (serial,commonname)

try:

    os.makedirs(cert_folder, 0755)

except OSError:
    pass



commands.getstatusoutput("sed s/hostname/%s/ /usr/local/my/web/certs/client.tpl > %s/client.tpl" % (commonname,cert_folder))

commands.getstatusoutput("openssl genrsa -des3 -passout pass:mypassword -out %s/web_client.key 4096" % cert_folder)

commands.getstatusoutput("openssl req -new -key %(cert_folder)s/web_client.key -out %(cert_folder)s/web_client.csr -config %(cert_folder)s/client.tpl -passin pass:mypassword" % ({'cert_folder':cert_folder}))

commands.getstatusoutput("openssl x509 -req -days 3650 -in %(cert_folder)s/web_client.csr -CA /usr/local/my/web/certs/ca.crt -CAkey /usr/local/my/web/certs/ca.key -out %(cert_folder)s/web_client.crt -passin pass:mypassword"  % ({'cert_folder':cert_folder}))

commands.getstatusoutput("openssl pkcs12 -export -clcerts -in %(cert_folder)s/web_client.crt -inkey %(cert_folder)s/web_client.key -out %(cert_folder)s/web_client.P12 -passin pass:mypassword -passout pass:mypassword" % ({'cert_folder':cert_folder}))

现在,您将获取 .p12 文件并将其导入到客户端浏览器。系统将要求您输入密码(上面的密码为“mypassword”),然后系统将安装并准备就绪。

答案2

经过一番努力,我们终于找到了解决方案。虽然不是非常理想,但现在看来效果不错。

在 Apache 中,我们首先必须启用 mod_ssl,要求客户端身份验证,然后将验证深度设置为 1。然后我们必须将服务器证书和密钥设置为由我们的 CA 生成和签名的内容(我稍后会讲到这一点),并将 SSLCACertificateFile 设置为我们的 CA 证书。在创建 CA 时,指南非常详尽,我发现它非常准确。除了稍微修改一些目录路径以使其与 Ubuntu 兼容(即使用 /etc/ssl)之外,它运行良好。我们创建了一个 CA,然后生成了一个 CA 证书。然后,我们生成了一个服务器密钥和服务器证书请求,并使用 CA 对该请求进行了签名。然后,我们将 Apache 设置为使用新的服务器证书和密钥。此时,您可以执行服务器身份验证,但不能执行客户端身份验证。为了完成后面的部分,我们只是基于上面链接中的一些示例。创建/签署证书密钥组合的过程是通用的,即您可以在服务器或客户端上使用该组合。因此,我们只需重复该过程即可创建客户端证书(并且可以反复执行以创建更多证书)。一旦我们有了证书,我们就将这两个文件转换为 .pk12

# openssl pkcs12 -export -in certs/client.crt -inkey private/client.key -out ~/clientcred.p12

最后,我们将证书导入 Firefox 以供使用。我们还将新 CA 添加到 Firefox 的内部受信任 CA 列表中。希望这对尝试类似操作的其他人有所帮助。

相关内容