32.6 Setting Up a Secure Web Server with SSL

Whenever sensitive data, such as credit card information, is transferred between Web server and client, it is desirable to have a secure, encrypted connection with authentication. mod_ssl provides strong encryption using the secure sockets layer (SSL) and transport layer security (TLS) protocols for HTTP communication between a client and the Web server. Using SSL/TLS, a private connection between Web server and client is established. Data integrity is ensured and client and server can authenticate each other.

For this purpose, the server sends an SSL certificate that holds information proving the server's valid identity before any request to a URL is answered. In turn, this guarantees that the server is the uniquely correct end point for the communication. Additionally, the certificate generates an encrypted connection between client and server that can transport information without the risk of exposing sensitive, plain-text content.

mod_ssl does not implement the SSL/TLS protocols itself, but acts as an interface between Apache and an SSL library. In SUSE Linux Enterprise Server, the OpenSSL library is used. OpenSSL is automatically installed with Apache.

The most visible effect of using mod_ssl with Apache is that URLs are prefixed with https:// instead of http://.

32.6.1 Creating an SSL Certificate

To use SSL/TLS with the Web server, you need to create an SSL certificate. This certificate is needed for the authorization between Web server and client, so that each party can clearly identify the other party. To ensure the integrity of the certificate, it must be signed by a party every user trusts.

There are three types of certificates you can create: a dummy certificate for testing purposes only, a self-signed certificate for a defined circle of users that trust you, and a certificate signed by an independent, publicly-known certificate authority (CA).

Creating a certificate is a two step process. First, a private key for the certificate authority is generated then the server certificate is signed with this key.

HINT: For More Information

To learn more about concepts and definitions of SSL/TLS, refer to http://httpd.apache.org/docs/2.4/ssl/ssl_intro.html.

Creating a Dummy Certificate

To generate a dummy certificate, call the script /usr/bin/gensslcert. It creates or overwrites the files listed below. Use gensslcert's optional switches to fine-tune the certificate. Call /usr/bin/gensslcert -h for more information.

  • /etc/apache2/ssl.crt/ca.crt

  • /etc/apache2/ssl.crt/server.crt

  • /etc/apache2/ssl.key/server.key

  • /etc/apache2/ssl.csr/server.csr

A copy of ca.crt is also placed at /srv/www/htdocs/CA.crt for download.

IMPORTANT: For Testing Purposes Only

A dummy certificate should never be used on a production system. Only use it for testing purposes.

Creating a Self-Signed Certificate

If you are setting up a secure Web server for an intranet or for a defined circle of users, it is probably sufficient if you sign a certificate with your own certificate authority (CA). Note that visitors to such a site will see a warning like this is an untrusted site, as Web browsers do not recognize self-signed certificates.

IMPORTANT: Self-Signed Certificates

Only use a self-signed certificate on a Web server that is accessed by people who know and trust you as a certificate authority. It is not recommended to use such a certificate for a public shop, for example.

First you need to generate a certificate signing request (CSR). You are going to use openssl, with PEM as the certificate format. During this step, you will be asked for a passphrase, and to answer several questions. Remember the passphrase you enter as you will need it in the future.

sudo openssl req -new > new.cert.csr
Generating a 1024 bit RSA private key
writing new private key to 'privkey.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) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (for example server FQDN, or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Fill in your passphrase,

...fill it in once more (and remember it).

Fill in your 2 letter country code, such as GB or CZ.

Fill in the name of the state where you live.

Fill in the city name, such as Prague.

Fill in the name of the organization you work for.

Fill in your organization unit, or leave blank if you have none.

Fill in either the domain name of the server, or your first and last name.

Fill in your work e-mail address.

Leave the challenge password empty, otherwise you will need to enter it every time you restart the Apache Web server.

Fill in the optional company name, or leave blank.

Now you can generate the certificate. You are going to use openssl again, and the format of the certificate is the default PEM.

Generating the Certificate

  1. Export the private part of the key to new.cert.key. You will be prompted for the passphrase you entered when creating the certificate signing request (CSR).

    sudo openssl rsa -in privkey.pem -out new.cert.key
  2. Generate the public part of the certificate according to the information you filled out in the signing request. The -days option specifies the length of time before the certificate expires. You can revoke a certificate, or replace one before it expires.

    sudo openssl x509 -in new.cert.csr -out new.cert.cert -req \
    -signkey new.cert.key -days 365
  3. Copy the certificate files to the relevant directories, so that the Apache server can read them. Make sure that the private key /etc/apache2/ssl.key/server.key is not world-readable, while the public PEM certificate /etc/apache2/ssl.crt/server.crt is.

    sudo cp new.cert.cert /etc/apache2/ssl.crt/server.crt
    sudo cp new.cert.key /etc/apache2/ssl.key/server.key

