Apache Secure Default Configuration

The content of httpd.conf should have the following entries:

User apache
Group apache

ServerTokens Prod
ServerSignature Off

TraceEnable off
Timeout 45

FileETag None

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header always append X-Frame-Options SAMEORIGIN
Header set X-XSS-Protection “1; mode=block”
Header set Cache-Control “max-age=290304000, public”

SetOutputFilter DEFLATE

SetEnvIfNoCase Request_URI \.(?:rar|zip)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:gif|jpg|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:avi|mov|mp4)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary

<Directory />
Options None
Order Deny,Allow
Deny from all
AllowOverride None

<Directory /opt/apache/htdocs>
Options -Indexes -ExecCGI -FollowSymLinks -Includes
Order allow,deny
Allow from all

RewriteEngine On
RewriteCond %{THE_REQUEST} !HTTP/1.1$
RewriteRule .* – [F]

<Files ~ “^\.ht”>
Order allow,deny
Deny from all
Satisfy All


The content of ssl.conf should have the following entries:

SSLProtocol –SSLv2 -SSLv3


nginx Secure Default Configuration (with php-fpm)

# A virtual host using mix of IP-, name-, and port-based configuration

server {
listen 443 ssl http2;
server_name http://www.website.com;
ssl on;
ssl_certificate /etc/nginx/conf.d/ssl/www.website.com.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/www.website.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/conf.d/ssl/dhparams.pem;

ssl_session_cache shared:SSL:5m;
ssl_session_timeout 1h;
add_header Strict-Transport-Security “max-age=15768000; includeSubDomains: always;”;

server_tokens off;
add_header X-Frame-Options “SAMEORIGIN” always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection “1; mode=block” always;
add_header Content-Security-Policy “default-src ‘self’; script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’ https://www.gstatic.com https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net https://ajax.googleapis.com https://www.google.com; img-src ‘self’ https://www.google.com https://www.facebook.com https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src ‘self’ ‘unsafe-inline’ https://fonts.googleapis.com https://assets.zendesk.com; font-src ‘self’ https://fonts.gstatic.com https://themes.googleusercontent.com; child-src https://www.google.com https://staticxx.facebook.com https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com https://tautt.zendesk.com; object-src ‘none'” always;

# auth_basic “Restricted”;
# auth_basic_user_file /etc/nginx/conf.d/passwd;

root /var/www/html;
index index.php index.html index.htm;

location / {
try_files $uri $uri/ /index.php?$query_string;

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

location ~/\.ht {
deny all;


server {
listen 80;
server_name http://www.website.com;
return 301 https://$host$request_uri;

How to Clear CloudFlare’s Cache

Run this command to clear all of CloudFlare’s cache:

curl -X DELETE “https://api.cloudflare.com/client/v4/zones/yourzoneid/purge_cache” -H “X-Auth-Email: your@email.com” -H “X-Auth-Key: yourglobalapikey” -H “Content-Type: application/json” –data ‘{“purge_everything”:true}’

yourzoneid is your CloudFlare’s zone ID
your@email.com is the email address used to login to CloudFlare
yourglobalapikey is your CloudFlare’s Global API key

You should see the response similar to this:

{ “success”: true, “errors”: [], “messages”: [], “result”: { “id”: “123d56a89f123e5678901b34567890a2” } }

If you want to clear certain file only from the cache, just run the following command:

curl -X DELETE “https://api.cloudflare.com/client/v4/zones/yourzoneid/purge_cache” -H “X-Auth-Email: your@email.com” -H “X-Auth-Key: yourglobalapikey” -H “Content-Type: application/json” –data ‘{“files”:[“http://www.yourwebsite.com/somedirectory/filename.ext“],”tags”:[“some-tag“,”another-tag“]}’

To find out your CloudFlare’s Zone ID, please see my previous post here.

How to Find CloudFlare Zone ID

Currently you can’t find your CloudFlare Zone ID from the CloudFlare control panel. Run the curl command below to get your Zone ID and other details as well. Just change your@email.com with the email address used to login to CloudFlare. Also change yourglobalapikey with your CloudFlare’s Global API Key. You can get it from https://www.cloudflare.com/a/account/my-account.

curl -X GET “https://api.cloudflare.com/client/v4/zones&#8221; -H “X-Auth-Email: your@email.com” -H “X-Auth-Key: your-global-api-key” -H “Content-Type: application/json”

You will see the output similar to this:


Your CloudFlare Zone ID is the one displayed after id (in this example: 123d56a89f123e5678901b34567890a2).

Estimating Web Hosting Needs

To have a website on the Internet, the most basic needs you require are disk space and bandwidth.

Disk space is the amount of data you can store on the web server. Obviously, the amount of space needed depends on the size of your website. Most websites are composed of HTML (text), images, Flash, or a combination of all.

Text is very economical, it occupies very little space. Images and flash are more expensive, as they require more disk space.

Ideally, your web page should stay under 50-60KB, including images and flash. This is because there are some people using slow dial-up connections of under 56Kbps. For these people, a 60KB page will take more than 8 seconds to load. 8 seconds seems like a small number, but imagine you have to sit there and stare at a blank white page for 8 seconds. That’s a lot of time. Use the slow dial-up connection as your reference. If your website loads fast using slow dial-up, it will be even faster for broadband, high-speed connection.

If your average page size is 50KB, you can put approximately 20 pages on 1Mb of space. If you have 100MB of disk space, you can host 200 pages.

Bandwidth is the amount of data you are allowed to transfer to and from your web server per month. This includes all uploads and downloads, both HTTP and FTP. Bandwidth depends on your web page size, as well as the number of visitors to your website and the number of pages they visit.

For an average page size of 50KB, 20,000 visitors per month, and 5 pages per visitor your website will need about 5000MB, or 5GB, of bandwidth per month. Note that 20,000 visitors per month equates to approximately 667 visitors per day. This is a number even most large websites cannot achieve.

If you are just launching your website, chances are you will not need a huge amount of space, nor a huge amount of bandwidth. Unless you have reasons to believe, and evidentiary numbers to support, that your website will have lots of visitors and/or you are offering movie and music downloads, there is little reason for many of us to worry about space and bandwidth. However, in choosing a web host, choose one that allows you to upgrade your disk space and bandwidth if you should need it later on.

You can use the following formula if you need to do a load test, you can determine the number of concurrent users to test if you know daily visits to your site (you may want to use Google Analytics report to find visits per hour):

Concurrent_users = (peak hourly_visits * visit_duration in seconds) / 3600


Adding Swap from Instance Store (Amazon Linux)

Below is the procedure to add a swap from instance-store volumes to Amazon Linux instance.
In this example the instance-store device is /dev/xvdb. Feel free to change it according to your instance-store device.

a. Ensure the Instance includes instance-store volumes or add one instance-store volume to your instance during launch time.

b. SSH into the instance and query for the instance-store:
# df -ah | grep ephemeral
The above command should return output like the following (note this may be different based on your AMI and you have to manually test to see which device is mounted as ephemeral storage):
/dev/xvdb 37G 177M 35G 1% /media/ephemeral0

c. Unmount the mounted instance-store:
# umount /media/ephemeral0

d. Create swap partition:
# mkswap /dev/xvdb

e. Comment out the line for /media/ephemeral0 within /etc/fstab:
#/dev/sdb /media/ephemeral0 auto defaults,nofail,comment=cloudconfig 0 2

f. Activate the swap space:
# swapon /dev/xvdb

g. Check that the swap space is active:
# cat /proc/meminfo | grep Swap
The above command should return output like the following:
SwapCached: 0 kB
SwapTotal: 39313404 kB
SwapFree: 39313404 kB

Should you stop start the instance to move underlying hosts, you will need to re-do the above procedure in order to ensure that you have instance-store configured as swap. You can bypass this by creating a script to prepare swap space so that if the instance is shutdown and then moved to a different underlying host, a pristine instance-store will be converted to swap space again. Adding it inside /etc/fstab will not work as the volume will not be prepared for swap when an instance is stopped and started. Invoking the script within /etc/rc.local would be ideal to perform this. For example:

cat << EOF >> /etc/rc.d/rc.local

# Create swap space – /dev/xvdb
if file /dev/xvdb | grep -q block; then
umount /dev/xvdb;
mkswap /dev/xvdb;
swapon -a /dev/xvdb;