Securing Apache HTTP Server

Apache HTTP Server is secure for general use in it’s default configuration. However additional steps can be performed to make it further secure.

Securing Apache HTTP Server involves the following steps.
1) Disabling unnecessary modules
2) Disabling the sending of Version information
3) Disabling directory browsing
4) Setting up Access Control (OPTIONAL)
5) Setting up Authentication and Authorization (OPTIONAL)
6) Enabling SSL support (OPTIONAL)



1) Disabling unnecessary modules
The first step to security is – Do not use things that we do not need.
Apache HTTP Server comes with several modules installed. If we are concerned of security, we must disable all the unnecessary modules. We can disable specific modules at compile time by using the option syntax --disable-MODULE with the configure script. For example to disable the module mod_lua.so, we can use the option --disable-lua with configure script. In this way, that specific module would never be compiled.

If we are not sure about the need for a specific module, what given below should be followed.
Apache HTTP Server loads only a pre-defined set of 21 modules(other than 1 MPM module) at runtime, regardless of how many modules we have compiled. Out if this 21 modules, we can again disable any of them if we need. All we have to do is goto the main configuration file httpd.conf, comment out the line corresponding to the specific module and then reload the apache service.

NOTE:
  The configure option --enable-mods-shared=VALUE accepts the values none, few, most, all, reallyall.
View the option wise comparison of modules.
View the table wise comparison of modules.
  The configure option --with-ldap --with-included-apr forms a single unit. This option enables compiling of modules mod_ldap.so and mod_authnz_ldap.so. If you decide to not have this feature, only remove --with-ldap but not --with-included-apr. Module mod_session_crypto.so and Apache HTTP Server itself needs the option --with-included-apr.
  The configure option --with-crypto --with-openssl --with-included-apr forms a single unit. This option enables the module mod_session_crypto.so. If you decide to not have this feature, just remove the --with-crypto --with-openssl but not --with-included-apr. Modules mod_ldap.so, mod_authnz_ldap.so and Apache HTTP Server itself needs this option.
  The configure option --with-openssl is NOT intended to enable SSL support for Apache HTTP ServerSSL support for Apache HTTP Server comes with the module mod_ssl.so which is compiled by default on all installations unless we explicitly disable it using the option --disable-ssl or --enable-mods-shared=few.
In fact what this option specifies is that, the Crypto Driver to be used with the module mod_session_crypto.so is OpenSSL Cryto Driver.
There are two Crypto drivers provided with Apache HTTP Server.
OpenSSL Cryto Driver (apr_crypto_openssl). Enabled using --with-openssl option.
NSS Crypto Driver (apr_crypto_nss). Enabled using --with-nss option.
Unless we need NSS for a specific purpose, it is always good to go with OpenSSL, considering the Interoperability Matrix given at http://howtolamp.com/lamp/httpd/2.4/openssl-nss-crypto-driver-interoperability-matrix/

 

 

 

 

2) Disabling the sending of Version information
Apache HTTP Server by default sends the following information in HTTP header  – Product name, Product version, Generic Operating System type and information about compiled modules. Automatic revealing of these information increases the visibility to attacks that rely on simple reconnaissance techniques which look for a specific version with security holes to exploit. We can turn this off.
Turning this feature may not make our server any more secure, but it makes less of a target. If someone is determined to get through a server nothing can stop them. It does not mean we have to do them a favor by giving away information.

Open the Apache HTTP Server‘s configuration file that holds the various default values, httpd-default.conf. Look for the line containing ServerTokens Full. Change the value of ServerTokens from Full to Prod. Now the line must look as shown below.

ServerTokens Prod

This will transmit only the product name in HTTP headers, which is Apache.


Restart the apache service gracefully.

# service apache graceful

 

 

 

 

3) Disabling directory browsing
Apache HTTP Server will display a list of available files and sub directories inside a directory, under any of the two conditions.
• When there is no DirectoryIndex (example: index.html) in that directory.
• When URL points to a directory instead of a file.

To turn off this feature, perform the following steps.

Open Apache HTTP Server‘s main configuration file httpd.conf.
Look for the line containing <Directory “/usr/local/apache2/htdocs”>.
Inside this Directory block, look for the line containing Options directive. This directive will have two values Indexes and FollowSymLinks. The directory browsing feature is controlled by value Indexes.
Change Indexes to -Indexes and FollowSymLinks to +FollowSymLinks. Now the line must look as shown below.
NOTE:
• If there is more than one value for Options directive, either all values must start with + or -, or no values must.
• This is per DocumentRoot change. We must perform this step for all DocumentRoots.

