ModSecurity – Adjustments for WordPress

How to secure an Ubuntu 12.04 LTS server – Part 1 The Basics is a great resource to secure a VPS.

Mod_Security is a web application firewall. I found a couple things to add to my servers.

The same site includes a very good guide to installing it (you also may well want to whitelist Googlebot, instructions in the link). However it blocked my access to one of my sites. You end up just getting the message:

“Forbidden

You don’t have permission to access / on this server.”

There are tips on some edits to include when using WordPress on an Apache server with modsecurity.

One simple action is to include

SecRule SERVER_NAME “[your-domain.com]” phase:1,nolog,allow,ctl:ruleEngine=off

[bash]SecRule SERVER_NAME "code.curiouscatnetwork.com" phase:1,nolog,allow,ctl:ruleEngine=off[/bash]

on the bottom of modsecurity.conf which is found /etc/modsecurity (for me, on Ubunutu 12.04). Then restart Apache

[bash]sudo service apache2 restart[/bash]

and see if the problem goes away. If it does then you have a very good indication modsecurity was blocking access and can continue to narrow the scope of the problem by adding the WordPress whitelist rules in the link above.

Another note, service apache2 start, failed in a non-obvious way to me anyway. For me if I use sudo it works fine. If I don’t it gives odd errors which lead me on a 10 minute wild goose chase before remembering to try sudo.

Related: Upgrading VPS Web Server from Ubuntu 10.04 to 12.04Keeping Your Hosted Ubuntu Web Server Software Up to DateLinux/Ubuntu File and Directory Permissions

Upgrading VPS Web Server from Ubuntu 10.04 to 12.04

I am not a “real” system administrator but I manager sever VPS servers for my own web sites. This is what I did to update from Ubunutu LTS 10.04 to Ubunutu VPS 12.04.

  1. I already have all the code and databases backed up, off the server, regularly. I backed up various things to another machine: sites-available files, cron directories, .bashrc, .profile, keys.
  2. I tried running the preferred upgrade command

    [bash]do-release-upgrade[/bash]

    But got the message

    -bash: do-release-upgrade: command not found

    Then I ran

    [bash]sudo apt-get install update-manager-core[/bash]

    Then I was able to run [bash]sudo do-release-upgrade[/bash]

  3. Which resulted in this somewhat scary message

    This session appears to be running under ssh. It is not recommended to perform a upgrade over ssh currently because in case of failure it is harder to recover.

    If you continue, an additional ssh daemon will be started at port ‘9004’.
    Do you want to continue?

    I look around on the web for advice. What’s the risk of upgrading over SSH? seems a good recap. I then continued. I then got this message

    To make recovery in case of failure easier, an additional sshd will be started on port ‘1022’. If anything goes wrong with the running ssh you can still connect to the additional one.
    If you run a firewall, you may need to temporarily open this port. As this is potentially dangerous it’s not done automatically. You can open the port with e.g.:
    ‘iptables -I INPUT -p tcp –dport 1022 -j ACCEPT’

  4. 12 minutes after the upgrade started, the download was complete and I got a message to decide if I wanted to manually approve every restart required or just automatically approve them all. I chose the option to have all restart automatically.
  5. Then lots of files were installed and I was asked about various files; where I (or some script) had changed (or deleted) the default file and now the upgrade wanted to replace the existing file. I had to guess what to do in those cases. They let you look at the diff between your existing file and the proposed overwrite. I think I would like it if they default behavior was to create a backup of the file in that same directory (you choosing whether to set your file or the updated file as active).

The entire process took exactly 30 minutes, with the system restarting in Ubuntu 12.04.

Thankfully the upgrade seems to have gone without causing any problems. This is normally the case. But, even with a very small likelihood of encountering issues it is worrisome as those issues might pose some serious problems. Especially for someone with very limited system administration ability.

I am extremely thankful for all the programmers that created the code to make this process so straightforward and reliable.

[bash]lsb_release -a[/bash]

lets you see the current Ubunutu version you are running.

When I updated a server that had Ruby on Rails applications everything almost worked fine. Passenger was unable to load the application talking about

libmysqlclient_r.so.16: cannot open shared object file: No such file or directory – /usr/local/rvm/gems/ruby-1.9.2-p290/gems/mysql2-0.3.11/lib/mysql2/mysql2.so

I was able to find the solution to that issue was to uninstall the mysql2 gem and then run bundle update: which worked great. The uninstall would work for me unless I was actually root (sudo didn’t work), so I used su to login as root and then

[bash]gem uninstall mysql2[/bash]

Then I went back to being my other user ran bundle update

[bash]bundle update rake[/bash]

Then everything was working fine.

