You are on page 1of 14

POLETTIX!

menu

Yellow Water al Kakadu National Park, Australia

Setup a Taskwarrior server


Do you use Taskwarrior and want to setup a private remote server for
backing stuff up and sync across multiple devices? Heres a few notes
you might find interesting.

Table of Contents
Table of Contents
What will we talk about?
Securing The Communications
Keys
Certificates
Certification Authorities
A chain of CAs
Which CA for Taskwarrior?
What about clients?
Expiration and Certificate Revocation List
Summary
Setup Remote Sync
User accounts
Alternative 1: DIY
Server configuration
Client configuration
Alternative 2: Real certificate
Server configuration
Client configuration
Quick consideration on clients authentication
Summing Up

What will we talk about?


First of all, the Taskwarrior site has comprehensive instructions on how
to setup your own sync server. Take it as a good starting point, it will
actually work quite well if you are doing all on your own.
In the following sections, we will begin with a brief introduction to
the concepts related to setting up the security part of the Taskserver.
This is by far the most tricky part of the setup, and the one more likely to
make you angry.
If youre in a hurry, you can skip the following section about securing
the communications, and jump directly to the configuration parts.
Enjoy!

Securing The Communications


Taskwarrior allows you to setup encrypted communications between
client and server, and rightly so. This is done using a protocol called
Transport Layer Security (or TLS), which requires you to use keys,
certificates, certification authorities and certificate revocation lists.
Sounds complicated? It is! We will not get into the details but just
look at the core concepts that matter in configuring Taskwarrior (see
Information security for additional resources).
When you care about security in syncing your local changes to a
remote server, the immediate issue you are probably worried with is
confidentiality, i.e.: how do I make sure that nobody else is able to
understand what me and the server are saying?
Another aspect you should care about is whether the system youre
syncing with is actually what it claims to be, and not something set up to
appear so. If you have confidentiality, but youre telling your secrets to
the wrong system thats not very secure, is it? This works also the
other way around, of course: they system accepting sync requests has to
be sure that you are who you claim to be, otherwise others might
impersonate you and mess with your data.
For both aspects (there are more, of course) maths come to the
rescue. In particular, encryption can give you confidentiality, while digital
signatures can give you reasonable proof of someones identity.

Keys
Keys
At the core of both are techniques that go under the umbrella of
asymmetric cryptography. Asymmetric means that for security reasons
each subject has two keys, one called private that has to be kept secret at
all times, and one public that can be distributed freely. They act as keys
where one can open whatever the other is capable of closing, so they
always come as a key pair.
For example, if you want to send a message (think of it like closing
the message in a box) you use the recipients public key to do that, and
be sure that only the recipient will be able to read it using the private
key. This is encryption.
On the other hand, if you want proof that the peer has the private
key corresponding to the public key you already have, you tell them to
lock a message you invent on the spot inside a box, and use their public
key to open the box: it will work only if the two keys form a pair. This is
signing, or putting a signature.

Certicates
At this point you might be thinking that this whole construction works
only as long as you actually trust that the public key you have actually
comes from the right source. The best way to ensure this is to get this
public key in some way that you trust, like e.g. meet the person and get
the key from a USB pen, or ask them to spell it on the phone. Whatever
makes you feel good for your level of secrecy.
While theoretically correct, this method has the non-trivial flaw of
being completely impractical for todays Internet size. This would mean
going to your bank and taking the key, going to Googles and take their
key, then Facebook, Twitter, and whatever service you use that leverages
TLS. This is where certificates come into play.
A certificate is basically a public key with some information
attached, in particular with the identity of the owner of that public key,
in the form of a Common Name (abbreviated CN), which is basically a
domain name owned by the organization (like www.example.com ). Its
like you had a key and put a label on it saying that this key is owned by
the same people that run www.example.com .

Certication Authorities
Of course everybody would be able to put a label about www.example.com
on their own public key, so were the catch? In addition to containing a
public key and a CN, a certificate also contains a signature by a third
party called the Certification Authority (abbreviated CA). So the
certificate says: this public key is owned by the people that also own this
CN, and this is guaranteed by the CA. At this point, of course, you must
have the CA certificate to verify that their signature is valid (because the
CA certificate will contain their public key and their identity!).
This shifts your trust from the people that run the CN to the people
that run the CA. While it may seem that this didnt improve things too
much (you still have to figure out how to trust the CA people!), this
actually makes things easier for you, because the same CA can emit
certificates for a lot of CNs. Hence, instead of going to everyones and
get their public key, you just go to the CA and get theirs: this will make
sure that all the certificate they signed actually come from the CNs
written in the certificates.