Options -Indexes +FollowSymLinks


Restart the apache service gracefully.

# service apache graceful

 

 

 

 

4) Setting up Access Control (OPTIONAL)
Access control refers to any means of controlling access to any resource. Access control features are provided by different modules and deployed by different methods.
NOTE: Traditional method of Access control involved using the directives Allow, Deny, Order and Satisfy provided by the module mod_access_compat.so. But these features are deprecated and will not be used here.

The modules providing Access control features are.
•  core module
•  mod_authz_core.so
•  mod_authz_host.so
•  mod_rewrite.so
•  mod_setenvif.so

• core module
core module enables Apache HTTP Server‘s core features. This module should always be present for Apache HTTP Server to function.
core module also provides the <If> directive that can be used for setting up Access control.
http://httpd.apache.org/docs/2.4/mod/core.html

• mod_authz_core.so
mod_authz_core.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-authz-core. It provides core authorization capabilities so that authenticated users can be allowed or denied access to portions of the web site. It also provides the functionality to register various authorization providers. This allows applying advanced logic in the authorization processing.
The directives provided by this module are AuthMerging, <AuthzProviderAlias>, AuthzSendForbiddenOnFailure, Require, <RequireAll>, <RequireAny> and <RequireNone>.
NOTE: If you are using Require directive, and proxying content to your server, you need to be aware that the client address will be the address of your proxy server, not the hostname of the client, and so using the Require directive in this context may not do what you mean. The module mod_remoteip.so presents a possible solution to this problem.
http://httpd.apache.org/docs/2.4/mod/mod_authz_core.html

• mod_authz_host.so
mod_authz_host.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-authz-host. It provides group authorization based on Hostname or IP Address.
This module provides no directives.
http://httpd.apache.org/docs/2.4/mod/mod_authz_host.html

• mod_rewrite.so
mod_rewrite.so is compiled by default on an Apache HTTP Server installation, unless we explicitly disable it using the configure option --disable-rewrite or --enable-mods-shared=fewmod_rewrite.so uses a rule-based rewriting engine, based on a PCRE regular-expression parser, to rewrite requested URLs on the fly. It provides a flexible and powerful way to manipulate URLs using an unlimited number of rules. Each rule can have an unlimited number of attached rule conditions, to allow us to rewrite URL based on server variables, environment variables, HTTP headers, or time stamps.
The directives provided by this module are RewriteBase, RewriteCond, RewriteEngine, RewriteMap, RewriteOptions and RewriteRule.
NOTE: Read about enabling mod_rewrite.so module.
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html

• mod_setenvif.so
mod_setenvif.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-setenvif. This module allows us to set internal environment variables according to whether different aspects of the request match regular expressions we specify.
The directives provided by this module are BrowserMatch, BrowserMatchNoCase, SetEnvIf, SetEnvIfExpr and SetEnvIfNoCase.
http://httpd.apache.org/docs/2.4/mod/mod_setenvif.html

 

The methods of deploying Access Control are.
♦  Access Control based on Hostname
♦  Access Control based on IP Address
♦  Access Control for localhost
♦  Access control based on time
♦  Access control using variables
♦  Access Control using HTTP methods

NOTE:
• The sample configurations provided below should be placed in the configuration files according to their Context.

• The hostname addresses used in below configurations can be a Partial Domain Name or FQDN.
• The IP addresses used in below configurations can be a full IP address, or a partial IP address, or a network/netmask pair, or a network/nnn CIDR specification; in IPv4 or IPv6 format.

♦ Access Control based on Hostname
This method allows access control for portions of a website based on the hostname address of the visitors.

To deny access to the hostname mysite.example.com while allowing all others, add the below content to configuration file.

<RequireAll>
Require all granted
Require not host mysite.example.com
</RequireAll>


To allow access to the hostname mysite.example.org while denying all others, add the below content to configuration file.

Require host mysite.example.org


To allow access to the hostnames ending with .net and example.edu while denying all others, add the below content to configuration file.

Require host .net example.edu

NOTE:
• With Partial Domain Names, only complete components are matched. So the above example will match foo.example.edu but not fooexample.edu.
• This configuration will also cause Apache HTTP Server to perform a double Reverse DNS lookup on the client IP address, regardless of the setting of the HostnameLookups directive. First will be a Reverse DNS lookup on the IP address to find the associated hostname. Second will be a forward lookup on the hostname to assure that it matches the original IP address. Only if both DNS records are consistent, the hostname match occurs and access is allowed.

 

♦ Access Control based on IP Address
This method allows access control for portions of a website based on the IP address of the visitors.

To deny access to the IP address 10.252.46.165 while allowing all others, add the below content to configuration file.

<RequireAll>
Require all granted
Require not ip 10.252.46.165
</RequireAll>


To allow access to only the IP addresses 10.1.2.3, 192.168.1.104 and 192.168.1.205 while denying all others, add the below content to configuration file.

Require ip 10.1.2.3
Require ip 192.168.1.104 192.168.1.205


To allow access to only the IP addresses in the format 10.xxx.xxx.xxx, 172.20.xxx.xxx and 192.168.2.xxx while denying all others, add the below content to configuration file.

Require ip 10 172.20 192.168.2


To allow access to only the range of IP addresses belonging to the network 10.1.0.0 and coming under the subnet mask 255.255.0.0 while denying all others, add the below content to configuration file.

Require ip 10.1.0.0/255.255.0.0


To allow access to only the range of IP addresses belonging to the network 10.1.0.0 and coming under the CIDR prefix /16 while denying all others, add the below content to configuration file.

Require ip 10.1.0.0/16


To allow access to the IP address 2001:db8::a00:20ff:fea7:ccea and the range of IP addresses belonging to the network 2001:db8::a00:20ff:fea7:ccea coming under the CIDR prefix /10 while denying all others, add the below content to configuration file.

Require ip 2001:db8::a00:20ff:fea7:ccea
Require ip 2001:db8::a00:20ff:fea7:ccea/10

 

♦ Access Control for localhost
This method allows access control for connections that originate from localhost.
To allow access only to localhost while denying all others, add the below content to configuration file.

Require local

The local provider allows access to the server if any of the following conditions are true.
• Client address matches 127.0.0.0/8
• Client address is ::1
• Both the Client and Server address of the connection are the same.

 

♦ Access control based on time
This method allows access control for a resource during specific duration. It can be implemented using any of the below methods.
Using Expression
Using Rewrite rule

Using Expression
This method makes use of the expr provider given by Require directive. It allows access control based on arbitrary variables.
NOTE: Read about Expressions in Apache HTTP Server.

To allow access to a resource between 08:00 PM and 06:00 AM, add the below content to configuration file.

Require expr "%{TIME_HOUR} -ge 20 && %{TIME_HOUR} -le 06"


To allow access to a resource between 08:00 PM and 06:00 AM, add the below content to configuration file.

Require expr "%{TIME_HOUR}%{TIME_MIN} -ge 2010 && %{TIME_HOUR}%{TIME_MIN} -le 0615"


Using Rewrite rule
This method makes use of the mod_rewrite.so module. It allows access control based on arbitrary variables.
NOTE: Read about enabling mod_rewrite.so module.

To allow access to a resource between 08:00 PM and 06:00 AM, add the below content to configuration file.

RewriteEngine On
RewriteCond %{TIME_HOUR} >=20 [OR]
RewriteCond %{TIME_HOUR} <=06
RewriteRule .* - [F]
OPTIONS EXPLAINED

RewriteEngine On
Enables the runtime rewriting engine


RewriteCond %{TIME_HOUR} >=20 [OR]
Condition under which rewriting takes place.
Proceeds to next line, only if this condition is true. %{TIME_HOUR} >=20 - Time in hour, is greater than or equal to 08:00PM [OR] - Or next condition RewriteCond %{TIME_HOUR} <=07 Condition under which rewriting takes place.
Proceeds to next line, only if this condition is true. %{TIME_HOUR} <=06 - Time in hour, is less than or equal to 06:00AM RewriteRule .* - [F] Defines rules for the rewriting engine.
Rewriting happens only if any of the 2 conditions are true. . - Matches any 1 character .* - Matches any character 0 to infinite times [F] - Causes a 403 forbidden response to be sent


To allow access to a resource between 08:10 PM and 06:15 AM, add the below content to configuration file.

RewriteEngine On
RewriteCond %{TIME_HOUR}%{TIME_MIN} >=2010 [OR]
RewriteCond %{TIME_HOUR}%{TIME_MIN} <=0615
RewriteRule .* - [F]
OPTIONS EXPLAINED


RewriteEngine On
Enables the runtime rewriting engine


