Setup of iExperiment on Amazon’s Elastic Compute Cloud (EC2) Server

A research organization’s experiment records are the foundation of its intellectual property, and, as such, must be stored in a way that allows the research organization to maintain control over these records. Enterprise electronic notebooks, such as our iExperiment, store their experiment records on a server. Many organizations, including Colabrativ, Inc., are using cloud computing to lower the cost of a server and IT costs in general. Amazon’s Elastic Compute Cloud (EC2) is one of the lower cost cloud service providers. Amazon is Statement on Auditing Standards No. 70 (SAS70) compliant. They completed the Type II audit in 2009 (see AWS Completes SAS70 Type II Audit announcement). Thus, one can be comfortable that they are doing everything they can to keep one’s data secure. Amazon Web Services places the responsibility of the enterprise application setup and maintenance on the client’s administrator. Other full-service SAS70-compliant cloud service providers will happily take on these responsibilities for you, for a fee.

In my previous post, I described the Setup of Amazon’s Elastic Compute Cloud (EC2) Server for iExperiment, our enterprise electronic notebook application. That post covered the following topics:

You may want to take a quick look at iExperiment Server Requirements.

In this post we will go over the setup and configuration of the EC2 server and the installation and setup of iExperiment on it. Topics in this post include:

The majority of these tasks are preformed on the iExperiment EC2. Tests of the server’s operation were made using Firefox 5. We use PuTTY to log onto our EC2 server (Instructions can be found in an Amazon appendix on PuTTY.

Updating the EC2 Server using Amazon’s Yum repository

The update of the EC2 server from Amazon’s Yum repository takes only a single command “sudo yum update”. It produces a large output. During the update you will be asked two yes-no question. You should answer “yes” to both of these questions. Below I have edited the session to only include the yum command and text around the two questions.

> sudo yum update
...
===============================================================================
Install       1 Package(s)
Upgrade      47 Package(s)

Total download size: 113 M
Is this ok [y/N]: Y
...
Importing GPG key 0x21C0F39F "Amazon Linux AMI (Beta)
" from /etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-beta
Is this ok [y/N]: Y

Mounting Elastic Block Storage Volume (optional)

In order to format the elastic block storage (EBS) volume, we need to install XFS filesystem utilities (xfsprogs) from the Amazon Yum repository.

The /proc/partitions file contains a list of the volumes associated with the EC2 instance. The /dev/xvda1 device is the system volume. The other volume is the unformatted EBS volume we associated with the EC2 instance. The EBS volume has two related device names; the system refers to the device as dev/xvd[f-p], but mkds.xfs takes /dev/sd[f-p]. In the case below, the device names are /dev/xsdf and /dev/sdf, respectively.

  1. Format the EBS volume using mkfs.xfs and the device name (/dev/sdf)
  2. Create a mount point for the volume (/ebs1).
  3. Add the mount point to the /etc/fstab file.
  4. Mount the volume.
> sudo yum install xfsprogs
Is this ok [y/N]: y

> more /proc/partitions
major  minor  #blocks  name
 202        1    8388608 xvda1
 202       80   10485760 xvdf

> sudo mkfs.xfs /dev/sdf
meta-data=/dev/sdf               isize=256    agcount=4, agsize=65536 blks
         =                       sectsz=512   attr=2
data     =                       bsize=4096   blocks=2621440, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0sudo vi /etc/fstab

> sudo mkdir /ebs1

> sudo cp -p /etc/fstab /etc/fstab.orig
> sudo vi /etc/fstab
> more /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/dev/xvdf   /ebs1       xfs     noatime         0   0

> sudo mount /ebs1

After mounting the EBS volume on /ebs1, we create and link both the iExperiment and MySQL directories. We add the mounts to the /etc/fstab file, then mount the directories.

> sudo mkdir /ebs1/etc
> sudo mkdir /ebs1/etc/mysql
> sudo mkdir /ebs1/lib
> sudo mkdir /ebs1/lib/mysql
> sudo mkdir /ebs1/log
> sudo mkdir /ebs1/log/mysql
> sudo mkdir /ebs1/log/iexperiment
> sudo mkdir /ebs1/local/iexperiment

> sudo mkdir /etc/mysql
> sudo mkdir /var/lib/mysql
> sudo mkdir /var/log/mysql
> sudo mkdir /var/log/iexperiment
> sudo mkdir /var/local/iexperiment

> sudo vi /etc/fstab
> more /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/dev/xvdf   /ebs1       xfs     noatime         0   0
/ebs1/etc/mysql          /etc/mysql              none    bind
/ebs1/lib/mysql          /var/lib/mysql          none    bind
/ebs1/log/mysql          /var/log/mysql          none    bind
/ebs1/log/iexperiment    /var/log/iexperiment    none    bind
/ebs1/local/iexperiment  /var/local/iexperiment  none    bind

> sudo mount /etc/mysql
> sudo mount /var/lib/mysql
> sudo mount /var/log/mysql
> sudo mount /var/log/iexperiment
> sudo mount /var/local/iexperiment

If MySQL has already been installed and setup, then instead of making the /mysql directories, we would move (mv) the existing MySQL directories to the EBS volume. We continue from the snippet above remaking mysql directories that are used as mount bind points.

> sudo mkdir /ebs1/etc
> sudo mkdir /ebs1/lib
> sudo mkdir /ebs1/log
> sudo mv /etc/mysql     /vol/etc/
> sudo mv /var/lib/mysql /vol/lib/
> sudo mv /var/log/mysql /vol/log/

> sudo mkdir /etc/mysql
...

Installing MySQL

MySQL and MySQL Server (mysqld) are available from the Amazon Yum repository. Like update snippets above, the snippet below has been edited to show only what is necessary.

> sudo yum install mysql
Is this ok [y/N]: y

> sudo yum install mysql-server
Is this ok [y/N]: y

After installing MySQL and MySQL Server, we start the MySQL service.

> sudo service mysqld start
Initializing MySQL database:  Installing MySQL system tables...
OK
Filling help tables...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h ip-10-176-31-62 password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &

You can test the MySQL daemon with mysql-test-run.pl
cd /usr/mysql-test ; perl mysql-test-run.pl

Please report any problems with the /usr/bin/mysqlbug script!

[  OK  ]
Starting mysqld:                                           [  OK  ]

Finally the mysql_secure_installation script is run.

> /usr/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
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):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? [Y/n] Y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!

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] Y
... 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] Y
... 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] Y
- 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] Y
... 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!
    

