What is web server

What is web server ?

You must be wondering what the heck is web server and why we require it

It is really simple!!¬† ūüôā

For example you want to buy some fruits, groceries and shirt from one place. What comes first to your mind ? Yes you are correct Supermarket.

Web server is just like a supermarket!!  

In above example let’s replace ‚Äúyou‚ÄĚ with browser and what you to buy with requests like below


As explained in above example supermarket job is to only provide space , security, maintenance(like cleaning, map of location to get what you want). It is not the job of supermarket to make clothes, fruits or electronic equipment’s. This complex job is done by producer of the companies like Apple, Samsung will make phones. Same like that web server is not responsible for complex operations or to perform business logic, it is the job of programming languages ( like PHP, JAVA, PYTHON, PERL , C and C++) to do the business logic. Web Server only requires static data in the form of HTML, CSS, images or files.

Technical definition:

“Web server are programs that enables a computer to present web pages on internet.”


“Server which actually servers the web pages that you see in any web browser”

Apache Server Alias

How to set Apache web server Alias?

While setting up the apache webserver, we have to deal with various scenarios. So here we are going discusses ServerAlias. Before going ahead, we assume that you have done with Apache Installation and setting up the Virtual Hosting

So What is the ServerAlias?

ServerAlias is alternate names for a host, when we enter the hostname in browser webserver is get identified with ServerName but there are situations when we want have another address our webserver with another name also or you want to nick name your webserver, so this nick name is called as ServerAlias.

To elaborate more, consider our webserver has hostname as example.com

                ServerName example.com

So when we enter example.com in browser then webserver servers the page, but if you want to have webserver name identified by another name like we use ServerAlias.

                ServerAlias www.example.com

This setting can be done in VirtualHost configuration

<VirtualHost *:80>
                ServerName example.com
                ServerAlias www.example.com

Start nicknaming you web server ūüôā

Please feel free to ask the questions in comment box !!!


Apache Mod_Rewrite

This article we will demonstrates how to activate and manage URL rewrites using Apache mod_rewrite module.

Mod_Rewrite Topics

  1. What is mod_rewrite ?
  2. Advantages of  mod_rewrite
  3. mod_rewrite internal processing
  4. Examples of mod_rewrite
    1. URL redirect from www.example.com to example.com
    2. Redirect both http and https from www to non-www
    3. Redirect both http and https from non-www to www
    4. Enforcing both www. and https
    5. Redirect based on domain name
    6. Protect images from being hotlinked

What is mod_rewrite ?

mod_rewrite is an Apache module used for manipulation of requested URLs, It will rewrite requested URLs on the fly. It checks the incoming URLs with a set/series of rules. The rules contain a regular expression ( based on a PCRE regular-expression parser) to match a particular pattern of URL. If the URL pattern is matches and the proper conditions are met, then that pattern is replaced with a provided substitution string or action. This process continues until there are no more rules left or we can stop the process explicitly if one of the rule and conditions matches with flag L ([L] or [last] stop rewriting process).

Before we deep dive into mod_rewrite let’s first understand What is URL?

What is URL?

Uniform Resource Locator (URL). It is the address of a resource on the Internet. A URL indicates the location of a resource as well as the protocol used to access it.


Note: %{ NAME_OF_VARIABLE } these are all server-variables which hold the above values like %{REQUEST_METHOD} will have one of value of http method  (POST or GET or PUT or DELETE)

A URL contains the following information:

  1. The protocol used to a access the resource (By Default it is 80 or 443 for Secure communication )
  2. The the location of the server (whether by IP address or domain name)
  3. The port number on the server (optional)
  4. The location of the resource in the directory structure of the server
  5. The Query String (Optional)

Some examples of URLS:

  1. http://example.com/user.php?id=12 (Not friendly URL)
  2. http://example.com/user.php?id=12&prd_id=101 (Not friendly + multiple args )
  3. http://example.com/user/12 (Friendly URL/slug)
  4. http://example.com/technology#apache (Internal Link)
  5. http://example.com:8080/user.php?id=12 (Different Port)

Advantages of mod_rewrite:

  • Provides a flexible and powerful way to manipulate URLs using an unlimited number of rules.
  • It is most commonly used to transform ugly URLs into what are known as ‚Äúfriendly URLs‚ÄĚ or ‚ÄúClean URLs” or “SEO friendly URLs” or often called as “Slug“. E.g You must have seen stackoverflow.com or wordpress URLs
  • It is easy to enforce SSL or https URL
  • Widely used for redirecting URLs based on some conditions and set of rules

