This repository contains the open source code for the Buckets relay server, which allows users to share budget data between their devices in an end-to-end encrypted way.
If you want to run the relay on your own computer with only one user account, do the following:
git clone https://github.com/buckets/relay.git buckets-relay.git
cd buckets-relay.git
nimble singleuserbins
RELAY_USERNAME=someusername
RELAY_PASSWORD=somepassword
bin/brelay server
This will launch the relay on the default port. Run brelay --help
for more options.
If instead of nimble singleuserbins
you run nimble multiuserbins
the server will be built in multi-user mode.
Register users via brelay adduser ...
or through the web interface.
Registration-related emails are sent through Postmark. Set POSTMARK_API_KEY
to your Postmark key to use it. Otherwise, disable emails with -d:nopostmark
.
Users can authenticate with their Buckets license if you set an environment variable AUTH_LICENSE_PUBKEY=<A PEM FORMATTED PUBKEY>
To run the server locally:
nimble run brelay server
If you'd like to run a relay server on fly.io, sign up for the service then do one of the following. If you'd like to host somewhere else, you could use the Dockerfiles in docker/ as a starting point.
fly launch --dockerfile docker/singleuser.Dockerfile
fly secrets set RELAY_USERNAME='someusername' RELAY_PASSWORD='somepassword'
Variable | Description |
---|---|
RELAY_USERNAME |
Username or email you'll use to authenticate to the relay. |
RELAY_PASSWORD |
Password you'll use to authenticate to the relay. |
fly launch --dockerfile docker/multiuser.Dockerfile
fly secrets set POSTMARK_API_KEY='your key' AUTH_LICENSE_PUBKEY='the key' LICENSE_HASH_SALT='choose something here'
Variable | Description |
---|---|
POSTMARK_API_KEY |
API key from Postmark |
AUTH_LICENSE_PUBKEY |
RSA public key of Buckets licenses. If empty, license authentication is disabled. |
LICENSE_HASH_SALT |
A hashing salt for the case when a license needs to be disabled. Any random, but consistent value is fine. |
Relay clients communicate with the relay server using the following protocol. See ./src/bucketsrelay/proto.nim for more information, and ./src/bucketsrelay/stringproto.nim for encoding details.
In summary, devices connect with websockets and exchange messages. Messages sent from client to server are called commands. Messages sent from server to client are called events.
Clients authenticate with the server in two ways:
A single relay account can have multiple public/private keys; typically one for each device.
Clients send the following commands:
Command | Description |
---|---|
Iam |
In response to a Who event, proves that this client has the private key for their public key. |
Connect |
Asks the server for a connection to another client identified by the client's public key. |
Disconnect |
Asks the server to disconnect a connection to another client. |
SendData |
Sends bytes to another client. |
The relay server sends the following events:
Event | Description |
---|---|
Who |
Challenge for authenticating a client's public/private keys |
Authenticated |
Sent when a client successfully completes authentication |
Connected |
Sent when a client has connected to another client |
Disconnected |
Sent when a client has been disconnected from another client |
Data |
Data payload from another, connected client |
Entered |
Sent when a client within the same user account has authenticated to the relay |
Exited |
Sent when a client within the same user account has disconnected from the relay |
ErrorEvent |
Sent when errors happen with authentication, connection or message sending |
Authentication happens like this:
Who(challenge=ABCD...)
Iam(pubkey=MYPK..., signature=SIGN...)
Authenticated
Client Relay
│ │
│ Who │
│◄────────────────┤
│ │
│ Iam │
├────────────────►│
│ │
│ Authenticated │
│◄────────────────┤
│ │
After authenticating, clients connect to each other and send data like this:
Connect(pubkey=BOBPK)
Connect(pubkey=ALICEPK)
Connected(pubkey=BOBPK)
Connected(pubkey=ALICEPK)
SendData(data=hello, pubkey=BOBPK)
Data(data=hello, sender=ALICEPK)
Alice Relay Bob
│ │ │
├───Authenticated─┼─Authenticated───┤
│ │ │
│Connect(Bob) │ │
├────────────────►│ Connect(Alice) │
│ │◄────────────────┤
│ │ │
│ Connected(Bob) │ Connected(Alice)│
│◄────────────────┼────────────────►│
│ │ │
│SendData(Bob) │ │
├────────────────►│ Data(Alice) │
│ ├────────────────►│
│ │ │
The relay server will announce client presence to all clients that use the same HTTP Auth credentials. For example, if both Alice and Bob signed in as alicenbob@example.com
the following would happen:
Entered(pubkey=BOBPK)
Entered(pubkey=ALICEPK)
Exited(pubkey=ALICEPK)