Set Up the iExperiment Database

  1. Log in as root to the MySQl database. We recommend that you not put the root password in the mysql command, so that it does not end up in .bash_history.
  2. Create a user ‘iexperiment‘@‘localhost‘.
  3. Grant the iexperiment user appropriate privileges.
> mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.1.52 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create user 'iexperiment'@'localhost' identified by 'iexperimentpassword';
Query OK, 0 rows affected (0.00 sec)

mysql> grant usage on *.* to 'iexperiment'@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all privileges on *.* to 'iexperiment'@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye
    
  1. Create the /var/log/iexperiment, /var/local/iexperiment and /var/local/iexperiment/ddl directories.
  2. Upload the iExperiment SQL files to the /var/local/iexperiment/ddl directory using an FTP application that supports SSL, such at FileZilla.
> sudo mkdir /var/log/iexperiment
> sudo mkdir /var/local/iexperiment
> sudo mkdir /var/local/iexperiment/ddl
    
  1. Log in to MySQL as iexperiment.
  2. Create a database named iexperiment.
  3. Load the database by sourcing the initial_setup.sql file.
> pushd /var/local/iexperiment/ddl
/var/local/iexperiment/ddl ~
> ls -lt
total 136
-rw-rw-r-- 1 root root   917 Jul 17 21:22 initial_setup.sql
-rw-rw-r-- 1 root root  3465 Jul 17 21:08 insert_permissions_START-UP.sql
-rw-rw-r-- 1 root root   944 Jul 17 21:08 insert_admin_START-UP.sql
-rw-rw-r-- 1 root root 22612 Jul 14 17:33 create_tables.sql
-rw-rw-r-- 1 root root 73893 Jul 14 17:09 insert_record_categories.sql
-rw-rw-r-- 1 root root 18355 Jul 14 17:09 create_constraints.sql
-rw-rw-r-- 1 root root   932 Jul 14 17:08 insert_admin.sql

> mysql -h localhost -u iexperiment -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.1.52 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show grants;
+-----------------------------------------------------------------------------------------------------------------------------+
| Grants for iexperiment@localhost                                                                                            |
+-----------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'iexperiment'@'localhost' IDENTIFIED BY PASSWORD '*BAA33824FACE624B5B0AAC8A604733A5648A7A6B' |
+-----------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> create database iexperiment;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| iexperiment        |
| mysql              |
+--------------------+
3 rows in set (0.00 sec)

mysql> use iexperiment;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> source initial_setup.sql;

Query OK, 1 row affected (0.00 sec)
.
.
.
Query OK, 1 row affected (0.00 sec)

mysql> show tables;
+------------------------+
| Tables_in_iexperiment  |
+------------------------+
| admin_group_member     |
| ...
| version                |
+------------------------+
55 rows in set (0.00 sec)

