Bill Carney's picture

I’m having an issue I can’t solve.  I have a number of Wordpress sites running on a TKL LAMP instance.  If the root page is requested, or the link/manually typed URL includes https, they are being forwarded to the https version of the site properly.  However, if one simply types www.mysite.com/coolpage/  (without the https) the server responds to the http request and then forwards to the https version, but it strips out any slashes in the URL – so you wind up going to https://www.mysite.comcoolpage which obviously doesn’t work.  

Any idea on what I’ve done wrong?  

Here is my .htaccess

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

## Wordfence WAF
<IfModule mod_php5.c>
    php_value auto_prepend_file '/var/www/Mysite.com/htdocs/wordfence-waf.php'
</IfModule>
<IfModule mod_php7.c>
    php_value auto_prepend_file '/var/www/Mysite.com/htdocs/wordfence-waf.php'
</IfModule>
<IfModule mod_php.c>
    php_value auto_prepend_file '/var/www/Mysite.com/htdocs/wordfence-waf.php'
</IfModule>
<Files ".user.ini">
<IfModule mod_authz_core.c>
    Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
    Order deny,allow
    Deny from all
</IfModule>
</Files>

And here is my website’s config file (edited for privacy)

<VirtualHost *:80>
    ServerName Mysite.com
    ServerAlias www.Mysite.com
    Redirect / https://www.Mysite.com
</VirtualHost>

<VirtualHost *:443>
    ServerName www.Mysite.com
    ServerAlias Mysite.com
    ServerAdmin me@Mysite.com

    DocumentRoot /var/www/Mysite.com/htdocs

    SSLEngine on
    ServerAdmin me@mysite.com

    Alias /.well-known/acme-challenge /var/www/lets-encrypt
    <Directory /var/www/lets-encrypt>
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    SSLCertificateFile /var/lib/dehydrated/certs/mysite.com/fullchain.pem
    SSLCertificateKeyFile /var/lib/dehydrated/certs/mysite.com/privkey.pem

     <Directory />
        Options FollowSymLinks
        AllowOverride All
    </Directory>

    <Directory /var/www/>
        Options FollowSymLinks
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>

    CustomLog /var/log/apache2/Mysite.com-access.log combined
    ErrorLog /var/log/apache2/Mysite.com-error.log
    LogLevel warn

</VirtualHost>
 

 

Forum: 
Jeremy Davis's picture

My guess is that it's the "Redirect / https://www.Mysite.com" line (in the VirtualHost *:80 section) that is eating the rest of your URLs. Please note that this is all theoretical, I haven't tested any of it...

After having a quick look at the Apache docs on the subject I suggest trying RedirectMatch instead.

E.g. within the <VirtualHost *:80> section, replace:

    Redirect / https://www.Mysite.com

with:

    RedirectMatch ^(.*)$ https://www.Mysite.com$1

Don't forget to restart Apache (as I'm sure you're aware):

systemctl restart apache2

If that doesn't work, then perhaps try another approach. Again within the <VirtualHost *:80> section, replace the same line above with:

  <Location "/">
    Redirect https://www.Mysite.com%{REQUEST_URI}
  </Location>

If that still doesn't work (and you don't figure out something better yourself), then there's always the good old reliable Rewrite module. That has support for powerful regex. IIRC it is enabled by default, but if not (it will error), enable it like this:

a2enmod rewrite

Then once again, within the <VirtualHost *:80> section, try replacing the above line with:

    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^(.*) https://www.Mysite.com$1 [R,L]

Regardless of which path you go, once you've double checked that it works exactly as you want, you'll likely want to make it permanent. I suggest making it 308 (Permanent Redirect). (IIRC by default it's a 302 (Found)!?).

For Redirect & RedirectMatch you insert the numerical code inline. E.g.:

    RedirectMatch 308 ^(.*)$ https://www.Mysite.com$1

For Rewrite you change the last bit of the last line, like this:

    RewriteRule ^(.*) https://www.Mysite.com$1 [R=308,L]

Obviously you could change the redirect to something else if you prefer (301, 302, 307) but I think that 308 is the preference for a permanent redirect these days.

FWIW the difference between the old 301 (Moved Permanently) and 308 (Permanent Redirect) is that the latter does not allow changing the request method during the redirect. I.e. 301 (& 302) allow the requester to change the request from a POST to GET during the redirect; 308 (& 307) doesn't.

For full details, please see RFC7231 for most HTTP codes, and the RFC7538 for the addition of 308.

PS I'd love to hear how you go! If none of those work and the docs don't help, post back and I'll check it out myself whne I get a chance...

Bill Carney's picture

Excellent info, very informative and educational!

I wound up using

RedirectMatch 308 ^(.*)$ https://www.Mysite.com$1

as it worked right out of the box.

Appreciate the knowledge as usual, Jeremy!

 

Bill

Jeremy Davis's picture

Great news. I love it when things that should work in my mind actually work in the real world; so that's great! :)

Add new comment