Setting up a secure server with Apache and mod-ssl

Posted by Steve on Thu 14 Oct 2004 at 10:38

When it comes to setting up a secure webserver you have two choices apache-ssl, or mod-ssl. This simple introduction walks you through setting up and using the latter.

mod-ssl is a well known and well respected module for the popular Apache webserver.

On Debian systems you can install mod-ssl with one command executed as root 'apt-get install libapache-mod-ssl'.

(You can also find a documentation package libapache-mod-ssl-doc which will place useful information in /usr/share/doc/libapache-mod-ssl-doc).

Installing the mod-ssl package will install the module along some dummy certificate files which will be placed in /etc/apache/, however it will not touch your existing apache configuration or configure itself.

There are three things that you need to do to get mod-ssl working:

  • Generate an SSL certificate.
  • Load the module in your apache configuration file /etc/apache/httpd.conf and enable it.
  • Configure an Apache virtual host, or normal host, to use the SSL certificate.

In this example we will generate a dummy, or test, certificate. This will not be accepted by a browser because it will not be signed by a certificate authority (CA) which your browser is setup to trust.

If you wish you can cause it to become trusted, or if you are interested in setting up a real public SSL server you can pay a company such as Verisign to generate a certificate for you which they will sign.

Obtaining a real certificate is outside the scope of this piece, but it is very straightforward. All of the companies offering this service will ask you for some details and explain the process to you.

One thing that's worth noting is that you can only run one secure webserver upon a machine - as the certificates are server wide, and must contain the name of the site they are representing.

Because the initial connection and SSL negotiation occurs before the browser has sent its request it isn't possible for Apache to send the relevent server fingerprint, or options, in advance.

Generating an SSL certificate which you can use is very straightforward thanks to the mod-ssl-makecert command. This will guide you through the process of creating a certificate.

When you run mod-ssl-makecert you will be asked some questions, and here are some sample answers to get you going:

  • Do you really want to overwrite the existing certificate
    • Yes
  • What type of certificate do you want to create ?
    • "test" (2)
  • 1. Country Name (2 letter code) [XY]:
    • GB
  • 2. State or Province Name
    • Scotland
  • Locality Name
    • Edinburgh
  • Oranization name
    • Steve
  • Organization unit Name
    • Webserver Team
  • Common Name
    • The domain name you wish to be served via SSL
  • STEP 3: Generating X.509 certificate signed by Snake Oil CA [server.crt]
    • 3
  • STEP 4: Enrypting RSA private key with a pass phrase for security [server.key]
    • Choose to encrypt the key now, and enter a passphrase.

That's the key generated now, and setup for a specific hostname.

Now we need to setup our apache server to use it.

At the top of your apache configuration file /etc/apache/httpd.conf you need to add the following line:

LoadModule ssl_module /usr/lib/apache/1.3/mod_ssl.so

This will cause your server to load the mod-ssl module.

Then you need to cause your Apache process to listen upon the SSL port, 443, and add the SSL options to your configuration. Do this just before your first virtual host by adding the following to your file.


<IfModule mod_ssl.c>

##
##  SSL Global Context
##
##  All SSL configuration in this context applies both to
##  the main server and all SSL-enabled virtual hosts.
##


Listen 443

#
#   Some MIME-types for downloading Certificates and CRLs
#
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

#   Pass Phrase Dialog:
#   Configure the pass phrase gathering process.
#   The filtering dialog program (`builtin' is a internal
#   terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog  builtin

#   Inter-Process Session Cache:
#   Configure the SSL Session Cache: First either `none'
#   or `dbm:/path/to/file' for the mechanism to use and
#   second the expiring timeout (in seconds).
#SSLSessionCache        none
#SSLSessionCache        shm:logs/ssl_scache(512000)
SSLSessionCache         dbm:/var/run/ssl_scache
SSLSessionCacheTimeout  300

#   Semaphore:
#   Configure the path to the mutual explusion semaphore the
#   SSL engine uses internally for inter-process synchronization.
SSLMutex  file:/var/run/ssl_mutex

#   Pseudo Random Number Generator (PRNG):
#   Configure one or more sources to seed the PRNG of the
#   SSL library. The seed data should be of good random quality.
#   WARNING! On some platforms /dev/random blocks if not enough entropy
#   is available. This means you then cannot use the /dev/random device
#   because it would lead to very long connection times (as long as
#   it requires to make more entropy available). But usually those
#   platforms additionally provide a /dev/urandom device which doesn't
#   block. So, if available, use this one instead. Read the mod_ssl User
#   Manual for more details.
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
#SSLRandomSeed startup file:/dev/random  512
#SSLRandomSeed startup file:/dev/urandom 512
#SSLRandomSeed connect file:/dev/random  512
#SSLRandomSeed connect file:/dev/urandom 512