mysql> select * from version;
+-------------+----------------------------------+
| version_num | comment                          |
+-------------+----------------------------------+
|           6 | May 25, 2010 - Switch to Records |
+-------------+----------------------------------+
1 row in set (0.00 sec)

mysql> exit
Bye
  

Create SSL Certificate

iExperiment runs under the secure HTTPS protocol; thus, we need a Secure Sockets Layer (SSL) certificate. If you already have a wildcard certificate for your domain, then you can skip this step.

Note, that if you use a self-signing certificate, then your iExperiment users will be notified of this. In FireFox they will see a “This Connection is Untrusted” page, in which they will need to open the “I understand the Risks” link and click on the “Add Exception…” button.

  1. Make a directory for the SSL certificate.
  2. Generate the self-signing SSL certificate. In the snippet below, the certificate’s file name, temp.iexperiment.bin, reflects the URL we are using.
> sudo mkdir /usr/etc/cert
> cd /usr/etc/cert

> sudo keytool -genkey -alias tomcat -keypass sslcert1 -keystore temp.iexperiment.bin -storepass sslcert1
What is your first and last name?
[Unknown]:  Marc Whitlow
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]:  Colabrativ, Inc.
What is the name of your City or Locality?
[Unknown]:  El Sobrante
What is the name of your State or Province?
[Unknown]:  California
What is the two-letter country code for this unit?
[Unknown]:  US
Is CN=Marc Whitlow, OU=Unknown, O="Colabrativ, Inc.", L=El Sobrante, ST=California, C=US correct?
[no]:  y

> ls -l
total 4
-rw-r--r-- 1 root root 1292 Jul 18 02:30 temp.iexperiment.bin
    

Write down the certificate “keypass” as you will need it to set up Tomcat.

Setup Apache & Tomcat

  1. Install Apache Hypertext Transfer Protocol Server (httpd), Apache Tomcat 6 (tomcat6), Tomcat’s web application service (tomcat6-webapps) and Apache Interface to OpenSSL (mod_ssl) from Amazon’s Yum repository.
  2. Start the Apache (httpd) and Tomcat (tomcat6) services.
> sudo yum install httpd
Is this ok [y/N]: y

> sudo yum install tomcat6
Is this ok [y/N]: y

> sudo yum install tomcat6-webapps
Is this ok [y/N]: y

> sudo yum install mod_ssl
Is this ok [y/N]: y

> sudo service httpd start
Starting httpd:                                            [  OK  ]
> sudo service tomcat6 start
Starting tomcat6:                                          [  OK  ]
    

Now we can check to see if the “Amazon Linux AMI Test Page” loads in a Browser using:

  • EC2 Instance’s public URL that is found in the EC2 Instance information on the AWS Management Console, e.g. http://ec2-204-236-137-138.us-west-1.compute.amazonaws.com
  • The URL that was assigned to the Elastic IP address associated with the EC2 Instance in the Domain Name Server (DNS), e.g. http://temp.iexperiment.net/

Next, we will configure Tomcat to support applications and services under the secure https protocol on port 8443. We do this by editing the server.xml file in /etc/tomcat.

> cd /etc/tomcat6
> sudo cp -p server.xml server.xml.orig
> sudo vi server.xml
> diff server.xml.orig server.xml
83,88c83,92
<     
<
---
>
>                     protocol="HTTP/1.1"
>                SSLEnabled="true"
>                maxThreads="150"
>                scheme="https" secure="true"
>                clientAuth="false" sslProtocol="TLS"
>                keystoreFile="/usr/etc/cert/temp.iexperiment.bin"
>                keystorePass="sslcert1" />

> sudo service tomcat6 restart
Stopping tomcat6:                                          [  OK  ]
Starting tomcat6:                                          [  OK  ]
    

We should now beable to see the sample web applications supplied with the tomcat6-webapps Yum distribution found in /var/lib/tomcat6/webapps/sample, using the following URLs:

  • “EC2 Public URL”:8080/sample e.g. http://ec2-204-236-137-138.us-west-1.compute.amazonaws.com:8080/sample
  • http://”iExperiment Domain”:8080/sample, e.g. http://temp.iexperiment.net:8080/sample
  • https://”iExperiment Domain”:8443/sample, e.g. https://temp.iexperiment.net:8443/sample

Adding index.html

Upload the iExperiment index.html page and any images associated with the page to the /var/www/html directory. You can either overwrite the existing index.html page or rename it.

iExperiment Applications Installation

