Sunday 30 November 2014

Cloudbusters - A Website

Cloudbusters - Building a Web/DB app

We've pretty much finished our first submission, describing our design, and public and private clouds.

Now i'm going to attempt to build a web service so we can see if we can enhance our project a bit, and maybe help with the security bit.

So first - i'm building up a mysql server. 

I've deployed 2 ubuntu instances into AWS, a web and a db servers.


on the db server:

sudo apt-get update
sudo apt-get install mysql-server

I have to set the password on this

Installs mysql

Install a new db now:
sudo mysql_install_db

Now to secure it:

sudo mysql_secure_installation

It asks me to reset the password for the root db user id - well - i just had to set it in the db bit so i'm going to say no.

It asks me if i want to remove the anonymous open user id. in the name of a securer world, i hit the Y button!

I'll only allow root logon locally as well. cant be having people logging onto my db server with root!

I'll get rid of the open test db as well. thanks.

Reload privilege tables to set those changes in motion. Y of course.

done and done.

btw - i'm taking a bit of this info from this blog:

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-remote-database-to-optimize-site-performance-with-mysql

Next step: Allow remote access to the db. we need this of course because we want the web server to be able to access our db server, and multiple web servers, if we go that way (watch this space)

sudo vi /etc/mysql/my.cnf

scroll down to the [mysqld] section

we need to change bind_address from 127.0.0.1 (the local server) to a public ip address. However, we dont want to leave our server unsecured, so we want to put in the ip address in the vpc (so its effectively on the private network). for me its xxx.xxx.xxx.xxx.

Save it, quit out of vi, and restart the mysql service:

sudo service mysql restart.

