Reduce EC2 Root Volume Size

0. Tested to work on Ubuntu 14.04
1. Stop source instance
2. Snapshot source instance root volume
3. Create a clone volumn from the snapshot from #2, name it INSTANCEKEY-origin
4. Launch a new instance with a volumn of the desired smaller size (don’t delete volumn on instance termination)
5. Terminate the new instance (all we need is the volume)
6. Name the volume from the new instance INSTANCEKEY-target
7. Attach INSTANCEKEY-origin volume to the source instance, as /dev/sdg
8. Attach INSTANCEKEY-target volume to the source instance, as /dev/sdf
9. Start source instance again
10. Run following:

mkfs -t ext4 /dev/xvdf1
mkdir /mnt/origin
mkdir /mnt/target
mount /dev/xvdg /mnt/origin
mount /dev/xvdf1 /mnt/target
rsync -aHAXxSP /mnt/origin/ /mnt/target

11. Check LABEL (all 3 should be the same) via

blkid

12. From the result of blkid, remember UUID of /dev/sda1 and /dev/sdf, replace UUID from /dev/sda1’s to /dev/sdf’s

vim /mnt/target/boot/grub/grub.cfg
:%s/FROM/TO/g

13. Poweroff the source instance
14. Detach all volumes
15. Attach the target volume to the source instance, with Device set to /dev/sda1
16. Start the source instance again, should be working with the new volume
17. Delete the snapeshot created from #2
18. Delete the original volume of the source instance, and the volume created from step 3 (i.e. the origin volume)
19. Update your snapshot backup script with the new volume id

Reference:

http://cloudacademy.com/blog/amazon-ebs-shink-volume/
http://serverfault.com/questions/673048/how-to-reduce-aws-ebs-root-volume-size

Single site Varnish

This settings only work for single site per server because nginx would otherwise get confused about which site to serve.

# /etc/default/varnish
# ...
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"
# ...
# /etc/varnish/default.vcl
# ...
backend default {
    .host = "localhost";
    .port = "8080";
}
# ...
# /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 50M;

    server_name_in_redirect on;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_disable "msie6";

    server {
        listen 8080;
        root /mnt/projects/the_sands;
        index index.php;

        location / {
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass backend;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include /etc/nginx/fastcgi_params;
        }
    }

    upstream backend {
        server unix:/var/run/php5-fpm.sock;
    }
}

Symfony 2 Nginx Config

server {
    root /PATH/TO/PROJECT/web; # make sure you point it at the "web" subfolder
    server_name SERVER_NAME;

    index app.php;
    try_files $uri $uri/ /app.php?$query_string;

    location ~ ^/(app_dev|app)\.php(/|$) {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

Passing custom server headers to php running under Nginx

Nginx doesn’t seem to pass any additional custom header to $_SERVER variable. To make this happen you need to:

1. First the custom http header sending out (from your REST client) need to use dash instead of underscore, for example “HTTP-X-REST-USERNAME”.

2. On the server side, in your fastcgi_params file (/etc/nginx/fastcgi_params) add this:

fastcgi_param   HTTP_X_REST_USERNAME    $http_x_rest_username;

3. Restart server you will see $_SERVER[‘HTTP_X_REST_USERNAME’] inside php land.

Nginx VHost for WordPress

server {
        listen 80;
        index index.php;

        root /mnt/projects/wordpress;
        server_name wordpress.server.local;

        location / {
                try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
        }

        location = /(favicon.ico|robots.txt)$ {
                log_not_found off;
                access_log off;
        }

        location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
        }
}

Nginx VHost

The example is for YiiFramework project

server {
        listen 80;
        index index.php;

        root /mnt/projects/yiihaw;
        server_name yiihaw.server.local;

        location / {
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
        }

        location = /(favicon.ico|robots.txt)$ {
                log_not_found off;
                access_log off;
        }       

        location ~ /((protected|framework|nbproject)|\.) {
                deny all;
                access_log off;
                log_not_found off;
        }
}

Find file created or modified within certain time range

# ctime search in created at time
# mtime search in modified at time
# -1 in this example is 1 day
find . -type f -ctime -1 -exec ls -al {} \;
find . -type f -mtime -1 -exec ls -al {} \;
# this line search in between time
# this example search all file changed on 1st of Oct 2010
find . -type f -newermt 2010-10-01 ! -newermt 2010-10-02

Running bash script at background

# append & will run the script into background
./myscript &
# jobs will list background jobs
jobs
[1]+  Running ./myscript &
# fg [job number] will bring the job to foreground
fg 1
# Ctrl + z on a running script will suspend the job
# hit Ctrl + z
[1]+  Stopped ./myscript &
# To resume the job into background again
bg 1
# To completely terminate the job
# first back it to fg
fg 1
# then Ctrl + c

Tighten up security

A list of things you can do to improve your (ubuntu) server security.

Install mod_evasive and mod_security

apt-get install libapache2-mod-evasive libapache-mod-security
mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

Tweak php.ini (/etc/php5/apache2/php.ini)

# append those to disable_functions
# system,show_source,symlink,exec,dl,shell_exec,passthru,phpinfo,escapeshellarg,escapeshellcmd

allow_url_fopen = Off

open_basedir = /home/www-data/

Install curl so you can still grab remote files after fopen turned off

apt-get install curl php5-curl

Install fail2ban

apt-get install fail2ban

Let unattended upgrades

apt-get install unattended-upgrades
dpkg-reconfigure unattended-upgrades