A chain of CAs

This same process might apply to CAs too. A little CA might ask a bigger
one to sign its certificate to declare that they are entitled to sign
certificates, and so on. Hence, when some web site sends you their
certificate, they might also send you a chain of intermediate CA
certificates where each certificate is about the CA that signed the
certificate immediately before, up to the last that is signed by some well-
known CA.
At this point you might ask: Hey! I didnt ever go to any well known
CA to get this rule-them-all CA certificate!. Right, you didnt. But most
browsers come with a bunch of pre-recorded certificates of well known
CAs, so heres how you got them behind the scenes. Now you should ask
yourself if you really trust your browser, shouldnt you?
There are quite some CAs out there, from the most famous like
Comodo, Symantec and GoDaddy, to minor ones. The most famous are
those whose certificates get installed in browsers and TLS libraries by
default. They have a non-trivial work to do, because they have to keep
their private keys very private (if someone stole them, they could be
used to issue false certificates!) and they also have to make sure that
people asking a certificate for a CN actually own that CN (i.e. they have
to go there instead of you). This is why certificates usually come with a
cost, which varies depending on the level of trust that they provide
(banks certificates undergo a much deeper scrutiny with respect to some
casual users home page), and this is also why browsers can show a
simple lock for lesser certificates up to a full green indication for the
most trusted ones.

Which CA for Taskwarrior?

Back to Taskwarrior, if you dont want to shell out money for setting up
your own sync server, you have a couple of alternatives:

you can set up your fake CA and sign your own certificates. In a
private context this makes absolutely sense, because you are sure
to trust everyone involved unless you suffer from multiple
personalities and you are not sure about a couple of them!
if you have a real domain hosted somewhere, you can get
certificates for free in a few places, one of which is Lets Encrypt.
They will issue you real certificates, although they are an
intermediate CA so they will also provide their own certificate that
is signed by a bigger well-known company.

Which way should you go? In a private or very controlled environment,


you can definitely go with the first option. The instructions you find in
Taskwarriors instructions page actually assume that this is they way you
are going to take. This will require a bit more complicated procedure on
the client side, because you will have to take care that the client actually
trusts the fake CA you set up (but you have the certificate for this fake
CA, so youre going to be fine).
On the other hand, if you plan to give access to a wider audience,
your best chance is probably to go for a certificate issued by a real CA,
like Lets Encrypt. Which one you choose depends on which guarantees
you want to have about the CA: the higher you need, the more you will
have to spend on it.

What about clients?


Up to now, we discussed how can your client be sure about the server
(which might be a web server, or a taskd installed somewhere). For the
web, this is most of the times all that you need.
In the case of Taskwarrior this is not all, though. Put yourself into
taskd s shoes: should it blindly accept all updates that claim to come
from you as valid? What if someone else tries to sync updated pretenting
to be you, and mess up with your precious activities?
The same story we saw above with key pairs and certificates applies to
clients as well. So, you can generate a pair of key, set the private one in
the client and keep the public one in the server, inside a certificate that
tells who you are.

Expiration and Certicate Revocation List


One last thing to keep in mind is that certificates are usually issued with
an expiration date. The more time passes, the more the public key can be
subject to an attack to try to figure out the associated private key, for
example; or the more you might have leaked your private key. So,
although its a hassle to take care of renewing your keys and certificates,
this is actually a safety measure.
In addition to expiration, you might want to invalidate certificates
ahead of time. This might e.g. happen if you discover that the private
key was leaked somehow. For this reason. so-called Certificate Revocation
Lists (abbreviated CRL) can help you track certificates that arent trusted
anymore, even if they have a valid signature and have not expired yet.
The CRL is usually kept by the CA, because its the entity that
guarantees about the validity of the certificates it signs.

Summary
After this long digression, we come to the following summary
conclusions:

there are three types of entities involved in this whole TLS story:
users
servers
CAs
there are three basic kind of artifacts that we have to take care of:
private keys, which we will simply call keys in the following;
(public) certificates
(public) certificate revocation lists

