10

我想使用 X509 客户端身份验证来进行安全 API 访问。

X509 证书由我们的 CA (memberca) 生成。

目的是:

  1. 客户端使用 SSL 连接 API
  2. 持有我们 memberca 的有效 X509 证书的人可以访问它
  3. 我们使用 CRL 检查证书是否被吊销。

我想,我也许可以直接在 Nginx 配置中进行管理。我该怎么做?

我可以用 Django 做吗?那我该怎么办呢?我可以使用任一解决方案将证书发送给用户吗?

例如,Nginx 可以使用 WSGI 标头映射一些证书数据,以便我可以匹配我的用户吗?

4

2 回答 2

10

我已经配置了类似的设置。

首先,我使用 Apache2 对用户进行身份验证。

您需要启用mod_ssl,并且必须(全局)定义:

  • SSLCertificateFile:指向您的 PEM 编码服务器证书;
  • SSLCertificateKeyFile:指向您的 PEM 编码服务器密钥;
  • SSLCertificateChainFile:指向您的 PEM CA 证书列表;
  • SSLCACertificatePath:指向包含所有 PEM CA 证书的文件夹;
  • SSLCACertificateFile :指向您的 CA 证书(应与 SSLCertificateChainFile 具有相同的值);
  • SSLCARevocationPath :指向包含所有 CRL 的文件夹;
  • SSLCARevocationFile :指向已撤销证书的列表(您的 ca-bundle.crl)
  • SSLCARevocationCheck 链。

现在您的服务器已准备好验证客户端 X.509 证书。

如果您不想将 apache2 用作前端 Web 服务器,则可以通过启用mod_proxy将其配置为反向代理。

您只需要像这样定义一个虚拟主机:

<VirtualHost *:443>
    ServerName test.example.com:443
    ServerAdmin webmaster@example.com

    RequestHeader set Front-End-Https "On"

    # Here I define two headers, Auth-User and Remote-User
    # They will contain the key SSL_CLIENT_S_DN_CN which is the name of the
    # client certificate's owner.
    <If "-n %{SSL_CLIENT_S_DN_CN}">
        # If the key doesn't exist, it means that the certificate wasn't sent or
        # it was revoked.

        RequestHeader set Auth-User "%{SSL_CLIENT_S_DN_CN}s"
        RequestHeader set Remote-User "%{SSL_CLIENT_S_DN_CN}s"
    </If>

    # Now enable SSL, and SSL via the proxy
    SSLEngine on
    SSLProxyEngine on

    ## Require a client certificate
    # SSLVerifyClient require
    ## NB: I prefer set it to optional, in order to allow the user
    ##     to connect to my application with a degraded mode (login+password)
    ##     It's easy to detect if the user was authenticated by apache by looking
    ##     at HTTP_AUTH_USER or HTTP_REMOTE_USER

    SSLVerifyClient optional

    # Maximum depth of CA Certificates in Client Certificate verification
    SSLVerifyDepth 4

    # Now, I pass all of this to my application, which is runned in nginx for example :
    <Location />
        ProxyPass http://<applciation host>
        ProxyPassReverse http://<applciation host>
        ProxyPreserveHost on
        # Send all informations about the client/server certificates to the application
        SSLOptions +StdEnvVars +ExportCertData
    </Location>
</VirtualHost>

现在,使用 django,您只需按照此处所述启用远程身份验证后端。

从客户端证书中提取的所有信息都将发送到应用程序,因此您可以使用请求对象(和/或中间件)来使用它们。

我希望它对你有所帮助。

于 2012-09-07T13:56:52.803 回答
2

我们通过让 mod_ssl 负责证书验证和吊销检查来使用 Apache 来做到这一点。如果证书有效且未被撤销,我们只需将证书的 CN 放入 HTTP 标头中,然后使用 Django 检索并匹配我们的用户数据库。

于 2012-09-07T13:31:00.597 回答