5

I am using Apache using Docker on AWS. The Apache listens on port 80 and serves HTTP.

The Apache is behind an AWS ELB load balancer, which listens only on port 443 serving HTTPS.

When I request https://example.com/foo/ (with trailing slash) it works fine, my content is served.

When I request https://example.com/foo (without trailing slash) it redirects to http://example.com/foo/ - that is to say it adds the trailing slash (correctly) but redirects from HTTPS to HTTP (incorrect).

What can I do about that?

My Dockerfile is

FROM httpd:2.4
COPY . /usr/local/apache2/htdocs/

When I do the request via 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

Thanks in advance.

4 Answers 4

3
< Server: Apache/2.4.29 (Unix)
< Location: http://example.com/foo/

This is your back-end Apache speaking. It doesn't understand your client is using HTTPS and does the redirection as it was working standalone. Without providing any of your configuration it's hard to tell how the redirection is done, but you have to modify it to redirect to the https://, instead.

This (not the but a) solution from AWS knowledge center may guide you a step forward. While the original issue is a bit different, the provided resolution probably applies to this case, too.

How do I redirect HTTP traffic on my server to HTTPS on my load balancer?

Resolution

Using the X-Forwarded-Proto header of the HTTP request, change your web server’s rewrite rule to apply only if the client protocol is HTTP. Ignore the rewrite rule for all other protocols used by the client.

This way, if clients use HTTP to access your website, they are redirected to an HTTPS URL, and if clients use HTTPS, they are served directly by the web server.

Apache

<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
...
</VirtualHost>
6

In httpd.conf, change ServerName from localhost to

ServerName https://localhost

Adding https:// at beginning of this parameter solved me the exact same problem.

2
  • This is the only thing that actually worked, thanks Jul 10, 2020 at 20:37
  • 1
    @nullability you're welcome my friend :)
    – Roey
    Jul 12, 2020 at 16:04
1

I have the same problem. Putting this in a .htaccess file solves the issue for me using (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>

I would prefer using:

RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L,QSA]

but it didn't work in my tests, not sure why. I would love to find a better solution.

1
  • According to the Apache documentation for RewriteOptions, AllowNoSlash only works if DirectorySlash for mod_dir is off. Additionally, you should use RewriteCond to ensure that %{REQUEST_FILENAME} is not a file, and IS a directory. Dec 16, 2020 at 18:20
0

I'd suggest looking over your config rules in your .conf file(s) for that domain. Should be in /etc/httpd/conf/httpd.conf unless you configured apache to deal with subdomains, in which case it might be in a folder called sites-enabled.

It seems to me to be a rewrite rule most likely, so look for that. If you need more help or details, post your .conf files here so we can go over them to check, if you're unsure.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .