Getting Started
===============

## Configuration

```shell
# base configuration
BOLTDB_PATH=/routed/route.db
WEB_ADDR=:80
SSL_ADDR=:443
BACKEND_TCP_ADDR=:8757
BACKEND_KCP_ADDR=:8804
GRPC_ADDR=:7268
DOMAIN_SUFFIX=
ACME_EMAIL=
SSL_CERT_KEY=
```

Fill out the missing parts of this and save it as `.env` somewhere.

### `DOMAIN_SUFFIX`

type: string

When a domain is not supplied for a newly created route, domains will be a random
string prepended to this setting. Set up a wildcard DNS entry for this prefix pointed
to the server running routed.

Example: `.route.xeserv.us`

### `ACME_EMAIL`

type: string, email address

This email address will be used to establish an account with Let's Encrypt. By
using the ACME support route has you agree to follow all of the Let's Encrypt
terms and conditions [here][letoc].

### `SSL_CERT_KEY`

type: string, encryption key

This will be used to encrypt and decrypt all SSL certificates on the disk.
New keys can be generated by running `route generate-key`.

## Node Setup

The target node must have a direct route from the internet to TCP ports
`80`, `443`, `7268`, and `8757` and UDP port `8804`. In order they are used
for:

| kind | port | usage |
|:-- |:-- |:-- |
| tcp | `80` | plain http traffic to backends |
| tcp | `443` | https (and http/2) traffic to backends |
| tcp | `7268` | grpc interface for management |
| tcp | `8757` | backend connections |
| udp | `8804` | backend connections |

### Docker Volume Creation

```console
$ docker volume create routed
```

### Initial Setup

```console
$ docker run --rm -it -v routed:/routed xena/route:latest sh
(ctr)$ cd /routed
(ctr)$ route-cli token generate-root --key=<ssl cert key from above> --username=<username> --db=./route.db
Your token is e73831bc-f40a-4cd4-84a6-b6b1e4529fa2
(ctr)$ exit
```

Save this username and token as they will be very important.

### Persistent setup with runit

- Create a folder in `/etc/system` named `routed`
  `# mkdir -p /etc/system/routed`
- Copy the `.env` file created above into `etc/system/routed`
- Create a file named `run` with the following contents:

```sh
#!/bin/sh

routeVer='latest'

docker rm -f routed
sleep 2
docker run --net host --name routed --rm -it --env-file .env -v routed:/routed -e BOLTDB_PATH=/routed/route.db xena/route:$routeVer
```

```console
# chmod +X /etc/system/routed/run
```

### Usage

Change the definition of this variable as is needed for your setup. For now this must
be publicly facing but later versions of `route` will not require this. Set this in
a variable named `ROUTED_GRPC_ADDR`:

```console
$ export ROUTED_GRPC_ADDR=h.routed.xeserv.us:7268
```

Similarly, point this to the TCP backend connections port:

```console
$ export ROUTED_TCP_BACKEND_ADDR=h.routed.xeserv.us:8757
```

Next, open `~/.netrc` in your favorite editor and add the following to the end of it:

```
machine h.routed.xeserv.us:7268
  login usename
  password token
```

#### Create a route

```
$ route-cli --routed-addr=$ROUTED_GRPC_ADDR route create --help
‹master*!+1› »»»» ./route route create --help                         0|12:57:46
usage: route route create [<flags>]

create a new route

Flags:
  --help                        Show context-sensitive help (also try
                                --help-long and --help-man).
  --routed-addr="127.0.0.1:7268"
                                routed grpc address
  --netrc="/Users/xena/.netrc"  netrc path
  --domain=DOMAIN               domain for the route (if not given one will be
                                generated for you)

$ route-cli --routed-addr=$ROUTED_GRPC_ADDR route create
86d50f43-221d-4a57-99c9-8056dea0f12c
$ route-cli --routed-addr=$ROUTED_GRPC_ADDR route list
+--------------------------------------|--------------------------------+
|                  ID                  |              HOST              |
+--------------------------------------|--------------------------------+
| 86d50f43-221d-4a57-99c9-8056dea0f12c | wfall-hu-crow.routed.xeserv.us |
+--------------------------------------|--------------------------------+
$ curl -v https://wfall-hu-crow.routed.xeserv.us
> GET / HTTP/2
> Host: wfall-hu-crow.routed.xeserv.us
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 502
< accept: */*
< content-type: text/html; charset=utf-8
< user-agent: curl/7.54.0
< x-clacks-overhead: GNU Ashlynn
< x-forwarded-for: 24.17.183.23
< x-remote-ip: 24.17.183.23
< x-request-id: 01BVA69BJJKNSX05W4NS0PHECY
< x-request-ingress: 2017-09-30T22:05:21+02:00
< content-length: 228
< date: Sat, 30 Sep 2017 20:05:21 GMT
<
* Connection #0 to host wfall-hu-crow.routed.xeserv.us left intact
<html><head><title>no backends connected</title></head><body><h1>no backends connected</h1><p>Please ensure a backend is running for wfall-hu-crow.routed.xeserv.us. This is request ID 01BVA69BJJKNSX05W4NS0PHECY.</p></body></html>
```

#### Connect a backend

In another terminal window:
```console
$ route-cli test-server 
```

In yet another terminal window:
```conosle
$ route-httpagent -token=<token from above> -domain=<domain from above> -server=$ROUTED_TCP_BACKEND_ADDR 
```

Now to your main terminal window:
```console
$ curl -v https://wfall-hu-crow.routed.xeserv.us
> GET / HTTP/2
> Host: wfall-hu-crow.route.xeserv.us
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< content-type: text/plain; charset=utf-8
< date: Sat, 30 Sep 2017 20:15:59 GMT
< x-clacks-overhead: GNU Ashlynn
< x-request-id: 01BVA6WT90M20ZH6NVSKYT68SS
< content-length: 298
<
Route is go!
map[X-Forwarded-For:[24.17.183.23, 193.164.132.229] X-Request-Id:[01BVA6WT90M20ZH6NVSKYT68SS] Accept-Encoding:[gzip] User-Agent:[curl/7.54.0] Accept:[*/*] X-Remote-Ip:[24.17.183.23] X-Request-Ingress:[2017-09-30T22:15:59+02:00]]
Served by cadance-3.local running darwin
* Connection #0 to host wfall-hu-crow.routed.xeserv.us left intact
Hit count: 1617
```

---

[letoc]: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf
