My Guide to a perfect server

In this guide I will show you how to setup the perfect server using CentOS 6.5

  • Secure SSH setup
  • Firewall with APF
  • OpenVPN setup
  • Webserver with NginX + PHP-FPM
  • Ghost Blog setup

Step 1

Securing SSH

The problem with running SSH on the default port is that you will get a million bots trying to bruteforce your login you could mitigate this by using fail2ban but i find it easyer to just change the default port. This can be done by changing the default port
open up /etc/ssh/sshd_config with your favriot text editor and uncomment the Port section and change the number to something else i usually go with something over 20000. After you change this restart the ssh service using service sshd restart and then open up a new terminal and try to connect to the server on the new port. You will find many tutorials saying to deny root login but I like to be root so i dont usually do this you can secure your config further by installing two factor authentication. I use duo security sign up for a new account there and follow there guide on how to secure ssh with there two factor solution great thing with duo security is that you can specify whitelisted networks witch will come into play later on in the tutorial

Step 2


Most sofware firewalls are some implementation of IPTables like UFW and APF. I personally use APF as its more customizeable than other solutions i have tried
ensure you have iptables installed by using yum install iptables next i will show you how to configure APF
Get the package for installation:

tar xvf apf-current.tar.gz
cd apf-9*

start the install with:


this will display what default ports it will be using and what interface it will be using
now comes the configuration of the firewall. open /etc/apf/conf.apf in your editor and edit the following lines:

line 20: DEVEL_MODE="1"
change to DEVEL_MODE="0"

make sure lines 28 and 29 reflect your public interface

line 111: RAB="0"
change to RAB="1"

line 125: RAB_PSCAN_LEVEL="1"
change to RAB_PSCAN_LEVEL="2"

line 344 change this line to reflect your ssh port

if you dont use FTP change this
line 346: HELPER_FTP="1"
change to HELPER_FTP="0"

lines 361 365 these lines are important!! ports you define in here will be open
it has one line for ports using tcp and one line for ports using udp
add your ssh port to the IG_TCP_CPORTS line

lines 438 to 467 active these rules by changing 0 to 1
these are rules from blacklist databases and known dodgy ip's

Ok config complete! you can add custom iptable rules in the /etc/apf/preroute.rules and postroute.rules files I will come back to these files later in the tutorial

start apf with:

apf -s

when you edit your conf.apf file active the new rules with:

apf -r 

this will restart the firewall

you can examin your iptables database by using:

iptables -L > iptables.txt

Remember when making rules that could affect remote access to your box leave your terminal open and test the new settings in a new terminal!!


OpenVPN setup

Setting up a VPN can be very helpful in so many ways you can tunnel all your webtraffic through the server to secure webtraffic leaving your computer. But in this setup we are going to be using it to access resoruces on the server

Start by installing the repo where openvpn can be found

rpm -Uvh rpmforge-release*

then install openvpn and openssl

yum install openvpn openssl openssl-devel -y

now copy the ssl key building folder to /etc/openvpn

cd /etc/openvpn

Next we can configure some keys

cd /etc/openvpn/easy-rsa-master/easyrsa2

Then we will create the PKI with

./easyrsa init-pki

Build the Certificate authority cert by using

./easyrsa build-ca

Be sure to use a strong passphrase to protect the CA private key. Note that you must supply this passphrase in the future when performing signing operations with your CA, so be sure to remember it.
Then it will ask for the Common name use your servers hostname

Now we can generate keys for the server:

./easyrsa build-server-full server

This will ask you for the passphrase for the CA

Then sign the cert that's done
Build Diffie Hellman (wait a moment until the process finish)

./easyrsa gen-dh

Now we can make keys for the client (yourself)

./easyrsa build-client-full client

you will need to find a way to export these to your computer

Now we can make the server configuration. Create the config file:

touch /etc/openvpn/server.conf

Open the file and enter:

	port 1194 #- you can use whatever port you like 1194 is the default
	proto udp #- this is the protocol you will be using
	dev tun
	tun-mtu 1500
	tun-mtu-extra 32
	mssfix 1450
	ca /path/to/ca.crt
	cert /path/to/server.crt
	key /path/to/server.key
	dh /path/to/dh.pem
	cipher AES-256-CBC
	status openvpn-status.log
	verb 3
	tun-mtu 1500
	tun-mtu-extra 32
	mssfix 1450
	keepalive 5 30
	mute 20

