More WordPress permalink tomfoolery - this time on a https install:(

March 8, 2017 1k views
Apache WordPress Ubuntu 16.04

Hi,

I have a Wordpress site running on Ubuntu 16.04 installed using Digital Oceans wonderful 1-click install - I even have multiple domains redirecting to one primary parent domain! Not bad for a rookie! I then got some confidence and upgraded my site to https using LetsEncrypt also thanks to the useful guides available from DO. Rookie confidence increasing!

Yesterday I purchased a premium theme, installed it and moved the permalink structure to 'post name' and all hell broke lose as any permalinks on the homepage to my site no longer work (they now get a The requested URL <subURL> was not found on this server.).

I recognize this is something this is something that catches out a number of people so have tried various DO articles on the matter to no avail. Fixes attempted include:

  • updating permissions of the main .htaccess from 664 to 666 using chmod.
  • making sure is a2enmod is running using: a2enmod rewrite - it is.
  • Updating /etc/apache2/sites-enabled/000-default.conf to AllowOverride (it now has the following in it:
    <Directory /var/www/html/> Options FollowSymLinks AllowOverride All Order allow,deny allow from all Require all granted </Directory>
  • Updating /etc/apache2/sites-enabled/default-ssl.conf to AllowOverride - if I try and put the same text as added in 000-default.conf the site failts to load and delivers an 'ERR TOO MANY REDIRECTS' message.
  • Updating /etc/apache2/sites-enabled/apache2.conf to AllowOverride - as soon as I restart Apache2, the site fails to load and delivers an 'ERR TOO MANY REDIRECTS' message.

Rookie confidence draining, any expertise thrown my way would be much-appreciated Team DO:) The most re-booted site in the world today is available at www.wealth-hack.com......

4 comments
  • You've come a very long way for a rookie, so don't get discouraged by a small hickup.

    Can you post the contents of .htaccess ?

    And how many .conf files do you have in the sites-enabled folder? Only two files has anything to do with wealth-hack.com right?

    Dang it, @jtittle was faster than me again :-)

  • Wow, 2 people to learn from, many thanks for the quick response guys.

    Firstly, to @jtittle, great call. Backup my existing .htaccess file (which had been updated in the struggle to get up to full https) and then used your advice to create a new one. Unfortunately, the same outcome as the pesky 'not found' message on all permalink settings except for 'plain'. In terms of sharing config, do you mean the '.htaccess file itself? If so, this is it in all its glory (although I suspect you've already taken the need to re-use my old one out of the equation):

    #BEGIN Wordpress
    # Allow font assets to be used across domains and subdomains
    <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
      <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "*"
      </IfModule>
    </FilesMatch>
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{HTTP:X-Forwarded-Proto} !=https
    RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
    </IfModule>
    
    # BEGIN rlrssslReallySimpleSSL rsssl_version[2.5.7]
    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTPS} !=on [NC]
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    </IfModule>
    # END rlrssslReallySimpleSSL
    # BEGIN WordPress
    
    # END WordPress
    

    Thanks also to @hansen for the advice (and for the positive support). I've posted the .htaccess above but think I slightly failed to be precise in my documentation at the start of this thread. I think there are 3 .conf files in the running as the culprit! The three as follows (together with my understanding on how they might be implicated:

    /etc/apache2/sites-enabled/000-default-ssl.conf - standard conf file I got the site up and running on.
    /etc/apache2/sites-enabled/default-ssl.conf - the file that either compliments it or replaced it when i went to https
    /etc/apache2/apache2.conf

    Is it worth posting config fragments from any of these? 000 I think looks good, its when I try and change default-ssl to add in the code below it doesn't like it (or add Override to apache2.conf).

    <Directory /var/www/html/>
    Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    allow from all
    Require all granted
    </Directory>
    
  • @hansen - I can't tell as of late, we both seem to be on the ball :-). That and there seems to be an issue with notifications / replies showing up. I shot an e-mail over to DO support about it. I even received a notification on-site that @jamesburns77 mentioned me in a response but it's not showing up for me.

  • Sorry about the slow response guys, I typed in the above response twice last night, only to see them deleted due to DO's spam filter. Ryan@digitalocean helped me get back in the game:)

    I think that's why you received the notification @jtittle, security is a wonderful thing;)

    Now, onto the new comments as my education continues....

