7

似乎是 apache 的地方,所以这里是 :)

古老的问题:我如何重定向 HTTP-> HTTPS,然后且仅当 HTTPS 时才进行身份验证?

哦 - 我希望它的大部分都在一个片段中,可以包含在多个 <directory> 或 <location> 块中,所以没有虚拟主机级别的基于随机路径的重写......

好吧,这就是我所拥有的似乎确实有效的东西:

在 VirtualHost 块的顶部

# Set ssl_off environment variable 
RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=ssl]

在位置或目录块中

RewriteEngine on
# Case 1 redirect port 80 SSL
RewriteCond %{HTTPS} !=on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301]

AuthType Basic
AuthBasicProvider external
AuthExternal auth_pam
AuthName "My Underpants"
AuthzUnixgroup on
Order Deny,Allow
Deny from all
Allow from env=!ssl
Satisfy any
Require group nice-users

优点

Require 的所有条都可以抽象为一个片段文件,以包含在每个位置的一行中

它修复了对每个位置强制 SSL 和身份验证,因此出错的机会更少

缺点

该死的地狱,这几乎不直观!据我所知,可能很脆弱...

有没有更好的方法(不是我发现的......)?

非常欢迎评论这是否有任何严重的缺陷:)

如果 Apache 有一个合理的配置语法和泛型 ,那么生活会容易得多

<If 表达式> </If>

可以在任何地方使用的块。它具有某些特殊情况块,例如 IfModule,然后您有特殊情况条件,例如 RewriteCond(如果您不习惯它,很难理解)。

干杯,

蒂姆

4

3 回答 3

3

如果你想强制整个站点使用 https,你可以使用VirtualHost指令,然后就很简单了:

<VirtualHost *:80>
    ServerName example.com

    RedirectMatch (.*) https://example.com$1

</VirtualHost>

<VirtualHost *:443>
    ServerName example.com

    ...
    ...
    ...
</VirtualHost>
于 2011-06-25T20:49:59.400 回答
2

Tim Watts 的解决方案似乎最适合我,但需要进行一些调整。此外,我的情况略有不同,因为我希望允许某些 IP 地址没有 HTTP 身份验证,但这只是增加了一行。

mod_rewrite 默认不会从 VirtualHost 继承配置。

请参阅:http ://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions

我打算使用“RewriteOptions inherit”,但似乎这在子规则之后应用了父规则。无论如何,我想到了一个不同的解决方案。

在我的 SSL <VirtualHost> 我有一行:

SetEnvIf Request_URI "/" using_ssl=yes

如果请求 URI 包含正斜杠(即一直),这将设置 using_ssl 环境变量。这有点 hack,因为我更喜欢使用无条件的 SetEnv 但显然:

该指令设置的内部环境变量是在大多数早期请求处理指令运行后设置的,例如访问控制和 URI 到文件名的映射。如果您设置的环境变量是作为早期处理阶段的输入(例如 RewriteRule 指令),则应改为使用 SetEnvIf 设置环境变量。

(来源:http ://httpd.apache.org/docs/2.2/mod/mod_env.html#setenv )

我的容器中的配置如下所示:

# Require a basic HTTP auth user
AuthName "realm-name-goes-here"
AuthType Basic
AuthUserFile /var/www/etc/htpasswd
Require valid-user

# OR allow from non-SSL (which will be redirected due to mod_rewrite below!)
Order Allow,Deny
Allow from env=!using_ssl

# OR allow from a trusted IP range
# NB: This allows certain IPs without a username & password
Allow from 192.168.0.0/16

Satisfy Any

# Force a redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]

出于测试目的,您可能只想先尝试使用“R”而不是“R=permanent”。

希望这对其他人有用:)

于 2013-12-15T14:36:55.983 回答
-1

我已经测试了你的解决方案,但它没有工作......

经过很长时间搜索解决方案,谷歌搜索太多并且总是发现相同的东西不起作用,我终于做到了:我使用SSLRequireSSLErrorDocument 403配置了一个包含 JavaScript 代码的静态页面(感谢这个博客页面)。

/etc/apache2/conf.d.opt/redirect_if_not_https.conf

SSLRequireSSL
ErrorDocument 403 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\
<html><head>\
<title>403 Forbidden</title>\
<script language=\"JavaScript\">\
window.location='https://'+window.location.hostname+window.location.pathname;\
</script>\
</head><body>\
<h1>Forbidden</h1>\
<p>You don't have permission to access that resource using simple HTTP. Please use HTTPS instead.</p>\
</body></html>"

(注意我创建的/etc/apache2/conf.d.opt/

在 app conf 中包含该文件(例如在 中/etc/apache2/conf.d/trac.conf):

<LocationMatch "/trac">
    # All the classical configurations here
    # ...

    Include conf.d.opt/redirect_if_not_https.conf
</LocationMatch>
于 2011-10-19T14:18:58.207 回答