mod_rewrite Internal Processing/Flow Chart:

Mod_Rewrite is combination of following things

  1. Rewrite rules / Ruleset
  2. Rewrite conditions (optional)
  3. Substitutes the URL with a new value ( URL Substitution Could be optional if we want to send any warning ( like 403 Forbidden status code to the client ) using Flag substitution instead of URL substitution ) + Flags substitution (optional)

Common flags:

[R] or [redirect] – force a redirect (defaults to a 302 temporary redirect)
[R=301] or [redirect=301] – force a 301 permanent redirect
[L] or [last] – stop rewriting process (see note below in common pitfalls)
[NC] or [nocase] – specify that matching should be case insensitive

The rewriting engine processes the Rewrite rules from Top to Bottom order. The rewriting engine loops through the Rewrite rules and when a particular rule matches it optionally loops through existing corresponding Rewrite conditions.

Mod rewrite internal processing is like below, also refer the above mod rewrite diagram while we explain it

  1. User enters a particular URL through browser and it comes to Apache web server
  2. If a rule/pattern matches then Go to Step 3, otherwise Go to Step 5
  3. It checks for conditions (It could be set of conditions or we can say Multiple Conditions), if conditions are present then it loops through it. If all conditions are true then Go to Step 4 otherwise Go to Step 5 as we fails to match the conditions. If there is no single condition present then Go to Step 4
  4. Make substitution (Substitution:  New URL+ FLAG(Optional))  (Go to Step 5). We can also go to Step 6 which is exit using Flag L ([L] or [last] stop rewriting
  5. Check next rule. If next rule is present then Go to Step 2 otherwise Go to Step 6
  6. Exit

IMP Note: When we substitute new URL and that URL is “internal” then again it goes goes through above processing.


1) Redirect www.example.com to example.com

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]

Follwing way is more generic without hardcoding the domain name:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

2) Enforcing both http and https to redirect from www to non-www (both: http + https)

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

3) Enforcing both http and https to redirect from non-www to www (both: http + https)

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

4) Enforcing both www. and https

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

5) Redirect based on domain name

Real life example of mod_rewrite module that I recently worked on, Here scenario is company which I worked is buying a lot of small and medium scale companies where our task was to redirect all (bought) sites URL request to the main site of company.

Ans: We have created a single redirect server where all the bought companies sites started pointing (Changed the DNS A record pointing of all sites to public IP xxx.xxx.xxx.xxx).

Suppose my main site is maincompany.com and main company bought example1.com and example2.com sites. On main site we have created a particularpage for example1.com and example2.com. Here we had to check the domain name and redirect it according to specific page

for example:
if user hits http://example1.com then user should be redirected to https://www.maincompany.com/example1

if user hits http://example2.com then user should be redirected to https://www.maincompany.com/example2

RewriteEngine on

#redirect example1.com
RewriteCond %{HTTP_HOST} example1\.com
RewriteRule .* https://www.maincompany.com/example1 [R=301,L]

#redirect example2.com
RewriteCond %{HTTP_HOST} example2\.com
RewriteRule .* https://www.maincompany.com/example2 [R=301,L]

6. Protect site being hotlinked

Usually one site will include a link of some media file (let’s say css, javascript, image or video) that is hosted on another site, the Content Host. In this scenario, the Content Host‚Äôs servers are wasting bandwidth serving content to some other website.

The most common approach for preventing hotlinking is to whitelist a specified number of websites and block everything else. To determine who is requesting the content from your site, you can check the referrer.

# Give Hotlinkers a 403 Forbidden warning.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)example.com/.*$ [NC]
RewriteRule \.(gif|jpg|jpeg|bmp|zip|rar|mp3|flv|swf|xml|png|css|pdf)$ - [F,NC]

Serve alternate content:
You can also serve the alternate content when you detect hotlinking. This is commonly done with images suggesting that your not happy with this activity

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)example.com/.*$ [NC]
RewriteRule \.(gif|jpg|jpeg|bmp|zip|rar|mp3|flv|swf|xml|png|css|pdf)$ http://www.example.com/angryman.gif [R,L]

How to setup ADFS authentication to Apache webserver URLs using mod_auth_mellon