Each entity involved (users, servers, CAs) will have the first two kind of
artifact (a key and a certificate), while CAs will also have a CRL. So, you
will have to deal with the following artifacts:

user key and user certificate


server key and server certificate
CA key, CA certificate and CA CRL.

It helps to remember that they are all data that is saved into files,
although there might be a many-to-one relation (e.g. a file containing
certificates might contain a server certificate, followed by a chain of CA
certificates up to one signed by a well-known CA).

Setup Remote Sync


Before starting, we will assume that:

you have some degree of control over a domain. It must not


necessarily be a real one, i.e. visible from the outside or registered
in official DNSs; it suffices that you can somehow control the
resolution process in clients so that that particular domain points
to the IP Address of the Taskserver you set up. In this example, we
will call this domain taskd.example.com , although we will also
assume that it is stored in environment variable DOMAIN ;
you will use the port stored in the environment variable PORT ,
which you already ensured that will be available elsewhere (e.g.
you opened the right ports in the firewall, etc.). Just for you to
know, its customary to set the port to 53589 ;
your Taskserver software is already installed and ready to be
started, only missing the right configuration for security. We will
assume it is stored in a directory whose path is stored in
environment variable TWSERVER ;
your Taskwarrior software in the client is already installed and
working. We will assume that its base directorys path is stored in
environment variable TWCLIENT .

User accounts
Whatever the way you choose to configure keys, certificates etc. you will
need to enable your user(s) for syncing their tasks, ensuring that they
will not trump onto each other.
Users can be grouped in organizations. To create an organization you
can issue the following command on the server:

taskd add org name-of-your-org


where name-of-your-org can be whatever you choose to call your
organization. Suggestion: use letters, numbers, underscores and
hyphens only. If you plan to keep things simple (all users inside the same
organization) this is the only time you will need to issue this command.
After this, for each user you want to create you have to run the
following command, still on the server:

taskd add user name-of-your-org 'Name O. User'

You will get back something like this:

New user key: cf31f287-ee9e-43a8-843e-e8bbd5de4294


Created user 'Name O. User' for organization 'name-of-your-org'

