开发者

Problem with redirecting *.example.com & example.com to www.example.com for HTTPS

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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