Compare commits
17 Commits
v0.1.0-bet
...
v0.1.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f9406d44 | ||
|
|
7c79ff62ee | ||
|
|
32c369257b | ||
|
|
08dd719aa1 | ||
|
|
84c714dd93 | ||
|
|
996c8d7c62 | ||
|
|
25e68ce493 | ||
|
|
4881dcbd51 | ||
|
|
d505f70972 | ||
|
|
6a80684378 | ||
|
|
2624a7c4e6 | ||
|
|
9a412e7bf1 | ||
|
|
b5d1690129 | ||
|
|
d4bec15ca3 | ||
|
|
3212aca7c7 | ||
|
|
b97a2251d3 | ||
|
|
528a26ea3e |
31
.github/workflows/release.yml
vendored
@@ -51,28 +51,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
||||
|
||||
-
|
||||
id: get_version
|
||||
uses: battila7/get-version-action@v2
|
||||
-
|
||||
name: Install makensis
|
||||
run: sudo apt update && sudo apt install -y nsis nsis-pluginapi
|
||||
-
|
||||
name: Download EnvVar Plugin
|
||||
run: curl -L -o EnVar_plugin.zip https://nsis.sourceforge.io/mediawiki/images/7/7f/EnVar_plugin.zip
|
||||
-
|
||||
name: Extract EnVar plugin
|
||||
run: sudo 7z x -o"/usr/share/nsis/" EnVar_plugin.zip
|
||||
-
|
||||
name: Generate Windows installer
|
||||
run: makensis -V4 client/installer.nsis
|
||||
env:
|
||||
APPVER: ${{ steps.get_version.outputs.major }}.${{ steps.get_version.outputs.minor }}.${{ steps.get_version.outputs.patch }}.${{ github.run_id }}
|
||||
-
|
||||
name: Upload windows installer to release page
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
name: Trigger Windows binaries sign pipeline
|
||||
uses: benc-uk/workflow-dispatch@v1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: wiretrustee-installer.exe
|
||||
asset_name: wiretrustee_installer_${{ steps.get_version.outputs.version-without-v }}_windows_amd64.exe
|
||||
tag: ${{ github.ref }}
|
||||
workflow: Sign windows bin and installer
|
||||
repo: wiretrustee/windows-sign-pipeline
|
||||
ref: v0.0.1
|
||||
token: ${{ secrets.SIGN_GITHUB_TOKEN }}
|
||||
inputs: '{ "tag": "${{ github.ref }}" }'
|
||||
4
.gitignore
vendored
@@ -3,4 +3,6 @@
|
||||
dist/
|
||||
.env
|
||||
conf.json
|
||||
http-cmds.sh
|
||||
http-cmds.sh
|
||||
infrastructure_files/management.json
|
||||
infrastructure_files/docker-compose.yml
|
||||
28
README.md
@@ -4,9 +4,12 @@ A WireGuard®-based mesh network that connects your devices into a single privat
|
||||
|
||||
**Note**: The `main` branch may be in an *unstable or even broken state* during development. For stable versions, see [releases](https://github.com/wiretrustee/wiretrustee/releases).
|
||||
|
||||
**Hosted demo version:** [https://beta.wiretrustee.com/](https://beta.wiretrustee.com/peers)
|
||||
Hosted demo version:
|
||||
[https://beta.wiretrustee.com/](https://beta.wiretrustee.com/peers).
|
||||
|
||||
Please don't use the hosted demonstration version for production purposes.
|
||||
The number of peers is limited to 15.
|
||||
|
||||
Please don't use the hosted demonstration version for production purposes. We appreciate your usage of the demonstration version and will love to hear your feedback, please reach out via Issue or [Slack](https://wiretrustee.slack.com/).
|
||||
|
||||
[UI Dashboard Repo](https://github.com/wiretrustee/wiretrustee-dashboard)
|
||||
|
||||
@@ -26,7 +29,7 @@ Please don't use the hosted demonstration version for production purposes.
|
||||
* Open-source (including Management Service)
|
||||
|
||||
### Secure peer-to-peer VPN in minutes
|
||||

|
||||

|
||||
|
||||
### A bit on Wiretrustee internals
|
||||
* Wiretrustee features a Management Service that offers peer IP management and network updates distribution (e.g. when new peer joins the network).
|
||||
@@ -42,6 +45,10 @@ Please don't use the hosted demonstration version for production purposes.
|
||||
- [Public Roadmap](https://github.com/wiretrustee/wiretrustee/projects/2)
|
||||
- [Public Roadmap Progress Tracking](https://github.com/wiretrustee/wiretrustee/projects/1)
|
||||
|
||||
### Getting started
|
||||
|
||||
See [Docs](docs/README.md) for managed and self-hosting guides.
|
||||
|
||||
### Client Installation
|
||||
#### Linux
|
||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases)
|
||||
@@ -149,11 +156,20 @@ netsh interface ip show config name="wt0"
|
||||
|
||||
4. Repeat on other machines.
|
||||
|
||||
### Running Management, Signal and Coturn
|
||||
### Running Dashboard, Management, Signal and Coturn
|
||||
Wiretrustee uses [Auth0](https://auth0.com) for user authentication and authorization, therefore you will need to create a free account
|
||||
and configure AUTH0 variables in the compose file (dashboard and management).
|
||||
and configure Auth0 variables in the compose file (dashboard) and in the management config file.
|
||||
We chose Auth0 to "outsource" the user management part of our platform because we believe that implementing a proper user auth is not a trivial task and requires significant amount of time to make it right. We focused on connectivity instead.
|
||||
It is worth mentioning that dependency to Auth0 is the only one that cannot be self-hosted.
|
||||
|
||||
Under infrastructure_files we have a docker-compose example to run both, Wiretrustee Management and Signal services, plus an instance of [Coturn](https://github.com/coturn/coturn), it also provides a turnserver.conf file as a simple example of Coturn configuration.
|
||||
Configuring Wiretrustee Auth0 integration:
|
||||
- check [How to run](https://github.com/wiretrustee/wiretrustee-dashboard#how-to-run) to obtain Auth0 environment variables for UI Dashboard
|
||||
- set these variables in the [environment section of the docker-compose file](https://github.com/wiretrustee/wiretrustee/blob/main/infrastructure_files/docker-compose.yml)
|
||||
- check [Auth0 Golang API Guide](https://auth0.com/docs/quickstart/backend/golang) to obtain ```AuthIssuer```, ```AuthAudience```, and ```AuthKeysLocation```
|
||||
- set these properties in the [management config files](https://github.com/wiretrustee/wiretrustee/blob/main/infrastructure_files/management.json#L33)
|
||||
|
||||
|
||||
Under infrastructure_files we have a docker-compose example to run Dashboard, Wiretrustee Management and Signal services, plus an instance of [Coturn](https://github.com/coturn/coturn), it also provides a turnserver.conf file as a simple example of Coturn configuration.
|
||||
You can edit the turnserver.conf file and change its Realm setting (defaults to wiretrustee.com) to your own domain and user setting (defaults to username1:password1) to **proper credentials**.
|
||||
|
||||
The example is set to use the official images from Wiretrustee and Coturn, you can find our documentation to run the signal server in docker in [Running the Signal service](#running-the-signal-service), the management in [Management](./management/README.md), and the Coturn official documentation [here](https://hub.docker.com/r/coturn/coturn).
|
||||
|
||||
@@ -189,14 +189,7 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
||||
// in case the remote peer is in the local network or one of the peers has public static IP -> no need for a Wireguard proxy, direct communication is possible.
|
||||
if !useProxy(pair) {
|
||||
log.Debugf("it is possible to establish a direct connection (without proxy) to peer %s - my addr: %s, remote addr: %s", conn.Config.RemoteWgKey.String(), pair.Local, pair.Remote)
|
||||
var endpoint string
|
||||
if isPublicIP(net.ParseIP(pair.Local.Address())) {
|
||||
//skip endpoint because we are public - it will be discovered by Wireguard automatically
|
||||
endpoint = ""
|
||||
} else {
|
||||
endpoint = fmt.Sprintf("%s:%d", pair.Remote.Address(), iface.WgPort)
|
||||
}
|
||||
err = conn.wgProxy.StartLocal(endpoint)
|
||||
err = conn.wgProxy.StartLocal(fmt.Sprintf("%s:%d", pair.Remote.Address(), iface.WgPort))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -254,24 +247,22 @@ func useProxy(pair *ice.CandidatePair) bool {
|
||||
myIp := net.ParseIP(pair.Local.Address())
|
||||
remoteIsPublic := isPublicIP(remoteIP)
|
||||
myIsPublic := isPublicIP(myIp)
|
||||
if pair.Local.Type() == ice.CandidateTypeHost && pair.Remote.Type() == ice.CandidateTypeHost {
|
||||
if remoteIsPublic || myIsPublic {
|
||||
//one of the hosts has a public IP
|
||||
return false
|
||||
}
|
||||
|
||||
//one of the hosts has a public IP
|
||||
if remoteIsPublic && pair.Remote.Type() == ice.CandidateTypeHost {
|
||||
return false
|
||||
}
|
||||
if myIsPublic && pair.Local.Type() == ice.CandidateTypeHost {
|
||||
return false
|
||||
}
|
||||
|
||||
if pair.Local.Type() == ice.CandidateTypeHost && pair.Remote.Type() == ice.CandidateTypeHost {
|
||||
if !remoteIsPublic && !myIsPublic {
|
||||
//both hosts are in the same private network
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (pair.Local.Type() == ice.CandidateTypeHost && myIsPublic) && pair.Remote.Type() == ice.CandidateTypePeerReflexive {
|
||||
// same as the case when either host is public but adds additional case when remote is peer reflexive
|
||||
// remote is peer reflexive and we are public -> no proxy needed
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
31
docs/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
## Introduction
|
||||
|
||||
Wiretrustee is a WireGuard®-based platform that connects your devices securely into a peer-to-peer private network.
|
||||
|
||||
It simplifies VPN creation and management for your organization without the hassle of opening ports, complex firewall rules, and so forth.
|
||||
|
||||
It literally takes less than 5 minutes to provision a secure peer-to-peer VPN with Wiretrustee.
|
||||
|
||||
### High-level overview
|
||||
In essence, Wiretrustee is an open source platform consisting of a collection of systems, responsible for handling peer-to-peer connections, tunneling and network management (IP, keys, ACLs, etc).
|
||||
|
||||
<p align="center">
|
||||
<img src="media/high-level-dia.png" alt="high-level-dia" width="781"/>
|
||||
</p>
|
||||
|
||||
Wiretrustee uses open-source technologies like [WireGuard®](https://www.wireguard.com/), [Pion ICE (WebRTC)](https://github.com/pion/ice), [Coturn](https://github.com/coturn/coturn),
|
||||
and [software](https://github.com/wiretrustee/wiretrustee) developed by Wiretrustee authors to make it all work together.
|
||||
|
||||
To learn more about Wiretrustee architecture, please refer to the [architecture section](../docs/architecture.md).
|
||||
|
||||
### Getting Started
|
||||
|
||||
There are 2 ways of getting started with Wiretrustee:
|
||||
- use Cloud Managed version
|
||||
- self-hosting
|
||||
|
||||
We recommend starting with the cloud managed version hosted at [beta.wiretrustee.com](https://beta.wiretrustee.com) - the quickest way to get familiar with the system.
|
||||
See [Quickstart Guide](../docs/quickstart.md) for instructions.
|
||||
|
||||
If you don't want to use the managed version, check out our [Self-hosting Guide](../docs/self-hosting.md).
|
||||
|
||||
2
docs/architecture.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Architecture
|
||||
TODO
|
||||
BIN
docs/media/add-peer.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
docs/media/auth.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
docs/media/empty-peers.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/media/high-level-dia.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 5.9 MiB |
BIN
docs/media/peers.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
41
docs/quickstart.md
Normal file
@@ -0,0 +1,41 @@
|
||||
## Quickstart guide (Cloud Managed version)
|
||||
Step-by-step video guide on YouTube:
|
||||
|
||||
[](https://youtu.be/cWTsGUJAUaU "Wiretrustee - secure private network in less than 5 minutes")
|
||||
|
||||
This guide describes how to create secure VPN and connect 2 machines peer-to-peer.
|
||||
|
||||
One machine is a Raspberry Pi Compute Module 4 hosted at home (Peer A), and the other one is a regular Ubuntu server running in the Data Center (Peer B).
|
||||
Both machines are running Linux (Raspbian and Ubuntu respectively), but you could also use Mac or Windows operating systems.
|
||||
|
||||
1. Sign-up at [https://beta.wiretrustee.com/](https://beta.wiretrustee.com/peers)
|
||||
|
||||
You can use your email and password to sign-up or any available social login option (e.g., GitHub account)
|
||||
|
||||
<img src="media/auth.png" alt="auth" width="350"/>
|
||||
|
||||
2. After a successful login you will be redirected to the ```Peers``` screen which is empty because you don't have any peers yet.
|
||||
|
||||
Click ```Add peer``` to add a new machine.
|
||||
|
||||
<img src="media/empty-peers.png" alt="empty-peers" width="700"/>
|
||||
|
||||
3. Choose a setup key which will be used to associate your new machine with your account (in our case it is ```Default key```).
|
||||
|
||||
Choose your machine operating system (in our case it is ```Linux```) and proceed with the installation steps on the machine.
|
||||
|
||||
<img src="media/add-peer.png" alt="add-peer" width="700"/>
|
||||
|
||||
4. Repeat #3 for the 2nd machine.
|
||||
5. Return to ```Peers``` and you should notice 2 new machines with status ```Connected```
|
||||
|
||||
<img src="media/peers.png" alt="peers" width="700"/>
|
||||
|
||||
6. To test the connection you could try pinging devices:
|
||||
|
||||
On Peer A:
|
||||
```ping 100.64.0.2```
|
||||
|
||||
On Peer B:
|
||||
```ping 100.64.0.1```
|
||||
7. Done! You now have a secure peer-to-peer VPN configured.
|
||||
92
docs/self-hosting.md
Normal file
@@ -0,0 +1,92 @@
|
||||
### Self-hosting
|
||||
Wiretrustee is an open-source platform that can be self-hosted on your servers.
|
||||
|
||||
It relies on components developed by Wiretrustee Authors [Management Service](https://github.com/wiretrustee/wiretrustee/tree/main/management), [Management UI Dashboard](https://github.com/wiretrustee/wiretrustee-dashboard), [Signal Service](https://github.com/wiretrustee/wiretrustee/tree/main/signal),
|
||||
a 3rd party open-source STUN/TURN service [Coturn](https://github.com/coturn/coturn) and a 3rd party service [Auth0](https://auth0.com/).
|
||||
|
||||
All the components can be self-hosted except for the Auth0 service.
|
||||
We chose Auth0 to "outsource" the user management part of the platform because we believe that implementing a proper user auth requires significant amount of time to make it right.
|
||||
We focused on connectivity instead.
|
||||
|
||||
If you would like to learn more about the architecture please refer to the [Wiretrustee Architecture section](architecture.md).
|
||||
|
||||
### Requirements
|
||||
|
||||
- Virtual machine offered by any cloud provider (e.g., AWS, DigitalOcean, Hetzner, Google Cloud, Azure ...).
|
||||
- Any Linux OS.
|
||||
- Docker Compose installed (see [Install Docker Compose](https://docs.docker.com/compose/install/)).
|
||||
- Domain name pointing to the public IP address of your server.
|
||||
- Open ports ```443, 33071, 33073, 3478``` (Dashboard, Management HTTP API, Management gRpc API, Coturn STUN/TURN respectively) on your server.
|
||||
- Maybe a cup of coffee or tea :)
|
||||
|
||||
### Step-by-step guide
|
||||
|
||||
For this tutorial we will be using domain ```test.wiretrustee.com``` which points to our Ubuntu 20.04 machine hosted at Hetzner.
|
||||
|
||||
1. Create Auth0 account at [auth0.com](https://auth0.com/).
|
||||
2. Login to your server, clone Wiretrustee repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wiretrustee/wiretrustee.git wiretrustee/
|
||||
```
|
||||
|
||||
and switch to the ```wiretrustee/infrastructure_files/``` folder that contains docker compose file:
|
||||
|
||||
```bash
|
||||
cd wiretrustee/infrastructure_files/
|
||||
```
|
||||
3. Prepare configuration files.
|
||||
|
||||
To simplify the setup we have prepared a script to substitute required properties in the [docker-compose.yml.tmpl](../infrastructure_files/docker-compose.yml.tmpl) and [management.json.tmpl](../infrastructure_files/management.json.tmpl) files.
|
||||
|
||||
The [setup.env](../infrastructure_files/setup.env) file contains the following properties that have to be filled:
|
||||
|
||||
```bash
|
||||
# e.g. app.mydomain.com
|
||||
WIRETRUSTEE_DOMAIN=""
|
||||
# e.g. dev-24vkclam.us.auth0.com
|
||||
WIRETRUSTEE_AUTH0_DOMAIN=""
|
||||
# e.g. 61u3JMXRO0oOevc7gCkZLCwePQvT4lL0
|
||||
WIRETRUSTEE_AUTH0_CLIENT_ID=""
|
||||
# e.g. https://app.mydomain.com/
|
||||
WIRETRUSTEE_AUTH0_AUDIENCE=""
|
||||
# e.g. hello@mydomain.com
|
||||
WIRETRUSTEE_LETSENCRYPT_EMAIL=""
|
||||
```
|
||||
|
||||
Please follow the steps to get the values.
|
||||
|
||||
4. Configure ```WIRETRUSTEE_AUTH0_DOMAIN``` ```WIRETRUSTEE_AUTH0_CLIENT_ID``` ```WIRETRUSTEE_AUTH0_AUDIENCE``` properties.
|
||||
|
||||
* To obtain these, please use [Auth0 React SDK Guide](https://auth0.com/docs/quickstart/spa/react/01-login#configure-auth0) up until "Install the Auth0 React SDK".
|
||||
|
||||
:grey_exclamation: Use ```https://YOUR DOMAIN``` as ````Allowed Callback URLs````, ```Allowed Logout URLs```, ```Allowed Web Origins``` and ```Allowed Origins (CORS)```
|
||||
* set the variables in the ```setup.env```
|
||||
5. Configure ```WIRETRUSTEE_AUTH0_AUDIENCE``` property.
|
||||
|
||||
* Check [Auth0 Golang API Guide](https://auth0.com/docs/quickstart/backend/golang) to obtain AuthAudience.
|
||||
* set the property in the ```setup.env``` file.
|
||||
6. Configure ```WIRETRUSTEE_LETSENCRYPT_EMAIL``` property.
|
||||
|
||||
This can be any email address. [Let's Encrypt](https://letsencrypt.org/) will create an account while creating a new domain.
|
||||
|
||||
7. Make sure all the properties set in the ```setup.env``` file and run:
|
||||
|
||||
```bash
|
||||
./configure.sh
|
||||
```
|
||||
|
||||
This will export all the properties as environment variables and generate ```docker-compose.yml``` and ```management.json``` files substituting required variables.
|
||||
|
||||
8. Run docker compose:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
9. Optionally check the logs by running:
|
||||
|
||||
```bash
|
||||
docker-compose logs signal
|
||||
docker-compose logs management
|
||||
docker-compose logs coturn
|
||||
docker-compose logs dashboard
|
||||
7
infrastructure_files/configure.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
unset $(grep -v '^#' ./setup.env | sed -E 's/(.*)=.*/\1/' | xargs)
|
||||
export $(grep -v '^#' ./setup.env | xargs)
|
||||
|
||||
envsubst < docker-compose.yml.tmpl > docker-compose.yml
|
||||
envsubst < management.json.tmpl > management.json
|
||||
@@ -1,56 +0,0 @@
|
||||
version: "3"
|
||||
services:
|
||||
#UI dashboard
|
||||
dashboard:
|
||||
image: wiretrustee/dashboard:main
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 80:80
|
||||
# - 443:443
|
||||
environment:
|
||||
- AUTH0_DOMAIN=<YOUR AUTH0 DOMAIN>
|
||||
- AUTH0_CLIENT_ID=<YOUR AUTH0 CLIENT ID>
|
||||
- AUTH0_AUDIENCE=<YOUR AUTH0 AUDIENCE>
|
||||
- WIRETRUSTEE_MGMT_API_ENDPOINT=http://localhost:33071
|
||||
# - NGINX_SSL_PORT: 443
|
||||
# - LETSENCRYPT_DOMAIN: <YOUR DOMAIN>
|
||||
# - LETSENCRYPT_EMAIL: <YOUR EMAIL>
|
||||
# Signal
|
||||
signal:
|
||||
image: wiretrustee/signal:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- wiretrustee-mgmt:/var/lib/wiretrustee
|
||||
- /varl/log/wiretrustee/signal.log:/var/log/wiretrustee/signal.log
|
||||
ports:
|
||||
- 10000:10000
|
||||
# # port and command for Let's Encrypt validation
|
||||
# - 443:443
|
||||
# command: ["--letsencrypt-domain", "<YOUR-DOMAIN>", "--log-file", "console"]
|
||||
# Management
|
||||
management:
|
||||
image: wiretrustee/management:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- wiretrustee-mgmt:/var/lib/wiretrustee
|
||||
- ./management.json:/etc/wiretrustee/management.json
|
||||
# - /var/log/wiretrustee/management.log:/var/log/wiretrustee/management.log
|
||||
ports:
|
||||
- 33073:33073 #gRPC port
|
||||
- 33071:33071 #HTTP port
|
||||
# # port and command for Let's Encrypt validation
|
||||
# - 443:443
|
||||
# command: ["--letsencrypt-domain", "<YOUR-DOMAIN>", "--log-file", "console"]
|
||||
# Coturn
|
||||
coturn:
|
||||
image: coturn/coturn
|
||||
restart: unless-stopped
|
||||
domainname: stun.wiretrustee.com
|
||||
volumes:
|
||||
- ./turnserver.conf:/etc/turnserver.conf:ro
|
||||
# - ./privkey.pem:/etc/coturn/private/privkey.pem:ro
|
||||
# - ./cert.pem:/etc/coturn/certs/cert.pem:ro
|
||||
network_mode: host
|
||||
volumes:
|
||||
wiretrustee-mgmt:
|
||||
wiretrustee-signal:
|
||||
62
infrastructure_files/docker-compose.yml.tmpl
Normal file
@@ -0,0 +1,62 @@
|
||||
version: "3"
|
||||
services:
|
||||
#UI dashboard
|
||||
dashboard:
|
||||
image: wiretrustee/dashboard:main
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
environment:
|
||||
- AUTH0_DOMAIN=$WIRETRUSTEE_AUTH0_DOMAIN
|
||||
- AUTH0_CLIENT_ID=$WIRETRUSTEE_AUTH0_CLIENT_ID
|
||||
- AUTH0_AUDIENCE=$WIRETRUSTEE_AUTH0_AUDIENCE
|
||||
- WIRETRUSTEE_MGMT_API_ENDPOINT=https://$WIRETRUSTEE_DOMAIN:33071
|
||||
- NGINX_SSL_PORT=443
|
||||
- LETSENCRYPT_DOMAIN=$WIRETRUSTEE_DOMAIN
|
||||
- LETSENCRYPT_EMAIL=$WIRETRUSTEE_LETSENCRYPT_EMAIL
|
||||
volumes:
|
||||
- /var/lib/wiretrustee/dashboard/letsencrypt:/etc/letsencrypt/
|
||||
# Signal
|
||||
signal:
|
||||
image: wiretrustee/signal:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- wiretrustee-signal:/var/lib/wiretrustee
|
||||
# - /var/log/wiretrustee/signal.log:/var/log/wiretrustee/signal.log
|
||||
ports:
|
||||
- 10000:10000
|
||||
# # port and command for Let's Encrypt validation
|
||||
# - 443:443
|
||||
# command: ["--letsencrypt-domain", "$WIRETRUSTEE_DOMAIN", "--log-file", "console"]
|
||||
# Management
|
||||
management:
|
||||
# image: wiretrustee/management:latest
|
||||
image: wiretrustee/management:v0.1.0-beta.2-SNAPSHOT-39d450b-amd64
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- dashboard
|
||||
volumes:
|
||||
- wiretrustee-mgmt:/var/lib/wiretrustee
|
||||
- /var/lib/wiretrustee/dashboard/letsencrypt:/etc/letsencrypt:ro
|
||||
- ./management.json:/etc/wiretrustee/management.json
|
||||
# - /var/log/wiretrustee/management.log:/var/log/wiretrustee/management.log
|
||||
ports:
|
||||
- 33073:33073 #gRPC port
|
||||
- 33071:33071 #HTTP port
|
||||
# # port and command for Let's Encrypt validation
|
||||
# - 443:443
|
||||
# command: ["--letsencrypt-domain", "$WIRETRUSTEE_DOMAIN", "--log-file", "console"]
|
||||
# Coturn
|
||||
coturn:
|
||||
image: coturn/coturn
|
||||
restart: unless-stopped
|
||||
domainname: <YOUR DOMAIN>
|
||||
volumes:
|
||||
- ./turnserver.conf:/etc/turnserver.conf:ro
|
||||
# - ./privkey.pem:/etc/coturn/private/privkey.pem:ro
|
||||
# - ./cert.pem:/etc/coturn/certs/cert.pem:ro
|
||||
network_mode: host
|
||||
volumes:
|
||||
wiretrustee-mgmt:
|
||||
wiretrustee-signal:
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"Stuns": [
|
||||
{
|
||||
"Proto": "udp",
|
||||
"URI": "stun:stun.wiretrustee.com:3468",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
}
|
||||
],
|
||||
"TURNConfig": {
|
||||
"Turns": [
|
||||
{
|
||||
"Proto": "udp",
|
||||
"URI": "turn:stun.wiretrustee.com:3468",
|
||||
"Username": "some_user",
|
||||
"Password": "c29tZV9wYXNzd29yZA=="
|
||||
}
|
||||
],
|
||||
"CredentialsTTL": "1h",
|
||||
"Secret": "c29tZV9wYXNzd29yZA==",
|
||||
"TimeBasedCredentials": true
|
||||
},
|
||||
"Signal": {
|
||||
"Proto": "http",
|
||||
"URI": "signal.wiretrustee.com:10000",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
},
|
||||
"Datadir": "",
|
||||
"HttpConfig": {
|
||||
"LetsEncryptDomain": "<PASTE YOUR LET'S ENCRYPT DOMAIN HERE>",
|
||||
"Address": "0.0.0.0:33071",
|
||||
"AuthIssuer": "<PASTE YOUR AUTH0 ISSUER HERE>,",
|
||||
"AuthAudience": "<PASTE YOUR AUTH0 AUDIENCE HERE>",
|
||||
"AuthKeysLocation": "<PASTE YOUR AUTH0 PUBLIC JWT KEYS LOCATION HERE>"
|
||||
}
|
||||
}
|
||||
39
infrastructure_files/management.json.tmpl
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"Stuns": [
|
||||
{
|
||||
"Proto": "udp",
|
||||
"URI": "stun:$WIRETRUSTEE_DOMAIN:3478",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
}
|
||||
],
|
||||
"TURNConfig": {
|
||||
"Turns": [
|
||||
{
|
||||
"Proto": "udp",
|
||||
"URI": "turn:$WIRETRUSTEE_DOMAIN:3478",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
}
|
||||
],
|
||||
"CredentialsTTL": "12h",
|
||||
"Secret": "secret",
|
||||
"TimeBasedCredentials": false
|
||||
},
|
||||
"Signal": {
|
||||
"Proto": "http",
|
||||
"URI": "$WIRETRUSTEE_DOMAIN:10000",
|
||||
"Username": "",
|
||||
"Password": null
|
||||
},
|
||||
"Datadir": "",
|
||||
"HttpConfig": {
|
||||
"LetsEncryptDomain": "",
|
||||
"CertFile":"/etc/letsencrypt/live/$WIRETRUSTEE_DOMAIN/fullchain.pem",
|
||||
"CertKey":"/etc/letsencrypt/live/$WIRETRUSTEE_DOMAIN/privkey.pem",
|
||||
"Address": "0.0.0.0:33071",
|
||||
"AuthIssuer": "https://$WIRETRUSTEE_AUTH0_DOMAIN/",
|
||||
"AuthAudience": "$WIRETRUSTEE_AUTH0_AUDIENCE",
|
||||
"AuthKeysLocation": "https://$WIRETRUSTEE_AUTH0_DOMAIN/.well-known/jwks.json"
|
||||
}
|
||||
}
|
||||
10
infrastructure_files/setup.env
Normal file
@@ -0,0 +1,10 @@
|
||||
# e.g. app.mydomain.com
|
||||
WIRETRUSTEE_DOMAIN=""
|
||||
# e.g. dev-24vkclam.us.auth0.com
|
||||
WIRETRUSTEE_AUTH0_DOMAIN=""
|
||||
# e.g. 61u3JMXRO0oOevc7gCkZLCwePQvT4lL0
|
||||
WIRETRUSTEE_AUTH0_CLIENT_ID=""
|
||||
# e.g. https://app.mydomain.com/
|
||||
WIRETRUSTEE_AUTH0_AUDIENCE=""
|
||||
# e.g. hello@mydomain.com
|
||||
WIRETRUSTEE_LETSENCRYPT_EMAIL=""
|
||||
@@ -14,7 +14,8 @@ Flags:
|
||||
-h, --help help for management
|
||||
--letsencrypt-domain string a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS
|
||||
--port int server port to listen on (default 33073)
|
||||
|
||||
--cert-file string Location of your SSL certificate. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect
|
||||
--cert-key string Location of your SSL certificate private key. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect
|
||||
Global Flags:
|
||||
--config string Wiretrustee config file location to write new config to (default "/etc/wiretrustee/config.json")
|
||||
--log-level string (default "info")
|
||||
|
||||
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/wiretrustee/wiretrustee/management/server"
|
||||
@@ -25,6 +26,8 @@ var (
|
||||
mgmtDataDir string
|
||||
mgmtConfig string
|
||||
mgmtLetsencryptDomain string
|
||||
certFile string
|
||||
certKey string
|
||||
|
||||
kaep = keepalive.EnforcementPolicy{
|
||||
MinTime: 15 * time.Second,
|
||||
@@ -71,12 +74,23 @@ var (
|
||||
|
||||
var httpServer *http.Server
|
||||
if config.HttpConfig.LetsEncryptDomain != "" {
|
||||
//automatically generate a new certificate with Let's Encrypt
|
||||
certManager := encryption.CreateCertManager(config.Datadir, config.HttpConfig.LetsEncryptDomain)
|
||||
transportCredentials := credentials.NewTLS(certManager.TLSConfig())
|
||||
opts = append(opts, grpc.Creds(transportCredentials))
|
||||
|
||||
httpServer = http.NewHttpsServer(config.HttpConfig, certManager, accountManager)
|
||||
} else if config.HttpConfig.CertFile != "" && config.HttpConfig.CertKey != "" {
|
||||
//use provided certificate
|
||||
tlsConfig, err := loadTLSConfig(config.HttpConfig.CertFile, config.HttpConfig.CertKey)
|
||||
if err != nil {
|
||||
log.Fatal("cannot load TLS credentials: ", err)
|
||||
}
|
||||
transportCredentials := credentials.NewTLS(tlsConfig)
|
||||
opts = append(opts, grpc.Creds(transportCredentials))
|
||||
httpServer = http.NewHttpsServerWithTLSConfig(config.HttpConfig, tlsConfig, accountManager)
|
||||
} else {
|
||||
//start server without SSL
|
||||
httpServer = http.NewHttpServer(config.HttpConfig, accountManager)
|
||||
}
|
||||
|
||||
@@ -136,14 +150,37 @@ func loadConfig() (*server.Config, error) {
|
||||
config.Datadir = mgmtDataDir
|
||||
}
|
||||
|
||||
if certKey != "" && certFile != "" {
|
||||
config.HttpConfig.CertFile = certFile
|
||||
config.HttpConfig.CertKey = certKey
|
||||
}
|
||||
|
||||
return config, err
|
||||
}
|
||||
|
||||
func loadTLSConfig(certFile string, certKey string) (*tls.Config, error) {
|
||||
// Load server's certificate and private key
|
||||
serverCert, err := tls.LoadX509KeyPair(certFile, certKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the credentials and return it
|
||||
config := &tls.Config{
|
||||
Certificates: []tls.Certificate{serverCert},
|
||||
ClientAuth: tls.NoClientCert,
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
mgmtCmd.Flags().IntVar(&mgmtPort, "port", 33073, "server port to listen on")
|
||||
mgmtCmd.Flags().StringVar(&mgmtDataDir, "datadir", "/var/lib/wiretrustee/", "server data directory location")
|
||||
mgmtCmd.Flags().StringVar(&mgmtConfig, "config", "/etc/wiretrustee/management.json", "Wiretrustee config file location. Config params specified via command line (e.g. datadir) have a precedence over configuration from this file")
|
||||
mgmtCmd.Flags().StringVar(&mgmtLetsencryptDomain, "letsencrypt-domain", "", "a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS")
|
||||
mgmtCmd.Flags().StringVar(&certFile, "cert-file", "", "Location of your SSL certificate. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect")
|
||||
mgmtCmd.Flags().StringVar(&certKey, "cert-key", "", "Location of your SSL certificate private key. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect")
|
||||
|
||||
rootCmd.MarkFlagRequired("config") //nolint
|
||||
|
||||
|
||||
@@ -36,7 +36,11 @@ type TURNConfig struct {
|
||||
// HttpServerConfig is a config of the HTTP Management service server
|
||||
type HttpServerConfig struct {
|
||||
LetsEncryptDomain string
|
||||
Address string
|
||||
//CertFile is the location of the certificate
|
||||
CertFile string
|
||||
//CertKey is the location of the certificate private key
|
||||
CertKey string
|
||||
Address string
|
||||
// AuthAudience identifies the recipients that the JWT is intended for (aud in JWT)
|
||||
AuthAudience string
|
||||
// AuthIssuer identifies principal that issued the JWT.
|
||||
|
||||
@@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rs/cors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -17,10 +18,11 @@ type Server struct {
|
||||
server *http.Server
|
||||
config *s.HttpServerConfig
|
||||
certManager *autocert.Manager
|
||||
tlsConfig *tls.Config
|
||||
accountManager *s.AccountManager
|
||||
}
|
||||
|
||||
// NewHttpsServer creates a new HTTPs server (with HTTPS support)
|
||||
// NewHttpsServer creates a new HTTPs server (with HTTPS support) and a certManager that is responsible for generating and renewing Let's Encrypt certificate
|
||||
// The listening address will be :443 no matter what was specified in s.HttpServerConfig.Address
|
||||
func NewHttpsServer(config *s.HttpServerConfig, certManager *autocert.Manager, accountManager *s.AccountManager) *Server {
|
||||
server := &http.Server{
|
||||
@@ -32,6 +34,18 @@ func NewHttpsServer(config *s.HttpServerConfig, certManager *autocert.Manager, a
|
||||
return &Server{server: server, config: config, certManager: certManager, accountManager: accountManager}
|
||||
}
|
||||
|
||||
// NewHttpsServerWithTLSConfig creates a new HTTPs server with a provided tls.Config.
|
||||
// Usually used when you already have a certificate
|
||||
func NewHttpsServerWithTLSConfig(config *s.HttpServerConfig, tlsConfig *tls.Config, accountManager *s.AccountManager) *Server {
|
||||
server := &http.Server{
|
||||
Addr: config.Address,
|
||||
WriteTimeout: time.Second * 15,
|
||||
ReadTimeout: time.Second * 15,
|
||||
IdleTimeout: time.Second * 60,
|
||||
}
|
||||
return &Server{server: server, config: config, tlsConfig: tlsConfig, accountManager: accountManager}
|
||||
}
|
||||
|
||||
// NewHttpServer creates a new HTTP server (without HTTPS)
|
||||
func NewHttpServer(config *s.HttpServerConfig, accountManager *s.AccountManager) *Server {
|
||||
return NewHttpsServer(config, nil, accountManager)
|
||||
@@ -71,13 +85,26 @@ func (s *Server) Start() error {
|
||||
if s.certManager != nil {
|
||||
// if HTTPS is enabled we reuse the listener from the cert manager
|
||||
listener := s.certManager.Listener()
|
||||
log.Infof("http server listening on %s", listener.Addr())
|
||||
log.Infof("HTTPs server listening on %s with Let's Encrypt autocert configured", listener.Addr())
|
||||
if err = http.Serve(listener, s.certManager.HTTPHandler(r)); err != nil {
|
||||
log.Errorf("failed to serve https server: %v", err)
|
||||
return err
|
||||
}
|
||||
} else if s.tlsConfig != nil {
|
||||
listener, err := tls.Listen("tcp", s.config.Address, s.tlsConfig)
|
||||
if err != nil {
|
||||
log.Errorf("failed to serve https server: %v", err)
|
||||
return err
|
||||
}
|
||||
log.Infof("HTTPs server listening on %s", listener.Addr())
|
||||
|
||||
if err = http.Serve(listener, r); err != nil {
|
||||
log.Errorf("failed to serve https server: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Infof("http server listening on %s", s.server.Addr)
|
||||
log.Infof("HTTP server listening on %s", s.server.Addr)
|
||||
if err = s.server.ListenAndServe(); err != nil {
|
||||
log.Errorf("failed to serve http server: %v", err)
|
||||
return err
|
||||
|
||||