Redirect HTTP to HTTPS Using Apache mod_rewrite
If you want to force HTTPS on your site, add this to your .htaccess file:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The key parts:
RewriteCond %{HTTPS} off— matches only HTTP requests^(.*)$— matches any requesthttps://%{HTTP_HOST}%{REQUEST_URI}— rebuilds the URL with HTTPS[L,R=301]— uses a permanent redirect (301) and stops processing further rules
Redirect specific domains only
If you’re running multiple domains and only want HTTPS on some:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The [NC] flag makes the match case-insensitive.
Exclude specific paths
To allow HTTP on certain paths (useful for ACME challenges):
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
VirtualHost method (preferred for production)
For better performance and security, use VirtualHost configuration instead of .htaccess. Add this to your Apache config:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
# Your site content here
</VirtualHost>
VirtualHost redirects are faster because they don’t require .htaccess parsing on every request.
Using HSTS for extra security
After redirecting to HTTPS, add HTTP Strict-Transport-Security (HSTS) headers to prevent downgrade attacks:
<VirtualHost *:443>
ServerName example.com
SSLEngine on
# ... SSL config ...
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>
This tells browsers to always use HTTPS for your domain. Start with a short max-age for testing:
Header always set Strict-Transport-Security "max-age=300"
Enable mod_rewrite if needed
If rewrites aren’t working, verify mod_rewrite is enabled:
a2enmod rewrite
systemctl restart apache2
For .htaccess files to work, your VirtualHost must allow overrides:
<Directory /var/www/example.com>
AllowOverride All
</Directory>
Check your setup
Test the redirect:
curl -I http://example.com
You should see:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
Then verify HTTPS works:
curl -I https://example.com
Use the VirtualHost approach in production for better performance. Reserve .htaccess for shared hosting where you can’t edit the main config files.