ok all seems good now we need to check is selinux is enable as this can cause us problems trying to start services

check /etc/selinux/config to see if SELINUX=enforcing or as we want it SELINUX=disabled if you changed it the next reboot it will be disabled.

Ok now start the openvpn service with

service openvpn start


chkconfig openvpn on

to make sure it starts on boot

Enable ipv4 routing open /etc/sysctl.conf and change

net.ipv4.ip_forward = 0


net.ipv4.ip_forward = 1

Save this with:

sysctl -p

We will now add the tun interface to the trusted interface list on APF
find the line IFACE_TRUSTED="" and change it to IFACE_TRUSTED="tun0" save the changes by restarting APF apf -r

Also be sure to open the VPN port in APF too so you can connect to it

Make the config on your computer and test the connection you should be able to ping the VPN gateway
You can now access services that are blocked by the firewall but not on the VPN good for development

Step 4

NginX with PHP-FPM

We start off by creating the file /etc/yum.repos.d/nginx.repo and paste

name=nginx repo

Now we will install NginX and PHP-FPM with

yum install -y nginx php-fpm

Set NginX and PHP-FPM to run on boot with

chkconfig nginx on
chkconfig php-fpm on

Now we will start the configuration of NginX
Open /etc/nginx/nginx.conf and add the line with in the http block

include /etc/nginx/sites-enabled/*;

Next create the folders for the vhost information to sit in with

mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled

Create a vhost config inside /etc/nginx/sites-available paste and edit

server {
    	access_log /var/log/nginx/;
    	error_log /var/log/nginx/;
    	root /var/www/html/;
 location / {
        index index.html index.htm index.php;
 location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;

We can see that .php files will be handled by PHP-FPM listening on port 9000 ( you dont have to open this port as its only used internally )

To activate this vhost change directory to /etc/nginx/sites-enabled and create a symbolic link with

ln -s /etc/nginx/sites-available/

this is usful so you can disable vhosts but still keep the config

Start NginX and PHP-FPM with

service nginx start
service php-fpm start

Hopfully no errors, now we can test the install by creating test.php inside your document root with

echo -e "<?php\n\tphpinfo()\n?>" > /var/www/html/

Navigate to and it should display the php info page!

Step 5

Setting up Ghost blog

To install the needed dependancies for the ghost blog run these commands

yum install npm nodejs
npm install forever -g

Then we will add a new user for ghost to run under

adduser ghost

then we must deny SSH access for this user do this by editing /etc/ssh/sshd_config and adding the line DenyUsers ghost restart the sshd service for changes to take affect. Now we can setup ghost blog
change to the ghost user by typing su ghost && cd this will switch user to ghost and then change directory to there home folder. Now download ghost with

unzip -d

change to your domain and port number you intend to use (incase you plan to host multiple ghost instances)

Then use

npm install --production

to install all the node modules needed for ghost
next thing to do is edit the config.js file

cp config.example.js config.js

in the production: {} section edit this to suite your requirements you can also add your mailgun details in this section too. This will enable you to invite editors to the ghost blog and also reset passwords etc

mail: {
  transport: 'SMTP',
    options: {
      service: 'Mailgun',
        auth: {
          user: '', // mailgun username
          pass: ''  // mailgun password

when you have editied all this to suite your requirements start the blog by using
NODE_ENV=production forever start index.js

This will start up the blog with the options set in the production: {} section if you wanted to start the blog with the development options replace NODE_ENV=production with NODE_ENV=development also replace the with anything you would like to call the service. When you make changes to a ghost blog like the theme or something you will need to restart it to see those changes do this by restarting the name given with the uid option for example

forever restart

will restart the ghost blog.
Now we will setup a reverse proxy on NginX so you can view it at the correct domain with out using the port number

open up a new .conf file inside /etc/nginx/sites-available folder and paste/edit this

	server {
    	access_log /var/log/nginx/;
    	error_log /var/log/nginx/; 
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;

Restart NginX with service nginx restart and then proceede to setup your ghost blog by going to this will allow you to set up the owner details

Nice server bro!!!