where the key will be different (each user will get its own unique key).
In the following, we will assume that environment variables
ORGANIZATION , USER_NAME and USER_KEY contain what you think that
they should contain. In our example, they contain respectively the
strings name-of-your-org , Name O. User' and
cf31f287-ee9e-43a8-843e-e8bbd5de4294`.

Alternative 1: DIY
If your setup is sufficiently restricted and you have good control over
your clients, you can go the do it yourself way and be the CA of yourself.
This is also the easiest thing to do with what ships with Taskwarrior by
default, because there are scripts that allow you to do exactly this.
All the heavy lifting is done within a directory named pki .
Depending on the distribution/system you use, it might be located in a
different location; we will let you find it and wait patiently here. Just for
a hint, this is what you should find in that directory (this example was
run in Alpine Linux):

/ $ cd /usr/share/taskd/pki/
/usr/share/taskd/pki $ ls -l
total 28
-rw-r--r-- 1 root root 1272 May 10 2015 README
-rwxr-xr-x 1 root root 664 May 10 2015 generate
-rwxr-xr-x 1 root root 633 May 10 2015 generate.ca
-rwxr-xr-x 1 root root 778 May 10 2015 generate.client
-rwxr-xr-x 1 root root 889 May 10 2015 generate.crl
-rwxr-xr-x 1 root root 866 May 10 2015 generate.server
-rw-r--r-- 1 root root 138 May 10 2015 vars

Before running anything, you MUST edit the file vars , that initially
appears like this:

BITS=4096
EXPIRATION_DAYS=365
ORGANIZATION="Gteborg Bit Factory"
CN=localhost
COUNTRY=SE
STATE="Vstra Gtaland"
LOCALITY="Gteborg"

The only, single important thing that you MUST change is the CN
setting (remember the Common Name? Well, this is it!). As we are
assuming to operate taskd.example.com , this is what we have to setup
here. It does not hurt to change a few of the other parameters of course,
but its not strictly necessary. This is how we will change it in this
example:

BITS=4096
EXPIRATION_DAYS=365
ORGANIZATION="Yadda Yadda Yadda"
CN=taskd.example.com
COUNTRY=IT
STATE="Lazio"
LOCALITY="Roma"

It does not hurt to repeat: change CN to your domain.


Now, you just run the shell script generate inside the directory, and
let the magic happen. It boils down to the following four commands (at
least as of release 2.5.1):

./generate.ca
./generate.server
./generate.crl
./generate.client client
It should be pretty clear at this point:

first of all, a fake CA is generated. This is us acting as a CA, that is


not widely recognised but that we can totally trust! This step
generates files ca.key.pem (the CAs private key) and
ca.cert.pem (the public certificate). This certificate is somehow
special, because it tells two things:
first, that its from a Certification Authority, so it should be
trusted when used for signing other certificates;
second, that its signed by the certificate owner itself. This
is why its also called a self-signed certificate.
Now that we have a CA, we can sign certificates for other entities,
i.e. servers and clients. The second step takes care to generate the
servers key pair, saving the private key in server.key.pem and
generating a certificate that includes the public key in
server.cert.pem . This is where the details in file vars are used.
The third step generates a Certificate Revocation List. This is
probably overkill for a small setup, but it does not hurt to have one
anyway. The step generates the file server.crl.pem .
The fourth step generates a (private) key and a certificate for a
client, so that it will be able to demonstrate its identity back to the
server. This step generates client.key.pem and client.cert.pem .

One interesting thing is that the CA we created in the first step has a
double role here, because it signs the certificates for both the server and
the clients. This is not the most generic setup that you can have, as we
will see below; for the moment, we will stick with it.
This is a summary of the generated files and where you should put
them:

SERVER CLIENT
--------------------------- ---------------------------
"$TWSERVER"/server.key.pem "$TWCLIENT"/client.key.pem
"$TWSERVER"/server.cert.pem "$TWCLIENT"/client.cert.pem
"$TWSERVER"/server.crl.pem "$TWCLIENT"/ca.cert.pem
"$TWSERVER"/ca.cert.pem

To be completely right, you should also ensure to keep ca.key.pem


somewhere, because it will be needed to regenerate the server.crl.pem
file in case of need.
Server conguration

Now you only have to do the configurations. On the server you have to
setup the files we generated and moved into the right location, plus
where the daemon should be listening (we will copy also a couple of
additional configurations while we are at it):

taskd config --force -- server "$DOMAIN:$PORT"


taskd config --force -- log "$TWSERVER"/taskd.log
taskd config --force -- pid.file "$TWSERVER"/taskd.pid
taskd config --force -- server.key "$TWSERVER"/server.key.pem
taskd config --force -- server.cert "$TWSERVER"/server.cert.pem
taskd config --force -- server.crl "$TWSERVER"/server.crl.pem
taskd config --force -- ca.cert "$TWSERVER"/ca.cert.pem

Client conguration

Configuration on the client involves the following items:

tell the client where the server for synchronization is;


make sure we will accept the servers certificate. As this is signed
by our fake CA, we have to make sure that the TLS library will
accept it by loading the fake CA certificate at the right time;
set the trust model to the strict est mode, because we care about
security (otherwise, you wouldnt be reading this!)
tell the client about our own user identifier and the organization
we will save our data within;
set the client key and certificate so that it will be able to provide
them when requested by the server.

This is what we can do then:

task config --force -- taskd.server "$DOMAIN:$PORT"


task config --force -- taskd.ca "$TWCLIENT"/ca.cert.pem
task config --force -- taskd.trust strict
task config --force -- taskd.credentials "$ORGANIZATION/$USER_NAME/$USER_KEY"
task config --force -- taskd.key "$TWCLIENT"/client.key.pem
task config --force -- taskd.certificate "$TWCLIENT"/client.cert.pem

Done!
Alternative 2: Real certicate
Alternative 2: Real certicate
First thing to do: just do Alternative 1 and start from there. Its really not
much different and you dont really want to read it again.
Done? OK, now lets move on.
One thing to keep in mind is that with real certificates there are two
CAs that come into play:

the CA that signs your server certificate, and


the CA that signs your clients certificates.

In the previous example, we used the same CA for both, but in this case
the first one is outside of our control (unless you are the people behind
some well-known CA, of course!) while the second one most probably
will remain ours. Why? Well, those certificates are needed to ensure that
the people that ask to connect actually were allowed by us, so its quite
reasonable that we do still provide them without asking those people to
pay for a certificate.
To start with, just repeat whatever was described in Alternative 1
above. We will be using probably a different key and surely a different
certificate for the server, but all the rest remains exactly as described so
its worth to just repeat the steps.
In this example, we will assume that you get your certificate with
Lets Encrypt. Its a bit of work to set it up, but after that you can
automate the renewal of the certificate (as a matter of fact, this
automation is encouraged) and forget about it in some crontab line.
Now go get your certificate for your domain. We will wait here until
youre done.
Really.
At the end you will end up with the same files as in the previous
section, with the addition of a domain.key and a domain.crt file that
come from the setup for Lets Encrypt. Its worth to remember that you
MUST NEVER send your domain.key to anyone, including Lets Encrypt!

Server conguration

On the server side, all you have to do is copy domain.key over


server.key.pem and domain.crt over server.cert.pem , then restart
taskd if it was running using the previous certificates.
This is really all that you need to do on the server side. The CA
certificate in the server does not change, because this is the certificate for
the CA that generates the clients certificates, not the servers.

Client conguration

Theoretically, on the client side you should not need to do anything. This
is because the certificate file you get from Lets Encrypt should already
contain two certificates inside, one for your server followed by one for
the CA of Lets Encrypt (this latter signed by a well-known CA, of
course). Clients are able to follow the chain of certificates in a file they
receive, automatically.
Anyway, as of version 2.5.1 you will discover that this does not really
work out of the box. Why is this? Well, its because the code does not
load the well-known certificates, so the client follows the chain of
certificates (correct) but it eventually lands on a CA that it does not
know of, despite its a well-known one. This will be probably corrected in
some future release (although most probably it will work only for clients
compiled against a version of the library GnuTLS that is at least 3.0.20).
So are we out of luck? Not really. After completing the configuration
like in the Alternative 1 above, all we have to do is to get the last (CA)
certificate from the new server certificate, and save it inside file
$TWCLIENT/ca.cert.pem in the client.
Its easy to extract the certificate, just look for the last section in the
file that is included between clear BEGIN CERTIFICATE and END
CERTIFICATE markers:

-----BEGIN CERTIFICATE-----
MIIGNTCCBR2gAwIBAgISAyzjWXqpc+Xbd... \
.................................... | THIS IS THE SERVER CERTIFICATE
pOlsXXuFidxtdN6ey7iA+SgLE+ZEZWfC9... /
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc... \
.................................... | THIS IS THE CA CERTIFICATE
+X+Q7UNKEkROb3N6KOqkqm57TH2H3eDJA... /
-----END CERTIFICATE-----

Now, from the next invocation of task sync , the server will send the
new shiny real certificate, and the client will not reject it because its
configured to trust the Lets Encrypt CA. YAY!

Quick consideration on clients authentication


You might have noticed at this point that theres something going on
with client authentication. This actually happens at two levels:

at the TLS level, the server asks the client for its client certificate;
at the Taskwarrior level, the server asks the client for the
organization, the username and the user key (the one generated by
taskd , not the TLS private key!) that acts both as a unique
identifier for the account AND as a password.

These two authentications are not actually connected together, although


they probably should. In particular, it would be great if the clients
certificate CN included the string we are setting for taskd.credentials
in the client.
Anyway, this is not how it works today. So, for any practical reason,
you dont strictly need to generate a new TLS key and certificate for each
new user you want to manage because everyone will just be fine with
the client.key.pem and client.cert.pem files you generated in the
first place. Which also means: if some of your users figures out the
username and the taskd user key of someone else, they will be able to
sync against them. Theres always space for improvement!

Summing Up
Taskwarrior is really a great and useful piece of code. Being able to setup
your own Taskserver for syncing up all your devices is a very useful
addition too; doing it properly requires some attention but its really not
difficult as long as you follow the instructions carefully.
Using it with real certificates is definitely doable, although the
process can be enhanced to make it even simpler (with less
configurations needed on the client side). Even now its not really
difficult and just requires one step more than what would be ideal.
The clients authentication process should probably relate user
accounts managed by Taskwarrior to the certificates generated for
clients. This would allow better restriction of access (like you can access
a specific resource if and only if you know the resources details and you
also have the certificate attached to that resource) and also an effective
usage of the Certificate Revocation List. Anyway, Taskwarrior is under
active development and you might be the one to implement those
enhancements!
Until then happy tasking!

You might also like