WordPress on AWS EC2 – part 8

Series summary

In this series my goal was to give you information sufficient to launch your own WordPress on AWS EC2 platform. I wanted to keep balance between detailed descriptions of what and why I do something, and length of the posts. Do i made it? I hope that you give me some feedback in comments below. I’ll do my best to take your opinion into account when I’ll be writing next posts.

What we have done?

  • We lunched new EC2 instance
  • We done some basic configuration of our system
  • We talked a bit about security
  • We installed Apache, PHP-FPM and MySQL
  • We talked a bit about WP-CLI, createed new MySQL database and installed WordPress
  • We investigated what and why not working correctly and we solve those issues

In fact it’s quite a lot! 🙂
However I must say, that this series omitted some things. We doesn’t talk about further optimization, backup strategies or versioning. There is also so much more to say in subject of security. If you want to use this system in production environment you should do some more work but this is out of scope of this series so i won’t dive into this topic. Below i present list of terms you can search for. As I wrote in introduction: if you know how to do something better or just have another opinion about something, please leave your comment. I’m constantly learning and improving my skill set so I’ll be happy to look on something from different point of view than mine.

Happy blogging! 🙂

Further reading:

Part 1
Part 2
Part 3
Part 4
Part 5
Part 6
Part 7

WordPress on AWS EC2 – part 5

Apache, PHP, MySQL

To launch WordPress we need to have some additional tools. First of all we need to install server which will pending requests from users browsers and sending them responses. WordPress is written in PHP so we also need to install interpreter of this language. Last but not least we need database server because our blog can’t work without it. WordPress is designed to work with MySQL so we need to install this one.

Apache installation

To install apache you need to SSH your instance and run following command:

sudo apt-get update && sudo apt-get install apache2

As I mention in previous part sudo apt-get update will fetch information about software available in Ubuntu repository. The && operator stands as: “if command on the left side will ran successfully, run command on the right side”. Command sudo apt-get install apache2 launch installation of package apache2.

After this operation when you type IP address of your instance to browser address bar, following page should appears. This indicates that our server works. 🙂

ec2_apache

Before we continue it’s worth to look if apache is using mpm-events module instead of mpm-prefork. It’s about performance. My installation has this module installed and activated by default. You can check this with command which lists all loaded modules:

sudo apache2ctl -M

If you don’t have it you can install it manually:

sudo apt-get install apache2-mpm-event
sudo a2enmod mpm_event
sudo service apache2 restart

PHP Installation

In Ubuntu 14.04 repository newest PHP version is 5.5.9. If you want to install newer version like 5.6.x you should use additional repositories.

As I mention at the beginning of the series I want to use PHP5-FPM. It’s mainly because of performance. Here you can read comparison of mod_php and php-fpm. To install run the command:

sudo apt-get install php5-fpm

Żeby taka instalacja PHP chciała współpracować z apachem musimy doinstalować do niego dodatkowy moduł. Ze względu na zawiłości licencyjne, jest on dostępny w repozytorium multiverse, które domyślnie jest wyłączone, więc najpierw musimy je włączyć. O różnicach między repozytoriami można poczytać tutaj. Otwórzmy w ulubionym edytorze tekstowym plik /etc/apt/sources.list (ja korzystam z nano)…

To get this installation to work with apache we should install another apache module. Because of license incompatibilities this module is available in multiverse repository which is disabled by default so we need to enable it. About differences between types of repositories you can read here. Please open file /etc/apt/sources.list in your favorite text editor (I will use nano).

sudo nano /etc/apt/sources.list

We should uncomment appropriate lines (URLs can be different for different regions):

ec2_sources

Now we can run command

sudo apt-get update
sudo apt-get install libapache2-mod-fastcgi

After installation module should be enabled automatically and apache should be restarted.

ec2_fcgi

If that is not true in your case, you can anytime enable module and restart server yourself running following commands:

sudo a2enmod fastcgi
sudo service apache2 restart

CAUTION!
If you have had installed mod_php previously you should turn it off. You can do this similarly:

sudo a2dismod php5
sudo service apache2 restart

Now we’ll configure apache a bit. I assume that only one site will be running on our instance. Configuration provided below is very simple then. Let’s enable another two modules which we’ll need:

sudo a2enmod alias actions
sudo service apache2 restart

