我在 AWS 上使用 Docker 运行 Apache。Apache 监听端口 80 并提供 HTTP 服务。
Apache 位于 AWS ELB 负载均衡器后面,该均衡器仅监听提供 HTTPS 服务的端口 443。
当我请求https://example.com/foo/(带有尾部斜杠)它运行良好,我的内容已提供。
当我请求https://example.com/foo(没有尾部斜杠)它会重定向到http://example.com/foo/- 也就是说,它添加了尾随斜杠(正确),但从 HTTPS 重定向到 HTTP(不正确)。
我能做什么呢?
我的 Dockerfile 是
FROM httpd:2.4
COPY . /usr/local/apache2/htdocs/
当我通过 curl 发出请求时:
$ curl -v https://example.com/foo
* Trying 1.2.3.4...
* TCP_NODELAY set
* Connected to example.com (1.2.3.4) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: example.com
* Server certificate: Amazon
* Server certificate: Amazon Root CA 1
* Server certificate: Starfield Services Root Certificate Authority - G2
> GET /foo HTTP/1.1
> Host: example.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Tue, 28 Nov 2017 09:17:26 GMT
< Content-Type: text/html; charset=iso-8859-1
< Content-Length: 247
< Connection: keep-alive
< Server: Apache/2.4.29 (Unix)
< Location: http://example.com/foo/
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://example.com/foo/">here</a>.</p>
</body></html>
* Connection #0 to host example.com left intact
提前致谢。
答案1
< Server: Apache/2.4.29 (Unix)
< Location: http://example.com/foo/
这是您的后端 Apache 在说话。它无法理解您的客户端正在使用 HTTPS,因此像独立工作一样进行重定向。如果不提供任何配置,很难判断重定向是如何完成的,但您必须对其进行修改以重定向到https://
。
这(不是这但A) 解决方案可能会指导您向前迈出一步。虽然原始问题有点不同,但提供的解决方案可能也适用于这种情况。
如何将服务器上的 HTTP 流量重定向到负载均衡器上的 HTTPS?
解决
使用
X-Forwarded-Proto
HTTP 请求的标头,将 Web 服务器的重写规则更改为仅在客户端协议为 HTTP 时才应用。忽略客户端使用的所有其他协议的重写规则。这样,如果客户端使用 HTTP 访问您的网站,他们会被重定向到 HTTPS URL,如果客户端使用 HTTPS,他们会直接由 Web 服务器提供服务。
阿帕奇
<VirtualHost *:80> ... RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} =http RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent] ... </VirtualHost>
答案2
在 httpd.conf 中,将 ServerName 从 localhost 更改为
ServerName https://localhost
在此参数开头添加 https:// 解决了我完全相同的问题。
答案3
我有同样的问题。.htaccess
使用 (Apache 2.4.29) 将其放入文件中可以解决此问题:
# We noticed a issue where https://www.example.com/foo was being redirected to http://www.example.com/foo/ (notice not using SSL)
# Q: Why does a redirect occur?
# A: In Apache, mod_dir provides "trailing slash" redirects and defaults to "DirectorySlash On".
# Q: Why does it redirect to http?
# A: The AWS ALB decrypts the request and Apache gets HTTP so it matches the protocol.
# How we fix it: We redirect to HTTPS before Apache mod_dir DirectorySlash redirects to HTTP, using "RewriteOptions AllowNoSlash".
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /foo/
RewriteOptions AllowNoSlash
RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/foo/ [R=301,L,QSA]
</IfModule>
我更喜欢使用:
RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L,QSA]
但在我的测试中它不起作用,不知道为什么。我很想找到更好的解决方案。
答案4
我建议你查看一下你 .conf 文件中针对该域的配置规则。/etc/httpd/conf/httpd.conf
除非你配置了 apache 来处理子域,否则应该在 中,在这种情况下它可能位于名为 的文件夹中sites-enabled
。
在我看来,这很可能是一条重写规则,因此请查找它。如果您需要更多帮助或详细信息,请在此处发布您的 .conf 文件,以便我们对其进行检查(如果您不确定的话)。