Apache and SSL – The Easy Way

It’s no secret–SSL is confusing. Creating and signing certificates is a convoluted process, especially from the command line. Fortunately, Debian-based systems have an easy way for Apache users to create, sign, and install their own SSL certs. This tutorial assumes that Apache is already installed with the default configuration.

### Configure SSL ###

Step one is to configure Apache to enable `mod_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.
Run ‘/etc/init.d/apache2 restart’ to activate new configuration!

The documentation referred to by that script’s output explains that, on Debian systems, an SSL certificate is installed automatically when the `ssl-cert` package is installed. It also outlines the process of creating a new certificate (useful when usen name-based virtual hosts). From the manual:

> If you install the ssl-cert package, a self-signed certificate will be
> automatically created using the hostname currently configured on your
> computer. You can recreate that certificate (e.g. after you have
> changed /etc/hosts or DNS to give the correct hostname) as user root
> with:
> make-ssl-cert generate-default-snakeoil –force-overwrite
> To create more certificates with different host names, you can use
> make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /path/to/cert-file.crt
> This will ask you for the hostname and place both SSL key and
> certificate in the file /path/to/cert-file.crt . Use this file with the
> SSLCertificateFile directive in the Apache config (you don’t need the
> SSLCertificateKeyFile in this case as it also contains the key). The
> file /path/to/cert-file.crt should only be readable by root. A good
> directory to use for the additional certificates/keys is
> /etc/ssl/private .

So, let’s create a new virtual host–one which can only be accessed via SSL.

Use the syntax from the manual to create a new certificate:

# make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/securehost.crt

When prompted, enter a hostname for the virtual host. For this example, the hostname is `securehost`.

### Create the Virtual Host ###

Once SSL is configured, it’s time to create the virtual host which will be accessed via SSL. Create the file */etc/apache2/sites-available/securehost* containing the following:

ServerName securehost

SSLEngine on
SSLCertificateFile /etc/ssl/private/securehost.crt

The above example assumes knowledge on how to configure a virtual host. Much of the necessary configuration has been omitted and replaced with an ellipsis.

It may be desirable to redirect port 80 traffic addressed to this hostname so that visitors do not have to explicitly designate the `https://` protocol. To do this, rename the virtual host file you just created to *securehost-ssl*, then create a new file called *securehost* containing the following:

Redirect / https://phpmyadmin/

### Configure Apache ###

All that’s left is to configure apache to recognize the new virtual hosts. The first step is to enable them:

# a2ensite securehost securehost-ssl
Enabling site securehost.
Enabling site securehost-ssl.
Run ‘/etc/init.d/apache2 reload’ to activate new configuration!

Before reloading Apache, it may be necessary to enable name-based virtual hosting for ports 80 and 443. In Debian, this is done in the file */etc/apache2/ports.conf*. Look for the lines that say `Listen 80` and `Listen 443`. Add the following options:

NameVirtualHost *:80
Listen 80

NameVirtualHost *:443
Listen 443

Finally, reload Apache to reflect the new configuration:

# service apache2 reload

### Try It ###

Now try navigating to https://securehost. This will most likely result in a certificate warning, which can be ignored/bypassed. Assuming that the document root contains an index page, it should be displayed here.

Once successful, try removing the **s** in the protocol to test the redirection from port 80. If redirection is working properly, the location bar in the browser should update to include the **s** again and the index page should again be displayed.

### Other Tips ###

It is possible for the same hostname to serve completely different sites based on the port specified. For example, a corporate site may display generic marketing info for visitors to port 80, but employees know that they need to use `https://` to access the login area. This keeps visitors from being presented with irrelevant employee prompts, and ensures that all employees are logging in securely.


Shred Empty Drive Space

If you are familiar with the **shred** command, you know it is an easy way to make sure sensitive data is *really* deleted. Shred overwrites a file with random data before deleting it, so that the original data cannot be recovered. Shred works by overwriting the data *in place*, or over top of the original file. But what if the file has already been deleted?

One way to destroy the data is to overwrite all unused space on the drive (or partition) with random data. The simplest way to do this is to invoke the **dd** command to create a new file full of random data:

dd if=/dev/urandom of=somefile.tmp bs=1024

The above command will run until the drive (or partition) runs out of space, writing random bits to a file called *somefile.tmp*, 1 kilobyte at a time.

Depending on the amount of free space, this could run for a long time. Also, depending on how you’ve configured your partitions and mount points, it may cause stability issues as the drive approaches full capacity. If you plan on running this command and walking away, you may want to append a command to remove the file when finished, to prevent crashes or errors due to low storage space:

dd if=/dev/urandom of=somefile.tmp bs=1024; rm somefile.tmp

If you’re short on time and willing to settle for a less secure method, you can replace */dev/urandom* with */dev/zero*, which should read in data much more quickly:

dd if=/dev/zero of=somefile.tmp bs=1024

This method can help keep your data secure, but it should be used sparingly. Writing to an entire drive is hard on the media, particularly flash-based media such as USB drives and SSDs, which have a limited number of write cycles. Use this method with care. If you have a lot of sensitive data, you may want to consider encrypting your files before writing to disk. But that’s a topic for another post.


Strong Password Generator in Python

I wanted a CLI-based strong password generator for Linux. `mkpasswd` is
nice, but I wanted something more flexible. I didn’t like having to
provide my own character sequence. I wanted something with a built-in
character sequence generator with an easy way to control the likelihood
of numbers and symbols. I wanted something that could read in a
character sequence from a file or standard input. And I wanted
something that not only had sensible default values, but was easily
configurable. It was one of those times where searching for such a tool
was a bigger hassle than writing my own. So I opened up vim and got to
work. The result is a Python-based password generator called

`mkstrongpw` can generate a character sequence based on four character
categories: lowercase letters, uppercase letters, numerical digits, and
non-alphanumeric symbols. By default, the likelihood (or odds) of each
character type is as follows: lowercase: 5/10; uppercase: 2/10; digits:
2/10; symbols: 1/10. These values can be easily changed via command
line options. A single, non-option argument can be passed, specifying a
filename to be read in as the character sequence. If this argument is a
single hyphen (-), standard input is used. Newlines and whitespace are
stripped from the beginning and end of each line of the input file.

By default, `mkstrongpw` uses its built-in sequence generator to
produce 10 passwords, 8 characters in length. Command line options can
be used to modify these values. Take a look at the following examples:

Default operation (no arguments):

$ mkstrongpw
U3Kja!/dev/null | uuencode – | mkstrongpw –
`<1^_NT_ 8":\7%R- DJSLJ*I` =MQ^]2D9 That's a broad overview of `mkstrongpw`. Use the `--help` option for more details. ### Get it ### * [Latest version (github)]( * [Download mkstrongpw 1.0 (.tar.gz)]( (md5sum: 34725c0509e0d0d9c5ef7441c8b5088c) * [View source](