我有一个Apache服务器,提供mercurial存储库,它目前使用ldap凭据进行身份validation。
我想允许单个用户(首先)使用SSL客户端证书,其余所有用户仍然可以使用ldap凭证身份validation方法。
我已经通过堆栈溢出和其他更广泛的(谷歌)search,但无法find信息/指导如何设置。
<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
看来我需要以某种方式为目录块创build一个别名,然后应用逻辑来检查是否存在客户端证书。 我不知道如何去做。
如果还有其他的方法来解决这个问题。 我很乐意听到它。
这是一个猜测(我没有任何简单的方法来尝试这个),但也许SSLOptions +FakeBasicAuth和Satisfy Any一些组合将看到你通过?
我已经想出了一个Apache 2.2和2.4的方法,不pipe你需要什么,都需要进行一些最后的清理,但是这个棘手的问题应该完成(或者至less已经足够让其他人去弄清楚在哪里从这里出发)。
两种configuration都会产生相同的最终目标:客户端/用户可能会提供证书,如果没有提供证书,系统会提示您inputLDAP凭证。
你需要启用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>
您将不得不在后端服务器上执行这种types的逻辑,无论是PHP还是Java或Perl。 然后通过将标题Location:设置为实际的源代码控制进行redirect。
如果你想要一个if / then / elsetypes的逻辑,你必须用编程语言实现它。
我不确定你的陈述是什么意思。 你说这个configuration只允许通过客户端证书,你也说LDAP将工作。 这听起来就像你有一切工作,你都设置了!
我会改变。 目录通常用于特定于文件系统的东西,尽pipe它们是相似的。
尝试使用两种不同的方法,并允许用户根据他们想要尝试的身份validation来selectURL。
SSLVerifyClient optional将只允许客户提交一个证书,如果他们觉得喜欢它。 您可能必须更改为require 。 身份validation将在Apache级别发生,如果失败,则会发生服务器错误。
https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslverifyclient
把LDAP放到另一个,用户可以去那里。 我没有使用Apache的LDAPauthentication模块。
您可以修改错误文件,使其包含链接或自动redirect到LDAP链接(如果SSL链接失败)。