web-dev-qa-db-ja.com

Apacheがクライアントssl証明書(存在する場合)を受け入れるように、またはLDAP(証明書がない場合)を使用して認証するように構成するにはどうすればよいですか?

Mercurialリポジトリを提供するApacheサーバーがあり、現在LDAP資格情報を使用して認証を行っています。

(最初に)1人のユーザーがSSLクライアント証明書を使用できるようにしたいのですが、残りのすべてのユーザーは引き続きLDAP資格情報認証方式を使用できます。

Stack Overflowやその他の幅広い(google)検索を調べましたが、これを設定する方法に関する情報やガイダンスが見つかりません。

次のvhost構成では、クライアント証明書の通過のみが許可されます。 SSLクライアントに関連する3つのステートメントをコメントアウトします。ラップは動作します。

<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

どういうわけか、ディレクトリブロックのエイリアスを作成し、ロジックを適用してクライアント証明書の有無を確認する必要があるようです。私はそれを行う方法がわかりません。

これを達成する他の方法がある場合。私はそれについて聞いてみたいです。

6
jmwood051

私はこれを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の第一人者ではないので、私がやったことでひどく何かが間違っているかもしれませんが、それは国家の目的を達成しているようです。

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>

Apache 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>
1
Kyle

これは推測のようなものです(これを試す簡単な方法はありません)が、おそらくSSLOptions +FakeBasicAuthSatisfy Anyのいくつかの組み合わせが通じますか?

1
nickgrim

PHPまたはJavaまたはPerl)のいずれかで、バックエンドサーバーでそのタイプのロジックを実行する必要があります。次に、ヘッダーLocation:を設定してリダイレクトします。実際のソース管理に。

If/then/elseタイプのロジックが必要な場合は、プログラミング言語で実装する必要があります。

あなたの発言の意味がわかりません。この構成ではクライアント証明書の通過のみを許可し、LDAPが機能することも述べました。これで、すべてが正常に機能し、準備が整いました。

に変更します。ディレクトリは、ファイルシステムに固有のものですが、類似しています。

2つの異なるを使用して、ユーザーが試行する認証に基づいてURLを選択できるようにします。

SSLVerifyClient optionalは、必要に応じてクライアントが証明書を提示できるようにします。 requireに変更する必要がある場合があります。認証はApacheレベルで行われ、失敗するとサーバーエラーが発生します。

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

LDAPを別の場所に置くと、ユーザーは代わりにそこに移動できます。 ApacheのLDAP認証モジュールを使用していません。

エラーファイルを変更して、SSLリンクに失敗した場合にLDAPリンクへのリンクまたは自動リダイレクトを含めることができます。

0
Chloe