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.
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
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.
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/
.
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
The setup is explained in README_docker.md.
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.
# /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
listen 443 ssl http2
to use any port.proxy_pass http://localhost:8080;
and grpc_pass grpc://localhost:8080;
to use any local port.sudo certbot --nginx
Don't forget to renew your certificate or setup an automatic renewal cron job !
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>
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:
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.
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:
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.
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 !
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.
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.
Drand also accepts the path of the certificates to use them directly, without passing through nginx:
drand start --tls-key <path> --tls-cert <path>
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).
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.
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--period
indicates the period of the randomness beacon to use. It must be[time.ParseDuration]
(https://golang.org/pkg/time/#ParseDuration) method.--secret
indicates the secret that the coordinator uses to authentify the--connect
is the host:port
address of the leader. By default, drand will--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
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.
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"
}
drand allows for "semi-dynamic" group update with a resharing protocol that offers the following:
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.