Назад | Перейти на главную страницу

Как настроить apache для принятия клиентского ssl-сертификата (если он есть) или аутентификации с помощью ldap (если сертификат отсутствует)?

У меня есть сервер Apache, который обслуживает ртутные репозитории и в настоящее время аутентифицируется с использованием учетных данных ldap.

Я хочу разрешить одному пользователю (для начала) использовать сертификат клиента SSL, а все остальные пользователи по-прежнему могут использовать метод аутентификации учетных данных ldap.

Я просмотрел Stack Overflow и другие более широкие (Google) поиски, но не могу найти информацию / руководство о том, как это настроить.

Следующая конфигурация vhost разрешает только клиентский сертификат. Закомментирую три заявления по SSL-клиенту; хлопец будет работать.

<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 webmaster@yourdomain.com
        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


Похоже, мне нужно как-то создать псевдоним для блока каталога, а затем применить логику для проверки наличия / отсутствия сертификата клиента. Я не знаю, как это сделать.

Если есть другие способы прижиться к этому. Я хотел бы услышать об этом.

Я придумал способ сделать это как для 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>

Это в некоторой степени предположение (у меня нет простого способа попробовать это), но, возможно, какая-то комбинация SSLOptions +FakeBasicAuth и Satisfy Any увидим вас до конца?

Вам придется выполнять такую ​​логику на внутреннем сервере, будь то 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 в другой, и вместо этого пользователь сможет перейти туда. Я не использовал модуль аутентификации LDAP от Apache.

Вы можете изменить файл ошибки, чтобы включить ссылку или автоматическое перенаправление на ссылку LDAP, если они не работают по ссылке SSL.