Try   HackMD

Drand: Operator Guide

This document explains the technical steps necessary to setup and maintain a drand network. The first section explains how to install drand. The second section explains how to setup a distributed drand network. Finally, the third section shows the most commonly used commands to maintain the network such as adding/removing nodes) and to get information about a running drand daemon.

Hardware requirement

Drand is a lightweight process that runs as a daemon and as such can run with any low profile CPU. There is a minimum disk space of 1GB. As well, given the nature of drand, a good uptime must be guaranteed!

NOTE: This minimum disk space is already way over what drand actually uses. Over the course of one year, given a period of 1mn and a beacon of

48+48+8=104 bytes, drand stores only
1046024365=54
MB !

NOTE2: Expect this section to change to also include requirements in terms of "sysadmin time" if one wants to participate in the global network: there are operations to run if case there is a failure or new members join in.

Install drand

Installation

Drand can be installed via Golang or Docker. By default, drand saves the configuration files such as the long-term key pair, the group file, and the collective public key in the directory $HOME/.drand/.

Via Golang

Make sure that you have a working Golang installation and that your GOPATH is set. Then install drand via:

go get -u github.com/drand/drand

Via Docker

The setup is explained in README_docker.md.

TLS setup: Nginx with Let's Encrypt

Running drand behind a reverse proxy is the default method of deploying drand. Such a setup greatly simplify TLS management and network issues (renewal of certificates, rate limiting, etc). We provide here the minimum setup using nginx and certbot - make sure you have both binaries installed with the latest version; nginx version must be at least >= 1.13.10 for gRPC compatibility.

  • First, add an entry in the nginx configuration for drand:
# /etc/nginx/sites-available/default
server {
  server_name drand.nikkolasg.xyz;
  listen 443 ssl http2;
 
  # all grpc calls
  location / {
    grpc_pass grpc://localhost:8080;
  }
  
  # JSON REST endpoints, converted from gRPC
  location /group/ {
    proxy_pass http://localhost:8080;
    proxy_set_header Host $host;
  }
}  

Note: you can change

  1. the port on which you want drand to be accessible by changing the line listen 443 ssl http2 to use any port.
  2. the port on which the drand binary will listen locally by changing the line proxy_pass http://localhost:8080; and grpc_pass grpc://localhost:8080; to use any local port.
  • Run certbot to get a TLS certificate:
sudo certbot --nginx

Don't forget to renew your certificate or setup an automatic renewal cron job !

  • Running drand now requires to add the following options:
drand start --tls-disable --listen 127.0.0.1:8080

The --listen flag tells drand to listen on the given address instead of the public address generated during the setup phase (see below).
The --tls-disable is a historical flag to explicitely show that the binary do not accept secured connections.

Setting the certificates manually: Drand also accepts the path of the certificates to use them directly, without passing through nginx:

drand start --tls-key <path> --tls-cert <path>

Setup the network

This section explains in details the workflow to have a working group of drand nodes generate randomness. On a high-level, the workflow looks like this:

  • Starting Drand: starting each drand daemon with the group file
  • Distributed Key Generation: each drand node collectively participates in the DKG.
  • Randomness Generation: the randomness beacon automatically starts as soon as the DKG protocol is finished.

By default, drand saves the configuration files such as the long-term key pair, the group file, and the collective public key in the directory $HOME/.drand/. One can choose a different configuration folder with the --config <path> command-line option.

Group Configuration

All information regarding a group of drand nodes necessary for drand to function properly are located inside a group.toml configuration file.
The generation of this configuration file consists of two steps:

  1. Generate the long-term key pair for each node
  2. Setup the group configuration file

Long-Term Key

To generate the long-term key pair drand_id.{secret,public} of the drand daemon, execute

drand generate-keypair <address>

where <address> is the address from which your drand daemon is reachable. The address must be reachable over a TLS connection. In case you need non secured channel, you can pass the --tls-disable flag.

Randomness Beacon Period

