Message-ID: <6808331.501.1711718967313.JavaMail.serveradmin@t01app> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_500_3470742.1711718967309" ------=_Part_500_3470742.1711718967309 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html 6.x WordPress Simplified

6.x WordPress Simplified


=20 =20

Introduction

There is a better pattern using container technology to segregate accoun= ts by container and mount file systems between containers. I'll write this = up this approach if enough people want to use it.

As an application, WordPress is easy to use and feature rich. It has an = established community, and in my opinion, the best selection of themes= and the most usable blogging cms software package available. 

However, though the initial setup seems fast and easy, as an enterprise&= nbsp;administrator, it is very insecure. This article provides instructions= on setting up a secure WordPress that caters to multiple clients but with = one linux administrator called setupadmin.

This approach to setting up WordPress is,

  1. Segregates different clients from each other with multiple WordPre= ss instances.
  2. Minimize damage if WordPress itself is hacked.
  3. Is Easy to backup and recover.
  4. Will not be giving customers console access.

WordPress may use an array of technologies. The stack selected for the B= onsai Framework is,

Initially I tried to make this work with ACL permissions, but the technology do= es not work as you would expect and not workable.

Install Packages

Install the packages to run WordPress,

For Ubuntu 16 

=20
sudo ap=
t-get install php # Installs PHP
sudo apt-get install mysql-server # Installs MySQL
sudo apt-get install php-mysql # Libraries to connect PHP to MySQL
sudo apt-get install php-gd # Libraries to allow image editing through brow=
ser, "Edit Media"
sudo apt-get install libapache2-mod-php # As of Apache 2.4 php module is no=
 longer installed
sudo apt-get install php7.0-xml # Libraries to allow uploads
=20


For Ubuntu 12 and under run the commands listed below

=20
sudo ap=
t-get install php5 # Installs PHP
sudo apt-get install mysql-server # Installs MySQL
sudo apt-get install php5-mysql # Libraries to connect PHP to MySQL
sudo apt-get install php5-gd # Libraries to allow image editing through bro=
wser, "Edit Media"
=20

As of Ubuntu 12 (an maybe even earlier), the installer will automaticall= y restart Apache2 for you.

During the MySQL install, you will be prompted for the root=  administration database password. If following the Bonsai Fr= amework, use your standard password algorithm based on the server name.

Direct= ory and Permission Structure

This approach is more secure than most WordPress default setups. However= , it has some limitations around the security, namely administration of thi= s directory structure is restricted to serveradmin.

For the most part, if the WordPress user administer everything through t= he WordPress web interface this works perfectly well.

If you want to grant ssh access, then wait for my next article which wou= ld allow this, but would require an additional layer of security.

Permission= and Group Structure

We want website hosting for two different clients, The Daily Planet and = LexCorp. Employees from the respective companies will admin through their r= espective wordpress instances. Here is how the top level structure looks,

 Directories required for PHP,

PHP Directory Ownership Files and Directory Permissions Comment
/opt/web/ serveradmin:www-data serveradmin:www-data rwXr-X--- Main folder for all web related wo= rk.
/opt/web/php/ serveradmin:www-data serveradmin:www-data rwXr-X--- Top level folder for PHP.
/opt/web/php/tmp/ serveradmin:www-data serveradmin:www-data rwXrwX--- PHP requires write access to this = folder for temporary files.
/opt/web/php/logs/ serveradmin:www-data serveradmin:www-data rwXrwX--- PHP requires write access to this = folder for log files.

These directories are for WordPress,

WordPress Directory Files and Directory Permissions Comment
/opt/web/php/dailyplanet.com/ serveradmin:www-data rwXr-X--- Top level folder named by domain n= ame.
/opt/web/php/dailyplanet.com/blog/= serveradmin:www-data rwXr-X--- Location of WordPress instance for= the domain name. We are using this folder rather than just the domain name= to allow for more advanced configuration (such as separating the website w= ith static content).
/opt/web/php/dailyplanet.com/blog/= wp-admin/ www-data:serveradmin rwXr= wX---

Plugins and custom changes mana= ged through the WordPress interface and requires write access.

In add= ition, WordPress verifies the user it is running as (in this case www-data)= is the owner of this directory. So we must change the use= r for this directory.

There is a workaround if you prefer not to change the user = to www-data.

/opt/web/php/dailyplanet.com/blog/= wp-content/ www-data:serveradmin rwXr= wX---

Plugins and custom changes mana= ged through the WordPress interface and requires write access.

