• Skip to primary navigation
  • Skip to main content
  • Skip to footer
Onyx Research and Engineering, LLC

ONYX

Your Vision. Our solutions.

  • HOME
  • PAST WORK
  • CONTACT US
  • PRIVACY

https

WP and Permalinks

March 23, 2020 by Chris Lawcock

Once in a great while when upgrading a site or when an administrator gets overly ambitions one way or the other a site’s permalinks break if they are switched from default. Googling this issue will yield a wild array of “fixes”, I’m a big fan of actually understanding and not incantations. So, I thought I’d take a moment out of my day and go through this common and minor issue with Apache2 and WordPress.

WordPress does a marvelous job of managing its own .htaccess file. Using the default “Plain” permalinks selection from Settings > Permalinks will produce a blank .htaccess file in the root of your WordPress folder. Selecting “Post name” will generate an .htaccess file similar to the following:

# 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
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

So, the above file gives us quite a few hints on where we should start our journey.

  1. If our .htaccess file in the root of our WP site doesn’t contain this, then permissions or flags are probably borked on our server. You should check your permissions and user/group for your site and server. (Permissions)
  2. You have something like the above! Congrats! So now we are on to your Apache site config is improperly configured to utilize the .htaccess file (Check your config) or somehow Apache’s mod_rewrite module is not installed.

PERMISSIONS AND OWNERSHIP

Your permissions shouldn’t change much under various Linux distros. The following examples reference a Ubuntu server (16.04 – 18.04) LAMP installation.

OWNERSHIP

So let’s get ownership of our folder out of the way. Your WordPress folder should be owned by the server’s web server user. In Ubuntu land this is www-data is a user and group which is utilized by Apache and other web servers. So we will make sure our folder is “owned” by this user.

sudo chown -R www-data:root /var/www/[wordpress_site]

So, the above will set the owning user to www-data and leave the group owner to root. Performing a simple “ls -l /var/www/[wordpress_site]” should yield something similar to the following.

-rw-r-----  1 www-data root   420 Nov 30  2017 index.php
-rw-r-----  1 www-data root 19935 Jan  1  2019 license.txt
-rw-r-----  1 www-data root  7368 Sep  2  2019 readme.html
-rw-r-----  1 www-data root  6939 Sep  3  2019 wp-activate.php
drwxr-x---  9 www-data root  4096 Dec 18 22:16 wp-admin
-rw-r-----  1 www-data root   369 Nov 30  2017 wp-blog-header.php
-rw-r-----  1 www-data root  2283 Jan 21  2019 wp-comments-post.php
-rw-r-----  1 www-data root  3217 Mar 23 16:06 wp-config.php
drwxr-x---  7 www-data root  4096 Mar 23 15:18 wp-content
-rw-r-----  1 www-data root  3955 Oct 10 23:52 wp-cron.php
drwxr-x--- 20 www-data root 12288 Dec 18 22:16 wp-includes
-rw-r-----  1 www-data root  2504 Sep  3  2019 wp-links-opml.php
-rw-r-----  1 www-data root  3326 Sep  3  2019 wp-load.php
-rw-r-----  1 www-data root 47597 Dec  9 13:30 wp-login.php
-rw-r-----  1 www-data root  8483 Sep  3  2019 wp-mail.php
-rw-r-----  1 www-data root 19120 Oct 15 16:37 wp-settings.php
-rw-r-----  1 www-data root 31112 Sep  3  2019 wp-signup.php
-rw-r-----  1 www-data root  4764 Nov 30  2017 wp-trackback.php
-rw-r-----  1 www-data root  3150 Jul  1  2019 xmlrpc.php

If you are not running an Ubuntu server, you may need to determine what account your particular web server is running under. Give “lsof -i | grep :http” a try. This will list open files using with IP based connections and the grep will filter to only http/s ports. This will give you the user the file is opened under.

Chris

PERMISSIONS

Permission flags under Linux are always so concise and easy to understand (I’m looking at you Windows and Active Directory). In the case of a WordPress site, we want to lock down folders and files slightly differently.

FILES FIRST

sudo find /var/www/[wordpress_site] -type f -print0|xargs -0 chmod 640

DIRECTORIES NEXT

sudo find /var/www/wp.onyxrd.com -type d -print0|xargs -0 chmod 750

In case you were wondering what the above two snippets do exactly they leverage the find command to search for a file of a particular type. -type f (file) -type d (directory) -print0 changes the output to no formatting and then we pipe it to xargs which uses the output to call chmod with the appropriate access flags. So for files the user has read and write access and the group has read. Directories are set for user full control, while the group can only read and list the contents. Other permission is locked down.

READWRITEEXECUTEVALUEACCESS
X––4READ
–X–2WRITE
––X1EXECUTE
X–X5READ AND EXECUTE
XX–6READ AND WRITE
NO EXECUTE
XXX7DO EVERYTHING

SITE CONFIG

Oh boy, so our file permissions and ownership are just fine. Great! So now I guess we’ll check the site’s directory configuration. Joy. Ubuntu stores it’s Apache site configs in “/etc/apache2/sites-available/“. I’m going to make several assumptions here:

  1. Your site is WordPress site is operational, you just wanted to get fancy with your permalinks (and that breaks).
  2. You’re using Ubuntu server
  3. You’re using Apache2

If any of the above is not true, especially item one, then this post is probably not going to be helpful (Congrats though on reading all the way down to here!) Trudging on, find your particular conf file, I prefer sane naming conventions (i.e. yoursite.com.conf) here is an abbreviated sample conf.

#Basic HTTP Virtual Host
<VirtualHost *:80>
    ServerAdmin info@example.com
    DocumentRoot /var/www/example.com
    ServerName example.com
    ServerAlias *.example.com

    <Directory /var/www/example.com >
         AllowOverride All
    </Directory>
</VirtualHost>

So this is a simplified config for all IP virtual host of the server on port 80 (HTTP) [VirtualHost *:80]. The only important line for today’s struggle is the Directory declaration and the line that must exist:

AllowOverride All

If this line has been omitted then the .htaccess file will not be honored by the Apache server. Okay, so we’ve addressed the last known issue I’ve had with a WordPress setup and Permalinks. It’s time to throw a restart at your Apache and fingers crossed your new Permalink configuration just works.

sudo service apache2 restart

No one in this day and age should be hosting a site unsecured. If you are running an unprotected site then shame on you! Stop what you are doing and go hit up Let’s Encrypt and fix that shameful situation immediately.

Chris

Filed Under: Linux Software, Web, WordPress Tagged With: apache2, html, https, permalinks, web, wordpress, Wp

Footer

Recent Posts

  • ONYXCAM
  • TODAY’S SEO GAME
  • SIMPLE SITE GUIDANCE FOR A SMALL BUSINESS
  • PASSPORT DEV SETUP
  • BUILDROOT SMOKE TEST
  • Facebook
  • LinkedIn
  • Twitter
  • YouTube
  • PROJECTS
  • POSTS
  • LOGIN

Copyright © 2025 ยท Onyx Research and Engineering, LLC

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPT
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT