如何配置 apache 以接受客户端 ssl 证书(如果存在)或使用 ldap 进行身份验证(如果证书不存在)?

如何配置 apache 以接受客户端 ssl 证书(如果存在)或使用 ldap 进行身份验证(如果证书不存在)?

我有一个 Apache 服务器,它提供 mercurial 存储库,当前使用 ldap 凭据进行身份验证。

我想允许单个用户(首先)使用 SSL 客户端证书,而所有其余用户仍然能够使用 ldap 凭据身份验证方法。

我已经查看了 Stack Overflow 和其他更广泛的(谷歌)搜索,但找不到有关如何设置的信息/指导。

以下 vhost 配置仅允许客户端证书通过。我注释掉了与 SSL-client 相关的三个语句;ladp 可以正常工作。

<VirtualHost hg.mydomain.com:80>

    ServerName hg.mydomain.com:80
    RedirectMatch permanent ^(.*)$ https://hg.mydomain.com$1

</VirtualHost>

<VirtualHost hg.mydomain.com:443>

        ServerName hg.mydomain.com:443
        # ServerAdmin [email protected]
        DocumentRoot "/var/hg"
        CustomLog /var/log/httpd/hg-access.log combined
        ErrorLog /var/log/httpd/hg-error.log

        ScriptAliasMatch        ^/(.*)        /var/hg/hgweb.cgi$1
  # SSL Stuff...
        SSLEngine on
        SSLCipherSuite AES+HIGH:3DES+HIGH:RC4:!MD5:!EXPORT:!SSLv2:!aNULL:!eNULL:!KRB5

        # Server Certificate:
        SSLCertificateFile ssl/hg.mydomain.com.crt
        # Server Private Key:
        SSLCertificateKeyFile ssl/hg.mydomain.com.key
        # SSL Protocol Adjustments:
        BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

  <Directory /var/hg>
    Options ExecCGI FollowSymlinks
    AddHandler cgi-script .cgi

    AllowOverride AuthConfig
         Order deny,allow
        Allow from all

    #SSL-Client Statements
         SSLVerifyClient optional
         SSLVerifyDepth  1
         SSLRequire   %{SSL_CLIENT_S_DN_CN}  eq "robotuser"

     AuthName "Developers"
         AuthBasicProvider ldap
         # AuthLDAPEnabled On
         AuthLDAPUrl ldaps://ldap.applied.sec/dc=applied,dc=sec?uid
        AuthzLDAPAuthoritative On
        Require valid-user
  </Directory>

    # Taken from http://www.pmwiki.org/wiki/Cookbook/CleanUrls#samedir
    # Used at http://ggap.sf.net/hg/
    RewriteEngine On
    #write base depending on where the base url lives
    #RewriteBase /hg
    RewriteRule ^$ hgweb.cgi  [L]
    # Send requests for files that exist to those files.
    RewriteCond %{REQUEST_FILENAME} !-f
    # Send requests for directories that exist to those directories.
    RewriteCond %{REQUEST_FILENAME} !-d
    # Send requests to hgweb.cgi, appending the rest of url.
    RewriteRule (.*) /hgweb.cgi/$1  [QSA,L]

    Include repos.d/repos.*.conf


似乎我需要以某种方式为目录块创建一个别名,然后应用逻辑来检查客户端证书是否存在。我不知道该怎么做。

如果有其他方法可以实现这一点,我很乐意听听。

答案1

这有点像猜测(我没有任何简单的方法来尝试这一点)但也许某种组合SSLOptions +FakeBasicAuthSatisfy Any帮助你度过难关?

答案2

我已经找到了一种针对 Apache 2.2 和 2.4 执行此操作的方法,尽管需要根据您的需要进行一些最后的清理,但棘手的部分应该完成(或至少做得足够好,以便其他人可以弄清楚从这里去哪里)。

两种配置的最终目标相同:客户端/用户可以提供证书,如果没有提供,系统会提示他们输入 LDAP 凭据。

您需要启用 mod_ssl 和 mod_authnz_ldap。对于 Apache 2.2,您还需要启用 mod_rewrite 和 mod_alias。