In add= ition, WordPress verifies the user it is running as (in this case www-data)= is the owner of this directory. So we must change the use= r for this directory.

There is a workaround if you prefer not to change the user = to www-data.

web Folder

This is where everything starts for web related work,

=20
cd /opt=
/
sudo mkdir ./web/

# Next set the permissions.
sudo chown -R serveradmin:www-data ./web/
sudo chmod -R u+rwX,g+r-w+X,o-rwX ./web/
=20

Setting permissions early on will not allow you access to do the rest of= the instructions unless you belong to the groups

If we wanted to grant basic ssh access to manage static content we could= separate out another directory using the Apache directory directive here. = That would also require loosening of the web folder to allow other.

php Folders

This is where all php code will execute. In php centric applications thi= s will also be considered the web root for static files too and reflected i= n the virtual host configuration,

=20
cd /opt=
/web/
sudo mkdir php
sudo chown -R serveradmin:staff ./php/
sudo chmod -R u+rwX,g+r-w+X,o-r-w+X ./php/
=20

Next we create the php support directories,

=20
cd /opt=
/web/php/
sudo mkdir ./tmp/ ./logs/
sudo chown -R serveradmin:www-data ./tmp/ ./logs/
sudo chmod -R u+rwX,g+rwX,o-rwx ./tmp/ ./logs/
=20

Note the PHP process runs under Apache as the www-data data which belong= s to the www-data group. Giving the www-data group write access effectively= grants the PHP process the required write access.

Keep in mind that you can not go into the /opt/web/php directory as a no= rmal staff user. At the same time, if you use serveradmin you do not have a= ccess sudo.

Make your staff user part of the serveradmin and www-data group,

=20
sudo us=
ermod -a -G serveradmin bhitch
sudo usermod -a -G www-data bhitch
exit # If you used your own staff account to modify your staff account, you=
 need to exit and log back in.
=20

Finally logoff and log back in with your staff account for the group cha= nges to take effect.

Conf= igure PHP to Use Specified Folders

Edit php.ini to make use of the folders.
Ubuntu 16 

=20
sudo vi=
 /etc/php/7.0/cli/php.ini
=20

Ubuntu 12

=20
sudo vi=
 /etc/php5/apache2/php.ini
=20

Set Running Direct= ory

Search for the open_basedir line and modify to include the directories s= etup for WordPress,

=20
; open_=
basedir, if set, limits all file operations to the defined directory
; and below.  This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
; http://php.net/open-basedir
open_basedir =3D /opt/web/php/
=20

This helps minimizes the amount of damage that can be done in the event = that the system is compromised to the specified directory.

Set Temp Directory

Because open_basedir has been set, WordPress no longer = has access to the general temporary folder it expects which is required for= certain operations (for example to upload plugins through the Adminis= trator web interface).

Modify php.ini further by modifying the upload_tmp_dir line,

=20
; Tempo=
rary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
upload_tmp_dir =3D /opt/web/php/tmp/
=20

Increasing Th= e Upload Limit

The default upload limit is 2mb, the limit must be increased for uploads= higher than 2mb or else they will fail when you try to upload.

=20
; Maxim=
um allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize =3D 2M 
=20

This function displays the max size allowed to upload.without editing th= is the changes will not take on increasing filesize.

=20
; Maxim=
um size of POST data that PHP will accept.
; http://php.net/post-max-size
post_max_size =3D 2M
=20

Make Changes Tak= e Effect

Restart Apache for the changes to take effect,

=20
sudo se=
rvice apache2 restart
=20

You will now find that php scripts will only run in the designated direc= tories specified in php.ini.

Setup Website Root

Each website will have it's own root folder under /opt/web/php/,

=20
sudo mk=
dir /opt/web/php/dailyplanet.com
sudo chown -R serveradmin:www-data /opt/web/php/dailyplanet.com/
sudo chmod -R u+rwX,g+r-w+X,o-rwX /opt/web/php/dailyplanet.com/
=20

Setup Apache Virt= ual Host

Setup your A= pache Virtual Hosts with the website root.

For Ubuntu 16 php 7 mod needs to be enabled so run command sudo a2enmod php= 7.0

Setup WordPress

Make sure you are logged in a sudo enabled user. Setup WordPress as foll= ows,

=20
sudo su=
 - serveradmin
cd ~
wget http://wordpress.org/latest.tar.gz
tar -xvpf latest.tar.gz
mv ./wordpress/ ./blog/ # Rename as we not need to make the technology obvi=
ous.
=20

Finally move WordPress to the proper directory,

