Setting Up a New Amazon EC2 Server (2015-01-25)

Create Amazon EC2 Instance
1. Login to AWS Management Console
2. Select Amazon EC2
3. Click “Instances” from the left menu
4. Click “launch Instance”

Create Elastic IPs
1. Login to AWS Management Console
2. Click “Elastic IPs” from the left menu
3. Click “Allocate New Address”
4. Select “EC2” and click “Yes, Allocate”

Assign Elastic IP to an Instance
1. Right click an IP and select “Associate”
2. Select an instance and click “Yes, Associate”

First Time Connect
1. Download PuttyGen
2. Click “Load” and select the .pem file
3. Click “Save private key”
4. Open putty
5. From the left menu, select Connection > SSH > Auth
6. Click “Browse” and select the ppk file created in step 3
7. Connect to your instance with the username “ec2-user”

Change Password

sudo passwd root

Create user

adduser myhelper
passwd myhelper

Add user to sudoers

chmod 777 /etc/sudoers
vim /etc/sudoers
myhelper  ALL=(ALL)       ALL
chmod 440 /etc/sudoers

Configure sshd

vim /etc/ssh/sshd_config
PasswordAuthentication yes
AllowUsers myhelper
/etc/init.d/sshd restart

Change timezone

ln -sf /usr/share/zoneinfo/Hongkong /etc/localtime
(or use tzselect)

Install Apache, MySQL, PHP, FTP

yum install httpd mod_ssl mysql-server php php-mysql php-common php-gd php-mbstring php-mcrypt php-devel php-xml vsftpd

chkconfig httpd on
chkconfig mysqld on
chkconfig vsftpd on

Create virtual host directory

mkdir -p /var/www/vhosts/myhelper.com/subdomains
mkdir -p /var/www/vhosts/myhelper.com/htdocs
mkdir -p /var/www/vhosts/myhelper.com/logs
chown -R myhelper.myhelper /var/www/vhosts/myhelper.com

Configure Apache

vim /etc/httpd/conf/httpd.conf
NameVirtualHost *:80
Include /etc/httpd/conf/extra/httpd-vhosts.conf
<IfModule prefork.c>
    StartServers      30
    MinSpareServers   30
    MaxSpareServers   45
    ServerLimit     4000
    MaxClients      4000
    MaxRequestsPerChild  4000
</IfModule>

vim /etc/php.ini
upload_max_filesize = 5M
post_max_size = 8M
memory_limit = 256M

mkdir /etc/httpd/conf/extra
vim /etc/httpd/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
   DocumentRoot "/var/www/vhosts/my-helper/htdocs"
   ServerName my-helper.com
    ServerAlias www.my-helper.com
   <Directory "/var/www/vhosts/my-helper/htdocs">
      Options Indexes FollowSymLinks
      AllowOverride All
       Order allow,deny
        Allow from all
  </Directory>
  ErrorLog "/var/www/vhosts/my-helper/logs/error.log"
   #CustomLog "/var/www/vhosts/my-helper/logs/access.log" common
</VirtualHost>

/etc/init.d/httpd restart

Configure Vsftpd

vim /etc/vsftpd/vsftpd.conf
userlist_deny=NO
user_config_dir=/etc/vsftpd/userconfig
chroot_local_user=YES
allow_writeable_chroot=YES
port_enable=YES
pasv_enable=YES
pasv_min_port=21024
pasv_max_port=21048
pasv_address={your public ip address}
vim /etc/vsftpd/user_list
myhelper

mkdir /etc/vsftpd/userconfig
vim /etc/vsftpd/userconfig/myhelper
local_root=/var/www/vhosts/my-helper

/etc/init.d/vsftpd restart

Update sysctl.conf

vim /etc/sysctl.conf
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_max_syn_backlog=8192

sysctl -p

Update Security Group
1. Login to AWS Management Console
2. Click “Security Groups” from the left menu
3. Select your security group
4. Add TCP port 20-21, 80, 21024-21048

AWS Auto Scaling Terms

Load Balancing