RewriteCond %{TIME_HOUR}%{TIME_MIN} >=2010 [OR]
Condition under which rewriting takes place.
Proceeds to next line, only if this condition is true. %{TIME_HOUR} >=2010 - Time in hour, is greater than or equal to 08:10PM [OR] - Or next condition RewriteCond %{TIME_HOUR} <=07 Condition under which rewriting takes place.
Proceeds to next line, only if this condition is true. %{TIME_HOUR} <=0615 - Time in hour, is less than or equal to 06:15AM RewriteRule .* - [F] Defines rules for the rewriting engine.
Rewriting happens only if any of the 2 conditions are true. . - Matches any 1 character .* - Matches any character 0 to infinite times [F] - Causes a 403 forbidden response to be sent



♦ Access control using variables
This method allows access control for a server based on variables. It can be implemented using any of the below methods.
Using arbitrary variables
Using environment variables

Using arbitrary variables
This method makes use of the <If> directive. The <If> directive, replaces many things that the module mod_rewrite.so has traditionally been used to do. It can allow access to the server using arbitrary environment variables or request header values.

To allow access to a user agent, while denying all others, add the below content to configuration file.
NOTE:
• Set USERAGENT to your required value.
• Access control by UserAgent is unreliable, as the UserAgent header can be set to anything by the end user.
View a list of UserAgent strings.
View a list of Variables.

<If "%{HTTP_USER_AGENT} == 'USERAGENT'">
Require All Denied
</If>

Using environment variables
This method makes use of the env provider given by Require directive. It allows access control based on Environment Variables.

To allow access to a user agent, while denying all others, add the below content to configuration file.
NOTE:
• Set USERAGENT to your required value.
• Access control by UserAgent is unreliable, as the UserAgent header can be set to anything by the end user.
View a list of UserAgent strings.
View a list of Variables.

SetEnvIf User-Agent ^USERAGENT/x.y let_me_in
<Directory "/usr/local/apache2/htdocs">
Require env let_me_in
</Directory>



♦ Access Control using HTTP methods
This method allows access control for a server based on HTTP methods. It makes use of the method provider given by Require directive.
NOTE:
• The TRACE method is not available to method provider, instead you must use TraceEnable directive.
View the list of HTTP methods.

To allow only the access methods GET,POST and OPTIONS, add the below content to configuration file.

Require method GET POST OPTIONS



 

 

5) Setting up Authentication and Authorization (OPTIONAL)
Authentication refers to the process by which we verify that someone is who they claim they are. Authorization refers to the process by which someone is allowed to be where they want to go, or to have information that they want to have.

For setting up Authentication and Authorization, we must allow the use of directives matching the directive-type AuthConfig. This has been done during the Post Installation procedures.

TIP: Read more about htaccess directives.



TIP: View the complete list of modules providing Authentication and Authorization features.

The modules required for setting up Authentication and Authorization depends on the type of method used. However the Core Authentication modules given below are essential to every method used.
•  mod_authn_core.so
•  mod_authz_core.so

• mod_authn_core.so
mod_authn_core.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-authn-core. It provides core authentication capabilities to allow or deny access to portions of the web site.
The directives provided by this module are AuthName, <AuthnProviderAlias> and AuthType.
http://httpd.apache.org/docs/2.4/mod/mod_authn_core.html

• mod_authz_core.so
mod_authz_core.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-authz-core. It provides core authorization capabilities so that authenticated users can be allowed or denied access to portions of the web site. It also provides the functionality to register various authorization providers. This allows applying advanced logic in the authorization processing.
The directives provided by this module are AuthMerging, <AuthzProviderAlias>, AuthzSendForbiddenOnFailure, Require, <RequireAll>, <RequireAny> and <RequireNone>.
NOTE: If you are using Require directive, and proxying content to your server, you need to be aware that the client address will be the address of your proxy server, not the hostname of the client, and so using the Require directive in this context may not do what you mean. The module mod_remoteip.so presents a possible solution to this problem.
http://httpd.apache.org/docs/2.4/mod/mod_authz_core.html

 

We can set up Authentication and Authorization in Apache HTTP Server using any of the below methods.
Basic Authentication
Digest Authentication


♦ Basic Authentication
Basic Authentication provides basic HTTP authentication. It is important to note that, Basic Authentication sends the password from client to server in unencrypted form. This method should therefore not be used for highly sensitive data, unless that data is SSL/TLS encrypted.

The features of Basic Authentication are.
• Is the simplest and most widely supported method.
• Has official support for storing authentication files in DBM format.
• Has support for bcrypt.
• Is not secure unless used with SSL, because username and password is sent from Client to Server unencrypted.

Basic Authentication can be categorized into two types based on the method used to store authentication credentials.
1) Basic Authentication using Flatfile based storage
2) Basic Authentication using DBM based storage