=20
cd /opt=
/web/php/dailyplanet.com/
cp -R /home/serveradmin/blog/ ./
exit # To go back to your staff account.
sudo chown -R serveradmin:www-data /opt/web/php/dailyplanet.com/blog/
sudo chmod -R u+rwX,g+r-w+X,o-rwX /opt/web/php/dailyplanet.com/blog/
=20

This step is essential for WordPress to be able to install plugins throu= gh the web admin interface,

=20
sudo ch=
own -R www-data:serveradmin /opt/web/php/dailyplanet.com/blog/wp-admin/
sudo chown -R www-data:serveradmin /opt/web/php/dailyplanet.com/blog/wp-con=
tent/
sudo chmod -R g+w /opt/web/php/dailyplanet.com/blog/wp-admin/
sudo chmod -R g+w /opt/web/php/dailyplanet.com/blog/wp-content/
=20

Configure MySQL

Secure MySQL

As a staff user run the Secure Installation script included with MySQL,<= /p>

=20
sudo my=
sql_secure_installation
=20

The prompts are very straightforward. Except for "Change the Root p= assword?", answer yes to all prompts by hitting Enter,

=20
=20 =20  Expand source=20 =20
=20
=20
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQ=
L
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):=20
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.
You already have a root password set, so you can safely answer 'n'.
Change the root password? [Y/n] n
 ... skipping.
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]=20
 ... Success!
Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n]=20
 ... Success!
By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n]=20
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n]=20
 ... Success!
Cleaning up...
All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.
Thanks for using MySQL! 
=20
=20

For now that's it to securing MySQL.

Connect

Connect into MySQL,

=20
mysql -=
u root -p
=20

The password to use is the password set during the MySQL install. If eve= rything goes well you will be in the MySQL shell,

=20
Welcome=
 to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.24-0ubuntu0.12.04.1 (Ubuntu)
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved=
.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input stateme=
nt.
mysql>
=20

The remainder of this section happens inside of the mysql shell.

Create the WordPress Database and Accounts in MySQL

List the databases to makes sure what you want to create does not alread= y exists,

=20
SHOW DAT=
ABASES;
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.16 sec)
=20

In our case we should have nothing other than the three default database= s.

Enter the following MySQL commands,

=20
CREATE D=
ATABASE wpdailyplanetdb;
GRANT ALL PRIVILEGES ON wpdailyplanetdb.* TO 'wpdpdbuser'@'localhost' IDENT=
IFIED BY 'password';
FLUSH PRIVILEGES;
=20

Adjust the variables for your application.

wpdailyplanetdb - Name of the database for the Wor= dPress application instance. We use the domain name of the website.

wpdpdbuser - User account for accessing the databa= se cannot be longer than 16 characters

localhost - Address of the database server. In this exa= mple, the database is on the same server so use localhost.

password - Change to password using algorithm based on = name of the primary website domain, in this case dailyplanet.

Database Admins will not like granting all privileges. After the initial= setup is done we will restrict to more minimal privileges.

Exit MySQL Shell

Exit the MySQL shell,

=20
EXIT=20

Configure WordPress=

Crea= te Config File for Database Access

Launch a browser and hit the WordPress setup page for your machine at&nb= sp;http://dailyplanet.com/blog/wp-admin/install.php and you will be prompte= d to create a configuration file.

Click the button, "Create a Configuration File".

The next prompt reminds you of all the critical information you will nee= d.

Note, the message,

If for any reason this automatic file creation doesn=E2=80=99t work, don= =E2=80=99t worry. All this does is fill in the database information to a co= nfiguration file. You may also simply open wp-config-sample.php in a text e= ditor, fill in your information, and save it as wp-config.php.

The Bonsai Framework takes a high security posture, so the automatic fil= e creation should not work. Click the "Let's go!" button.

Enter the required information and click "Submit",

Field Value Comment
Database Name wpdailyplanetdb The Bonsai Framewok appraoch is to= base the user name on the site's primary domain name.
User Name wpdpdbuser 
Password
This is the application password s= et during the wpdailyplanetdb database creation step.
Database Host localhost Address of the database server. In= this example, the database is on the same server so use localhost is used.=
Table Prefix bf_ The Bonsai Framework approach gene= rally does not encourage changing an application's table prefix. However, g= iven the architecture of WordPress and popularity it is recommended to chan= ge the prefix to something other than wp_ to make the system less susceptib= le to attacks.

It is expected that you will receive a message that WordPress = can not write the wp-config file and the following prompt will appear on sc= reen,

=20

Sorry, but I can't write the wp-config.php file.

