We have a site I'll call example.com. Most of the time you see http://www.example.com and sometimes we redirect you to https://www.example.com.
We want to redirect anyone going to http://example.com or http://*.example.com to http://www.example.com, and the same for https. (It's mainly to avoid the alert you get if you go to https://example.com instead of https://www.example.com)
Our vhost file is at the end of the post. It works nicely except for one strange behavior:
- http://example.com -> successfully redirects to http://www.example.com
- http://www.example.com -> successfully does not redirect
- http://foo.example.com -> successfully redirects to http://www.example.com
- https://example.com -> successfully redirects to https://www.example.com
- https://www.example.com -> successfully does not direct
- https://foo.example.com -> ERROR - redirects to http://www.example.com
It's this last result I can't fathom. I've tried a lot of trial and error solutions from Google & Stack Overflow but nothing seems to change it. Even if we swap the order of the configurations (so that 443 is before 80) it still redirects https://foo.example.com to http://www.example.com
We are running Apache/2.2.12 on Ubuntu.
Here's the configuration file:
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com *.example.com
ServerSignature On
DocumentRoot /var/www/example.com/public
RailsEnv 'production'
PassengerHighPerformance on
<Directory /var/www/example.com/public>
AllowOverride all
Options -MultiViews
</Directory>
SSLEngine Off
CustomLog /var/log/apache2/example.log combined
ErrorLog /var/log/apache2/example-error.log
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^[^\./]+\.[^\./]+$
RewriteRule ^/(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
ServerAlias example.com *.acome.com
DocumentRoot /var/www/example.com/public
RailsEnv 'production'
PassengerHighPerformance on
<Directory /var/www/example.com/public>
AllowOverride all
Options -MultiViews
</Directory>
SSLCertificateFile /etc/ssl/certs/www.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.private.key
SSLCACertificateFile /etc/ssl/certs/EV_intermediate.crt
SSLEngine On
CustomLog /var/log/apache2/ssl-example.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
ErrorLog /var/log/apache2/ssl-example-error.lo开发者_高级运维g
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^[^\./]+\.[^\./]+$
RewriteRule ^/(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>
ServerAlias acme.com *.acome.com
Is that the problem right there? You have misspelled your domain name.
Thanks to everyone who took the time to read the question, or (even better) to try and help. It's what makes Stack Overflow such a useful resource.
We re-read TFM, learnt a bit more about Apache rewrite and here's the answer.
Problem #1: The rewrite rules (taken from Google) were designed to only redirect acme.com to www.acme.com, not any other sub-domain.
Problem #2: For some reason, Chrome was redirecting to http://www.acme.com by itself. When we removed the rewrite rules completely, the described behavior still happened.
Solution: Change the rewrite rules to actually catch any sub-domain other than www.
See below for a working solution.
There remains one issue. if you go to https://acme.com (or any sub-domain), some browsers will throw a warning saying the SSL certification does not match before redirecting you. The only way to fix this is to get a wildcard cert. As we're using an Extended Validation cert that was already very expensive we're just going to have to live with that warning for now. Would love to hear about any workarounds that would avoid showing an invalid cert warning before redirection.
<VirtualHost *:80>
ServerName www.acme.com
ServerAlias acme.com *.acme.com
ServerSignature On
DocumentRoot /var/www/acme.com/public
RailsEnv 'production'
PassengerHighPerformance on
<Directory /var/www/acme.com/public>
AllowOverride all
Options -MultiViews
</Directory>
SSLEngine Off
CustomLog /var/log/apache2/acme.log combined
ErrorLog /var/log/apache2/acme-error.log
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/(stats/|missing\.html|failed_auth\.html|error/).* [NC]
RewriteRule .* - [L]
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{HTTP_HOST} !^www\.[a-z-]+\.[a-z]{2,6} [NC]
RewriteCond %{HTTP_HOST} ([a-z-]+\.[a-z]{2,6})$ [NC]
RewriteRule ^/(.*)$ http://www.%1/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName www.acme.com
ServerAlias acme.com *.acme.com
DocumentRoot /var/www/acme.com/public
RailsEnv 'production'
PassengerHighPerformance on
<Directory /var/www/acme.com/public>
AllowOverride all
Options -MultiViews
</Directory>
SSLCertificateFile /etc/ssl/certs/www.acme.com.crt
SSLCertificateKeyFile /etc/ssl/private/acme.com.private.key
SSLCACertificateFile /etc/ssl/certs/EV_intermediate.crt
SSLEngine On
CustomLog /var/log/apache2/ssl-acme.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
ErrorLog /var/log/apache2/ssl-acme-error.log
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} ^/(stats/|missing\.html|failed_auth\.html|error/).* [NC]
RewriteRule .* - [L]
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{HTTP_HOST} !^www\.[a-z-]+\.[a-z]{2,6} [NC]
RewriteCond %{HTTP_HOST} ([a-z-]+\.[a-z]{2,6})$ [NC]
RewriteRule ^/(.*)$ https://www.%1/$1 [R=301,L]
</VirtualHost>
精彩评论