Response Timeout:

  • Allow a response timeout period of 5 seconds for the instance to respond
  • If the load balancer fails to connect with the instance at the specified port within the configured response timeout period, the instance is considered unhealthy.
  • Make sure this value is not too low. When the server is under heavy loading, it may takes longer time to response. Low response timeout will cause the instance to be terminated unexpectedly.

HealthCheck Interval:

  • Amount of time between health checks
  • Should be greater than Response Timeout

    Healthy Threshold:

    • Make sure this value is not too high
    • When an instance is registered with Elastic Load Balancing, it will not be considered healthy until the number of successful health checks that define a healthy state are completed
    • If you set a long interval for health checks and/or a high healthy threshold, it will take more time for instances to start receiving traffic from Elastic Load Balancing

    Unhealthy Threshold:

    • Make sure this value is not too low. Otherwise the instance may stopped unexpectedly.

    Example:
    Reponse Timeout: 14 seconds
    Health Check Interval: 15 seconds
    Unhealthy Threshold: 10
    Healthy Threshold: 2

    Reference:
    http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html
    https://aws.amazon.com/articles/1636185810492479

    Auto Scaling

    Health Check Grace Period:

    • The amount of time, in seconds, after an EC2 instance comes into service that Auto Scaling starts checking its health. During this time, any health check failures for the instance are ignored.
    • This parameter is required if you are adding an ELB health check. Frequently, new instances need to warm up, briefly, before they can pass a health check. To provide ample warm-up time, set the health check grace period of the group to match the expected startup period of your application.
    • This is an important consideration that prevents AWS from adding too many servers too quickly
    • Make sure the health check grace period is longer then instance startup time. Otherwise the new instance can be terminated before it finishes startup.

    CPUUtilization:

    • The average CPU usage of all the instances

    Default cooldown period:

    • Apply to any scaling activity that occurs within the Auto Scaling group.

    Scaling-Specific Cooldown:

    • Apply to a specific scaling policy. Override the default cooldown period.
    • Instance usually takes a couple of minutes to launch. During that time, the CloudWatch alarm could continue to fire, resulting in Auto Scaling launch another instance each time the alarm goes off. This is where the cooldown period comes into effect. With a cooldown period in place, Auto Scaling launches an instance and then suspends any scaling activities until a specific amount of time elapses.
    • Scale down policy terminates instances, less time is needed to determine whether to terminate additional instances in the Auto Scaling group. The default cooldown period of 300 seconds is too long—costs can be reduced by applying a scaling-specific cooldown period of 180 seconds.
    • When multiple instances are launched at the same time, the cooldown period (either the default cooldown or the scaling-specific cooldown) take effect starting when the last instance launches.

    Example:
    Health Check Grace Period: 300
    Default cooldown period: 300
    Scale up policy: CPUUtilization >= 50 for 60 seconds, Add 4 instances, 300 seconds cooldown time
    Scale down policy: CPUUtilization <= 10 for 60 seconds, Remove 1 instance, 180 seconds cooldown time

    Reference:
    http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/Cooldown.html
    http://www.cardinalpath.com/autoscaling-your-website-with-amazon-web-services-part-2/

    Automatically assign Elastic IP to ec2 instance

    Step 1. Create an IAM role
    AWS Service: Amazon EC2
    Actions: AssociateAddress, DescribeInstances
    Amazon Resource Name (ARN): *

    Step 2. Create this file on your Linux
    vim /etc/init.d/assign-eip

    export AWS_ACCESS_KEY=(insert key here) 
    export AWS_SECRET_KEY=(insert key here) 
    # get EC2 isntance ID
    
    instanceid=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id` 
    # Associate EIP with the captured instance ID.
    
    ec2-associate-address -i $instanceid--region ap-southeast-1 (insert EIP here)
    

    Step 3. Change file permission

    chmod +x /etc/init.d/assign-eip
    ln -s /etc/init.d/assign-eip /etc/rc.d/
    

    Step 4. Create a symlink to /etc/rc.d/

    ln -s /etc/init.d/assign-eip /etc/rc.d/
    

    References:
    https://www.linkedin.com/groups/Assigning-Elastic-IP-Auto-Scaled-3684105.S.209039689
    http://stackoverflow.com/questions/12973777/how-to-run-a-shell-script-at-startup

    Password Recovery

    1. Create a new instance

    2. Detach the volume from the old instance

    3. Attach the volume to the new instance (/dev/sdf)

    4. Change the passwd of ec2-user on the new instance

    passwd ec2-user

    5. Copy the encrypted password of ec2-user

    cat /etc/shadow

    6. Mount the old instance’s volume

    mkdir /mnt/ebs
    mount /dev/sdf /mnt/ebs

    7. Change the password of the old instance

    chmod 777 /mnt/ebs/etc/shadow
    vim /mnt/ebs/etc/shadow
    chmod 000 /mnt/ebs/etc/shadow

    8. Stop the new instance

    9. Detach the old volume from the new instance and then attach it to the old instance (/dev/sda1)

    10. Terminate the new instance

    Useful Commands

    List out the region names

    ec2-describe-regions

    Display Instance Information

    ec2-describe-instances –region ap-southeast-1 <instance-id>

    Check deleteOnTermination Flag of an Instance

    ec2-describe-instance-attribute –region ap-southeast-1 <instance-id> -b -v

    Turn Off deleteOnTermination Flag

    ec2-modify-instance-attribute –region ap-southeast-1 <instance-id> –block-device-mapping “/dev/sda1=::false”

    Reference: http://docs.amazonwebservices.com/AWSEC2/latest/CommandLineReference/OperationList-cmd.html

    Setting Up a New Amazon EC2 Server

    Create Certificate
    1. Login to http://aws.amazon.com/
    2. Click “Security Credentials”
    3. Click the X.509 Certificates tab
    4. Click “Create a New Certificate”
    5. Download the certificates

    Setup Amazon EC2 API Tools
    1. Download the Amazon EC2 API Tools from http://aws.amazon.com/developertools/351/
    2. Open command prompt and enter the following commands:

    set EC2_HOME=H:\Amazon\ec2-api-tools-1.5.6.0
    set PATH=%PATH%;%EC2_HOME%\bin
    set EC2_PRIVATE_KEY=H:\Amazon\certificate\pk-xxxxxxxxx.pem
    set EC2_CERT=H:\Amazon\certificate\cert-xxxxxxxxx.pem

    Create Amazon EC2 Instance
    1. Login to AWS Management Console (https://console.aws.amazon.com)
    2. Select Amazon EC2
    3. Click “Instances” from the left menu
    4. Click “launch Instance”

    Enable Termination Protection
    1. Login to AWS Management Console
    2. Right click an instance and click “Change Termination Protection”
    3. Click “Yes, Enable”

    Turn Off deleteOnTermination Flag

    ec2-modify-instance-attribute --region ap-southeast-1 <instance-id> --block-device-mapping "/dev/sda1=::false"

    Create Elastic IPs
    1. Login to AWS Management Console
    2. Click “Elastic IPs” from the left menu
    3. Click “Allocate New Address”
    4. Select “EC2” and click “Yes, Allocate”

    Assign Elastic IP to an Instance
    1. Right click an IP and select “Associate”
    2. Select an instance and click “Yes, Associate”

    First Time Connect
    1. Download PuttyGen
    2. Click “Load” and select the .pem file
    3. Click “Save private key”
    4. Open putty
    5. From the left menu, select Connection > SSH > Auth
    6. Click “Browse” and select the ppk file created in step 3
    7. Connect to your instance with the username “ec2-user”

    Change Password

    passwd ec2-user
    sudo passwd root

    Allow putty to connect to server using password instead of using ppk file

    vim /etc/ssh/sshd_config
    PasswordAuthentication yes
    /etc/init.d/sshd restart

    Change timezone

    ln -sf /usr/share/zoneinfo/Hongkong /etc/localtime

    Resize the filesystem

    resize2fs /dev/sda1

    Install Apache, Nginx, MySQL, PHP, FTP

    yum install httpd mod_ssl nginx mysql-server php php-mysql php-common php-gd php-mbstring php-mcrypt php-devel php-xml vsftpd postfix
    
    chkconfig httpd on
    chkconfig nginx on
    chkconfig mysqld on
    chkconfig vsftpd on
    chkconfig postfix on

    Basic Configuration

    adduser myhelper
    
    mkdir -p /var/www/vhosts/myhelper.com/subdomains
    mkdir -p /var/www/vhosts/myhelper.com/htdocs
    mkdir -p /var/www/vhosts/myhelper.com/logs
    chown -R myhelper.myhelper /var/www/vhosts/myhelper.com

    Configure Apache

    vim /etc/httpd/conf/httpd.conf
    Listen 8080
    NameVirtualHost *:8080
    Include /etc/httpd/conf/extra/httpd-vhosts.conf
    <IfModule prefork.c>
     StartServers      30
        MinSpareServers   30
        MaxSpareServers   45
        ServerLimit     4000
        MaxClients      4000
        MaxRequestsPerChild  4000
    </IfModule>
    
    vim /etc/php.ini
    upload_max_filesize = 5M
    post_max_size = 8M
    memory_limit = 256M
    
    mkdir /etc/httpd/conf/extra
    vim /etc/httpd/conf/extra/httpd-vhosts.conf
    <VirtualHost *:8080>
     DocumentRoot "/var/www/vhosts/my-helper/htdocs"
       ServerName my-helper.com
        ServerAlias www.my-helper.com
       <Directory "/var/www/vhosts/my-helper/htdocs">
          Options Indexes FollowSymLinks
          AllowOverride All
           Order allow,deny
            Allow from all
      </Directory>
      ErrorLog "/var/www/vhosts/my-helper/logs/error.log"
       #CustomLog "/var/www/vhosts/my-helper/logs/access.log" common
    </VirtualHost>
    
    /etc/init.d/httpd restart

    Configure Nginx

    vim/etc/nginx/nginx.conf
    worker_processes  4;
    worker_rlimit_nofile 10000;
    events {
      worker_connections  10000;
    }
    
    vim /etc/nginx/conf.d/virtual.conf
    server {
       listen 80;
      server_name www.my-helper.com my-helper.com;
        root    /var/www/vhosts/my-helper.com/htdocs/;
    
      # Static Contents
       location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
            access_log off;
         log_not_found off;
          server_tokens off;
          expires 30d;
        }
    
       # Dydamic Content forward to Apache
     location / {
            proxy_set_header X-Real-IP  $remote_addr;
           proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
       }
    }
    
    /etc/init.d/nginx restart

    Configure Vsftpd

    vim /etc/vsftpd/vsftpd.conf
    userlist_deny=NO
    user_config_dir=/etc/vsftpd/userconfig
    port_enable=YES
    pasv_enable=YES
    pasv_min_port=21024
    pasv_max_port=21048
    pasv_address={your public ip address}
    vim /etc/vsftpd/user_list
    myhelper
    
    mkdir /etc/vsftpd/userconfig
    vim /etc/vsftpd/userconfig/myhelper
    local_root=/var/www/vhosts/my-helper
    
    /etc/init.d/vsftpd restart

    Configure Postfix

    /etc/init.d/sendmail stop
    yum remove sendmail sendmail-cf
    
    vim /etc/postfix/main.cf
    myhostname = my-helper.com
    myorigin = $myhostname
    
    /etc/init.d/postfix start

    Configure sshd

    vim /etc/ssh/sshd_config
    AllowUsers myhelper
    
    /etc/init.d/sshd restart

    Update sysctl.conf

    vim /etc/sysctl.conf
    net.ipv4.tcp_tw_reuse=1
    net.ipv4.tcp_tw_recycle=1
    net.ipv4.tcp_fin_timeout=30
    net.ipv4.tcp_max_syn_backlog=8192
    
    sysctl -p

    Update Security Group
    1. Login to AWS Management Console
    2. Click “Security Groups” from the left menu
    3. Select your security group
    4. Add TCP port 20-21, 80, 21024-21048