This document will explain how to setup the single sign on ADFS authentication to Apache webserver directory, meaning when user wants to access particular location on your webserver he/she will be asked for authentication to LDAP directory.

Before we start below are some definitions:

  • ADFS:¬† Active Directory Federation Services is component to provide users with single sign-on access to systems and applications located across organizational boundaries.
  • SAML:¬† Security Assertion Markup Language as its name implies, SAML is an XML-based markup language for security assertions in simple words the method to communicate between Active Directory and Apache Webserver.
  • Mellon:¬† Mellon is nothing but the apache webserver from we are redirecting for authentication.
  • IDP:¬† Identity Service provider it is ADFS server used for authentication.

Here we assume that you have active and running apache webserver with SSL Certificate [Learn how to configure SSL on Apache].


  1. We need to protect directory location ‚Äú/restricted/location‚ÄĚ with user validation to LDAP

When user will try to access the URL for this location then he/she will be asked for valid username and password.

2. Sample URL:


URL parts

Required Packages: mod_auth_mellon

How ADFS authentication works:

So to simplify the process please consider below architecture diagram:

How ADFS authentication works

Installation and configuration process:

  • Install mod_auth_mellon from the regular centos repository.
[root@www ~]# yum -y install mod_auth_mellon
  • Create directory to store metadata XML files:
[root@www ~]# mkdir -p /etc/httpd/mellon
  • Once installation is complete, generate the MetaDATA script
    Metadata script requires two parameters:

1. Unique identifier these can be set anything, in our example we are setting with the combination of URN and domain ‚Äúurn:example:example.com‚ÄĚ

2. The URL we want to protect, with apended /endpoint to the URL [no need to create /endpoint directory]


[root@www ~]# /usr/libexec/mod_auth_mellon/mellon_create_metadata.sh urn:example:example.com "https://example.com/restricted/location/endpoint/"
  • After runing above command it will generate 3 files:
[root@www ~]# ls /etc/httpd/mellon
  • Copy all files to /etc/httpd/mellon directory
  • Share ‚Äú.xml‚ÄĚ file to ADFS server and ask your ADFS admin to import it.
  • Most Important step is to copy ADFS metadata and store it to local directory [/etc/httpd/mellon]

So, download or copy it from your ADFS server, for this post we have used:

wget https://adfs.example.in/federationmetadata/2007-06/FederationMetadata.xml -O /etc/httpd/mellon/FederationMetadata.xml
  • Create Mellon config file [apache configuration] and copy below content,¬†if you want to learn how to create separate .htaccess file follow instructions here
MellonEnable info
MellonEnable "auth"
AuthType "Mellon"
Require valid-user
MellonVariable "cookie"
MellonEndpointPath       /restricted/location/endpoint
MellonSPMetadataFile     /etc/httpd/mellon/urn_example_example.com.xml
MellonSPPrivateKeyFile   /etc/httpd/mellon/urn_example_example.com.key
MellonSPCertFile         /etc/httpd/mellon/urn_example_example.com.cert
MellonIdPMetadataFile    /etc/httpd/mellon/FederationMetadata.xml
  • Now Create file /var/www/html/example.com/restricted/location/index.html [change document root as per your apache config]
<head><title>Authorized zone</title></head>

<h1>Welcome to the authorized zone.</h1>

You should only be able to see this if you are authenticated.
  • Restart apache to load newly created configuration
     [root@www ~]# service httpd restart

And try to access the URL and See the magic!!!

Apache Security and hardening

This article we will demonstrates how to secure your most widely-used web server Apache.

Apache Security and hardening


  1. A server running CentOS v. 7 with Apache installed
  2. For testing we need Firefox browser with the Firebug add-on installed / Chrome develper tool (Press F12)

1. Information Leakage/Banner grabbing:

This technique is often called as Banner grabbing technique and it is used to gain information about a server and the services running on its open ports. An intruder/hacker can use this banner grabbing technique to reveal a lot of sensitive information about the services running on the target machine.

Attaker uses most common used services to grab the banner are Hyper Text Transfer Protocol (HTTP) which runs on port 80, Simple Mail Transfer Protocol (SMTP) which runs on port 25 and File Transfer Protocol (FTP) which runs on port 21.

In default Apache web server configuration you have much sensitive information disclosures, which can be used to prepare for an attack.