#   Logging:
#   The home of the dedicated SSL protocol logfile. Errors are
#   additionally duplicated in the general error log file.  Put
#   this somewhere where it cannot be used for symlink attacks on
#   a real server (i.e. somewhere where only root can write).
#   Log levels are (ascending order: higher ones include lower ones):
#   none, error, warn, info, trace, debug.
#SSLLog      /var/log/apache/ssl_engine_log
#SSLLogLevel info

</IfModule>

Now for whichever virtual host you wish to use SSL with you should modify it to read:


<VirtualHost newvhost.domain.org:443>
   <IfModule mod_ssl.c>

   SSLEngine on
   SSLCertificateFile    /etc/apache/ssl.crt/server.crt
   SSLCertificateKeyFile /etc/apache/ssl.key/server.key
   SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
     </IfModule>
</VirtualHost>


This will add the SSL options for your host - the normal things like DocumentRoot will be left unchanged.

Assuming all these changes have been made you should be able to restart your Apache server now. You must do a full stop and start for this to work.

Run:

root@skx:~/# /etc/init.d/apache stop
Stopping web server: apache.
root@skx:~/# /etc/init.d/apache start
Starting web server: apacheApache/1.3.26 mod_ssl/2.8.9 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide us with the pass phrases.

Server newvhost.domain.org:443 (RSA)
Enter pass phrase:

Ok: Pass Phrase Dialog successful.
.
root@skx:~/#

The passphrase being prompted for is the passphrase you entered when you created your key.

If you have any problems you should see them in the logfile /var/log/apache/error.log.

 

 


