wiki:Securing_a_website

Version 2 (modified by thomas, 9 months ago) ( diff )

--

Securing a website

Securing a website is usually one of the next steps after the Apache is serving it "It works!" page. That means enabling Apache to handle requests via https. The transport of data will be encrypted in both directions so reading whats on the wire will give a lot of garbage but no cleartext passwords of other critical data noone else should see.

Enabling https requires to install certificates on which the en- and decryption is based on. OpenSSL provides everything needed to create our own certificates and those certificates created by OpenSSL can be used by Apache pretty fine. The downside is that those certificates are self-signed which means that we, as we create the certificate, sign the certificate as being valid. All SSL engines complain about that (and so every browser does) as those certificates cannot really be trusted since everyone can quickly create one. How can a site verify that the certificate is valid when the only one who can be asked for that is the one who has created it? Technically, self-signed certificates are as good as commercial ones. The encryption based on self-signed certificates is as good - its just the fact that the origin of such a certificate cannot finally verified.

Solution is to order a certificate from big companies like Thawte or DigiCert (this are just examples, not a recommendation or so). They will ask a lot of questions so they can be sure that you are really you and the certificate will be created for a real installation. Finally, they will send you an invoice along with the certificate. That's contradictory to the recommendation that every site should communicate encrypted as many site owners refused to pay money.

Fortunately, there is a organization called LetsEncrypt who issues standard certificates at no cost. This has increased the amount of secured websites significantly. The certificates emitted by LetsEncrypt are accepted by all of the browsers so using them will not bring up any complains.

Prerequisites to get an "official" certificate

  • Site must be reachable from Internet
    If the site is not reachable from the internet, its hard to retrieve a LE-cert as LE will reach out to the site and query some special data. That means, the site must be reachable from the internet. Note that 'reachable from internet' means that the server you want a certificate be created for must be reachable from internet on http port 80.
  • Nameservice (DNS) must be set up
    To reach the site, the DNS records need to be in place. That means that the site you want to secure with a LE-cert must have a name, usually something like 'www.yourdomain.tld' or so.

Verification process by LetsEncrypt

LE needs to know that you are the administrator of the site. Usually an administrator has access to the server and this is what LE is using. They will create a set of data (two cryptic strings) which needs to be placed as a file in a specific path using one of the strings as filename. The file itself must contain the other string. When done, LE can access this well known path and read the file and its content. If the file is there and the content matches, LE assumes that you really have access to that site (as you were able to create that file there). If this test succeeds, LE will create the certificate. The webserver can now configured to use that certificate. After that is done, the port 80 can be closed and the requested file created before can be removed.

This process of placing some data somewhere can be used on other platforms, too. Another option - beside placing a file in the webservers path - is to modify DNS records. LE expects you to add a specific TXT value to the domain name entry. when this TXT value can be retrieved by LE using a command like 'dig', your authentication as the site administrator also succeeds. Updating DNS can be time consuming as it may last a while until the TXT record is propagated thru the world wide DNS hierarchy so LE is able to find it. Thats the reason why most admins will use the file-in-path variant.

Tools to access LetsEntrypt

LE provides an API which can be used for tools to request the tokens and guide you thru the creation process. There are several implementations, two of them are covered here:

  1. certbot
    This is a feature-rich implementation of a client. It is the one recommended by LE. Due to the features built in into the client, this package became quite big and has an overwhelming amount of options.
  2. uacme
    Uacme is a nice and handy C-implementation which is quite easy to build and to use.

Note: In the following sections are version numbers shown. This page is not updated on a regular basis, so it might happen that the versions are outdated and newer version of the packages are available. Using the newest available version is recommended. If the instructions do no longer work with newer versions, tell us on the mailing list.

Note: Make sure that your webserver works fine on http (port 80). It might be checked by pointing the browser to the URL you want to secure with the new certificate. In this example, point the browser to 'http://www.yourdomain.tld' and verify that this produces the expected content. Doublecheck that port 80 (http) is used.

Certbot

Download: ...
MD5 checksum: ...
Dependencies: ...

Installation

...

Usage

...

Uacme

Download: https://github.com/ndilieto/uacme/archive/refs/tags/v1.7.4/uacme-1.7.4.tar.gz
MD5 checksum: 0a8ff9a73e1d8006d4eee9908ca5f035
Dependencies: curl
Optional: gnutls