♦ Digest Authentication
Digest Authentication provides digest HTTP authentication. Digest Authentication sends the password from client to server in hashed form. Therefore the data is secure, even if it is not SSL/TLS encrypted.

The features of Digest Authentication are.
• Is not widely supported, though presently all major browsers support digest authentication.
• Has only unofficial support for storing authentication files in DBM format.
• Has only unofficial support for bcrypt; which only works with DBM. Support is only provided for MD5 which has been cryptographically broken using Collision Attacks.
• Is secure even without SSL, because username and password are sent from client to server in hashed form.

Basic Authentication can be categorized into two types based on the method used to store authentication credentials.
1) Digest Authentication using Flatfile based storage (Without bcrypt support)
2) Digest Authentication using DBM based storage  (With bcrypt support)

 

 

 

 

6) Enabling SSL support (OPTIONAL)
SSL or Secure Socket Layer is a cryptographic protocol which is designed to provide communication security over the Internet. It makes use of PKI or Public Key Infrastructure. They use X.509 certificates and hence asymmetric cryptography to assure the authenticity of counterparty with whom they are communicating, and to exchange a symmetric key. This session key is then used to encrypt data flowing between the parties.

We know that, in public key cryptography, two keys are created; one Public key and one Private key. Anything encrypted with one key can only be decrypted with the other key. So what is the need for a signed certificate in between keys? The technical answer is; There is no need for a signed certificate.
However, certificates serve a crucial role in the communication process. The certificate, signed by a trusted CA or Certificate Authority, ensures that the certificate holder is really who he claims to be. With certificates, impersonation attacks would be less.
So, if we want to use an SSL certificate on a production server we probably want to purchase it from Trusted CA. But if we want to use this on a personal site or for testing purposes, a self-signed certificate is fine.

In real life if we want a SSL certificate for our website or server or an application we are developing, we will be contacting our hosting provider or a Trusted CA. If it is a hosting provider they will directly contact the CA in behalf of us. Afterwards which we will be presented with a contact form for filling in the Organization, Server and Personal details. Submitting this form will generate a CSR or Certificate Signing Request. The CA will create a signed SSL certificate using this CSR and sent it back to us or the hosting provider.
The time required for receiving a SSL certificate can vary from minutes to weeks depending on the type of certificate. See http://sslshopper.com/ssl-certificate-wizard.html for more details.
We can find a list of Trusted CAs at the following links.
http://tractis.com/countries
http://sslshopper.com
http://dmoz.org/Computers/Security/Public_Key_Infrastructure/PKIX/Tools_and_Services/Third_Party_Certificate_Authorities

WARNING: An SSL certificate that is self-signed or signed by an unknown/untrusted CA will always generate a security warning in the application(example: web browser) being used.

 


However if we do not wish to purchase a SSL certificate from a Trusted CA, instead we are planning to use a self-signed SSL certificate, the following procedure can be followed.

The modules required for enabling SSL support in our server are.
mod_log_config.so
mod_setenvif.so
mod_socache_shmcb.so
mod_ssl.so

• mod_log_config.so
mod_log_config.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-log-config. This module provides flexible logging of client requests. Logs are written in a customizable format, and may be written directly to a file, or to an external program. Conditional logging is also provided so that individual requests may be included or excluded from the logs based on characteristics of the request.
The directives provided by this module are BufferedLogs, CustomLog, LogFormat and TransferLog.
http://httpd.apache.org/docs/2.4/mod/mod_log_config.html

• mod_setenvif.so
mod_setenvif.so is compiled and enabled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-setenvif. This module allows us to set internal environment variables according to whether different aspects of the request match regular expressions we specify.
The directives provided by this module are BrowserMatch, BrowserMatchNoCase, SetEnvIf, SetEnvIfExpr and SetEnvIfNoCase
http://httpd.apache.org/docs/2.4/mod/mod_setenvif.html

• mod_socache_shmcb.so
mod_socache_shmcb.so is compiled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-socache-shmcb or --enable-mods-shared=few. We have to manually enable this module. This module is a shared object cache provider which provides for creation and access to a cache backed by a high-performance cyclic buffer inside a shared memory segment.
This module provides no directives.
http://httpd.apache.org/docs/2.4/mod/mod_socache_shmcb.html

• mod_ssl.so
mod_ssl.so is compiled by default on an Apache HTTP Server installation unless we explicitly disable it using the configure option --disable-ssl or --enable-mods-shared=few. We have to manually enable this module. This module provides SSL v3 and TLS v1.x support for the Apache HTTP Server. It relies on OpenSSL to provide the cryptography engine.
View the list of directives provided by this module.
http://httpd.apache.org/docs/2.4/mod/mod_ssl.html