Now we should create configuration file which tells apache what should be done with PHP files. All of apache configuration files are stored in /etc/apache2/conf-available directory so we put our file here also. I will name it php5-fpm.conf. We can do this for example with nano:

sudo nano /etc/apache2/conf-available/php5-fpm.conf

Next we put this content to the file:

Couple words of explanation:
IfModule checks if module is active and if yes performs instructions in block.
AddHandler tells apache which action it should take for described files – in this case for files with php extension, action php5-fcgi will be fired
Action defines program to which request will be passed when action is fired – in this case for action php5-fcgi request will be routed to /php5-fcgi path
Alias is used to map paths – in this case we define that path /php5-fcgi from previous line is actually /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer indicates how to handle file which we catch with the above lines – in this case it will be run by server pending on unix socket on /var/run/php5-fpm.sock path. This path is defined in php-fpm configuration file. You can find it here: /etc/php5/fpm/pool.d/www.conf. Option -pass-header gives us ability to pass to the script http headers which won’t be passed by default. For example Authorization Header.
Directory defines path in which following settings will apply.
Require all granted gives permission to read localization by all – we need to add this line because otherwise we’ll see “Access denied” instead of results of any PHP script.

Nie pozostało nam nic innego, jak zapisać konfigurację, włączyć ją i przetestować czy wszystko działa. Zapisujemy plik, wychodzimy z edytora, wydajemy polecenia:

There’s nothing else to do except saving configuration. Now we should enable it and test if everything works.

sudo a2enconf php5-fpm
sudo service apache2 reload

Teraz utwórzmy plik php, dzięki któremu przetestujemy to, co do tej pory zrobiliśmy. Domyślna konfiguracja apache-a kieruje nas na ścieżkę /var/www/html, więc tam też utworzymy nasz plik:

Let’s create PHP file so we can test our work so far:

sudo nano /var/www/html/info.php

Save, and navigate to your server in browser. In my case URL will be: http://52.29.70.252/info.php. We should see well known PHP Info page. 🙂

ec2_phpinfo

MySQL Installation

This should be easy. Let’s run MySQL installation. We additionally install php module which will be used for communication with database.

sudo apt-get install mysql-server php5-mysql

During installation we’ll be asked about creating password for root user of our database. We can create it now or leave it blank. We’ll back to this step in a moment.

When installation is complete we should run script which prepares our database to work which means for example creating appropriate directory structure.

sudo mysql_install_db

Last step is to run script which help us secure our server a bit.

sudo mysql_secure_installation

In first step we’ll be asked about current root password. If we set this during installation we need to provide it. If not we just hit enter.

Second step is to set root password. If you already set it you can change it in this step.

Third step gives us ability to delete anonymous user. In other words there will be no possibility to log in to database without having an account. Of course we confirm.

In fourth step we can define if root can or cannot login from another computer than this where server is running. Let’s disable remote login.

W fifth step we can delete “test” database which is created during installation and is available for everyone. Confirm deletion.

Last step is to flush privileges table. Confirm.

So… that’s all! We have almost everything which we need to launch our WordPress. See you in next part. 🙂

Part 1
Part 2
Part 3
Part 4
Part 6
Part 7
Part 8

WordPress on AWS EC2 – part 4

How to make your instance more secure?

This post is obviously not complete security guide and it’s not meant to be. However I want to talk about some basics which I think are minimum in subject of securing our Linux. I must emphasize that you have complete control of your instance and it’s your responsibility to take care about security of your data and your site users. I definitely encourage to constantly learn about server administration.

Updates

One of the most important things are regular updates of the system and other installed software. Unfortunately vulnerabilities happened everywhere (famous example of vulnerability in OpenSSL library from 2014) so we should install every security updates as fast as possible. Before we continue let’s update our system.

The first step will be following command:

sudo apt-get update

In this way we ensure that our system “knows” about all the updates available but nothing will be installed yet.

Next we can do this:

sudo apt-get upgrade

or this:

sudo apt-get dist-upgrade

There is significant difference between those two. In first case only packages that were already installed will be updated. However common practice is that one package depends on others. If new version of installed software depends on package which was not required previously and this package is not available in system, update will fail. All information about the problems will be printed to the console.

