我需要允许办公室网络无需 SSL 证书而外部网络使用 SSL 证书访问我的网站。
这是我的配置:
<Directory /srv/www>
AllowOverride All
Order deny,allow
Deny from all
# office network static IP
Allow from xxx.xxx.xxx.xxx
SSLVerifyClient require
SSLOptions +FakeBasicAuth
AuthName "My secure area"
AuthType Basic
AuthUserFile /etc/httpd/ssl/index
Require valid-user
Satisfy Any
</Directory>
当我在网络内部并且拥有证书时,我可以访问。当我在网络内部并且没有证书时,我无法访问,它需要证书。
当我在网络外部并且有证书时 - 我无法访问,它会显示我基本的登录屏幕 当我在网络外部并且没有证书时 - 我无法访问,它会显示我基本的登录屏幕
并且以下配置完美运行
<Directory /srv/www>
AllowOverride All
Order deny,allow
Deny from all
Allow from xxx.xxx.xxx.xxx
AuthUserFile /srv/www/htpasswd
AuthName "Restricted Access"
AuthType Basic
Require valid-user
Satisfy Any
</Directory>
答案1
以下是我实现的方法(xxx.xxx.xxx.xxx - 允许无需证书访问此地址):
SSLVerifyClient optional
SSLOptions -FakeBasicAuth +StrictRequire -StdEnvVars -ExportCertData
SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
RewriteEngine on
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
RewriteCond %{REMOTE_ADDR} !^xxx.xxx.xxx.xxx$
RewriteRule ^ - [F]
请注意,SSLVerifyClient 不应处于目录上下文中:
在每个目录上下文中,它会在读取 HTTP 请求之后但在发送 HTTP 响应之前强制与重新配置的客户端验证级别进行 SSL 重新协商。
答案2
据推测,在您的网络内部,服务器具有与从外部访问时不同的(内部、私有)IP。
在这种情况下,最简单的方法是设置两个虚拟主机 - 一个在 in.ter.nal.ip:443 上,一个在 ex.ter.nal.ip:443 上。
仅在外部虚拟主机上需要客户端证书。
答案3
我很惊讶地发现这个功能在 Apache 2.4 中有效:
<LocationMatch "^/some/secure/place">
<If "! -R 'xxx.xxx.xxx.xxx/32'">
SSLRequireSSL
SSLVerifyClient require
...etc
</If>
</LocationMatch>