10 Answers

@jamesburns77

One of the most common issues when it comes to Apache + .htaccess files is an extra space, line or a simple misconfiguration. This can sometimes happen even when you don't touch the file.

My first recommendation would be to simply delete your .htaccess file, login to ./wp-admin, browse over to the Permalinks section and simply click "Save." This should generate a new file for you which should be valid. Sometimes that's all it takes.

If that doesn't work, then the best course of action would be to post your configuration so we can look at it in detail. You can enclose it in a code block by using three backticks, hitting enter, pasting in your configuration, then closing the code block with three more backticks.

@jamesburns77

Unless you've modified apache2.conf, then we shouldn't need to venture there, however, posting the contents of both 000-default-ssl.conf and default-ssl.conf would be helpful so we can take a closer look at the full configuration.

As for your .htaccess file, I would keep it as basic as possible and stick to the plain-jane default that WordPress uses until we figure out what's going on.

The most basic/default would be something such as:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

By default, if you set the WordPress URL's to use https:// then you shouldn't need to rewrite them, which is why I recommend using the stock .htaccess over anything else right now.

@jamesburns77

To help expedite this so we can get this resolved for you, I just deployed a one-click image for WP to pull the configuration directly.

So let's get started :-).

I'm going to run through the steps again in this reply so we can better troubleshoot the issue as we go along. This allows provides a reference point for you to use in the future, should you need to.

...

To start, I've ran:

sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y install python-letsencrypt-apache

Ubuntu is now updated, all packages that need to be are upgraded, and LetsEncrypt is installed. Now before I run LetsEcrypt, let's take a look at my domain's configuration file.

I've added ServerName and ServerAlias to match both versions of my domain. Those are the only changes I've made and they exist on the 4th and 5th lines of the following VirtualHost block.

The contents of 000-default.conf are:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ServerName mydomain.com
        ServerAlias www.mydomain.com

        <Directory /var/www/html/>
            Options FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

The reason I did this is because LetsEncrypt tries to search for the domain you're trying to secure, so this makes it a little easier as it will automatically find that this configuration file is associated with my domain, so it's the right one to use.

Now we'll run LetsEncrypt to generate an SSL Certificate for my domain.

sudo letsencrypt --apache -d mydomain.com -d www.mydomain.com

After entering my e-mail and accepting the terms of service, I'll be asked:

Please choose whether HTTPS access is required or optional

Since I want HTTPS to be global, I'll choose:

Secure Make all requests redirect to secure HTTPS access

Once the above option is chosen, LetsEncrypt reports success, apache2 is automatically restarted and SSL now works without having to do anything further.

...

Now, here's the contents of my configuration files for reference.

/etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ServerName mydomain.com
        ServerAlias www.mydomain.com

        <Directory /var/www/html/>
            Options FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        RewriteEngine on
        RewriteCond %{SERVER_NAME} =mydomain.com [OR]
        RewriteCond %{SERVER_NAME} =www.mydomain.com
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</VirtualHost>

/var/www/html/.htaccess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

...

If you compare yours the the above, we should be able to figure out what's going on :-).

  • @jamesburns77
    As a side-note to jtittle's excellent answer, please remove the "helpful" plugin in WordPress called ReallySimpleSSL or similar, since it's doing double redirection, which might be one of the issues.

    @jtittle It's a nice ball to be at :)
    And by the way, pretty awesome that you just spun up a droplet to help answer this! Tip of hat.

    • @hansen @jamesburns77

      Agree 100% about the plugin if it's active, if it's not, delete it because you shouldn't need it.

      The rewrites in the 000-default.conf should be all that's required. Even modification to the .htaccess file should not be required to get SSL in working shape since LetsEncrypt adds it to the conf file directly.

      The .htaccess file I posted is the stock file that is created by the latest version of WP as of this post (4.7.3)

...just to mention this to exclude it from possible issues:

I see that the original poster tried chmod, but did not chown the .htacess. Sometimes a person will login as a user and create website files (like an .htaccess) and forget to change the owner (chown) back to www-data.

sudo chown -R www-data:www-data /var/www/html
sudo chmod 740 /var/www/html/.htaccess