Posted by Steve (127.0.xx.xx) on Thu 14 Oct 2004 at 18:17
[ View Steve's Scratchpad | View Weblogs ]

A couple of comments about Apache and the SSL key are probably in order too.

If you do go ahead and implement this recipe as described you'll find that when you reboot /sbin/init will be stalled - and you won't be able to ssh in remotely.

This is because the Apache process will block, waiting to read the passphrase.

There are three approaches you can take here:

The latter is the approach I've chosen - which is not a great concern because I'm not using a real certificate.

Save the password in /etc/apache/ssl-password.

Write a simple script /etc/apache/get-password


#!/bin/sh
cat /etc/apache/ssl-password

Make sure other users can't read the password file:


chown root:root /etc/apache/ssl-password
chmod 600 /etc/apache/ssl-password
chmod 755 /etc/apache/get-password

Then update the Apache configuration to read:


SSLPassPhraseDialog  exec:/etc/apache/get-password

This will cause the Apache program to run the relevent command, and read the password from it's output.

-- Steve.org.uk

[ Parent | Reply to this comment ]

Posted by Anonymous (216.220.xx.xx) on Fri 11 Feb 2005 at 17:31
I know this is quite a bit after the fact, in terms of when this article was first posted, but I thought it was worth pointing out anyway. Documentation is really lacking on setting up ssl support for Apache2. Although I am probably not best suited to contribute an article on the subject, it may be worth a follow up article here.

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Fri 11 Feb 2005 at 17:46
[ View Steve's Scratchpad | View Weblogs ]

Thanks for the tip, I'll try and get one sorted out fairly soon.

Steve
-- Steve.org.uk

[ Parent | Reply to this comment ]

Posted by Anonymous (216.220.xx.xx) on Wed 9 Mar 2005 at 18:48
Steve,

When I first tried to set up Apache2 with SSL, there was realy no useful documentation out there, which can be frustrating for new people like me. Since then, however, a number of other people have written some helpful howtos for Apache2/SSL:

http://wiki.ev-15.com/debian:mail_system
http://www.ianmiller.net/article.php?id=13
http://mario.espaciolinux.com/apache2_ssl.html

It's all about the community!

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Wed 9 Mar 2005 at 18:54
[ View Steve's Scratchpad | View Weblogs ]

Good links, thanks.

I covered this briefly in the small guide Upgrading from Woody -> Sarge part 4 : Apache2.

I still intend to do a bigger writeup, but haven't managed it yet :(

Steve
-- Steve.org.uk

[ Parent | Reply to this comment ]

Posted by Anonymous (24.7.xx.xx) on Fri 26 May 2006 at 15:47
I though this article was great, but it didn't give me everthing I needed. Here are some references which I really found usefull.

[ Parent | Reply to this comment ]

Posted by Anonymous (62.7.xx.xx) on Tue 15 Mar 2005 at 16:31
"One thing that's worth noting is that you can only run one secure webserver upon a machine"

Just to clarify...

A signed certificate will apply to a domain and the IP address. However, any given host could have multiple IP addresses and therefore multiple SSL certificates.

[ Parent | Reply to this comment ]

Posted by Anonymous (132.229.xx.xx) on Mon 30 May 2005 at 10:09
if you want both the secure webserver and the ssl-server you need to add:

Listen 80

to the section. So this is a complete example:


# These will make apache listen to port 443 in addition to the
# standard port 80. HTTPS requests use port 443.
Listen 80
Listen 443

# Some MIME-types for downloading Certificates and CRLs
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl

# Semaphore:
# Configure the path to the mutual exclusion semaphore the
# SSL engine uses internally for inter-process synchronization.
SSLMutex file:/var/run/mod_ssl_mutex

# Inter-Process Session Cache:
# Configure the SSL Session Cache: First either None'
# or Dbm:/path/to/file' for the mechanism to use and
# second the expiring timeout (in seconds).
#SSLSessionCache dbm:/var/run/mod_ssl_scache
#SSLSessionCacheTimeout 300
SSLSessionCache none

# Pseudo Random Number Generator (PRNG):
# Configure one or more sources to seed the PRNG of the
# SSL library. The seed data should be of good random quality.
SSLRandomSeed startup file:/dev/urandom 512
SSLRandomSeed connect file:/dev/urandom 512

# Logging:
# The home of the dedicated SSL protocol logfile. Errors are
# additionally duplicated in the general error log file. Put
# this somewhere where it cannot be used for symlink attacks on
# a real server (i.e. somewhere where only root can write).
# Log levels are (ascending order: higher ones include lower ones):
# none, error, warn, info, trace, debug.
#SSLLog /var/log/apache/ssl_engine.log
#SSLLogLevel info

[ Parent | Reply to this comment ]

Posted by Anonymous (66.1.xx.xx) on Thu 23 Jun 2005 at 04:31
> If you wish you can cause it to become trusted, or if you
> are interested in setting up a real public SSL server you
> can pay a company such as Verisign to generate a certificate
> for you which they will sign.

It's appropriate to point out, is it not, that this statement is untrue for those of us using Debian to run private servers. We could also distribute a private version of FireFox with a built-in CA list. If you don't want to cover these topics, please consider rewriting this statement so that it's not absolute. It's also appropriate, is it not, to point out that CACert.org is trying to include its root cert in Mozilla. FWIW, I'm not Duane.

[ Parent | Reply to this comment ]

Posted by sanchiro (166.70.xx.xx) on Mon 29 Aug 2005 at 18:10
I just tried to setup my Apache to run securely. I get the following message when attempting an https: login:

Could not establish an encrypted connection because certificate presented by fyrenice.com is invalid or corrupted. Error Code: -8182

I set up my certificate with option 3, but apparently,

[ Parent | Reply to this comment ]

Posted by nigel_horne (212.159.xx.xx) on Mon 23 Jan 2006 at 14:10
The documentation worked well, thanks.

One issue is that mod_ssl isn't compatible with mod_gzip, so if you use the latter you must disable it for your secure server:

<virtualhost default:443>
<ifmodule mod_gzip.c>
mod_gzip_on No
</ifmodule>
...

This will avoid errors of the type

[Mon Jan 23 13:05:56 2006] [error] mod_gzip: EMPTY FILE [/tmp/_12522_101_2.wrk] in sendfile2
[Mon Jan 23 13:05:56 2006] [error] mod_gzip: Make sure all named directories exist and have the correct permission

[ Parent | Reply to this comment ]

Posted by nigel_horne (212.159.xx.xx) on Fri 6 Jul 2007 at 10:58
What about Apache2?

[ Parent | Reply to this comment ]

Posted by Steve (62.30.xx.xx) on Fri 6 Jul 2007 at 11:01
[ View Steve's Scratchpad | View Weblogs ]

Covered here. At the time this article was written Apache2 wasn't in Debian ..

Steve

[ Parent | Reply to this comment ]

Posted by Anonymous (212.159.xx.xx) on Fri 6 Jul 2007 at 12:02
Where are the apache2 instructions on this site?

[ Parent | Reply to this comment ]

Posted by Steve (62.30.xx.xx) on Fri 6 Jul 2007 at 13:01
[ View Steve's Scratchpad | View Weblogs ]

The comment you replied to had a link. Click it. Or use the search box and type in "apache2 ssl".

Seriously it's not hard..

Steve

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 258 votes ~ 1 comments )

 

 

Related Links