Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdee committed Aug 25, 2020
1 parent 27aa5b8 commit 71a059e
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 210 deletions.
115 changes: 115 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Release

on:
push:
tags:
- 'v*'

jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v2

- name: Get dependencies
run: |
go get -v -t -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
- name: Set env
run: |
echo '::set-env name=GO111MODULE::on'
# Release tag comes from the github reference.
RELEASE_TAG=$(echo ${GITHUB_REF} | sed -e 's!.*/!!')
echo "::set-env name=RELEASE_TAG::${RELEASE_TAG}"
echo "::set-output name=RELEASE_TAG::${RELEASE_TAG}"
# Ensure the release tag has expected format.
echo ${RELEASE_TAG} | grep -q '^v' || exit 1
# Release version is same as release tag without leading 'v'.
RELEASE_VERSION=$(echo ${GITHUB_REF} | sed -e 's!.*/v!!')
echo "::set-env name=RELEASE_VERSION::${RELEASE_VERSION}"
echo "::set-output name=RELEASE_VERSION::${RELEASE_VERSION}"
- name: Build
run: go build -v -ldflags="-X github.com/attestantio/dirk/cmd.ReleaseVersion=${RELEASE_VERSION}" .

- name: Test
run: go test -v .

- name: Fetch xgo
run: |
go get github.com/suburbandad/xgo
- name: Cross-compile
run: xgo -v -x -ldflags="-X github.com/attestantio/dirk/cmd.ReleaseVersion=${RELEASE_VERSION}" --targets="linux/amd64,linux/arm64,windows/amd64" github.com/attestantio/dirk

- name: Create windows zip file
run: |
mv dirk-windows-4.0-amd64.exe dirk.exe
zip --junk-paths dirk-${RELEASE_VERSION}-windows-exe.zip dirk.exe
- name: Create linux AMD64 tgz file
run: |
mv dirk-linux-amd64 dirk
tar zcf dirk-${RELEASE_VERSION}-linux-amd64.tar.gz dirk
- name: Create linux ARM64 tgz file
run: |
mv dirk-linux-arm64 dirk
tar zcf dirk-${RELEASE_VERSION}-linux-arm64.tar.gz dirk
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ env.RELEASE_VERSION }}
draft: false
prerelease: false

- name: Upload windows zip file
id: upload-release-asset-windows
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dirk-${{ env.RELEASE_VERSION }}-windows-exe.zip
asset_name: dirk-${{ env.RELEASE_VERSION }}-windows-exe.zip
asset_content_type: application/zip

- name: Upload linux AMD64 tgz file
id: upload-release-asset-linux-amd64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dirk-${{ env.RELEASE_VERSION }}-linux-amd64.tar.gz
asset_name: dirk-${{ env.RELEASE_VERSION }}-linux-amd64.tar.gz
asset_content_type: application/gzip

- name: Upload linux ARM64 tgz file
id: upload-release-asset-linux-arm64
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dirk-${{ env.RELEASE_VERSION }}-linux-arm64.tar.gz
asset_name: dirk-${{ env.RELEASE_VERSION }}-linux-arm64.tar.gz
asset_content_type: application/gzip
200 changes: 7 additions & 193 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# dirk
# Dirk