It’s one of the most critical tasks of an administrator to hide this sensitive information and secure the web server.

Hide the Apache version:
Lets see from where hacker can grab this information:
Using Firefox:
Step 1. Visit your web server in Firefox.
Step 2. Activate Firebug by clicking the Firebug icon on the top right side.


If you check the HTTP response headers in Firebug, it will show you Apache version along with your OS name and version, as shown in this screenshot.

Using Telnet:

[root@web ~]# telnet example1.com 80
Connected to example1.com.
Escape character is '^]'.
HEAD http://www.example1.com/ HTTP/1.0

HTTP/1.1 200 OK
Date: Mon, 25 Jun 2018 14:08:14 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16
Last-Modified: Thu, 10 May 2018 15:23:09 GMT
ETag: "7a-56bdb98d4538e"
Accept-Ranges: bytes
Content-Length: 122
Connection: close
Content-Type: text/html; charset=UTF-8

Connection closed by foreign host.

To hide this information from browsers or any other tool, we need to make some changes in Apache’s main configuration file http.conf.

sudo vim /etc/httpd/conf/httpd.conf

Add the following line at the end of file:

ServerSignature Off
ServerTokens Prod

Save the file and restart the Apache service to reflect these changes.

sudo /bin/systemctl restart httpd.service

Now to verify lets open Firefox (firebug)/chrome (web developer tool) with F12 and access your Apache web server.

  1. ServerSignature removed the version information from the page generated by Apache web server.
  2. ServerTokens has changed Header to production only, i.e. Apache


2. Turn off directory listing

In absence of an index file (index.html or index.htm) Directory listing is enabled by default in Apache. Directory listing shows all the files and directories from the Apache web root directory. If this option is enabled, then an attacker can easily grab any file, analyze it, and obtain sensitive information about an application of your Apache server.

Let’s see how it looks like in default settings:

[root@web]# cd /var/www/html/
[root@web html]# mkdir {src, public, config}
[root@web html]# touch test.html test.php

Note: if you have not removed the /etc/httpd/conf.d/welcome.conf file then it will not show you directory listing as above. On absence of index.html file it will show you Apache welcome page.

To turn off this directory listing you can use the¬†“Options”¬†directive in the Apache configuration file for a specific web directory.

sudo vim /etc/httpd/conf/httpd.conf

Find the section that starts with¬†Directory /var/www/html¬†and add “-Indexes” in the “Options”¬†directive.

<Directory /var/www/html/>
Options -Indexes
AllowOverride None
Require all granted

Save the file, check for the syntax and restart Apache service to reflect these changes.

[root@web httpd]# httpd -t
Syntax OK
[root@web httpd]# /bin/systemctl restart httpd.service

Lets verify the changes by visiting website in a browser. You will get a “Forbidden” error as shown in the image below.


3. Disable unwanted modules

The Best practice is to configure Apache with required modules in your web applications, but by default Apache comes with lots of unwanted installed modules.

Use following command to list all enabled modules on your Apache server:

[root@vdevpril595plp httpd]# httpd -M
Loaded Modules:
core_module (static)
so_module (static)
http_module (static)
access_compat_module (shared)
actions_module (shared)
alias_module (shared)
allowmethods_module (shared)
auth_basic_module (shared)
auth_digest_module (shared)
authn_anon_module (shared)
authn_core_module (shared)
authn_dbd_module (shared)
authn_dbm_module (shared)
authn_file_module (shared)
authn_socache_module (shared)
authz_core_module (shared)
authz_dbd_module (shared)
authz_dbm_module (shared)
authz_groupfile_module (shared)
authz_host_module (shared)
authz_owner_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cache_module (shared)
cache_disk_module (shared)
data_module (shared)
dbd_module (shared)
deflate_module (shared)
dir_module (shared)
dumpio_module (shared)
echo_module (shared)
env_module (shared)
expires_module (shared)
ext_filter_module (shared)
filter_module (shared)
headers_module (shared)
include_module (shared)
info_module (shared)
log_config_module (shared)
logio_module (shared)
mime_magic_module (shared)
mime_module (shared)
negotiation_module (shared)
remoteip_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
slotmem_plain_module (shared)
slotmem_shm_module (shared)
socache_dbm_module (shared)
socache_memcache_module (shared)
socache_shmcb_module (shared)
status_module (shared)
substitute_module (shared)
suexec_module (shared)
unique_id_module (shared)
unixd_module (shared)
userdir_module (shared)
version_module (shared)
vhost_alias_module (shared)
dav_module (shared)
dav_fs_module (shared)
dav_lock_module (shared)
lua_module (shared)
mpm_prefork_module (shared)
proxy_module (shared)
lbmethod_bybusyness_module (shared)
lbmethod_byrequests_module (shared)
lbmethod_bytraffic_module (shared)
lbmethod_heartbeat_module (shared)
proxy_ajp_module (shared)
proxy_balancer_module (shared)
proxy_connect_module (shared)
proxy_express_module (shared)
proxy_fcgi_module (shared)
proxy_fdpass_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_scgi_module (shared)
proxy_wstunnel_module (shared)
ssl_module (shared)
systemd_module (shared)
cgi_module (shared)
fcgid_module (shared)
php5_module (shared)