In second case dependencies are resolved automatically and some packages can be deleted or new packages can be installed. Now it really doesn’t matter because we just launch our instance and we don’t using it for any purpose yet. However when we start web server, database and our site will be made public, we won’t want something stop working because of update. It doesn’t mean of course that we shouldn’t update our system. It only means that we always need to know what we are doing and why. We probably should consider launching stage environment and check any modifications there first. In AWS ecosystem it’s really easy to duplicate EC2 instance.

Some of you probably notice that though installation of all updates, OpenSSL library which I mention remains in version 1.0.1f, which is theoretically vulnerable to HeartBleed attack. In fact it’s not true. This version was patched by Ubuntu maintainers the same day which vulnerability was disclosed. More information here.

Now we should reboot our instance.

sudo reboot

When you run this command your connection will be interrupted. Wait minute or two and try to connect again.

Change the default SSH port

It’s worth to consider change the default SSH port from 22 to some other number grater than 1023. Many bots which are used to automatic attacks search for open SSH port, but they limit themselves to default port. It of course won’t stop all intrusion attempts but can help reduce the number of them. We can change port in SSH configuration file. We must edit it as root so we run command:

sudo nano /etc/ssh/sshd_config

Of course you can use your favorite text editor instead of nano. 🙂
Lets find following line in file

Port 22

and change the value to something else, for example:

Port 56321

ec2_custom_ssh_2

Now save changes (in nano ctrl+O and confirm hitting enter) and exit editor (in nano ctrl+X). We should restart SSH service to reload configuration:

sudo service ssh restart

Our current connection should not be interrupted but from now on every new connection to our instance must be on port which we put to config file. As you remember we define some security rules in our EC2 dashboard so we need to go back there and open up this port.

In group “Network & Security” we need to find tab called “Security Groups” and then right click group which our instance belongs to. From menu choose “Edit inbound rules”. Now in place of SSH we select “Custom TCP Rule” and enter the new port number. Remember to save the changes.

ec2_custom_ssh

Powinno być już możliwe nawiązanie nowego połączenia. Jeśli łączymy się z konsoli musimy dodać parametr “-p” i dopisać po nim numer portu, a więc w moim przypadku będzie to:

Now we should be able to start new connection. If you’re using console you should add “-p” followed by port number. In my case it will be:

ssh -i ~/.ssh/test1-keys.pem ubuntu@52.29.70.252 -p 56321

If you’re connecting by putty, find on list of saved sessions your instance and load settings. Now you should change port number and save your session again.

ec2_custom_ssh_3

Summary

After this part our system is up to date and SSH works on different than default port number. As I mention it’s not guarantee that you are 100% secure. I recommend that you read about some tools which can help you in process of hardening your system. In next part we’ll install software which is essential to run our virtual machine as web server.

Part 1
Part 2
Part 3
Part 5
Part 6
Part 7
Part 8

WordPress on AWS EC2 – part 3

How to connect to my instance

In previous post we launch our virtual machine so now is the time to log in via SSH. In this part we attach Elastic IP which will be our public IP address and we connect to our instance using previously downloaded private key.

How to attach Elastic IP

You can attach one public IP to any single instance without additional costs. This IP will be linked with our AWS account so we can easily attach and detach it from one instance to another as we need. One virtual machine can also have more than one public IP address if we need this kind of configuration for some reason. This address is reserved for us as long as we won’t release it. Theoretically our instance have public address attached in time of launching but it’s randomly picked so when we stop our machine it will be released and new address will be attached on resume.

In our case we want that our address will persist forever and ever and if we need to scale up in the future we probably want to have possibility of transfer this IP address to another machine. Fortunately this process is very easy. 🙂

Let’s find Elastic IPs tab in our EC2 dashboard. There we will click Allocate New Address and confirm.

ec2_elastic_ip

Next let’s right click on IP and choose action Associate Address. We can do the same thing from Actions dropdown. Click on input called Instance should revealed list of our instances where we can choose that we are recently created. We can also filter this list by instance ID or Name tag. Select your instance and then click Associate button.

ec2_elastic_ip2

If you check your list of instances you should see that this new address was really attached to your machine.

Connect through SSH

Linux / Mac

If you work on Linux or Mac, just add downloaded private key to your .ssh directory i home directory:

mv /path/to/your/key.pem ~/.ssh

If you doesn’t have this folder, create it:

mkdir ~/.ssh

Private key should have very restrictive settings of permissions. Let’s set 400 then (available only for reading, only for file owner).