Now we need to set a db up for wordpress (which is going to be the cms that i'm using)

connect to mysql using root

mysql -u root -p

>mysql  ... I'm in

Create a database for us:

CREATE DATABASE Wordpress;

Now - we want to create a db admin user - for local operations - so this is a user that can only run stuff from the local server (see the @'localhost' bit)

xxx is the password

CREATE USER 'admin'@'localhost' IDENTIFIED BY 'xxxxxxxxxx';

Granting the access to the Wordpress db:

GRANT ALL PRIVILEGES ON Wordpress.* TO 'admin'@'localhost';

ok - now we just need to setup a user for other servers to access. initially i'm going to just setup a single user so i can get wordpress configured. this user is to connect from my web server. So:

CREATE USER 'user'@'xxx.xxx.xxx.xxx' IDENTIFIED BY 'xxxxxxxxxx';

(thats a user that can only connect from that ip address)

So - we're granting a pile of permissions - we'll come back later after the installation of wordpress to clean this up - but lets grant them for the moment:

GRANT ALL PRIVILEGES ON Wordpress.* TO 'user'@'xxx.xxx.xxx.xxx';

we'll come back later to:

GRANT SELECT,DELETE,INSERT,UPDATE ON Wordpress.* TO 'user'@'xxx.xxx.xxx.xxx';

Commit them using:

FLUSH PRIVILEGES;

exit the mysql prompt

exit

Done for the moment. Now to the web server.

Install the mysql client

sudo apt-get install mysql-client

test the connection:

mysql -u -h xxx.xxx.xxx.xxx user -p 

where xxx.xxx is the ip address of the db server

nuts. doesnt work. thats because the port is blocked. Need to setup a security group for mysql to allow port 3306. Done.


now it works.

now need to install nginx (a web server) and some other packages:

sudo apt-get install nginx php5-fpm php5-mysql

now configure php:

sudo vi /etc/php5/fpm/php.ini

uncomment the line cgi.fix_pathinfo=1 and change the 1 to a 0

Thats a security measure to make sure that users can only look for the file that they are asking for - if its not found it just returns an error (as opposed to looking for other files)

now we need to set how php and nginx communciate:

sudo vi /etc/php5/fpm/pool.d/www.conf

Make sure the listen directive is set as follows:

listen = /var/run/php5-fpm.sock

exit and restart php:

sudo service php5-fpm restart

Time to configure nginx. We're copying the default website to a different one that we can modify:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/cloudbusters.info

(why cloudbusters.info - well - i'll talk about that in a while)

now open that file:

sudo vi /etc/nginx/sites-available/cloudbusters.info

ensure its listening on your specific port (port 80 for us). make sure the listen directive is there

We're also changing the root to our new file:

server {
        listen 80;
        root /var/www/cloudbusters.info
        index index.php index.html index.htm;

now we need to just set our server_names (to be cloudbusters.info) and make try_files is set, and our error pages. This is what we're changing the file to:


server {
    listen 80;
    root /var/www/cloudbusters.info;
    index index.php index.hmtl index.htm;
    server_name example.com;
    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/www;
    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}


now we link to our enabled directory and remove the link to the default file:

sudo rm /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/cloudbusters.info /etc/nginx/sites-enabled

and restart nginx:

sudo service nginx restart

Now we're installing wordpress:

cd ~
wget http://wordpress.org/latest.tar.gz

unpack it 

tar xzvf latest.tar.gz

copy the sample config file to be the 'prod' one:

cp ~/wordpress/wp-config-sample.php ~/wordpress/wp-config.php

then edit it

sudo vi ~/wordpress/wp-config.php

stick in the database user id and password etc:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'Wordpress');

/** MySQL database username */
define('DB_USER', 'user');

/** MySQL database password */
define('DB_PASSWORD', 'xxxxxxxx');

/** MySQL hostname */
define('DB_HOST', 'xxx.xxx.xxx.xxx');


close the file.

now we just need to set the server block for our website:

sudo mkdir -p /var/www/cloudbusters.info

now copy all the wordpress files over:

sudo cp -r ~/wordpress/* /var/www/cloudbusters.info

now we just need to modify permissions and ownership of our files:

cd /var/www/cloudbusters.info

give all the files access to the web server user (www-data):

sudo chown -R www-data:www-data *

we also need to make sure the normal user other than root can do stuff:

sudo usermod -a -G www-data USERID
sudo chmod -R g+rw /var/www/cloudbusters.info

now just head to the public ip of your site:

wait - need to open port 80 on there - update the security groups

nope - its no good - i cant get port 80 working no matter what - even from localhost. stupid. 

I'm going to continue for the moment and come back to that. i've set the port as 8080, set a security group and set cloudbusters.info to listen on port 8080. which works.

so - connecting to my public ip for my webserver on port 8080 brings me in to the config page on wordpress (so the db connection works)

I put in a user id and password and hit continue - Wordpress gave me errors. Create command denied to 'user'@'ip-xx-xx-xx-xx.eu-west-1.compute.internal' for table 'wp_users']

what? i set up the user id with the ip address - but aws is logging on with the domain that it has set for that computer. hmmm.

Doesnt matter - i need to change my user anyway - because the plans are to let any number of web servers access - so i'm going to have to give user@* access.

the command is:

CREATE USER 'user'@'%' IDENTIFIED BY 'xxxxxxxxxx';

i'm not granting it yet. i'm going to remove my original user and setup a new one with the domain set by aws, because i dont want my environment to be unsecured. (i still need the grant all bit)

so i'm removing my original user and setting up a new one with the AWS Domain.

Done - and wordpress installed with no issue.

And i've logged on now. So thats good.

back to the db to remove the access.

First of all - i'm removing that wordpress user and setting up the % generic one. so thats DROP USER.

Then i'm setting up the % one so that any host can access - and i'm only letting the permissions that i specified earlier in the blog:

GRANT SELECT,DELETE,INSERT,UPDATE ON Wordpress.* TO 'user'@'%';

So i've done good. Pretty crap having a site and referring to it by its ip address though. 

The good thing is - i've bought cloudbusters.info. so now i'm setting my dns entry.

Done (on godaddy)

So now my website is http://cloudbusters.info:8080

Need to figure out how to sort out that port 80.

Anyway. Whats next. What do i need to do next. I need to clone that web server and see does the site work from each webserver is what i need to do.

Into EC2 in AWS, right click and images - create image. 

Give it a description and bang, its an image.

Now i'm deploying an Instance of my image (effectively a copy of that 1st web server) as an instance in AWS.

I'm just going to see if i can access the wordpress site from the new instance.

YESS!!!!! it works!!!!!

of course it works!!! we have an app which demonstrates precisely what Cloud is all about. I can now hold a single point of information in my db, and expand that instance over and over. 

The things i have yet to sort out though are:

1. i need a load balancer. (haproxy will probably be the one)
2. i need a monitoring system (it will be nagios i'd say)
3. i need a way to stimulate cpu performance.
4. of course - i need to get that image to azure to deploy there.

phew - a couple more things to do alright - but considering the progress today into a website where we can truly demonstrate the power of the cloud, as well as giving us something to work with on the security part of our project, is quite exciting.

Thats all from me for today. 

Richie




No comments:

Post a Comment