From Apache 2.4 version “CentOS/RedHat”¬†has decided to introduce “conf.modules.d”¬†directory.¬† Modules under “conf.modules.d”¬†will ensure the correct load ordering. For Apache 2.2 please refer httpd.conf files for enabled modules

[root@web httpd]# ls -l /etc/httpd/conf.modules.d/
total 40
-rw-r--r-- 1 root root 3739 Jun 18 14:08 00-base.conf
-rw-r--r-- 1 root root 139 Apr 11 01:57 00-dav.conf
-rw-r--r-- 1 root root 41 Apr 11 01:57 00-lua.conf
-rw-r--r-- 1 root root 742 Apr 11 01:57 00-mpm.conf
-rw-r--r-- 1 root root 957 Apr 11 01:57 00-proxy.conf
-rw-r--r-- 1 root root 41 Apr 11 01:57 00-ssl.conf
-rw-r--r-- 1 root root 88 Apr 11 01:57 00-systemd.conf
-rw-r--r-- 1 root root 451 Apr 11 01:57 01-cgi.conf
-rw-r--r-- 1 root root 45 Jun 10 2014 10-fcgid.conf
-rw-r--r-- 1 root root 216 Jun 24 2015 10-php.conf

Some of the by default enabled modules like¬†mod_info,¬†mod_userdir and mod_autoindex¬†are not required. These modules are present in “00-base.conf” file.

mod_info: This module can leak sensitive information using .htaccess once this module is loaded. To see what kind of sensitive information it can leak , then put following content in httpd.conf

<Location "/server-info">
SetHandler server-info

Save the file and restart Apache service to reflect the above changes.

[root@web httpd]# /bin/systemctl restart httpd.service

Lets put “http://your_domain.com/server-info” in your browser


To disable this modules edit the /etc/httpd/conf.modules.d/00-base.conf file

sudo vim /etc/httpd/conf.modules.d/00-base.conf

Insert a # at the beginning of the following lines to disable the modules:

#LoadModule info_module modules/mod_info.so
#LoadModule info_module modules/mod_info.so
#LoadModule userdir_module modules/mod_userdir.so

Save the file and restart Apache service to reflect above changes.

[root@web httpd]# /bin/systemctl restart httpd.service

WebDAV¬†(Web-based Distributed Authoring and Versioning): This module allows remote clients to manipulate files on the server and subject to various Denial-of-Service¬†(DoS) attacks. To disable this module remove the¬†00-dav.conf file or rename it as¬†00-dav.conf.bk or¬†comment all the lines by putting “#”in the beginning of¬†00-dav.conf file as below

#LoadModule dav_module modules/mod_dav.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_lock_module modules/mod_dav_lock.so


4. Clickjacking Attack

Clickjacking is well-known web application vulnerabilities.¬†¬†Clickjacking¬†is a way to ‚Äútrick‚ÄĚ users into clicking on something malicious (could lead you to unwanted site or post/delete the contents) without even knowing what’s happening.

Make sure mod_headers.so is enabled in /etc/httpd/conf.modules.d/00-base.conf (For Apache 2.2 refer /etc/httpd/conf/httpd.conf file)
Add the following directive at the end of /etc/httpd/conf/httpd.conf and save the file

<IfModule mod_headers.c>
Header set X-Frame-Options DENY

Save the file and restart Apache service to reflect above changes.

[root@web httpd]# /bin/systemctl restart httpd.service