chmod 400 ~/.ssh/your_key.pem

Now you should be able to connect to your instance. Default user name for Ubuntu is… ubuntu. My private key are in test1-keys.pem file in .ssh directory and IP address of my instance is 52.29.70.252, so i type following command:

ssh -i ~/.ssh/test1-keys.pem ubuntu@52.29.70.252

I wrote down key fingerprint from server logs so now I can verify if I’m really connecting to my instance. If yes I can confirm that I want to connect. From now on my computer “knows” my virtual machine so I won’t need to check this fingerprint for every connection. If everything was fine you just logged in to your instance. Congratulations! 🙂

ec2_ssh_login

Windows

If you’re working on Windows, you’ll need to use additional tools. First of all Windows don’t support SSH natively (probably something will change about this in near future as we can read here). I use and recommend PuTTY as SSH client for Windows. Additionally we can’t use private key as it is, we need to convert it to format which can be read by PuTTY. We can do this with tool called PuTTYgen, which we can download here.

Let’s open PuTTYgen and load our private key. Next we click on Save private key button. We’ll be asked if we really want to save our private key without password protection. There are different opinions on this subject. Here you can read interesting discussion about it. Everyone should take this decision himself. One thing I want to tell is that if your key is not password protected, anyone who can read your key file, can access your instance also. I’m not creating password for sake of this tutorial.

ec2_puttygen

Where to save the new key file? I’ll follow the “Linux” way and create .ssh folder in my user directory, but you can place it anywhere you want. However it’s important to remember that if you are not the only user of this computer you should place it in directory not accessible by other users.

So last thing is to use PuTTY to log in on our machine. User name in Ubuntu is by deafult ubuntu nad IP address of my instance is 52.29.70.252. In Host Name I should type ubuntu@52.29.70.252 and in SSH -> Auth tab I need to select private key file.

ec2_putty

Now it is worth to save this settings so i won’t need to retype them in future.

ec2_putty2

When you click Open button security alert pop-up should appear with information that this server is not known. If you wrote down key fingerprints you can verify if they’re match. If yes confirm that you want to connect and you should be in. Next time this verification will not be required.

ec2_ssh_login_win

Summary

So we have established SSH connection to our EC2 instance. We are step closer to run WordPress. In next part we will talk a little bit about configuration of our server in terms of security.

Part 1
Part 2
Part 4
Part 5
Part 6
Part 7
Part 8

WordPress on AWS EC2 – part 2

How to launch EC2 instance

Of course we need to login to our AWS console here:
https://console.aws.amazon.com/console/home.

After login on the top right corner we should choose region in which we will operate. The best choice should be region geographically nearest place from which we expect most of the traffic. Next we should go to EC2 dashboard and click Launch Instance. We’ll be taken to the wizard, where we’ll be able to configure and launch our virtual server.

aws_console

Step 1 – Choose an Amazon Machine Image (AMI)

Instances are based on Amazon Machine Images (AMIs) which are prepared images of operating system. We can choose from wide range of images. Some of these have pre-installed environment for WordPress and WordPress itself. It’s worth to look on AWS Marketplace and Community AMIs tabs to be aware of how many prepared images you can use out of the box. My pick will be clean Ubuntu Server 14.04 LTS as I wrote in previous part. It’s the newest LTS release in time of writing.

ec2_wizard_step1

Step 2 – Choose an Instance Type

When you register new account to AWS you can use free tier for one year, which includes t2.micro instance, so I will focus on this type of machine. However you should know limitations of it. If you expecting high traffic on your blog you should consider launching more powerful instance. You can find the exact specifications and characteristics of various types of instances here and price list is here.

When you choose appropriate option you can click “Next: Configure Instance” button.

ec2_wizard_step2

Step 3 – Configure Instance Details

If this is your first server, probably most of the default options will be perfect for you so i won’t explain everything in detail. Some of this settings are self explanatory (like Number of instances), some are needed only on specific situations but these are out of scope of this tutorial. However I would like to mention two of them which is good to know:

“Shutdown behavior” – this option indicates how our machine will behave, when we run for example following command:

sudo shutdown -h now

If we set “stop” value, instance will be stopped and it will be possible to resume it in any moment of the future in the same state as it was. When server is stopped there is also no fee for usage – we pay only for running hours.

