Candidates should be able to configure a web server to provide HTTPS.
SSL configuration files, tools and utilities
Ability to generate a server private key and CSR for a commercial CA
Ability to generate a self-signed Certificate from private CA
Ability to install the key and Certificate
Awareness of the issues with Virtual Hosting and use of SSL
Security issues in SSL use
Apache2 configuration files
SSLEngine, SSLCertificateKeyFile, SSLCertificateFile, SSLCertificateChainFile
SSLProtocol, SSLCipherSuite, ServerTokens, ServerSignature, TraceEnable
Depending on the used distribution the following files may be used for configuring Apache:
$ apachectl configtest
To show all virtual hosts configured, use:
$ apachectl -t -D DUMP_VHOSTS
mime.types file is the default file that contains mime document types.
This file is set by the "TypesConfig" directive.
Apache has been modified to support Secure Socket Layers for secure online communication. The Secure Sockets Layer protocol (SSL) is a protocol which may be placed between a reliable connection-oriented network layer protocol (e.g., TCP/IP) and the application layer protocol (e.g., HTTP). SSL provides secure communication between client and server by allowing mutual authentication and the use of digital signatures for integrity and encryption for privacy. Currently there are two versions of SSL still in use: version 2 and version 3. Additionally, there is the successor to SSL, TLS (version 1, which is based on SSL), designed by the IETF organisation.
SSL uses Public Key Cryptography (PKC), also known as asymmetric cryptography. Public key cryptography is used in situations where the sender and receiver do not share a common secret, e.g., between browsers and web servers, but wish to establish a trusted channel for their communication.
PKC defines an algorithm which uses two keys, each of which may be used to encrypt a message. If one key is used to encrypt a message, then the other must be used to decrypt it. This makes it possible to receive secure messages by simply publishing one key (the public key) and keeping the other key secret (the private key). Anyone may encrypt a message using the public key, but only the owner of the private key will be able to read it. For example, Joan may send private messages to the owner of a key-pair (e.g., your web server), by encrypting the messages using the public key your server publishes. Only the server will be able to decrypt it using the corresponding private key.
A secure web server (e.g., Apache/SSL) uses HTTP over SSL,
using port 443 by default. This can be configured in
httpd.conf. Within the
browser, this is signified by the use of the https scheme in the URL. The public
key is exchanged during the set-up of the communication between server and client (browser). That
public key is signed (it contains a digital signature e.g., a message digest) by a so-called
CA (Certificate Authority). The browser contains a number of so-called
root-certificates: they can be used to determine the validity of the CA's that
signed the key.
A number of solutions are available to enable Apache to use SSL on Linux:
Commercially licensed: Raven, Stronghold
Apache with SSLeay or Open-SSL, aka Apache-SSL
Eric A. Young and Tim J. Hudson created SSLeay - a library containing encryption functions. Another team, lead by Ralf Engelschall and Ben Laurie, used this library as a starting point to create a complementary set of cryptography software named OpenSSL. A team lead by Ben Laurie combined OpenSSL with the Apache webserver to create Apache-SSL. In 1998, Ralf Engelschall and his team derived mod_ssl from Apache-SSL.
mod_ssl is not a replacement for Apache-SSL - it is an alternative. It is a matter of personal choice which you use. mod_ssl is what is known as a “fork” - i.e., it was originally derived from Apache-SSL, but has been extensively redeveloped. Many people find it very easy to install.
There are also a number of commercial products available: Red Hat's Secure Web Server (which is based on mod_ssl), Covalent's Raven SSL Module (also based on mod_ssl) and C2Net's product Stronghold (based on a different evolution branch named Sioux up to Stronghold 2.x and based on mod_ssl since Stronghold 3.x).
To use mod_ssl you will need to acquire and install Apache, patch it with the latest updates, and install and configure the module. You will also need to acquire and install OpenSSL, generate a key-pair, and either sign the public part of it yourself, thus creating a certificate, or have it signed by a commercial Certificate Authority (CA).
The mod_ssl package consists of the SSL module itself - and, surprisingly, a set of patches for Apache itself. This may puzzle you at first: why do we need to patch Apache to install the mod_ssl module? Well, the standard API that Apache uses for it's modules is unable to communicate with the SSL module. Therefore, the source patches add the Extended API (EAPI). In other words: you can only use the mod_ssl module when Apache's core code contains the Extended API. When building mod_ssl, the Apache source tree is automatically altered for you, adding the Extended API.
After installation of the software you will need to configure Apache with Apache-SSL. Some additional directives should be used to configure the secure server - for example the location of the key-files. It's beyond the scope of this book to document these directives, however, you can find them in the mod_ssl documentation and on the mod_ssl web-site .
mod_ssl can be used to authenticate clients using client certificates. These
client certificates can be signed by your own CA and mod_ssl will validate the
certificates against this CA. To enable this functionality set the
Use the value
none to turn it off.
Certificates are usually stored in
/etc/ssl$ ls -l total 32 drwxr-xr-x 3 root root 16384 2011-03-06 15:31 certs -rw-r--r-- 1 root root 9374 2010-09-24 22:05 openssl.cnf drwx--x--- 2 root ssl-cert 4096 2011-03-06 13:19 private
The openssl program is a command line interface to the
OpenSSL crypto library. You can use it to generate certificates, encrypt and decrypt
files, create hashes and many more. It is generally seen as “the Swiss Army
knife” of cryptography. One of the more common usages is to generate (self-signed)
certificates for use on a secured webserver (to support the
/etc/ssl/openssl.cnf is the standard location for its
configuration file, where you can set defaults for the name of your organization,
the address etc.
If you generate a certificate for a webserver you start by creating a Certificate
Signing Request. The openssl tool will prompt you for
information it needs to create the request, using defaults it fetches
from the configuration file. When you generate such a signing request,
make sure you enter the FQDN
("Fully Qualified Domain Name") of the server when openssl
prompts you for the “Common Name” (which is part of the
“Distinguished Name”). For example when you generate
a CSR for the web-site
You start by generating the RSA key file. It contains a pair of related keys, used to encrypt and decrypt messages to and from you. One half of the keypair will be used to encrypt messages that will be sent to you using the public key. The other half is used to decrypt these received messages using the private key. The public key will be made part of your digital certificate. This allows client systems to sent encrypted messages to your webserver that only this webserver can decrypt, as it holds the related private key;
The CSR is sent to a Certificate Authority (CA) which should verify the correctness of the information you provided and generate the certificate. This certificate contains a digital signature that allows verification that the CA has approved of the contents of the certificate. The certificate will contain the data you provided (including your public key) and it is signed by the CA using its private key. A certificate contains your RSA public key, your name, the name of the CA and is digitally signed by your CA. Browsers that know the CA can verify the signature on that certificate, thereby obtaining your RSA public key. That enables them to send messages which only you can decrypt.
You can create a signing request and then sign it yourself. In
fact, that is what Certificate Authorities do when they create
root certificate. A
certificate is simply a certificate that says that they
say they are whom they say they are. So, anybody can create a root
certificate and put any credentials on it just as they
please. The root certificate itself is no proof of anything. You
will need to ensure that it really was issued by a party you trust
yourself. Either you visit them and get a copy directly from them,
or fetch it using another method you trust or you rely on others you
trust to have done this for you. One of the ways you implicitly
“trust” a large number of CAs is by relying on their
root certificates that are made part of your browser.
As an example: to create an RSA private key that has a
keysize of 1024 bits, and which will be
triple-des (3DES) encrypted, stored in a file named
server.key in the default
format (which is known as PEM), type:
$ openssl genrsa -des3 -out server.key 1024
openssl will ask for a pass-phrase, which will be used as the key to encrypt the private key. Please store this file in a secure backup location and remember the pass-phrase. If you loose the pass-phrase you will not be able to recover the key.
To create a Certificate Signing Request (CSR) with the server RSA private key (output will be PEM formatted), execute the following:
$ openssl req -new -key server.key -out server.csr
The signing request can now either be sent to a real CA, which will sign the request and create a digital certificate, or you can create your own CA and do it yourself. Note that if you do it yourself, you will also need to install the root certificate of your CA into your clients (e.g. browser) to signal them that a certificate signed by your own CA can be trusted. If you omit this step, you will be getting a lot of disturbing warnings about missing trust and insecurity.
You can provide the openssl parameters yourself, but that
can be a daunting task for less experienced users. Hence, for conveniences
sake the OpenSSL software suite provides a perl script (
to handle most CA related tasks a lot easier. It has a simplified syntax and
supplies the more complex command line arguments to the underlying
CA.pl will default use values it reads from
the standard OpenSSL configuration file
To create your own CA do:
# /usr/lib/ssl/misc/CA.pl -newca CA certificate filename (or enter to create) Making CA certificate ... Generating a 2048 bit RSA private key ........................+++ ..................................+++ writing new private key to './demoCA/private/cakey.pem' Enter PEM pass phrase: ******** Verifying - Enter PEM pass phrase: ******** You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [NL]: State or Province Name (full name) [None]: Locality Name (eg, city) : Organization Name (eg, company) [Snow B.V.]: Organizational Unit Name (eg, section) : Common Name (e.g. server FQDN or YOUR name) :ssltest.snow.nl Email Address : Please enter the following 'extra' attributes to be sent with your certificate request A challenge password : An optional company name : Using configuration from /usr/lib/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: ca:d8:22:43:94:6d:ca:6c Validity Not Before: Jul 9 13:49:38 2013 GMT Not After : Jul 8 13:49:38 2016 GMT Subject: countryName = NL stateOrProvinceName = None organizationName = Snow B.V. commonName = ssltest.snow.nl X509v3 extensions: X509v3 Subject Key Identifier: 83:F3:99:4B:98:E0:F1:37:78:67:DC:04:AC:04:65:03:48:BB:31:FB X509v3 Authority Key Identifier: keyid:83:F3:99:4B:98:E0:F1:37:78:67:DC:04:AC:04:65:03:48:BB:31:FB X509v3 Basic Constraints: CA:TRUE Certificate is to be certified until Jul 8 13:49:38 2016 GMT (1095 days) Write out database with 1 new entries Data Base Updated
Next create a signing request:
# /usr/lib/ssl/misc/CA.pl -newreq Generating a 2048 bit RSA private key ...........................+++ ...........................+++ writing new private key to 'newkey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [NL]: State or Province Name (full name) :None Locality Name (eg, city) : Organization Name (eg, company) :Snow B.V. Organizational Unit Name (eg, section) : Common Name (e.g. server FQDN or YOUR name) :ssltest.snow.nl Email Address : Please enter the following 'extra' attributes to be sent with your certificate request A challenge password : An optional company name : Request is in newreq.pem, private key is in newkey.pem
Then, we sign the request:
# /usr/lib/ssl/misc/CA.pl -signreq Using configuration from /usr/lib/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: ca:d8:22:43:94:6d:ca:6d Validity Not Before: Jul 9 13:53:53 2013 GMT Not After : Jul 9 13:53:53 2014 GMT Subject: countryName = NL stateOrProvinceName = None organizationName = Snow B.V. commonName = ssltest.snow.nl X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 21:A4:61:83:B4:E7:C3:E9:2B:2C:0A:DD:36:FA:82:D0:77:3A:E2:01 X509v3 Authority Key Identifier: keyid:83:F3:99:4B:98:E0:F1:37:78:67:DC:04:AC:04:65:03:48:BB:31:FB Certificate is to be certified until Jul 9 13:53:53 2014 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Signed certificate is in newcert.pem
You now created a certificate signed by your own CA (
You might want to rename the file to something more distinguishable, e.g
Certificate:ssltest.snow.nl. While at it, rename the server
key file too, for example
Especially if you maintain a lot of keys and certificates on a lot of servers,
it really helps to be able to learn from the name of a file what is in it.
The Certificate Signing Request (CSR) could have been sent to an external Certificate
Authority (CA) instead. You usually have to post the CSR into a web form, pay for
the signing and await a signed Certificate. There are non-profit CA's that will
perform similar tasks free of charge, for example
their root certificate is not yet included into most browsers so you will need to
do that yourself if you are going to use their services.
SSLCertificateFile /path/to/Certificate:ssltest.snow.nl SSLCertificateKeyFile /path/to/PrivateKey:ssltest.snow.nl
The following Apache SSL configuration directives should be familiar to you:
This directive toggles the usage of the SSL/TLS Protocol Engine. This should be used inside a <VirtualHost> section to enable SSL/TLS for a that virtual host. By default the SSL/TLS Protocol Engine is disabled for both the main server and all configured virtual hosts.
This directive points to the PEM-encoded private key file for the server. If the contained private key is encrypted, the pass phrase dialog is forced at startup time. This directive can be used up to three times (referencing different filenames) when an RSA, a DSA, and an ECC based private key is used in parallel. For each SSLCertificateKeyFile directive, there must be a matching SSLCertificateFile directive.
This directive points to a file with certificate data in PEM format. At a minimum, the file must include an end-entity (leaf) certificate. This directive can be used up to three times (referencing different filenames) when an RSA, a DSA, and an ECC based server certificate is used in parallel.
This directive sets the optional all-in-one file where you can assemble the certificates of Certification Authorities (CA) which form the certificate chain of the server certificate. This starts with the issuing CA certificate of the server certificate and can range up to the root CA certificate. Such a file is simply the concatenation of the various PEM-encoded CA Certificate files, usually in certificate chain order.
Sometimes, it might be acceptable to use a self-signed SSL certificate
with Apache. The following steps explain how to accomplish this on a
Debian based system. First, create a directory to hold the SSL keys.
On the system we use as an example, all system-wide SSL certificates are
stored in the directory
/etc/ssl/certs. For our
purpose, we create a new directory called
and use it to store our new keypair:
# mkdir /etc/ssl/webserver # openssl req -new -x509 -days 365 -nodes \ > -out /etc/ssl/webserver/apache.pem -keyout /etc/ssl/webserver/apache.key Generating a 2048 bit RSA private key ...............................+++ .......+++ writing new private key to '/etc/ssl/webserver/apache.key' # ls /etc/ssl/webserver/ apache.key apache.pem
During creation, openssl wil use the contents of
/etc/ssl/openssl/cnf to fill in some variables.
Other values will be asked by an interactive script. Be sure to
use the proper FQDN here to distinguish this certificate from
certificates with another purpose later on.
In order to be able to use SSL with Apache, a module called
mod_ssl has to be loaded. On this system, we
can check the enabled modules by listing the contents of the
/etc/apache2/mods-enabled directory. All
currently available modules can be checked by listing the contents
# ls /etc/apache2/mods-enabled/ alias.conf autoindex.conf mime.conf reqtimeout.load alias.load autoindex.load mime.load setenvif.conf auth_basic.load cgi.load negotiation.conf setenvif.load authn_file.load deflate.conf negotiation.load status.conf authz_default.load deflate.load perl.load status.load authz_groupfile.load dir.conf php5.conf authz_host.load dir.load php5.load authz_user.load env.load reqtimeout.conf # ls /etc/apache2/mods-available/ actions.conf cgid.conf include.load proxy_ftp.conf actions.load cgid.load info.conf proxy_ftp.load alias.conf cgi.load info.load proxy_http.load alias.load charset_lite.load ldap.conf proxy.load asis.load dav_fs.conf ldap.load proxy_scgi.load auth_basic.load dav_fs.load log_forensic.load reqtimeout.conf auth_digest.load dav.load mem_cache.conf reqtimeout.load authn_alias.load dav_lock.load mem_cache.load rewrite.load authn_anon.load dbd.load mime.conf setenvif.conf authn_dbd.load deflate.conf mime.load setenvif.load authn_dbm.load deflate.load mime_magic.conf speling.load authn_default.load dir.conf mime_magic.load ssl.conf authn_file.load dir.load mod-dnssd.conf ssl.load authnz_ldap.load disk_cache.conf mod-dnssd.load status.conf authz_dbm.load disk_cache.load negotiation.conf status.load authz_default.load dump_io.load negotiation.load substitute.load authz_groupfile.load env.load perl.load suexec.load authz_host.load expires.load php5.conf unique_id.load authz_owner.load ext_filter.load php5.load userdir.conf authz_user.load file_cache.load proxy_ajp.load userdir.load autoindex.conf filter.load proxy_balancer.conf usertrack.load autoindex.load headers.load proxy_balancer.load vhost_alias.load cache.load ident.load proxy.conf cern_meta.load imagemap.load proxy_connect.load
ssl appears to be available but has not been
enabled yet because both ssl files,
ssl.conf, are still present in the
/etc/apache2/mods-available/ directory and not in the
We could create a symlink to activate support for ssl ourselves,
but Debian provides a utility written in perl called
a2enmod that takes care of this. Consult the
A2ENMOD(8) manpage for more information. It's
counterpart, conveniently called a2dismod, does
the opposite and disables Apache modules by removing the symlinks
Let's enable SSL:
# a2enmod ssl Enabling module ssl. See /usr/share/doc/apache2.2-common/README.Debian.gz on how to configure SSL \ and create self-signed certificates. To activate the new configuration, you need to run: service apache2 restart # service apache2 restart [ ok ] Restarting web server: apache2 ... waiting . # apachectl status |grep -i ssl Server Version: Apache/2.2.22 (Debian) PHP/5.4.4-15.1 mod_ssl/2.2.22 OpenSSL/
SSL has now been enabled on the Apache HTTP server. In order for a
site to actually use SSL, it's configuration has to be properly
configured. HTTPS uses tcp port 443 by default, so we want to specify
this in the apache config of Debian. Add the following line to your
Now, all sites that want to make use of SSL need to have their configuration files reconfigured. The following lines need to be added to each 'enabled' site that should serve it's content by HTTPS:
SSLEngine On SSLCertificateFile /etc/ssl/webserver/apache.pem SSLCertificateKeyFile /etc/ssl/webserver/apache.key
An example site configuration file for both a HTTP and HTTPS enabled site could be like the following:
NameVirtualHost *:80 NameVirtualHost *:443 <VirtualHost *:80> Servername webserver.intranet DocumentRoot /srv/http ErrorLog /var/log/apache2/error.log </VirtualHost> <VirtualHost *:443> SSLEngine On SSLCertificateFile /etc/ssl/webserver/apache.pem SSLCertificateKeyFile /etc/ssl/webserver/apache.key Servername webserver.intranet DocumentRoot /srv/http ErrorLog /var/log/apache2/error.log </VirtualHost>
Now, use apachectl configtest to test your
site configuration and if no errors occur restart the Apache HTTP
server. The SSL enabled sites should now be accessible by using
https URL instead of
Apart from the directives used above, the following Apache configuration directives should be familiar to you:
This directive sets the all-in-one file where you can assemble the certificates of Certification Authorities (CA) whose clients you deal with. These are used for Client Authentication. Such a file is simply the concatenation of the various PEM-encoded certificate files, in order of preference.
Sets the directory where you keep the certificates of Certification Authorities (CAs) whose clients you deal with. These are used to verify the client certificate on Client Authentication.
This complex directive uses a colon-separated cipher-spec string consisting of OpenSSL cipher specifications to configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the standard SSL handshake when a connection is established. In per-directory context it forces a SSL renegotiation with the reconfigured Cipher Suite after the HTTP request was read but before the HTTP response is sent.
This directive can be used to control the SSL protocol flavors mod_ssl should use when establishing its server environment. Clients then can only connect with one of the provided protocols.
ServerSignature directive allows the
configuration of a trailing footer line under server-generated
documents (error messages, mod_proxy ftp directory listings,
mod_info output, ...). The reason why you would want to enable
such a footer line is that in a chain of proxies, the user often
has no possibility to tell which of the chained servers actually
produced a returned error message.
This directive controls whether Server response header field which is sent back to clients includes a description of the generic OS-type of the server as well as information about compiled-in modules.
This directive overrides the behavior of
for both the core server and mod_proxy. The default
TraceEnable on permits
requests per RFC 2616, which disallows any request body to accompany
TraceEnable off causes the core server
and mod_proxy to return a
405 (method not allowed)
error to the client.
As we saw before, the FQDN plays an important part in SSL. With IP-based virtual hosts we have a different IP/port combination for every virtual host, which means we can configure an SSL certificate for every virtual host.
When working with name based virtual hosts however, we have no unique identifier for the resource being requested except for the hostname. So the Apache HTTP server receives all requests for the virtual hosts it serves on the same IP/port combination. It isn't until after the SSL connection has been established that the HTTP server knows which virtual host is actually being requested based on the URL. The URL discloses the hostname for the virtual host.
Currently, an extension called SNI (Server Name Indication, RFC4366) can be used to circumvent this name based issue. Using this extension, the browser includes the requested hostname in the first message of its SSL handshake. Both the browser and Apache need to support SNI. If SNI on the server is used and the browser doesn't support SNI the browser will show a “untrusted certificate” warning. As of this writing (September 2015) most browsers do support SNI, except for the default browser on Android 2.x, MS Internet Explorer on MS Windows XP and versions of Oracle Java before 1.7 on any operating system.
To use SNI on the Apache server and prevent those “untrusted certificate” warnings because of browsers not supporting SNI it is possible to use a multidomain certificate. This certificate should contain all the needed domain names and should be used in the Apache configuration in a separate virtual host. In this virtual host no servername should be configured and because of this it will match all requests without a hostname and therefore serving all browsers without SNI support. Apache will show the content of the right requested (SNI) site but in combination with the multidomain certificate it will prevent warnings and errors.
Without SNI, a web server can serve multiple
name based virtual hosts over HTTPS but the SSL certificate being
used will be the same for all virtual hosts. The virtual hosts also
have to be part of the same domain, e.g.:
virtual02.example.com. The SSL certificate has
to be configured in such a way that the CN (Common Name) points to
a wildcard for the domain being used, e.g.:
The cryptographic security aspect of SSL is entirely based on trust. Mid-2013, there were about 650 Certificate Authorities. Every one of these authorities may pose as the 'weakest link', and therefore the security of your SSL certificate only goes as far as your trust in it's CA.
sslstrip is a tool that aides in a man-in-the-middle-attack on HTTPS traffic. This tool proves that SSL is subjective to technical flaws, so even if you do trust your CA you might be vulnerable to information disclosure.