Securing Radicale

Following on from the previous post, this post is going to look at securing Radicale.

Encrypting network traffic

Radicale can use TLS/SSL to encrypt all network traffic between the server and client. For this post, the example is going to use a self-signed certificate. However you can obviously used a certificate signed by an external CA.

The OpenSSL req command can be used to generate a private key and self signed certificate:

openssl req -x509 -newkey rsa:4096 \
  -keyout /etc/radicale/key.pem \
  -out /etc/radicale/cert.pem \
  -days 365 -nodes  \
  -subj '/C=GB/ST=State/L=Locality/O=Organization/OU=Organization unit/CN=raspberrypi'

Once the private key has been generated, it's a good idea to update permissions on the key, as by default it will be world readable:

chmod 640 /etc/radicale/cert.pem
chown root:radicale /etc/radicale/cert.pem

The next step is to add the following configuration to the server section of the Radicale config (/etc/radicale/config):

[server]
ssl = True
certificate = /etc/radicale/cert.pem
key = /etc/radicale/key.pem

Note: if you used an external CA and have a certificate chain, it should be added at the end of the certificate file.

Finally restart the Radicale service:

systemctl restart radicle.service

Ciphers and protocols

It's also possible to tweak the cipher and protocol options. By default Radicale only uses TLSv1 or greater and "strong" ciphers. The Nmap ssl-enum-ciphers script can be used to verify this:

$ nmap --script +ssl-enum-ciphers -p 5232 raspberrypi

Starting Nmap 6.47 ( http://nmap.org ) at 2017-05-11 22:22 UTC
Nmap scan report for raspberrypi (127.0.1.1)
Host is up (0.00016s latency).
PORT     STATE SERVICE
5232/tcp open  sgi-dgl
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
...

...

|       NULL
|_  least strength: strong

For most users the defaults should be fine, however you can explicitly set ciphers and protocols in the server section of the config. For example to only use AES, the following would be added to the config:

[server]
ciphers = AES

Radicale uses the Python ssl module, so for more information please refer to the sections on cipher selection and protocol versions in the Python documentation.

Adding authentication

The auth section is used to configure authentication. Radicale supports a few different authentication methods, one of the easiest to configure is htpasswd. First make sure htpasswd is available, if it's missing you can install the apache2-utils package:

apt-get install apache2-utils python-passlib

Use htpasswd to create a new htpasswd file:

htpasswd -s -c /etc/radicale/users username

Note: htpasswd can use a few different hashing algorithms. Unfortunately the Raspbian version of Radicale (v0.9), doesn't support BCRYPT or MDR-APR1 which is why -s is used for SHA1. Support for both BCRYPT and MDR-APR1 was introduced in Version 1.0 though...

Once /etc/radicale/htpasswd has been created update the file permissions and ownership:

chmod 640 /etc/radicale/htpasswd
chown root:radicale /etc/radicale/htpasswd

Add the following to /etc/radicale/config:

[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = sha1

[rights]
type = authenticated

Finally restart Radicale to pick up the configuration change:

systemctl restart radicle.service

Note: the authenticated option allows authenticated users to read and write all collections managed by Radicale. Refer to the Radicale rights management docs for information on more granular permissions.