You can create the wp-config.php manually and paste the following text i= nto it.

=20

Copy the generated wp-config.php file.

Some shortcuts to ensure you get it all fast,

  1. Click inside of the text box
  2. Use the keyboard combo CTRL-A (to select all)
  3. CTRL-C (to copy) 

Go to your shell, load your favourite editor and paste the contents of t= he wp-config.php file,

=20
su - se=
rveradmin # If you are not already serveradmin
vi /opt/web/php/dailyplanet.com/blog/wp-config.php
=20

Once you have saved the file, go back to your browser and click "Run the= install".

Enter Site Information

Finally enter the site information,

Field Value Comment
Site Title dailyplanet We like to reference our domain name.
Username tempadmin

You probably do not want to use= the default admin for username. WordPress (as of Sep 2012) out of the box,= has no facilities to stop dictionary attacks against the administration sy= stem. Admin will be the first username guessed by automated attacks.

= Because the username put here will show up in the default site generated, t= his will be a temporary administrator account.

Password

As mentioned, WordPress has no = facilities to stop dictionary attacks. On top of that, the default setup ex= poses your administrator account name on the Internet.

Choose a very very long and complex password. (Anyone k= now of a good site that shows how quickly an entered password would be brok= en with a dictionary attack, put the link here)

Your E-mail
Whatever email is chosen here, it = will not be the final one used by the real administrator account. Keeping i= n mind that WordPress does not allow duplicate emails, in this example, the= administrator will use a personal email and then use a proper email accoun= t when the real administrator account is created.
Privacy
This depends on the purpose of you= r website. Unless this is a private site that should not show up on Google,= leave it checked.

Click, "Install WordPress" which should result in a success screen. At t= his point you are actually done the setup. Do not click "Log In".

If everything went well you will see a "Success!" message.

Customize WordPress=

At this point WordPress is already working. There are two urls to take n= ote of,

URL Area Purpose
http://www.dailyplanet.com/blog/ Public You can hit this url right now and see a default= working site. This url is where your users will enter.
http://www.dailypl= anet.com/blog/wp-admin/ Administration

This url results from clicking = the "Log In" button after the WordPress install is complete. It can also be= accessed through the Public homepage by click "Log In" located at the bott= om right under "META". The Administration area allows the customization and= configuration of WordPress.

Also, once logged into the administratio= n, if you browse to the public area, you will see additional buttons and op= tions to create posts and edit the website contents.

http://www.dailyplanet.com/ Public If WordPress is your main website = you should configure Apache to redirect to http://www.dailyplan= et.com/blog/.

If you have the Install WordPress Success Screen still up, click "Log In" will take you to the Word Press Administration url or us= e the url in the table above.

Mini= mal Security - Block Login Attacks

WordPress out of the box can be easily broken into with a brute force di= ctionary attack for the following combined reasons,

  1. The administrator account is available on the public portion of the blo= g as part of the default sample content.
  2. Nothing prevents the brute force attack from trying again and again on = the WordPress Administration login page.
  3. The Administration page well known.

For these reasons it is best to not make the website publicly available = until secured or at least, as mentioned choose a very complex password.

For a more secure setup, consider Installing one of these plugins,

Plugin Description Notes
Google Authenticator

The Google Authenticator plugin= for WordPress gives you two-factor authentication using the Google Authent= icator app for Android/iPhone/Blackberry.

The very first time your br= owser visits the website, it will require two-factor. Subsequent visits wit= h the browser will not.

The two-factor authentication requirement can= be enabled on a per-user basis. You could enable it for your administrator= account, but log in as usual with less privileged accounts.

Make sure time is synced with s= ame time servers across the phone and server. For example, my iphone was of= f by 2 minutes because it was set manually to Toronto.

Best thing to = do is turn on the 4 minute drift allowance.

When setting the password= make sure there are no spaces otherwise the barcode will not work.

