Oliver Nassar

AWS EC2 Micro Instance Setup

August 02, 2011

As mentioned in my previous post "Logging into my first AWS micro instance", I've setup my first micro instance for my own personal sites. And having done so, here is the setup I'm following for this instance. While it's not the most secure, it'll do for my small testing and play-sites.

Also, this setup obviously doesn't limit itself to a micro instance. I'm installing this on an Ubuntu 11.04 Natty Narwhal box, but I'm sure most of it translates to modern linux-distros.

This will be a command-heavy post, but I'll detail the reasoning behind each code segment.

Being logged in, let's start:

Packages and Timezone

sudo apt-get update
sudo apt-get -y upgrade
sudo dpkg-reconfigure tzdata

This updates your system's listing of the packages available to be installed/upgraded, upgrades the packages that are already installed, and prompts you to choose the timezone for your linux-box.

Shell Customizations

sudo vi ~/.bashrc

This file contains code that is executed/compiled each time you connect to your system via SSH. I enter the following commands, aliases and functions at the end of the file:

# pimping
export PS1="e[35;40mu@He[0m [w] e[33;1m: e[0m"
export LS_COLORS="di=36:fi=0:ln=31:pi=5:so=5:bd=5:cd=5:or=31:mi=0:ex=35"

# custom aliases
alias ls='ls -la --color=auto --time-style=long-iso'
alias c='clear'
alias cls='clear && ls'
alias php.ini-edit='sudo vi /etc/php5/apache2/php.ini'
alias apache-restart='sudo /etc/init.d/apache2 restart'
alias apache.conf-edit='sudo vi /etc/apache2/apache2.conf'
alias ftp-restart='sudo service vsftpd restart'
alias mysql-connect='mysql --user=root --password=PASSWORD[MYSQL::ROOT]'
alias mysql-restart='sudo service mysql restart'

# functions
ff () { sudo find / -name "*$@*" ; }
ft () { sudo grep -r "$@" /var/www/ --color ; }

The above commands do a few things.
The first set (commented as "# pimping") colour the terminal and ls program. While you may think it's a design/asthetic preference, it's actually pretty useful. My OSX box's terminal is coloured green. My VM's is purple, and my live, production-available boxes (whether AWS or Slicehost) are coloured red. This allows me to know exactly where I am whenever I'm in front of the terminal. This can help prevent potentially dangerous commands being run on the wrong box.

The section "# custom aliases" lists a set of alias that make using the terminal easier (eg. basically, shortcuts). They all me to manage my PHP, Apache and MySQL installs quickly.

Finally, the "# functions" block lists two functions that make it quick and easy to search through file names and file contents in the /var/www directory:

source ~./.bashrc

This reboots your .bashrc file and makes the changes made immediately available.

SSH Configuration

sudo vi /etc/ssh/sshd_config

This prompts you to edit your SSH config file. I generally change my port from the default 22. When doing this, however, you will have to make changes to your AWS Security Group to allow that port to be accessed.

sudo reload ssh

This simply reloads the ssh application, with the new configuration details applied (you may get disconnected at this time).

Application Server Setup

sudo apt-get -y install memcached unzip vsftpd apache2 libapache2-mod-php5 php-pear php5-dev make apache2-prefork-dev php5-imagick php5-gd php5-geoip php5-curl

This is a biggie, and takes a while. It installs a group of packages, including memcached, Apache, VSFTP (ftp-server), PHP5, along with some PHP extensions.

Memcached Setup

In the previous application server setup step, we installed the memcached package. But now we need to configure it.

sudo vi /etc/rc.local

While I honestly don't know the purpose of this file, I do know that the following needs to be put before the exit 0 statement to ensure memcached get booted after each system restart:

/usr/bin/memcached -u www-data -d -m 64 -p 11211

sudo reboot

This reboots your system.

sudo netstat -tap

This will print out information on your network connections; search for one that looks like "localhost:11211". This is the memcached daemon, and ensure that it's running properly after the reboot you just did.

sudo updatedb
cd
sudo apt-get -y install g++
wget http://launchpad.net/libmemcached/1.0/0.39/+download/libmemcached-0.39.tar.gz
tar zxvf libmemcached-0.39.tar.gz
cd libmemcached-0.39/
./configure
make
sudo make install
cd /usr/lib
sudo ln -s /usr/local/lib/libmemcached.so
sudo pecl install memcached
sudo rm -r ~/libmemcached-0.39
sudo rm ~/libmemcached-0.39.tar.gz

This is a fairly significant code chunk. It does quite a few things which I'll outline here in order:

  1. Update your system's file name database, to make searching relevant with all the new files that have recently been installed
  2. Move to your home directory
  3. Install the g++ compiler
  4. Download the libmemcached binary library
  5. Move into it, configure it, make it and install it
  6. Make a symbolic link to the generated libmemcached.so file
  7. Install the PECL extension (which allows PHP to talk to the libmemcached library; which talks to the Memcached application)
  8. Remove the garbage

    php.ini-edit
    