iExperiment has three applications: Admin, Record and ResetPassword.

  1. Upload the iExperiment applications .war files (admin.war, record.war and resetPassword.war) to the /var/lib/tomcat6/webapps/ directory in the EC2 server.
  2. Stop the Tomcat service.
  3. Create directories for the attachments and the Lucene search engine index.
  4. For each of the iExperiment applications.
    1. Create a directory for the application in /var/lib/tomcat6/webapps/
    2. Change the group to tomcat.
    3. li>Unzip the contents of the war file into the newly created directory.

    4. Upload and replace the “application”.html file with deployment specific version.
    5. Add deployment specific images to the images directory.
    6. Upload and replace existing iexperiment.properties, dbpool.properties and log4j.properties with files specific for this deployment.
  5. Start the Tomcat service.
> sudo service tomcat6 stop
Stopping tomcat6:                                          [  OK  ]

> sudo mkdir /var/local/iexperiment/attachments
> sudo mkdir /var/local/iexperiment/lucene
> sudo chown -R tomcat:tomcat /var/local/iexperiment/*

> cd /var/lib/tomcat6/webapps/
> ls -lt
total 12
drwxrwxr-x 5 root tomcat 4096 Jul 14 14:53 sample
drwxrwxr-x 5 root tomcat 4096 Jul 14 14:53 examples
drwxrwxr-x 3 root tomcat 4096 Jul 14 14:53 ROOT

> sudo mkdir record
> sudo mkdir admin
> sudo mkdir resetPassword
> sudo chgrp tomcat *

# Begein of admin application configuration.
> pushd admin
> sudo unzip ../admin.war

# After uploading Admin.html
> sudo chown -R root:root *.html

# After uploading deployment specific images to the images diectory.
> pushd images
> sudo chown -R root:root *
> popd

# After uploading the deployment specific properties files
# to the WEB-INF/classes directory
> pushd WEB-INF/classes/
> sudo chown -R root:root *.properties
> ls -lt
total 28
-rw-rw-r-- 1 root root 1287 Jul 14 18:33 log4j.properties
-rw-rw-r-- 1 root root 2020 Jul 14 18:33 iexperiment.properties
-rw-rw-r-- 1 root root 1514 Jul 14 18:33 dbpool.properties
drwxr-xr-x 3 root root 4096 Jul 14 17:49 net
drwxr-xr-x 3 root root 4096 Jul 14 17:49 org
drwxr-xr-x 4 root root 4096 Jul 14 17:49 com
-rw-r--r-- 1 root root 1370 May  3 19:05 mail.properties

# End of admin application configuration.
# Repeat for the record and resetPassword applications. 

> sudo service tomcat6 start
Starting tomcat6:                                          [  OK  ]
    

Removing Port 8443 from HTTPS Requests

The final task in setting up the iExperiment Server is to remove the port number from the secure https requests. We do this by relay the port 443 TCP connections to port 8443 using iptables in the Netfilter package that already installed on the EC2 instance.

  1. Using iptables redirect the incoming port 443 request to port 8443.
  2. Using iptables redirect the output from the incoming port 443 request to port 8443.
  3. We can see these rules in the “nat” table using the command “sudo iptables -t nat -L”.
  4. Save the iptable in /etc/iptables.conf, and change ownership to root.
  5. Finally, add “/sbin/iptables-restore < /etc/iptables.conf” to the bottom to /etc/rc.local file.
> sudo iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443
> sudo iptables -t nat -I OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 8443

> sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere            tcp dpt:https redir ports 8443

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere            tcp dpt:https redir ports 8443

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

> sudo iptables-save > iptables.conf
> more iptables.conf
# Generated by iptables-save v1.4.7 on Thu Sep  8 03:32:23 2011
*nat
:PREROUTING ACCEPT [5:300]
:OUTPUT ACCEPT [50:3801]
:POSTROUTING ACCEPT [50:3801]
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443
-A OUTPUT -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443
COMMIT
# Completed on Thu Sep  8 03:32:23 2011

> sudo cp -p iptables.conf /etc/.
> sudo chown -R root:root /etc/iptables.conf
> sudo ls -l /etc/iptables.conf
-rw-rw-r-- 1 root root 332 Sep  8 03:32 /etc/iptables.conf

> sudo vi /etc/rc.local
> more /etc/rc.local
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local
/sbin/iptables-restore < /etc/iptables.conf
    

Closing Remarks

iExperiment run on a typical AWS Apache Tomcat deployment.

Resources

  1. “Configuring MySQL to use the EBS volume” section of Eric Hammond’s article on Running MySQL on Amazon EC2 with EBS (Elastic Block Store).
  2. Installing Apache Tomcat on Linux by Werner Puschitz.
  3. How Do I Save Iptables Rules or Settings? by Vivek Gite.
This entry was posted in Technical and tagged , , , , . Bookmark the permalink.

Comments are closed.