If we set “terminate” value, instance will be erased. In our case this machine will act as webserver, so probably we don’t want this kind of situation.

Second option which is worth mentioning here is “Enable termination protection”. We can manipulate state of our instance not only by SSH but for example also from EC2 dashboard. There we can in any moment terminate (erase) our virtual machine. To be 100% sure that we won’t do this by accident, let’s check this option.

ec2_wizard_step3

Step 4 – Add Storage

To let our instance work, we’ll need some storage, where operating system will be installed and where we store all of our files and data such as WordPress files. By default wizard give us 8GB on one partition. We can use up to 30GB for free in free tier so we can grab more space it there is need for it. We can also do it later but this will remain shutting down our server for couple minutes. We can of course add additional drives if we want separate OS from database for example.

“Delete on Termination” is quite important setting. Because drives we are using are virtual, we can easily attach and detach them from particular instances. Therefor sometimes we might don’t want to erase all our data on instance termination. In this case we can deselect this option. Because in previous step I made sure that I won’t accidentally erase my machine, I will leave this option as it is. I don’t want to preserve my virtual drive with OS and I can easily transfer all of WordPress data to another server before i eventually delete my instance. If I’ll change my mind, I can change this behavior later following instructions here.

To sum up: I leave default values and I’m going to the next step.

ec2_wizard_step4

Step 5 – Tag Instance

In this step it’s all about organization. In case of single instance it doesn’t very important, but if you manage large number of virtual servers, tags are very handy tool which let you easily find resources (because not only instances you can tag) you need. Tags are simply key – value pairs and we can add up to 10 tags for any resource. For example we can name our server in a way that will be meaningful for us in the future. For the purpose of this series i will name my instance Test1.

ec2_wizard_step5

Step 6 – Configure Security Group

In this step we are setting up firewall rules for inbound traffic. From the security point of view it’s crucial to open only this ports that are really needed to work. Because our instance will act as web server we need to open ports for HTTP and HTTPS protocols. In addition we also need to manage remotely our server so we need to open port 22 for SSH service. If we have static IP or we will connect to server from specific IP range (for example through VPN) it is good practice to limit access only for those IPs. My home IP address is dynamic so I leave this port open globally.

I named my group www-open-ssh, because it is quite self explanatory. You can name it anything you like.

ec2_wizard_step6

Step 7 – Review

So now we are on review screen. We can one more time look through all the configuration details. If all settings are correct we can press “Launch” button and… Almost done! 🙂 Last thing we need to do is to generate key pair which we will use for authentication instead of password – this is in general more secure way to authenticate. We need to name this key pair somehow. It can be whatever you want. I will name it test1-keys. When you click Download Key Pair, the private key should be downloaded to your computer. This is the only time when you can get it. You won’t be able to re-download it again. The public key will be automatically added to your instance. Now we can press “Launch Instances”.

ec2_wizard_keys

If all goes well you can go to Instance List on your EC2 Dashboard and there you find your instance running.
Congratulations! 🙂

Last thing i recommend is to get fingerprints of SSH keys. If you are sure that your computer and network are secure we can skip this step. On the other hand it isn’t much effort to do this, so we can do this just for sure. On instance list right click on your instance and choose Instance Settings -> Get System Log.

ec2_wizard_keys_fingerprints_2

Popup contains boot messages should appear. If the window is empty give your machine another minute to boot up. On the very bottom we should find this section.

ec2_wizard_keys_fingerprints

Let’s write down somewhere this fingerprints. They will be helpful on first connection through SSH.

Part 1
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8

WordPress on AWS EC2 – part 1

Introduction

With this post I’m starting the series about deploying WordPress on Amazon AWS EC2. I’ll try to explain step by step what am I doing and why. If you know how to do something better or faster, please leave your comment on specific post. I’ll be happy to learn some new things or best practices. 🙂

Assumptions

Many people probably have set of tools which they like to use. Someone like this Linux distribution, someone else prefer that. Someone like Apache server and someone prefer Nginx. I won’t argue with that and I don’t think that one approach is better than another in every single situation. In many cases it’s just matter of preference. I’ll use following setup:

  • Ubuntu 14.04 Server (in time of writing this text it’s newest LTS version)
  • Apache2
  • PHP-FPM
  • MySQL

I’m assuming that you registered your Amazon AWS account so I’ll proceed straight to the first step – launching your EC2 instance.

Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8