Add in the following command to have PHP boot the memcached extension in:

extension="memcached.so"

APC Setup

cd /usr/local/src
sudo wget http://pecl.php.net/get/APC-3.1.9.tgz
sudo tar xzvf APC-3.1.9.tgz
cd APC-3.1.9
sudo phpize
sudo ./configure --enable-apc --enable-mmap
sudo make
sudo make install
cd ..
sudo cp APC-3.1.9/apc.php /var/www/apc.php
sudo rm -rf APC-3.1.9
sudo rm APC-3.1.9.tgz
sudo rm package.xml

The above code follows a very similar process as the memcached setup listed above. In short, it downloads the APC PECL extension, configures it, installs it, copies over a status PHP file to the Apache webroot, and removes the garbage generated by the installation/setup.

php.ini-edit

Add in the following command to have PHP boot the APC extension in:

extension="apc.so"

Apache Configuration

sudo ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
sudo ln -s /etc/apache2/mods-available/auth_digest.load /etc/apache2/mods-enabled/auth_digest.load
sudo ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load
sudo a2enmod headers
apache-restart

This will make symbolic links between the modules available and modules enabled for Apache. These modules allow mod_rewriting, auth_digest (security) and ssl to be usable via Apache. We then restart the server.

sudo vi /etc/apache2/sites-available/default

This default apache configuration file gets served when no specific virtual host can be found (eg. if you try connecting to your box's IP directly). To prevent directory listing and viewing the root /var/www directory, add in the following two rules at the top of the /var/www directory funnel:

RewriteEngine On
RewriteRule ^(.*) http://www.domain.com/ [R=301,L]

This will redirect all traffic to your Apache that isn't explicitly allowed via a VirtualHost to your domain. And finally, after those two rules, change the Options rule to the following:

Options -Indexes FollowSymLinks MultiViews

This prevents the directories from being indexable, Apache-wide (eg. should take effect in each VirtualHost).

PHP Configuration

php.ini-edit

There are some small modifications that need to be set to ensure clean running of PHP. Ensure the following is set:

expose_php = Off
apc.slam_defense = Off
default_charset = "UTF-8"

Those removes the PHP signature from header responses, prevents a cache-lookup collision/race-condition within APC, and sets the default encoding for PHP responses unless otherwise specified.

MySQL Setup

Before I started this installation, I'd assumed I would transition over to RDS. That was until I checked the price (about $80/month). Simply not worth it. Therefore this MySQL Setup process is near the end since I've got to circle back.

sudo apt-get -y install mysql-server php5-mysql

This installs the mysql-server itself, along with the PHP extension for it. You'll be prompted for a root password for the server.

apache-restart

You need to now change the alias you created earlier that points to the mysql server to have your newly changed passowrd.

sudo vi ~/.bashrc
source ~/.bashrc

Now, we need to create two new users. One for administration by third-party apps (Sequel Pro), and one for the applications themselves.

mysql-connect
CREATE USER 'admin'@'%' IDENTIFIED BY '13wQ991nsQm';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
CREATE USER 'app'@'localhost' IDENTIFIED BY '13wQ981bDm';
GRANT ALL PRIVILEGES ON *.* TO 'app'@'localhost' WITH GRANT OPTION;
exit

The above code created the new users and granted permissions for the from specific hosts (eg. wildcard % and localhost)

Now let's make some changes to how MySQL runs.

sudo vi /etc/mysql/my.cnf

We want to comment out the configuration line bind-address to allow for remote connections (eg. Sequel Pro). Next, I change the port to a non-default one for the mysql-server (not client). This port also needs to be opened in the AWS console Security Group/firewall. And finally, we want to ensure the following settings are set:

init_connect='SET collation_connection = utf8_unicode_ci; SET NAMES utf8;';
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_unicode_ci

mysql-restart
apache-restart

And boom. Both servers have been restarted, and should/are ready for use.

Language Installation

While I recently wrote a post "Adding a language package (french) to Ubuntu Linux (10.10)", in this step I'm only going to ensure the english language packages are installed properly:

sudo apt-get -y install language-pack-en
sudo locale-gen en_US.UTF-8
sudo dpkg-reconfigure locales
sudo vi /etc/default/locale

The above code installs the english language pack, generates the en_US.UTF-8 locale, reconfigures all available locales in the OS, and prompts you to choose which of those locales is actually usable (so many moving parts..).

As you're now prompted with an editor, your job is to simple ensure the following is present:

LANG="en_US.UTF-8"

sudo reboot

Now let's reboot :)