Related: Keeping Your Hosted Ubuntu Web Server Software Up to DateAdding a Key to Your Server for SSH LoginChecklist: Setting Up a New Domain on VPS

Set the Web Server to Use the Domain Without www

The main reason to bother with this is to help search rankings. Sub-domains (for example, www.curiouscat.com and curiouscat.com) are treated as separate websites even if you have entirely the same content displayed for both. If 20% of the links to your site use the www and 80% don’t then your sites ranking by search engines is less than it would be if it was just treated as one site.

You can set the domain to use in Google webmaster tools. But that doesn’t do anything for all the other search engines. Also if you have both, some reports some will keep statistics separately for the non-www and www domain (Google Adsense does this, for example).

Using virtual hosts file (sites-enabled)

For Apache you can place the following code in your virtual hosts file (in the sites-available directory under Apache).

Replace curiouscat.com with your domain name.

[bash]<Directory /srv/www/curiouscat.com/public_html/>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.curiouscat.com$ [NC]
RewriteRule ^(.*)$ http://curiouscat.com/$1 [R=301,L]
</Directory>[/bash]

Then you need to capture the update and reload Apache.

Disable the site (in order to enable it with the updates)
[bash]sudo a2dissite curiouscat.com[/bash]
Enable the site
[bash]sudo a2ensite curiouscat.com[/bash]
Reload Apache (new way – Ubuntu 12.04)
[bash]sudo service apache2 reload[/bash]
Old way to reload Apache was > sudo /etc/init.d/apache2 reload

If when you try to reload you get this error message:

“Invalid command ‘RewriteEngine’, perhaps misspelled or defined by a module not included in the server configuration” then enable modrewrite on apache:

[bash]sudo a2enmod rewrite[/bash]

You should then be told to restart apache

[bash]sudo /etc/init.d/apache2 restart[/bash]

Using .htaccess

Or you can include the following in your .htaccess file

[bash] RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.curiouscat.com$ [NC]
RewriteRule ^(.*)$ http://curiouscat.com/$1 [R=301,L][/bash]

Related: Checklist for Setting Up a New Domain on VPSPhusion Passenger Tips and Troubleshooting Ideas

If you wanted to force www to be used instead just flip the regular expression around:

[bash]<Directory /srv/www/curiouscat.com/public_html/>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^curiouscat.com$ [NC]
RewriteRule ^(.*)$ http://www.curiouscat.com/$1 [R=301,L]
</Directory>[/bash]

Testing Email Using The Ubuntu CLI

For a Virtual Private Server (VPS) or any other web or other server you should have alerts sent by email for various things. So for example if you automate security updates for an Ubuntu web server you want to be notified if there is some issue with the automatic update.

In order to check and be sure email is setup and working on the sever there is simple command line code to use:

[bash]mail -s Test[/bash]

you then get a prompt to enter

To: [enter the email and press return]

Cc: [press return]

then a blank where you can type in any text you want in the body of the message.

Then you send the message with by pressing CTRL-d

[bash]CTRL-d[/bash]

If you don’t receive the email then you can troubleshoot what is going wrong.

Keeping Your Hosted Ubuntu Web Server Software Up to Date

To setup automatic security updates follow the instructions from Ubuntu.

To run security update manually

[bash]sudo unattended-upgrade[/bash]

A full update of all packages can be done using the follow, remember this may create some issues is one update makes something else you have no longer work properly. You should test to make sure things all work after the updates (for production systems obviously you should test things before [first updating the staging server to make sure the updates don’t cause any problems] and after the updates).

First update the local package index (to find what needs to be upgraded).

[bash]sudo apt-get update[/bash]

Then upgrade the software.

[bash]sudo apt-get upgrade[/bash]

Adding a Key to Your Server for SSH Login

Using Ubuntu

An authentication key allows your server to authenticate the computer you are using has the right key and should be granted access. This lets you use the key instead of a username and password when using ssh.

If you don’t already have a key on your local machine (look for a file named id_rsa.pub in your user home directory under the .ssh folder

[bash]cd /.ssh[/bash]

will get you to the right directory) then you need to generate the key pair. On your desktop machine use:

[bash]ssh-keygen[/bash]

Next you copy the file to your server. scp ~/.ssh/id_dsa.pub [user]@[server]:.ssh/

[bash]scp ~/.ssh/id_dsa.pub username@servername:.ssh/[/bash]

Rename the file on the server to authorized_keys2
[bash]mv id_rsa.pub authorized_keys2[/bash]

The key is for to authenticate your computer. But on the ssh login Ubuntu will look in the user folder. So if you also had user2 access to the server and tried to ssh into the server you would not be authenticated because it would look in user2/.ssh for the authorized key file and not find it. You can put the same key in any user folder on your server to have that user also be automatically authenticated.