This X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe> or <object> . By ensuring that your site content is not embedded into other sites.

There are three possible directives for X-Frame-Options:

  1. X-Frame-Options: DENY  (Check facebook.com Response header)
  2. X-Frame-Options: SAMEORIGIN (Check google.com Response header)
  3. X-Frame-Options: ALLOW-FROM https://example.com/

5. X-XSS Protection

XSS is also known as Cross-site scripting. It is basically a way to inject source code (normally in the form of Javascript) that will perform actions in the victim user’s browser on behalf of a website. Sometimes this is seen by the victim user and sometimes it can go totally unnoticed in the background.

The x-xss-protection header is designed to enable the cross-site scripting (XSS) filter built into modern web browsers. This is usually enabled by default, but it can be bypassed in many browsers

Enabling X-XSS Protection Header in Apache:
The¬†x-xss-protection¬†header can be explicitly switched off from browser, causes the XSS to succeed, so it is recommended to implement/add¬†x-xss-protection¬†header on web server, so that site can enforce the browser to use “x-xss-protection” on their side and it only requires a slight¬†web server configuration changes.

This is used by a majority of giant web companies like Twitter, Google and Facebook etc.

Make sure mod_headers.so is enabled in /etc/httpd/conf.modules.d/00-base.conf (For Apache 2.2 refer /etc/httpd/conf/httpd.conf file)
Add the following directive at the end of /etc/httpd/conf/httpd.conf and save the file

<IfModule mod_headers.c>
Header set X-XSS-Protection "1; mode=block"

Save the file and restart Apache service to reflect above changes.

[root@web httpd]# /bin/systemctl restart httpd.service

There are four possible directives for x-xss-protection:

  1. X-XSS-Protection: 0  => Disables XSS filtering
  2. X-XSS-Protection: 1  => Enables XSS filtering (usually default in browsers). If a cross-site scripting attack is detected, the browser will sanitize the page (remove the unsafe parts).
  3. X-XSS-Protection: 1; mode=block => Enables XSS filtering. Rather than sanitizing the page, the browser will prevent rendering of the page if an attack is detected.
  4. X-XSS-Protection: 1; report=<reporting-uri>: Enables XSS filtering. If a cross-site scripting attack is detected, the browser will sanitize the page and report the violation.

The downside of X-XSS-Protection:
This header X-XSS-Protection has a support only in Internet Explorer and Chrome (which will probably cover a lot of your users), there is no guarantee this will continue.

A lot of it’s protection is likely to be replaced by¬†CSP (Content-Security-Policy) header which has much better cross browser support.

6. Content-Security-Policy

The HTTP¬†Content-Security-Policy¬†response header will guard against cross-site scripting attacks (XSS). CSP Version 3 is the current version of the standard but it is on it’s way be implemented by all browser. Currently¬†CSP Version 2 is supported by all modern browser. It works only when the web server sends a special header to the web browser identifying that the server implements a content security policy.¬† Browser then dictates from¬†Content-Security-Policy header where the it should load things like style-sheets, java script files, images and fonts. The web browser uses this information while loading the HTML code for the site and then fail to load any files that aren’t allowed by this policy.

Enabling Content-Security-Policy Protection Header in Apache:

Add the following directive at the end of /etc/httpd/conf/httpd.conf and save the file

<IfModule mod_headers.c> 
Header set Content-Secure-Policy "default-src 'self';"

Above set-up is the simplest one that you can have and informs the browser that the only content it should be allowing for your site is content that is loaded from your own domain.

Content-Secure-Policy directives: 

The Content-Secure-Policy header can be broken down to a number of directives starting with the directive type and then providing the sources for use with the directive. Following are the directives which can be used while designing Content-Secure-Policy for your site.

Directives :

  1. “default-src” :¬†This directive acts as a fallback for the below mentioned CSP¬†fetch directives. For each of the below directives that are absent in Content-Secure-Policy header, the browser will look for the “default-src” directive and will use this value for it, that means “default-src” directive applies to all forms of content such as images, CSS, Javascript, AJAX requests, Frame contents, fonts and media content
  2. “script-src”:¬†Sources for java-script files
  3. “style-src”: Sources for style-sheets
  4. “img-src”: Sources of images
  5. “media-src”: Sources for <audio> and <video>
  6. “frame-src”: Sources for frames
  7. “connect-src”: Sources for XMLHttpRequest, WebSocket and EventSource
  8. “font-src”: Sources for fonts
  9. “object-src”: Sources for <object>, <embed> and <applet>

