I have been forcing HTTPS upgrade through mod_rewrite for years on Ubuntu 18.04 LTS servers. I recently upgraded a few of these servers to Ubuntu 22.04.1 LTS to ensure the latest security and Apache versions could be used.
Everything seemed fine until I discovered that every one of the different Apache configurations that ensures http://
is always upgraded to https://
no longer works.
Here are my current configuration files. Certbot is even setting it up correctly but it doesn't work on the :80 configuration. All of the required modules are enabled.
I know mod_rewrite works because Laravel still functions. I'm completely baffled! I've tried RedirectMatch
, Redirect
, RewriteRule
etc. Every result on Google says to do all these same things. Certbot even sets it up "correctly".
<VirtualHost *:80>
ServerName mydomain.com.au
ServerAdmin [email protected]
DocumentRoot "/var/www/mydomain.com.au/public"
ErrorLog "/var/log/apache2/mydomain.com.au-error.log"
CustomLog "/var/log/apache2/mydomain.com.au-access.log" common
# Not exactly needed...
<Directory "/var/www/mydomain.com.au/public">
DirectoryIndex index.php
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
RewriteEngine on
RewriteCond %{SERVER_NAME} =mydomain.com.au
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
# This actually works in browsers at least
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
</VirtualHost>
<VirtualHost *:443>
ServerName mydomain.com.au
ServerAdmin [email protected]
DocumentRoot "/var/www/mydomain.com.au/public"
Header unset Upgrade
Protocols http/1.1 # AWS ELB runs HTTP/2
ErrorLog "/var/log/apache2/mydomain.com.au-error.log"
CustomLog "/var/log/apache2/mydomain.com.au-access.log" common
<Directory "/var/www/mydomain.com.au/public">
DirectoryIndex index.php
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch "\.(php)$">
SSLOptions +StdEnvVars
</FilesMatch>
SSLEngine on
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/mydomain.com.au/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.com.au/privkey.pem
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
</VirtualHost>
Update
I've since forced HTTPS in the Laravel project and required cookies to be only sent over secure connections which prevents any sessions from logging in. Browsers prevent forms from being sent insecurely these days too.
I'm just surprised at why the Apache HTTPS upgrade just does not work in the slightest now.