WordPress: Multiple Blog Network on One Server – Overcoming Conflicts

I ran into a problem when I added a second WordPress blog network to my server. I had the Curious Cat Blog Network up and running for quite some time with sub-domains for each individual blog in the network. WordPress automatically dealt with routing the sub-domains and having urls work. It really is very nice how easy it is to create a new blog and have everything up and running – just add it in WordPress, no need to touch the server directly. Blog networks are a new feature in WordPress 3.0 (I think) which are very nice. I would imagine it builds on effort with Wordpres MU but it is just part of regular WordPress now.

When I added the second blog network however the new faux-sub-domain that should be used affordable-funeral.moneyite.com would instead be redirected to curiouscatnetwork.com and since no such domain existed on curiouscatnetwork.com it gave the standard error message WordPress generates for the case where a sub-domain url is not recognized.

The main domain for the new site was working: moneyite.com. I tried searching around for some solutions to this problem online but couldn’t find any. I am not sure if multiple wordpress blog networks should work on the same server without any special needs. But it wouldn’t for me. I found a solution that did work so I will share what worked for me.

I created new sites-available records for each of the sub-domains and once you reload Apache everything seems to work. I am not sure their isn’t some problem with doing things this way that I haven’t uncovered yet. But it is working for me so I wanted to share this in case it can help anyone else trying to use multiple wordpress blog networks on one server.

Related: Checklist for moving an existing WordPress site to a new web hostWordPress error: Image could not be processed. Please go back and try again

Checklist: Setting Up a New Domain on VPS

Two great hosts for Ruby on Rails are Slicehost and Linode. With these hosts you fully manager your virtual private server, installing the operating system, modifying apache (on Ning…), etc.. I use Ubuntu as the operating system and Apache as the web server.

If you are moving a domain from elsewhere it can be wise to reduce the TTL time to say 5 minutes a few days before you make the switch. This is make the change propagate across the internet more quickly.

  1. And DNS entry on your profile (login to your, for example, Linode account)
  2. Add a new file for /etc/apache2/sites-available/your_site_name.com
  3. [bash]sudo nano /etc/apache2/sites-available/example.com[/bash]

    The file would look something like this: with your ip in place of 8.8.8.8

    ServerAdmin is the address Apache will use to send error messages to. Using gmail and the + option lets you use one gmail account and just use rules to filter all your sites.

  4. create the directories needed on your server
  5. enable the site (for apache)

    [bash]sudo a2ensite example.com[/bash]

  6. You should see the file you created /etc/apache2/sites-available/example.com now also at /etc/apache2/sites-enabled/example.com

  7. Test the site out to make sure the setup is working properly. Create a index.html page and just verify the page is displayed. Change your local hosts file to point to your server IP address for the new domain you created. If not, take steps to get this to work, before continuing with the rest of the checklist.
  8. copy over the site – if you are moving the site from elsewhere
  9. remember to move the database over, if the site relies on a database
  10. restart apache
    [bash]sudo /etc/init.d/apache2 restart[/bash]
  11. You can test the site out, before updating the DNS, by changing your local hosts file to point to your server IP address for the new domain you created.

    Resources: Install the Apache 2 Web Server on Ubuntu 10.04 LTS (Lucid)

Using Git and Github

To download a repository hosted on github
[bash]git clone [email protected]:account_name/repo_name.git[/bash]

The [email protected]:account_name/repo_name.git will be shown on the home page for the repository on github.com

To update your code from the master branch of the repo:

[bash]git pull origin master[/bash]

To commit the changes you have made locally:

[bash]git commit -m "the message explaining what these code changes did"[/bash]

To send your changes to the repo at github:
[bash]git push origin master[/bash]

Replacing a Host Key

Host keys are used to security log into remote servers (such as Virtual Private Servers – VPS). With Ubuntu if you are using host keys to sign into servers securely and have asked for strict checking, if you make a change (such as rebuilding your VPS) the host key will change and you cannot login and will get a message like:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is

Please contact your system administrator.

RSA host key for 128.0.0.128 has changed and you have requested strict checking.
Host key verification failed.

if that happens you need to remove your local host key. Then you can sign back in and you will be able to save a new copy of the host key. If you don’t know why the key has changed you should figure that out first as it maybe be an indication of an important security problem. To remove you local key, you can use ssh-keygen -R [ip address of server with the bad key] for example: ssh-keygen -R 128.0.0.128

Then when you try to sign in you will get

The authenticity of host '128.0.0.128 (128.0.0.128)' can't be established.

RSA key fingerprint is ed:...:ea.
Are you sure you want to continue connecting (yes/no)?

And if you know why (such as you made changes to the server) you can say yes and connect and save the new known host key.