probably not a good idea to make your .htaccess 666, since that is the mark of the devil

  • Also, once you have it all sorted, do me a favor and add these rules to the bottom of your .htaccess file:

    #prevents access to wp-config
        <Files wp-config.php>
        order allow,deny
        deny from all
        </Files>
    #prevents directory browsing
        Options All -Indexes
        <Files ~ "^.*\.([Hh][Tt][Aa])">
        order allow,deny
        deny from all
        satisfy all
        </Files>
    # STRONG HTACCESS PROTECTION
    <Files ~ "^.*\.([Hh][Tt][Aa])">
     order allow,deny
     deny from all
     satisfy all
    </Files>
    # protect xmlrpc
    <Files xmlrpc.php>
        Order Deny,Allow
        Deny from all
        ##if you need to allow someone access for pingbacks
        ##Allow from 123.456.789.11 ##yourserver
        ##Allow from 123.456.789.12 ##yourotherserver
    </Files>
    
  • @jamesburns77

    I'm not sure if you're joking on the last line or not, though 666, in terms of configuration, has nothing to do with religion :-). It's actually pretty common since it allows reading and writing by user, group, and public. I don't mean any offense, of course, just making a general note as it's often hard to discern based on text alone.

    In regards to chown, WordPress is running as the user and group www-data (in the case of the one-click image being used), so when the .htaccess file is created by WordPress, it's automatically assigned the user and group www-data. If the file was being created from the CLI, then that definitely be needed to ensure the file has proper permissions.

Nice, an incrementally built walkthrough, I get to learn how this beast actually works and the rest of the community get a reference point going forward!!:)

Learning started already, with 'plain' permalinks, my /var/www/.htaccess is essentially blank with only a # BEGIN WordPress and # END WordPress whereas when I flick 'post name' on as my permalink structure, .htaccess is dynamically updated - cool!

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

So think we are good on .htaccess - a now much cleaner version than my original thankfully! Great to know most of that additional config is redundant - less is more!:)

Onto my /etc/apache2/sites-available/000-default.conf file. My full virtual host data looks pretty similar with the exception I extended the number of server aliases to deal with the additional domains I have re-directed to my primary domain. For context, my primary domain is wealth-hack.com but I have a series of secondary domains (wealth-hack.co, wealth-hacker.com etc) that re-direct to wealth-hack.com using cname aliases (configured within networking section of DigitalOceans domain config utility).

<VirtualHost *:80>
        ServerAdmin james@wealth-hack.com
        ServerName wealth-hack.com
        ServerAlias www.wealth-hack.com *. wealth-hack.co *.wealth-hack.us *.wealth-hacker.co *.wealth-hacker.com *.wealth-hacker.us
        DocumentRoot /var/www/html

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

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =wealth-hack.com [OR]
RewriteCond %{SERVER_NAME} =www.wealth-hack.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</VirtualHost>

The aliases are the only thing that looks different. In the spirit of education, I took a backup of 000-default.conf then edited the live version to remove all the additional aliases except for the standard www.wealth-hack.com to align the files. No change to the issue but as expected, if I type www.wealth-hacker.com it no longer gracefully changes the URL to https://wealth-hack.com.

Could it be my default-ssl.conf that is creating the issue??

@hansen @jtittle - 'Really Simple SSL' de-activated and nothing broke (another thing I didn't need)!:) However, didn't remove the issue.

For full disclosure, I also have SSL Insecure Content Fixer running at 'capture' level as this was required to allow my site to consistently display 'secure' green ticks etc when moving to https. Again, to learn if this impacts anything, I deactivated it (knowing this would cause the site to move to 'unsecure') to see if the root cause disappeared, no joy. Subsequently, reactivated, I like my reassuring green tick.

Hi @sierracircle, thanks for the extra advice, I've followed your steps but same outcome.

Where next with our precision mallet all??;)

  • Can you deactivate "SSL Insecure Content Fixer" again, since this should be done by replacing http with https in the database. Not something that runs constantly - that's not good for performance.
    This can be done with https://wordpress.org/plugins/better-search-replace/

    EDIT: Can you activate permalinks again. Just trying to see something...

Can you change permalink structure to 'post name' and leave it on for a bit so we can see it behave?