[![Tag](https://img.shields.io/github/tag/attestantio/dirk.svg)](https://github.com/attestantio/dirk/releases/)
[![License](https://img.shields.io/github/license/attestantio/dirk.svg)](LICENSE)
Expand Down Expand Up @@ -26,201 +26,15 @@ go get github.com/attestantio/dirk
```

## Usage

`dirk` provides an interface to wallet operations such as listing accounts and signing requests. The daemon provides a number of security measures to avoid unauthorised uses of the private keys, and protection against invalid actions (_e.g._ slashing events).

## Architecture

### Configuration directory and files

By default `dirk` looks for its configuration in the file `.dirk.json` in the user's home directory. A different base directory for `dirk` can be given with the `--base-dir` flag, in which case it will look for a file `dirk.json` in that directory.

### Example

The architecture we want to achieve is shown below:

![Validator architecture](images/architecture.png)

In this architecture we have three validators clients. Validator clients 1 and 2 are in a cluster, and between them manage accounts 1, 2, and 3. Validator client 3 is standalone, and manages account 4.

#### Creating wallets and accounts
The first step is to create some wallets and validator keys for said wallets, using [ethdo](https://github.com/wealdtech/ethdo):

```
$ ethdo wallet create --wallet=wallet1
$ ethdo account create --account=wallet1/account1 --passphrase=secret
$ ethdo account create --account=wallet1/account2 --passphrase=secret
$ ethdo account create --account=wallet1/account3 --passphrase=secret
$ ethdo wallet create --wallet=wallet2
$ ethdo account create --account=wallet2/account4 --passphrase=secret
```

Here we have two wallets, one for each set of validator clients. It is possible for different wallets to have different features, such as level of security and location, but for the purposes of this example they are both standard (non-deterministic) wallets (see ethdo documentation for other options).

#### Creating certificates
We need a certificate for the wallet daemon. We could use a certificate from a well-known certificate authority such as LetsEncrypt, or we could create our own; we will create our own using [certstrap](https://github.com/square/certstrap).

First, we create the certificate authority. Note the key created in this process is critical to the security of your deposits and should be protected with all reasonable measures; this should include a passphrase when promted.
```
$ certstrap --depot-path . init --common-name "dirk authority" --expires "3 years"
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Created ./dirk_authority.key (encrypted by passphrase)
Created ./dirk_authority.crt
Created ./dirk_authority.crl
```

The server needs its own certificate. We use the sample name `server.example.com` here but you should replace this with the name of your server. If you are testing `dirk` locally you can use `localhost` instead of the server name.
```
$ certstrap --depot-path . request-cert --common-name server.example.com
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Created ./server.example.com.key
Created ./server.example.com.csr
$ certstrap --depot-path . sign --CA "dirk authority" --expires="3 years" server.example.com
Enter passphrase for CA key (empty for no passphrase):
Created ./server.example.com.crt from ./server.example.com.csr signed by ./dirk_authority.key
```

Next, we create and sign certificates for the three clients that will be connecting to the daemon. Note the keys created here should not have a passphrase supplied; they will reside with the valdiator clients so use of the key is should be possible without requiring human intervention (to allow for server restarts _etc._). For the first client:

```
$ certstrap --depot-path . request-cert --common-name client1
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Created ./client1.key
Created ./client1.csr
$ certstrap --depot-path . sign --CA "dirk authority" --expires="3 years" client1
Enter passphrase for CA key (empty for no passphrase):
Created ./client1.crt from ./client1.csr signed by ./dirk_authority.key
```

and the same commands can be used for the other clients, using "client2" and "client3" in place of "client1". At this point you should have the following files:

- `client1.crt`: the signed certificate for client1; needs to be moved to the server running client1
- `client1.csr`: the signing request for client1; can be deleted
- `client1.key`: the key for client1; needs to be moved to the server running client1
- `client2.crt`: the signed certificate for client2; needs to be moved to the server running client3
- `client2.csr`: the signing request for client2; can be deleted
- `client2.key`: the key for client2; needs to be moved to the server running client3
- `client3.crt`: the signed certificate for client3; needs to be moved to the server running client3
- `client3.csr`: the signing request for client3; can be deleted
- `client3.key`: the key for client3; needs to be moved to the server running client3
- `server.example.com.crt`: the certificate for `dirk`; needs to be moved to the server running `dirk`
- `server.example.com.csr`: the signing request for `dirk`; can be deleted
- `server.example.com.key`: the key for `dirk`; needs to be moved to the server running `dirk`
- `dirk_authority.crl`: the certificate revocation list for dirk; needs to be copied to the server running `dirk`
- `dirk_authority.crt`: the certificate for dirk; needs to be copied to all clients
- `dirk_authority.key`: the key for dirk; needs to be copied to the server running `dirk`

To provide the certificates for `dirk` make a directory `dirk/security` in your home directory and copy the `server.example.com.crt` and `server.example.com.key` files in to it. Also copy `dirk_authority.crt` to the same directory with the name `ca.crt`. The contents of the `security` directory in your configuration directory should be:

- `ca.crt`: copy of `dirk_authority.crt` from the previous step
- `server.example.com.crt`: copy of `server.example.com.crt` from the previous step
- `server.example.com.key`: copy of `server.example.com.key` from the previous step

At this point you also need a minimal configuration file so `dirk` knows which certificates to use. Create a file `dirk.json` in your home directory with the following contents:

```json
{
"server": {
"id": 212483780,
"name": "server.example.com",
"listen-address": "localhost:9091",
"cert-path": "security"
}
}
```

(The `id` and `listen-address` fields here will be explained later).

You can confirm the configuration of the certificates by running the command `dirk --show-certificates` which should return suitable information about the generated certificates:

```sh
$ dirk --show-certificates
Server certificate issued by: Dirk authority
Server certificate expires: 2023-03-24 13:47:19 +0000 UTC
Server certificate issued to: server.example.com

Certificate authority certificate is: Dirk authority
Certificate authority certificate expires: 2023-03-24 13:47:20 +0000 UTC
```

#### Adding permissions
The next step is to configure `dirk` to know which clients have access to which accounts, and which operations on those accounts. To do so, replace the `dirk.json` file above with the following:

```
{
"server": {
"id": 212483780,
"name": "server.example.com",
"listen-address": "localhost:9091",
"cert-path": "security"
},
"permissions": {
"client1": {
"wallet1": "All"
},
"client2": {
"wallet1": "All"
},
"client3": {
"wallet2": "All"
}
}
}
```

Once this is in place it can be confirmed by running `dirk --show-permissions`:

```
$ dirk --show-permissions
Permissions for "client1":
- accounts matching the path "wallet1" can carry out all operations
Permissions for "client2":
- accounts matching the path "wallet1" can carry out all operations
Permissions for "client3":
- accounts matching the path "wallet2" can carry out all operations
```

Permissions can be used to restrict the access of clients to wallets, accounts, and operations. More details can be found in ther permissions documentation.

#### Starting `dirk`

To start `dirk` type:

```sh
$ dirk
{"level":"info","version":"v0.1.0","time":"2020-07-27T23:20:51+01:00","message":"Starting dirk"}
{"level":"warn","time":"2020-07-27T23:20:51+01:00","message":"No stores configured; using default"}
{"level":"info","service":"api","impl":"grpc","address":"localhost:9091","time":"2020-07-27T23:20:51+01:00","message":"Listening"}
{"level":"info","time":"2020-07-27T23:20:51+01:00","message":"All services operational"}
```

At this point `dirk` is operational on port 9091 and can accept requests for key generation, signing _etc._

#### Testing client permissions
`ethdo` interacts with the dirk using additional options:
- `--remote` the address of the Dirk instance
- `--client-cert` and `--client-key` the path to the certificate and keyfile for the client
- `--ca-cert` the path to the certificate for the server authority

For example, to list accounts accessible in `wallet1` with the `client1` certificate:

```sh
$ ethdo --remote=server.example.com:9091 --client-cert=client1.crt --client-key=client1.key --server-ca-cert=dirk_authority.crt wallet accounts --wallet=wallet1
account1
account3
account2
```

As would be expected from the configured permissions, `client3` cannot access the accounts in `wallet1`:

```sh
$ ethdo --remote=server.example.com:9091 --client-cert=client3.crt --client-key=client3.key --server-ca-cert=Wallet_daemon_authority.crt wallet accounts --wallet=wallet1
```
## Documentation
The following documentation is available:

At this point it has been confirmed that the client permissions operate as expected, and that dirk is appropriately configured. The client certificates can now be used by validators to remotely access their keys.
- [Getting started](docs/getting_started.md) an introduction to configuring Dirk
- [Prometheus metrics](docs/metrics/prometheus.md) Prometheus metrics
- [Configuration](docs/configuration.md) Sample annotated configuration file
- [Permissions](docs/permissions.md) Details information about Dirk's permissions

## Maintainers

Expand Down
Loading

0 comments on commit 71a059e

Please sign in to comment.