# 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 $104*60*24*365=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](https://golang.org/) or [Docker](https://www.docker.com/). 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](https://golang.org/doc/install) and that your [GOPATH](https://golang.org/doc/code.html#GOPATH) is set. Then install drand via: ```bash go get -u github.com/drand/drand ``` ### Via Docker The setup is explained in [README_docker.md](https://github.com/drand/drand/blob/master/docker/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](https://www.nginx.com/) and [certbot](https://certbot.eff.org/lets-encrypt/) - 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: ```bash # /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: ```bash 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: ```bash 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 ```bash 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](https://golang.org/pkg/time/#ParseDuration) 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: ```bash 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 ```bash 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 ```go 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](https://github.com/coreos/bbolt). ## 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: ```bash 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: ```bash 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](https://github.com/pizzawhisperer/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: ```bash drand show cokey ``` Otherwise, you can contact an external drand node to ask it for its current distributed public key: ```bash 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: ```bash drand show private ``` **Long-Term Public Key**: To retrieve the long-term public key of your node, run: ```bash drand show public ``` **Private Key Share**: To retrieve the private key share of our node, as determined during the DKG, run the following command: ```bash drand show share ``` The JSON-formatted output has the following form: ```json { "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: ```bash 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: ```bash 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.