Also, when in Settings>Permalink , after you make the changes, push the save button an extra time. (I think Wordpress fixed this, but there used to be an issue where you had to save twice to activate permalink changes)

@jamesburns77

A file called 000-default-le-ssl.conf should have been created when LE ran, which would physically be located in ./sites-available and symlinked to ./sites-enabled.

That file should look like:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ServerName domain.com
        ServerAlias www.domain.com

        <Directory /var/www/html/>
            Options FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

If you don't have that file, or are using another file, the configuration should look identical to the one I posted above. That's verbatim from my one-click.

Hi @hansen - consider it de-activated. The site will look a bit goofier now but good to keep this as simple as we can to get it working. For info, I did search and replace + better search and replace before turning to SSL Insecure Content Fixer, didn't seem to work for me then. I'll hold of re-running just now as the dry run indicates the premium theme I purchased and installed has 1000+ http:// to convert to https://, don't want to change too much at the same time (unless we think this is related).

@hansen + @sierracircle, also done, the site has no SSL type plugins running and is set to 'post name' (with a double save just incase)!:)

  • Okay:
    rewrite does not seem to be working

    you saved permalinks twice and have restarted apache after enabling rewrite
    your htaccess is readable by www-data and looks correct

    I guess lastly we are waiting to see what your site.conf file looks like for SSL

  • @jamesburns77
    Great - can see you got permalinks working! Not bad for a rookie :-)

    About the https not going green, if you click F12 in your browser - think it's the same for Firefox and Chrome - you'll get the Developer Tools. Click the Network-tab, then press SHIFT+R (or CTRL+SHIFT+R) to refresh the page without cache, and it'll show you every file loaded - and you can see which ones are not https (those need to be changed).
    Several places on your site, you're linking to this domain:

    http://boombox.px-lab.com
    

    Go and do a search replace the http://boombox.px-lab.com to https://boombox.px-lab.com - since that site actually supports https too.

    • Final final update, my droplet was backed up last night so felt confident enough to use search and replace this morning on the many many http://'s that had crept in. Unlike this time when I tried it on a 'coming soon' plugin, worked first time without the need to continuously run SSL Insecure Content Fixer. Thanks again guys:)

      • @jamesburns77 Awesome, way to go rookie! ;-)
        In the future, you can go and take a Snapshot of your server in the control panel of DigitalOcean and that will create a "backup" of that moment.
        Then you can do whatever you feel like on the server, if anything goes very wrong, you can just revert to that snapshot. It works just like backups.
        Just remember that snapshots cost money (very little), so you want to remove snapshots, when you don't need it any longer.

@jtittle the plot thickens, another conf file to consider!

Ok, in my/.sites-available dir, I have two ssl type files, default-ssl.conf(which I knew about and mentioned in the first post above) and default-ssl.conf.save which I haven't spotted before.

default-ssl.conf.save has very similar to what you stated above

<IfModule mod_ssl.c>
        <VirtualHost _default_:443>
                ServerAdmin james@wealth-hack.com
                ServerName wealth-hack.com
                ServerAlias www.wealth-hack.com
                DocumentRoot /var/www/html

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

                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined
                SSLCertificateFile      /etc/letsencrypt/live/wealth-hack.com/fullchain.pem
                SSLCertificateKeyFile /etc/letsencrypt/live/wealth-hack.com/privkey.pem

There is a lot more text but almost all of it is commented out. I don't have the Include /etc/letsencrypt/options-ssl-apache.conf within the file however.

default-ssl.conf is the same (no Include /etc/letsencrypt/options-ssl-apache.conf) but it also doesn't have the following:

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

Breaking news, I think that was it! I added the config just referred to into default-ssl.conf and the post name permalinked URL's are now functioning!!:) I'll get back onto my find and replace to get secure back and I'll be fully working once again:):):)

So many thanks to @jtittle @hansen and @sierracircle for guiding me through this. Hopefully, the documentation chain above was good enough for other newbies like me to help them in the future. Loving being part of the DO community, will keep working hard and one day, I might be able to help others:)

  • Good work! you stuck with it until you found the answer. That is what it takes to run this sort of operation.

Have another answer? Share your knowledge.