Directive Values
All above directives that end with -src support below values

  • * => Wildcard character Allows everything
  • ‚Äėself‚Äô => Allows loading resources from the same origin (same scheme, host and port).
  • ‚Äėnone‚Äô => It prevents loading the resources from any other source.
  • data: => It allows loading the resources via the data scheme (example: Base64 encoded images).
  • domain.example.com => It allows loading resources from the specified domain.
  • *.example.com => It allows loading resources from any sub-domain under example.com
  • https://my.example.com => It allows loading of resources only over HTTPS matching the given domain.
  • https: => It allows loading resources only over HTTPS on any domain.
  • ‚Äėunsafe-inline‚Äô => It allows use of inline¬†resources,¬† such as inline¬†<script>¬†elements and inline¬†<style>¬†elements in web page.
  • ‚Äėunsafe-eval‚Äô =>¬†It allows the use of¬†eval()¬†and similar methods for creating code from strings.

Complex setup: 

Let’s imagine a more complex example of a blog that may require following access

  1. Images access:  Across the internet
  2. Java-script access: From it’s own domain, jquery access from Google’s CDN and Google analytics
  3. CSS (style-sheet) access:  Only uses it’s own CSS.

This could be handled with a header similar to the below:

<IfModule mod_headers.c>
Header set Content-Secure-Policy "default-src 'none'; script-src 'self' www.google-analytics.com ajax.googleapis.com; img-src *; style-src 'self';"

Lets understand above rule step by step:

  1. default-src ‘none’:¬† In this directives the browser would block all external files that aren‚Äôt explicitly defined later in the Content-Secure-Policy header
  2. “script-src”¬†directive: This directive tells the browser to allow java-script content to be loaded from own domain,¬†www.google-analytics.com and ajax.googleapis.com
  3. “img-src directive: It¬† uses an asterisk (*) as its source definition that means you have allowed to¬† integrate the images in your blog from any other site
  4. style-src ‘self’: Allow CSS (style-sheet) access from own domain not from any other domain

Points to remember:

  • Multiple values can be space separated as shown in above example (script-src ‘self’¬†www.google-analytics.com)
  • * and ‘none’ cannot be used with any other values
  • ‘self’, ‘none’, ‘unsafe-inline’ and ‘unsafe-eval’ needs to be put inside single quotes
  • Content security policies can also be applied through HTML <meta> tag like below
<meta http-equiv="Content-Security-Policy" content="default-src https:">

Content-Secure-Policy Browser compatibility:
Content Security Policy


7. HTTP request methods

By default Apache supports all the HTTP method (OPTIONS, GET, HEAD, POST, CONNECT, PUT, DELETE, and TRACE)  in HTTP 1.1 protocol. Some of them are not required and may pose a potential security risk. It is a best practice to enable only required methods, For example enable web applications require only HEAD, POST, and GET method

You can do this by editing the httpd.conf file:

vim /etc/httpd/conf/httpd.conf

Find the section that begins with Directory /var/www/html or virtual host directory. Add the following lines under that section:

<LimitExcept GET POST HEAD>
deny from all

Save the file and restart Apache:

[root@web httpd]# /bin/systemctl restart httpd.service

8. Protect cookies with HTTPOnly flag

To mitigate most of the common Cross Site Scripting attack you can use HttpOnly and Secure flag in a cookie. Without HttpOnly and Secure flag, it is possible to steal or manipulate web application session and cookies and it is dangerous.

httpOnly is a HTTP Cookie option used to inform the browser not to allow scripting languages (JavaScript, VBScript, etc.) access to the “document.cookie” object (normal XSS attack target). Any attempt to access the cookie from client script is strictly forbidden.

To work above things we presumes you have:

  • A modern web browser
  • A browser that actually implements HttpOnly correctly

The good news is that most modern browsers do support the HttpOnly flag

Add the following directive at the end of /etc/httpd/conf/httpd.conf and save the file

<IfModule mod_headers.c>
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure

Save the file and restart Apache:

[root@web httpd]# /bin/systemctl restart httpd.service

Note: Make sure with development team that they are not using “document.cookie” in Java-script

Apache logging

How to configure apache logging ?