Enabling SSL support for Apache HTTP Server using a self-signed certificate, involves the following steps.
Creating SSL Certficate
Configuring the Server
Setting up SSL VirtualHost



♦ Creating SSL Certficate
Open Apache HTTP Server‘s SSL configuration file httpd-ssl.conf.
Look for the line containing SSLCertificateKeyFile. This line contains the name and location of server’s Private key. It should look as shown below.

SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"

Look for the line containing SSLCertificateFile. This line contains the name and location of server’s Public key. It should look as shown below.

SSLCertificateFile "/usr/local/apache2/conf/server.crt"

Note the name and location of key files. We are going to use them later.


Generating the Private key

A Private Key contains the Private Certificate. Let us generate a Private key for server.
In the terminal, change to Apache HTTP Server‘s configuration files directory.

# cd /usr/local/apache2/conf


Execute the following command in terminal. We will be asked for a passphrase twice. Type the passphrase and press Enter.
NOTE:
• Do not forget the passphrase. We will need it later.
• To view the list of Public key alogorithms supported by OpenSSL, execute the below command in terminal.
# openssl list-public-key-algorithms
• To view the list of Cipher alogorithms supported by OpenSSL, execute the below command in terminal.
# openssl list-cipher-algorithms

# openssl genpkey -out server.key -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -aes-256-cbc
OPTIONS EXPLAINED

genpkey
Generation of Private Key or Parameters.

-out filename
the output filename. If this argument is not specified then standard output is used.

-outform DER|PEM
This specifies the output format DER or PEM.

-algorithm alg
public key algorithm to use such as RSA, DSA or DH. If used this option must precede any -pkeyopt options. The options -paramfile and -algorithm are mutually exclusive.

-pkeyopt opt:value
set the public key algorithm option opt to value. The precise set of options supported depends on the public key algorithm used and its implementation. See KEY GENERATION OPTIONS below for more details.

-cipher
This option encrypts the private key with the supplied cipher. Any algorithm name accepted by EVP_get_cipherbyname() is acceptable such as des3.

This will generate a Private key named server.key in the directory /usr/local/apache2/conf/. The key will follow PEM standard and use RSA public key algorithm using 2048-bit keysize. It will be encrypted using our passphrase with the block cipher algorithm AES-256 in CBC mode.

 

Generating the Certificate Signing Request
We need a CSR or Certificate Signing Request to present to the CA who may generate a signed certificate for us. When a CSR is generated a set of attributes is asked, which will be incorporated into the CSR and later into the certificate. These set of attributes form a DN or Distinguished Name used by a Certificate. A Distinguished Name uniquely identifies an entity in an X.509 certificate.

The set of attributes commonly asked when generating a CSR are.
⇒ countryName, C
Two letter code of the Country where the Organization resides. This is a ISO 3166-1 alpha-2 specification. View the complete list of Country Codes at http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2. eg: US

stateOrProvinceName, ST or SP or S
Name of the State or Province where the Organization resides. This should not be abbreviated. eg: Texas

locality, L
Name of the locality where the Organization resides. eg: Dallas

organizationName, O
Legal name of the Organization. This should include suffixes such as Inc, Corp, Ltd or LLC. This should not be abbreviated. eg: MyCompany Ltd

organizationalUnitName, OU
Identifies the unit. Unit is understood to be part of the Organization. eg: Support

commonName, CN
FQDN of the server. eg: example.com
NOTE: Name mismatch error will occur if the Common Name in certificate does not match the URL in the address bar of browser. For example if the certificate is for www.example.com and the site is accessed via example.com, we will get an SSL certificate name error. This can be worked around using any of the following methods.
• Generate the SSL certificate with www in the Common Name. Then, enable the use of www in URL always.
• Generate the SSL certificate without the www in the Common Name. Then, disable the use of www in URL always.
• Generate a Wildcard SSL certificate. This can be used with all single-level subdomains of that domain. For this we will have to give Common Name  *.example.com. But this SSL certificate cannot be used for EV.
• Generate the SSL certificate with a SAN or Subject Alternative Name for example.com. See the todo list.

emailAddress
Email address used to contact the Organization. eg: [email protected]

challengePassword
Password that will be send with the Certificate Request. Must be less than 20 bytes. The CA will request this during a Certificate revocation.

unstructuredName
Optional Company Name. eg: MyCompany


In the terminal, change to Apache HTTP Server‘s configuration files directory.

# cd /usr/local/apache2/conf