BAW More Secure Login Grid Cards
Login Security Solution Adds some common defences against = brute force attacks. Most useful feature is that it blo= cks user for x number of minutes progressively as more attempts are tried. = Also blocks by cookie and ip address.
Anti-Spam Stops the spam comments that show = up on your blog promoting other websites while filtering out real comments<= /td> Have yet to see a comment from a s= pammer
bodi0`s Bots visits counter This logs the bots that visit your= site and gives the option to block/unblock by editing the .htaccess file Its an interesting tool to see wha= t bots visit your site
Limit Login Attempts This lets you limit login attempts= and logs the IP and username of those who get banned Think of fail2ban in wordpress its= a lot easier to edit too than the actual fail2ban plugin
P3 (Plugin Performance Profiler) This is a plugin that tests page p= erformance and records what plugin is taking the most time and it has 2 ver= sions of scanning automatic and manual. This is really useful if your blog= is taking an unusually long amount of time to load and you have no clue wh= y
WP-Mail-SMTP If you cannot get Mail() to work i= n php you can install this plugin to use SMTP instead.

To setup to use Google use:
= SMTP Host: smtp.gmail.com
SMTP Port: 465
Username: example@gmail.com<= br>Password: *** 

Should have link to how to ssh in to disable plugins if they misbehave.<= /p>

Set Up Users

The default user created is an administrator and has more privilege= s than necessary. The very first step is to create users with spe= cific roles provided by WordPress. The roles are outlined below in order of= most privileges to least.

Keep in mind that when creating accounts, Wordpress requires unique emai= l addresses.

Role Description Sample User Name
Administrator Administrators have access to all the admi= nistration features. setupadmin
Editor Editors can publish posts, manage posts as well = as manage other people=E2=80=99s posts, etc. perrywhite
Author Authors can publish and manage their own posts, = and are able to upload files. clarkkent, loislane
Contributor Contributors can write and manage their posts bu= t not publish posts or upload media files. jimmyolsen
Subscriber Subscribers can read comments/comm= ent/receive newsletters, etc. but cannot create regular site content. lexluthor

Create your first user,

Field Value Comment
Site Title dailyplanet We like to reference our domain name.
Username setupadmin

This will be the real administr= ation account.  

Password

As mentioned, WordPress has no = facilities to stop dictionary attacks. On top of that, the default setup ex= poses your administrator account name on the Internet.

Choose a very very long and complex password. (Anyone k= now of a good site that shows how quickly an entered password would be brok= en with a dictionary attack, put the link here).

Your E-mail admin@bonsaiframework.c= om If there is more than one administ= rator, you should have a general support email box that only administrators= have access to. This email address will be used for password recovery purp= oses.

FAQ

Why do some of the php5 installations say to use install libapac= he2-mod-php5?

The instructions may be old. At least with Ubuntu 12.04 there is no need= for this package because it is included with the php5 package.

What is the difference between the php5  and libapache2-mod= -php5 packages?

Nothing I can see. It just looks like php5 is an overarching package nam= e.

References

Setup

Ubuntu Server Documentation - https://help= .ubuntu.com/12.04/serverguide/php5.html

Security

Has some ok details around suPHP - https://help.ubuntu.com/community/ApacheMySQLPHP#Installi= ng_MYSQL_with_PHP_5

Some good notes on securing PHP from Symantec - http://www.symantec.com/connect/articles/securing-php-ste= p-step

Start some good security practices for WordPress - http://www.howtospoter.com/web-2= 0/wordpress/triple-p-of-total-wordpress-security

Wordpress discussion on permissions, based their recomendations for suPH= P the community does not really understand permissions - http://codex.wordpress.org/Changing_File_Permissions

This restricts the php process to specific directories - = http://help.godaddy.com/article/1616

At least by looks this looks like it may be a good guide to securing wor= dpress - http://wpsecure.net/basics/

Wordpress' official article to getting started after setup - http://codex.wordpress.org/First_Steps_With_WordP= ress

Article which resolved manual upload issue - http://www.charleshooper.net/blog/wordpr= ess-auto-upgrade-and-dumb-permissions/

=20

Determine if this actually increases security - http://www.suph= p.org/Home.html. suPHP and LiteSpeed make the most sense for shared hos= ting.

This article indicates that suphp is slow as it makes php run as a cgi. = Instead a poster recommended using what is available with mod_php - http://serverfa= ult.com/questions/279938/should-i-use-suphp-or-mod-php-for-shared-hosting. Along this thread another poster recommends, http://mpm-itk.sesse.n= et/ which allows vhosts to be run under different uid and gid.

A great discussion on using permissions, same conclusion I was coming to= using www-data group - http://unix.stackexchang= e.com/questions/30879/what-user-should-apache-and-php-be-running-as-what-pe= rmissions-should-var-www

Probably the most complete but also complex solutions is to use ACLs - <= a class=3D"external-link" href=3D"http://serverfault.com/questions/339948/u= ser-permissions-for-both-apache-and-local-user/357977" rel=3D"nofollow">htt= p://serverfault.com/questions/339948/user-permissions-for-both-apache-and-l= ocal-user/357977

=20
------=_Part_500_3470742.1711718967309--