Every web server has important data hosted on it, the way visitors access, download the data can be monitored. All this monitoring gives the server administrator to be prepared for dangerous events that may happen, Logs are the records of the events that have occurred on your web server.in simple words logs are the eyes of server administrator ūüôā

Logs help use to analyze:

  1. Traffic or number of visitors to our server
  2. Number of different IP address visited the website or web server
  3. Error occurred while access webpage
  4. Times when website is more accessed

Of course, storing the information in the logs is only the start of log management. The next step is to analyze this information to produce useful statistics data.

There are two types of logs for apache:

1. Access log:

The server access log records all requests processed by the server, Contains information about requests coming in to the web server. This information can include what pages people are viewing, the success status of requests, and how long the request took to respond.

2. Error Log:

This is the most important log file, contains information about errors that the web server encountered when processing requests, such as when files are missing,

Error log is the first place to look when a problem occurs while starting the web server or with the operation of the server, since it will often contain details of what went wrong and how to fix it.

Logging methods:

1. Server Side:

It is the generic logging which will contain all errors and access information of all virtual hosts.

This kind of logging may become tedious job for administrator to find exact error from all virtual host. To make administration simpler and cleaner we use second logging method.

2. Virtual Host logging:

Specifying log files to each virtual host in known as virtual host logging, this method enables clean and separate log files.

You can specify your desired filename for error or access log, we are going to use this method in our example.


Now let’s start configuring our web server:

When we open default config file of apache and search for LogFormat Directive we can see different log formats as below:

/etc/httpd/conf/httpd.conf       for Ubuntu    /etc/apache2/apache2.conf

combined” and “common” are¬†name assigned to the format. Apache calls these “nicknames“.

LogFormat "%h %l %u %t\"%r\" %>s %b\"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t\"%r\" %>s %b" common

LogFormat” command defines a custom format for logs.

We can call using the “CustomLog” directive as we saw in the virtual host definition, this directive uses the following syntax:

CustomLog log_location log_format

now we will use CustomLog in our virtual host file [ how to set virtual host config ]:

<virtualhost *:80>
  ServerName www.example.com              #specify your own server name   
  DocumentRoot /var/html/www/             #specify your own document root
  ErrorLog     /var/www/example.com/logs/error.log
  CustomLog    /var/www/example.com/logs/access.log combined #nickname

Above configuration will create the error log file at:


and access log file at:


below will be the content of access log file : - frank [15/Oct/2018:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

Each part of this log entry is described below. (%h) :

This is the IP address of the client (remote host) which made the request to the server.
If a proxy server exists between the user and the server, this address will be the address of the proxy, rather than the originating machine.

–¬†(%l) :

The “hyphen” in the output indicates that the requested piece of information is not available. In this case, the information that is not available is the RFC 1413 identity of the client determined by¬†identd¬†on the clients machine. This information is highly unreliable and should almost never be used except on tightly controlled internal networks.

frank (%u) :

This is the userid of the person requesting the document as determined by HTTP authentication.

[15/Oct/2018:13:55:36 -0700] (%t) :

The time that the server finished processing the request. The format is:
[day/month/year:hour:minute:second zone]
day   = 2*digit
month = 3*letter
year  = 4*digit
hour  = 2*digit
minute= 2*digit
second= 2*digit
zone¬† = (`+’ | `-‘) 4*digit
It is possible to have the time displayed in another format by specifying %{format}t in the log format string.

“GET /apache_pb.gif HTTP/1.0″¬†(\”%r\”)

The request line from the client is given in double quotes. The request line contains a great deal of useful information.

First, the method used by the client is GET.

Second, the client requested the resource /apache_pb.gif,

Third, the client used the protocol HTTP/1.0.

It is also possible to log one or more parts of the request line independently. For example, the format string “%m %U%q %H” will log the method, path, query-string, and protocol, resulting in exactly the same output as “%r”.

200 (%>s)

This is the status code that the server sends back to the client. This information is very valuable, because it reveals whether the request resulted in a

successful response (codes beginning in 2),

a redirection (codes beginning in 3),

an error caused by the client (codes beginning in 4),

or an error in the server (codes beginning in 5).

2326 (%b)

The last entry indicates the size of the object returned to the client, not including the response headers.

So go ahead and log all activities of your sever to keep watch on users

Enjoy monitored administration….

Please feel free to ask the questions in comment box !!!