Apache 2.4 引入了通用的 If/ElseIf/Else 指令,大大简化了此任务:http://httpd.apache.org/docs/current/mod/core.html#if

我不是 Apache 专家,所以我所做的事情可能存在严重错误,但它似乎确实实现了国家目的。

阿帕奇 2.2:

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
    ServerName Dummy-testing-kbd
    ServerAdmin webmaster@localhost

    # Normal HTTPS Server Certificate Config
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/server.crt
    SSLCertificateKeyFile /etc/apache2/ssl/server.key
    # End HTTPS Config

    DocumentRoot /var/www

    Alias /ldap /
    <Location /ldap/>
        # LDAP Authentication Config
        AuthType Basic
        AuthBasicProvider ldap
        AuthzLDAPAuthoritative on
        AuthName "Password Protected. Enter your AD Username and Password"
        AuthLDAPURL "ldaps://ldaps-auth.mydomain.com/OU=People,DC=mydomain"
        Require valid-user
        # End LDAP
    </Location>

    <Location />
        # Client Cert Config
        SSLRequireSSL
        SSLCACertificateFile /etc/ssl/ca/private/ca.crt
        SSLVerifyClient optional
        SSLVerifyDepth 2

        # Populate REMOTE_USER with the value from the client certificate
        SSLUserName SSL_CLIENT_S_DN_CN
        # End Client Cert Config

        # Hacky way to use an internal redirect to force LDAP authentication if the certificate didn't populate the REMOTE_USER variable
        RewriteEngine on
        RewriteCond %{REMOTE_USER} ^$
        RewriteRule (.*) /ldap/$1 [L]
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/cert_or_ldap_error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel debug

    CustomLog ${APACHE_LOG_DIR}/cert_or_ldap_access.log combined
</VirtualHost>
</IfModule>

阿帕奇 2.4:

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
    ServerName Dummy-testing-kbd2
    ServerAdmin webmaster@localhost

    # Normal HTTPS Server Certificate Config
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/server.crt
    SSLCertificateKeyFile /etc/apache2/ssl/server.key
    # End HTTPS Config

    # Client Cert Config - setup Certificate Authority
    SSLCACertificateFile /etc/ssl/ca/private/ca.crt
    # End Client Cert Config

    DocumentRoot /var/www
    <Location />
        # Client Cert Config
        SSLRequireSSL
        SSLVerifyClient optional
        SSLVerifyDepth 2

        # Populate REMOTE_USER with the value from the client certificate
        SSLUserName SSL_CLIENT_S_DN_CN
        # End Client Cert Config

        # Configuring LDAP:
        # If no REMOTE_USER is defined (by the certificate) then do LDAP authentication
        <If "-z %{REMOTE_USER}">
            AuthType Basic
            AuthBasicProvider ldap
            AuthName "Password Protected. Enter your AD Username and Password"
            AuthLDAPURL "ldaps://ldaps-auth.mydomain.com/OU=People,DC=mydomain"
            Require valid-user
        </If>
        # End LDAP
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/cert_or_ldap_error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel debug

    CustomLog ${APACHE_LOG_DIR}/cert_or_ldap_access.log combined
</VirtualHost>
</IfModule>

答案3

您必须在后端服务器上执行此类逻辑,无论是 PHP、Java 还是 Perl。然后通过将标头设置Location:为实际源代码控制来进行重定向。

如果您想要 if/then/else 类型的逻辑,您必须在编程语言中实现它。

我不确定你这句话的意思。你说这个配置只允许客户端证书通过,你还说 LDAP 可以工作。这听起来好像一切都正常,一切就绪了!

我会改为。目录通常用于文件系统特定的东西,尽管它们有点相似。

尝试使用两种不同的方式并允许用户根据他们想要尝试的身份验证来选择 URL。

SSLVerifyClient optional仅允许客户端提供证书(如果他们愿意的话)。您可能必须更改为require。身份验证将在 Apache 级别进行,如果失败,他们将收到服务器错误。

https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslverifyclient

将 LDAP 放入另一个,用户就可以转到那里。我没有使用过 Apache 的 LDAP 身份验证模块。

如果 SSL 链接失败,您可以修改错误文件以包含链接或自动重定向到 LDAP 链接。

相关内容