By default, a randomness beacon has a period of 1min, i.e. new randomness is generated every minute. If you wish to change the period, you must include that information inside the group configuration file. You can do by appending a flag to the command such as :

drand group --period 2m <pk1> <pk2> ... <pkn>

Or simply by editing manually the group file afterwards: it's a TOML configuration file. The period must be readable by the time package.

NOTE: At this stage, this group file MUST be distributed to all participants !

Starting the drand daemon

The daemon does not go automatically in background, so you must run it with & in your terminal, within a screen / tmux session, or with the -d option enabled for the docker commands. Once the daemon is running, the way to issue commands to the daemon is to use the control functionalities. The control client must run on the same server as the drand daemon, so only drand administrators can issue command to their running daemons.

Drand behing nginx

The official setup makes it easy to launch drand:

drand start --tls-disable --listen 127.0.0.1:8080

The --listen flag tells drand to listen on the given address instead of the public address generated during the setup phase (see below).
The --tls-disable is a historical flag to explicitely show that the binary do not accept secured connections.

Standalone drand binary

Drand also accepts the path of the certificates to use them directly, without passing through nginx:

drand start --tls-key <path> --tls-cert <path>

With Docker

If you run drand in Docker, always use the following template

docker run \
    --rm \
    --name drand \
    -p <port>:<port> \
    --volume $HOME/.drand/:/root/.drand/ \
    dedis/drand <command>

where <port> specifies the port through which your drand daemon is reachable and <command> has to be substituted by one of the respective commands below. You must add the corresponding volumes pointing to your TLS private key and certificate in case you are using TLS (recommended).

Checking the connection

You can run

drand check <address>

to test if the gRPC connection is reachable from outside. The address is the one registered in the public key.

Distributed Key Generation

To setup a new network, drand uses the notion the of a coordinator that collects
the public key of the participants, setups the group configuration once all keys
are received and then start the distributed key generation phase. Once the DKG
phase is performed, the participants can see the list of members in the group
configuration file

Coordinator: The designated coordinator node must run the following command
before everyone else:

drand share --leader --nodes 10 --threshold 6 --secret mysecret --period 30s

Rest of participants: Once the coordinator has run the previous command, the
rest of the participants must run the following command:

drand share --connect <leaderaddress> --nodes 10 --threshold 6 --secret mysecret