Installation

Modify a path matching the BLFS installation of the Apache server:

sed -e "s;/var/www/;/srv/www/;" \
    -i uacme.sh \
    -i uacme.1 \
    -i docs/uacme.html

Compile the package by executing

autoreconf                 &&
./configure --prefix=/usr  \
            --disable-docs &&
make

Now, install the package by executing the following as the root user:

make install

Usage

First, create an account and a private key. The directory used in the subsequent command (/etc/uacme.d) can be freely chosen. The certificates will be stored there and the webserver should have read access to it.

uacme -v -c /etc/uacme.d new

Next, initiate creating a certificate for your domain

uacme -v -c /etc/uacme.d issue www.yourdomain.tld

Several status and informational messages scroll on the screen until it halts and waits for your input. At this stage, look for a line beginning with uacme: challenge=http-01 ident=www.yourdomain.tld .... The whole line might look like

uacme: challenge=http-01 ident=www.yourdomain.tld token=kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4 key_auth=kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4.2evcXalKLhAybRuxxE-HkSUihdzQ7ZDAKA9EZYrTXwU

The data of token= and key_auth= are essential. We need them to create the authentication file. The (sample) data of above are used in the next commands. Execute them in a new terminal (as the actual one is allocated by the waiting uacme program:

mkdir /srv/www/.well-known/acme-challenge
echo "kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4.2evcXalKLhAybRuxxE-HkSUihdzQ7ZDAKA9EZYrTXwU" \
   > /srv/www/.well-known/acme-challenge/kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4

Both of that cryptic values are taken from the output of the uacme program. The filename is the value of token and its content is taken from key-auth.

After the file has been created, verify that the webserver has access to it by pointing your browser to http://www.yourdomain.tld/.well-known/acme-challenge/kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4. The value of the key-auth should appear as simple text in your browser.

If done and the response in the browser is ok, switch back to the terminal where uacme is waiting for an answer.

Press 'y' + Enter

and the program will continue to run. When finished, the certificate is placed in /etc/uacme.d/www.yourdomain.tld/cert.pem and the private key is stored in /etc/uacme.d/private/www.yourdomain.tld/key.pem. The '.well-known' directory can now be deleted as its content is usable only one time so there is no use in keeping it:

rm -rf /srv/www/.well-known

todo:

  • Show how uacme can be automated (avoid the manual input and file creation, can be done by a hook script included in the uacme package; used in cron below, but can also be used for initial setup)
  • Configure Apache (valid for both, certbot & uacme)

Refresh certificates

LE-certificates are a relatively short time valid (90? days) but they can refreshed so the operation of your website is not interrupted. Best way is to setup a cron job which checks whether there are certificates expiring soon and if there are any, renew them.

A typical crontab entry might look like

  • for certbot:
    $ ls /etc/cron.weekly/
    certbot.sh
    
    $ cat /etc/cron.weekly/certbot.sh
    #!/bin/bash
    date                                        > /tmp/certbot
    /usr/bin/certbot --quiet renew
    ret=$?
    echo "certbot return value=$ret"           >> /tmp/certbot
    
    # Restart daemons that use certs
    echo "Restarting apache from cron.weekly"  >> /tmp/certbot
    /usr/sbin/apachectl -k restart 2>&1        >> /tmp/certbot 
    
    echo "Restarting postfix from cron.weekly" >> /tmp/certbot
    /etc/init.d/postfix reload 2>&1            >> /tmp/certbot 
    ret=$?
    echo "/etc/init.d/postfix reload return value=$ret" >> /tmp/certbot
    
    echo "Restarting dovecot from cron.weekly" >> /tmp/certbot
    #/etc/init.d/dovecot reload 2>&1            >> /tmp/certbot
    pid=$(cat /run/dovecot/master.pid)
    kill -HUP $pid
    ret=$?
    echo "dovecot 'kill -HUP' return value=$ret" >> /tmp/certbot
    
  • for uacme:
    6 15 * * * /usr/bin/uacme -c /etc/uacme.d -h /usr/share/uacme/uacme.sh issue www.yourdomain.tld
    
    The argument -h /usr/share/uacme/uacme.sh makes uacme using a hook script to handle the output. With this, uacme can run unattended which is required when running as a cronjob.
Note: See TracWiki for help on using the wiki.