HINT: Public Certificate Location

The last step is to copy the public certificate file from /etc/apache2/ssl.crt/server.crt to a location where your users can access it to incorporate it into the list of known and trusted CAs in their Web browsers. Otherwise a browser complains that the certificate was issued by an unknown authority.

Getting an Officially Signed Certificate

There are several official certificate authorities that sign your certificates. The certificate is signed by a trustworthy third party, so can be fully trusted. Publicly operating secure Web servers usually have an officially signed certificate. A list of the most used Certificate Authorities (CAs) is available at https://en.wikipedia.org/wiki/Certificate_authority#Providers.

When requesting an officially signed certificate, you do not send a certificate to the CA. Instead, issue a Certificate Signing Request (CSR). To create a CSR, run the following command:

openssl req -new -newkey rsa:2048 -nodes -keyout newkey.pem -out newreq.pem

You are asked to enter a distinguished name. This requires you to answer a few questions, such as country name or organization name. Enter valid data—everything you enter here later shows up in the certificate and is checked. You do not need to answer every question. If one does not apply to you or you want to leave it blank, use .. Common name is the name of the CA itself—choose a significant name, such as My company CA. Last, a challenge password and an alternative company name must be entered.

Find the CSR in the directory from which you called the script. The file is named newreq.pem.

32.6.2 Configuring Apache with SSL

The default port for SSL and TLS requests on the Web server side is 443. There is no conflict between a regular Apache listening on port 80 and an SSL/TLS-enabled Apache listening on port 443. In fact, HTTP and HTTPS can be run with the same Apache instance. Usually separate virtual hosts are used to dispatch requests to port 80 and port 443 to separate virtual servers.

IMPORTANT: Firewall Configuration

Do not forget to open the firewall for SSL-enabled Apache on port 443. This can be done with YaST as described in Section 15.4.1, Configuring the Firewall with YaST, (↑Security Guide).

The SSL module is enabled by default in the global server configuration. In case it has been disabled on your host, activate it with the following command: a2enmod ssl. To finally enable SSL, the server needs to be started with the flag SSL. To do so, call a2enflag SSL (case-sensitive!). If you have chosen to encrypt your server certificate with a password, you should also increase the value for APACHE_TIMEOUT in /etc/sysconfig/apache2, so you have enough time to enter the passphrase when Apache starts. Restart the server to make these changes active. A reload is not sufficient.

The virtual host configuration directory contains a template /etc/apache2/vhosts.d/vhost-ssl.template with SSL-specific directives that are extensively documented. Refer to Virtual Host Configuration for the general virtual host configuration.

To get started, copy the template to /etc/apache2/vhosts.d/MYSSL-HOST.conf and edit it. Adjusting the values for the following directives should be sufficient:

  • DocumentRoot

  • ServerName

  • ServerAdmin

  • ErrorLog

  • TransferLog

Name-Based Virtual Hosts and SSL

By default it is not possible to run multiple SSL-enabled virtual hosts on a server with only one IP address. Name-based virtual hosting requires that Apache knows which server name has been requested. The problem with SSL connections is, that such a request can only be read after the SSL connection has already been established (by using the default virtual host). As a result, users will receive a warning message stating that the certificate does not match the server name.

SUSE Linux Enterprise Server comes with an extension to the SSL protocol called Server Name Indication (SNI) addresses this issue by sending the name of the virtual domain as part of the SSL negotiation. This enables the server to switch to the correct virtual domain early and present the browser the correct certificate.

SNI is enabled by default on SUSE Linux Enterprise Server. To enable Name-Based Virtual Hosts for SSL, configure the server as described in Name-Based Virtual Hosts (note that you need to use port 443 rather than port 80 with SSL).

IMPORTANT: SNI Browser Support

SNI must also be supported on the client side. However, SNI is supported by most browsers, except for certain older browsers. For more information, see https://en.wikipedia.org/wiki/Server_Name_Indication#Support.

To configure handling of non-SNI capable browsers, use the directive SSLStrictSNIVHostCheck. When set to on in the server configuration, non-SNI capable browser will be rejected for all virtual hosts. When set to on within a VirtualHost directive, access to this particular host will be rejected.

When set to off in the server configuration, the server will behave as if not having SNI support. SSL requests will be handled by the first virtual host defined (for port 443).