Execute the following command in terminal. We will be asked for the passphrase of Private key. Type it and press Enter. This will ask us for the attributes to be incorporated into the CSR. Completing this step will generate our CSR.
NOTE:
• The field values by default are interpreted as ASCII. If you want the field values to be interpreted as UTF8 strings, use the option -utf8.
• To view the list of Public key alogorithms supported by OpenSSL, execute the below command in terminal.
# openssl list-public-key-algorithms
• To view the list of Message Digest algorithms supported by OpenSSL, execute the below command in terminal.
# openssl list-message-digest-algorithms

# openssl req -new -key server.key -keyform PEM -out server.csr -pkeyopt rsa_keygen_bits:2048 -sha256 -verbose
OPTIONS EXPLAINED

req
PKCS#10 certificate request and certificate generating utility.

-verbose
print extra details about the operations being performed.

-new
this option generates a new certificate request. It will prompt the user for the relevant field values. The actual fields prompted for and their maximum and minimum sizes are specified in the configuration file and any requested extensions. If the -key option is not used it will generate a new RSA private key using information specified in the configuration file.

-key filename
This specifies the file to read the private key from. It also accepts PKCS#8 format private keys for PEM format files.

-keyform PEM|DER
the format of the private key file specified in the -key argument. PEM is the default.

-out filename
This specifies the output filename to write to or standard output by default.

-pkeyopt opt:value
set the public key algorithm option opt to value. The precise set of options supported depends on the public key algorithm used and its implementation. See KEY GENERATION OPTIONS in the genpkey manual page for more details.

-[digest]
this specifies the message digest to sign the request with (such as -md5, -sha1). For full list of possible digests see openssl dgst -h output. This overrides the digest algorithm specified in the configuration file. Some public key algorithms may override this choice. For instance, DSA signatures always use SHA1, GOST R 34.10 signatures always use GOST R 34.11-94 (-md_gost94).

OpenSSL will use the configuration file /etc/pki/tls/openssl.cnf to generate a CSR file named server.csr in the directory /usr/local/apache2/conf/. The CSR will follow PEM standard and use RSA public key algorithm using 2048-bit keysize. It will be signed using the hash algorithm SHA-256.

 

Generating the signed Certificate
We will use the CSR generated in the previous step to create a Self-signed SSL certificate. This SSL certficate will contain the Public key used by the server.

In the terminal, change to Apache HTTP Server‘s configuration files directory.

# cd /usr/local/apache2/conf


Execute the following command in terminal.

# openssl x509 -in server.csr -req -signkey server.key -keyform PEM -out server.crt -sha256 -days 365
OPTIONS EXPLAINED

x509
Certificate display and signing utility

-in filename
This specifies the input filename to read a certificate from or standard input if this option is not specified.

-req
by default a certificate is expected on input. With this option a certificate request is expected instead.

-signkey filename
this option causes the input file to be self signed using the supplied private key. If the input file is a certificate it sets the issuer name to the subject name (i.e.  makes it self signed) changes the public key to the supplied value and changes the start and end dates. The start date is set to the current time and the end date is set to a value determined by the -days option. Any certificate extensions are retained unless the -clrext option is supplied. If the input is a certificate request then a self signed certificate is created using the supplied private key using the subject name in the request.

-keyform PEM|DER
specifies the format (DER or PEM) of the private key file used in the -signkey option.

-out filename
his specifies the output filename to write to or standard output by default.

-md2|-md5|-sha1|-mdc2
the digest to use. This affects any signing or display option that uses a message digest, such as the -fingerprint, -signkey and -CA options. If not specified then SHA1 is used. If the key being used to sign with is a DSA key then this option has no effect: SHA1 is always used with DSA keys.  For full list of digests see openssl dgst -h output.

-days arg
specifies the number of days to make a certificate valid for. The default is 30 days.

This will generate the Self-signed SSL certificate named server.crt in the directory /usr/local/apache2/conf/. The key will follow PEM standard and use RSA public key algorithm using 2048-bit keysize. It will be signed using the hash algorithm SHA-256.



♦ Configuring the Server
Open Apache HTTP Server‘s main configuration file httpd.conf.

The module mod_ssl.so is disabled by default. Let us enable it.
Look for the line containing mod_ssl.so. Uncomment the line. Now it must look as shown below.

LoadModule ssl_module modules/mod_ssl.so


The module mod_socache_shmcb.so is disabled by default. Let us enable it.
Look for the line containing mod_socache_shmcb.so. Uncomment the line. Now it must look as shown below.