The flags usage is as follow:

  • --leader indicates this node is a coordinator, `
  • --nodes indicates how many nodes do we expect to form the network
  • --threshold indicates the threshold the network should use, i.e. how many
    nodes amongst the total needs to be online for the network to be live at any
    point.
  • --period indicates the period of the randomness beacon to use. It must be
    valid duration as parsed by Golang's [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) method.
  • --secret indicates the secret that the coordinator uses to authentify the
    nodes that wants to participate to the network.
  • --connect is the host:port address of the leader. By default, drand will
    connect to the leader by using tls. If you are not using tls, use the
    --tls-disable flag.

Interactive command: The command will run as long as the DKG is not finished
yet. You can quit the command, the DKG will proceed but the group file will not
be written down. In that case, once the DKG is done, you get the group file by
running:

drand show group --out group.toml

Secret: For participants to be included in the group, they need to have a
secret string shared by all. This method is offering some basic security
however drand will provide more manual checks later-on and/or different secrets
for each participants. However, since the set of participants is public and consistent
accross all participants after a setup, nodes can detect if there are some unwanted nodes
after the setup and in that case, setup a new network again.

Custom entropy source: By default drand takes its entropy for the setup
phase from the OS's entropy source (/dev/urandom on Unix systems). However,
it is possible for a participant to inject their own entropy source into the
creation of their secret. To do so, one must have an executable that produces
random data when called and pass the name of that executable to drand:

drand share <regular options> --source <entropy-exec>

where <entropy-exec> is the path to the executable which produces the user's
random data on STDOUT. As a precaution, the user's randomness is mixed by
default with crypto/rand to create a random stream. In order to introduce
reproducibility, the flag user-source-only can be set to impose that only the
user-specified entropy source is used. Its use should be limited to testing.

drand share <group-file> --source <entropy-exec> --user-source-only

Randomness Generation

After a successful setup, drand will switch automatically to the randomness generation mode after a timeout (by default 2m), where each node broadcasts randomness shares at regular intervals. Once a node has collected a threshold of shares in the current phase, it computes the public random value and stores it in its local instance of BoltDB.

Maintain the drand network

Control Functionalities

drand's local administrator interface provides further functionalities, e.g., to update group details or retrieve secret information. By default, the daemon listens on 127.0.0.1:8888, but you can specify another control port when starting the daemon with:

drand start --control 1234

In that case, you need to specify the control port for each of the following commands.

Group File: Once the DKG phase is done, the group file is updated with the newly created distributed public key. That updated group file needed by drand to securely contact drand nodes on their public interface to gather private or public randomness. A drand administrator can get the updated group file it via the following:

drand show group

It will print the group file in its regular TOML format. If you want to save it to a file, append the --out <file> flag.

Distributed Public Key: More generally, for third party implementation of randomness beacon verification, one only needs the distributed public key. For example, drandjs can securely verify drand's randomness thanks to this cokey. If you are an administrator of a drand node, you an fetch it with:

drand show cokey

Otherwise, you can contact an external drand node to ask it for its current distributed public key:

drand get cokey --nodes <address> <group.toml>

where <group.toml> is the group file identity file of a drand node. You can use the flag --nodes <address(es)> to indicate which node you want to contact specifically (it is a whitespace-separated list). Use the--tls-cert flag to specify the server's certificate if needed. The group toml does not need to be updated with the collective key.

NOTE: Using the last method (get cokey), a drand node can lie about the key if no out-of-band verification is performed. That information is usually best gathered from a trusted drand operator and then embedded in any applications using drand.

Long-Term Private Key: To retrieve the long-term private key of your node, run:

drand show private

Long-Term Public Key: To retrieve the long-term public key of your node, run:

drand show public

Private Key Share: To retrieve the private key share of our node, as determined during the DKG, run the following command:

drand show share

The JSON-formatted output has the following form:

 {
    "round": 1969,
    "previous": "e3a3e302335812e3bf4b684e1ddccef42eeff4d8a3625467d516286100d43744",
    "signature": "8019f77e6e3ef94a477d9dd0f9ca169e1fca917f3a6412eef581f855bc72c711c155fe0b6c2dc6ae005baa00a04ece3f1845955d408442a84a7a91a48327ff5ddb5d95d0363a79da27a929e4e05d22c3314c69435c6049da824335461437a01b",
    "randomness": "2b8a2db9fd29462991e3cc7b664eab2832a0b102d85ab70dc987c35d1d008862"
}

Updating Drand group

drand allows for "semi-dynamic" group update with a resharing protocol that offers the following:

  • new nodes can join an existing group and get new shares. Note that, in fact, all nodes get new shares after running the resharing protocol.
  • nodes can leave their current group. It may be necessary for nodes that have been deemed corrupted or do not wish to operate drand anymore.
  • nodes can update the threshold associated with their current distributed public key.

The main advantage of this method is that the distributed public key stays the same even with new nodes coming in. That can be useful when the distributed public key is embedded inside the application using drand, and hence is difficult to update securely.

Updating is simple in drand, it uses the same command as for the DKG:

drand share --from old-group.toml new-group.toml

for new nodes joining the system. The old group toml is fetched as shown above, and the new group toml is created the usual way (drand group ....).

For nodes already in current the group, there is actually a shortcut (the previous command works also) where there is no need to specify the old group:

drand share <newGroup.toml>

As usual, a leader must start the protocol by indicating the --leader flag.

After the protocol is finished, each node listed in the new-group.toml file, will have a new share corresponding to the same distributed public key. The randomness generation starts immediately after the resharing protocol using the new shares. Note that performing the resharing protocol requires the explicit action as shown above of all nodes that wish to be included into the new group.