LoadModule socache_shmcb_module modules/mod_socache_shmcb.so


Apache HTTP Server‘s SSL configuration file is disabled by default. Let us enable it.
Look for the line containing httpd-ssl.conf. Uncomment the line. Now it must look as shown below.

Include conf/extra/httpd-ssl.conf

Save the configuration file and close it.


Apache HTTP Server by default binds to all IP addresses on all interfaces of a given system. It is always good to specify which address to bind to.
Open Apache HTTP Server‘s SSL configuration file httpd-ssl.conf. Look for the line containing Listen 443. The IP address of my machine is 192.168.0.100. So I have modified the content as shown below.
NOTE: Replace 192.168.0.100 with the IP address of your machine.

Listen 127.0.0.1:443
Listen 192.168.0.100:443

This makes Apache to bind to the IP addresses 192.168.0.100 and 127.0.0.1 on port 443.
NOTE: If you wish Apache HTTP Server to bind only to a selected set of IP addresses or ports, follow the steps here.



♦ Setting up SSL VirtualHost
We have to setup a Virtualhost for the SSL communication.
Open Apache HTTP Server‘s SSL configuration file httpd-ssl.conf. Look for the Virtualhost section. It must start with the line <VirtualHost _default_:443>. Make following changes to the VirtualHost section.

My machine has the IP address 192.168.0.100 and hostname example.com. I have decided to keep the contact E-mail root@localhost. See more details in the Post Installation procedure. My Virtualhost section now looks as shown below.
NOTE:
• Replace 192.168.0.100 with IP address of your machine.
• Replace example.com with hostname of your machine.
• Replace root@localhost with your preferred contact E-mail.

<VirtualHost 192.168.0.100:443>

#   General setup for the virtual host
DocumentRoot "/usr/local/apache2/htdocs"
ServerName example.com
ServerAdmin root@localhost


We have made the necessary changes. Now, all we have to do is restart the apache service. But this will not do the trick.
Remember; we have set a passphrase for the SSL certificate. This passphrase should be asked when the service starts. But the command service apache restart does not present us with an interactive mode for entering the password. The result – apache service shuts down, tries to start up and then silently dies. So will have to stop and start the service.

Stop the apache service

# service apache stop

Start the apache service. This will ask for the passphrase. Type the passphrase press Enter.

# service apache start

 


Now let us view our SSL encrypted webpage. Open the web browser and type in the hostname of our machine prefixed by https://. Because the certificate is self-signed, there will be a security warning about Untrusted connection. Confirming this will take use to our webpage. I have my webpage accessible at https://example.com.

TIP: Read how to force SSL for all connections.

 

 

WARNING: Removing the encryption of a Private key is dangerous. If the system is ever compromised and a third party obtains our unencrypted private key, they will be able to impersonate us on the internet. Perform the below steps only if you know what you are doing.

Still there is a minor issue. The apache service will ask us the passphrase each time it is started.
What if we can’t be present at the time passphrase is asked? For example, when the server reboots after a crash OR while a script executes.
This can be solved by removing the encryption of Private key. Perform the following steps for this.

In the terminal, change to Apache HTTP Server‘s configuration files directory.

# cd /usr/local/apache2/conf


Backup the original SSL Private key.

# mv server.key server.key.org


Remove the encryption of Private key. We will be asked for the passphrase. Type the passphrase and press Enter.

# openssl rsa -in server.key.org -inform PEM -out server.key -outform PEM
OPTIONS EXPLAINED

rsa
RSA key processing tool

-in filename
This specifies the input filename to read a key from or standard input if this option is not specified. If the key is encrypted a pass phrase will be prompted for.

-inform DER|NET|PEM
This specifies the input format. The DER option uses an ASN1 DER encoded form compatible with the PKCS#1 RSAPrivateKey or SubjectPublicKeyInfo format.  The PEM form is the default format: it consists of the DER format base64 encoded with additional header and footer lines. On input PKCS#8 format private keys are also accepted. The NET form is a format is described in the NOTES section.

-out filename
This specifies the output filename to write a key to or standard output if this option is not specified. If any encryption options are set then a pass phrase will be prompted for. The output filename should not be the same as the input filename.

-outform DER|NET|PEM
This specifies the output format, the options have the same meaning as the -inform option.

This will create an unencrypted Private key named server.key.


Let us make this unencrypted Private key only readable by root.

# chmod 400 server.key

Done.

 

 

 

After securing Apache HTTP Server, it is recommended to view the following sections.
Customizing Apache HTTP Server

OR

You may go directly to the following section.
Installing PHP