Compare commits

...

17 Commits

Author SHA1 Message Date
Maycon Santos
e4f9406d44 Removed installer and add workflow dispatch (#120) 2021-09-25 19:30:12 +02:00
braginini
7c79ff62ee fix: coturn port 2021-09-25 19:29:43 +02:00
Mikhail Bragin
32c369257b management/support cert from file (#122)
* feature: support cert file in management service

* docs: add new management commands
2021-09-25 19:22:49 +02:00
Mikhail Bragin
08dd719aa1 self-hosting guide (#121)
* docs: first steps of the self-hosting guide

* feature: add setup configurator for the self-hosted guide

* docs: add setup.env comments

* docs: simplify installation steps - support ./configure.sh

* docs: fix file references

* docs: fix minor docs issues

* docs: remove unused title
2021-09-25 19:12:05 +02:00
Mikhail Bragin
84c714dd93 Update quickstart.md 2021-09-23 14:39:55 +02:00
Mikhail Bragin
996c8d7c62 docs: referer to the new video 2021-09-23 14:38:51 +02:00
Mikhail Bragin
25e68ce493 docs: fix broken intro link 2021-09-22 14:18:48 +02:00
Mikhail Bragin
4881dcbd51 docs: add Getting Started hosted version guide (#119)
* docs: add Getting Started hosted version guide

* docs: fix screenshot sizes

* docs: self-hosting section

* docs: increase screenshots width

* docs: reference getting started from main readme

* docs: add refs to sections

* docs: move docs to a separate folder

* docs: add intro

* docs: correct intro docs

* docs: correct image location

* docs: correct language
2021-09-22 14:16:46 +02:00
Mikhail Bragin
d505f70972 Update README.md 2021-09-13 08:50:15 +02:00
Mikhail Bragin
6a80684378 docs: add slack 2021-09-13 08:18:18 +02:00
Mikhail Bragin
2624a7c4e6 docs: update Auth0 notes 2021-09-13 08:06:28 +02:00
Mikhail Bragin
9a412e7bf1 Update README.md 2021-09-13 07:58:52 +02:00
Mikhail Bragin
b5d1690129 Update README.md 2021-09-12 20:38:26 +02:00
Mikhail Bragin
d4bec15ca3 Update README.md 2021-09-12 20:37:55 +02:00
Mikhail Bragin
3212aca7c7 docs: add reference to auth0 react guide 2021-09-12 09:39:03 +03:00
Mikhail Bragin
b97a2251d3 fix docker compose signal volume 2021-09-12 09:08:55 +03:00
braginini
528a26ea3e chore: simplify direct connection logic 2021-09-09 16:43:52 +02:00
24 changed files with 401 additions and 147 deletions

View File

@@ -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
View File

@@ -3,4 +3,6 @@
dist/
.env
conf.json
http-cmds.sh
http-cmds.sh
infrastructure_files/management.json
infrastructure_files/docker-compose.yml

View File

@@ -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
![animation](media/peers.gif)
![animation](docs/media/peers.gif)
### 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).

View File

@@ -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
View 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
View File

@@ -0,0 +1,2 @@
### Architecture
TODO

BIN
docs/media/add-peer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
docs/media/auth.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
docs/media/empty-peers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 5.9 MiB

After

Width:  |  Height:  |  Size: 5.9 MiB

BIN
docs/media/peers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

41
docs/quickstart.md Normal file
View File

@@ -0,0 +1,41 @@
## Quickstart guide (Cloud Managed version)
Step-by-step video guide on YouTube:
[![IMAGE ALT TEXT](https://img.youtube.com/vi/cWTsGUJAUaU/0.jpg)](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
View 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

View 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

View File

@@ -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:

View 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:

View File

@@ -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>"
}
}

View 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"
}
}

View 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=""

View File

@@ -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")

View File

@@ -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

View File

@@ -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.

View File

@@ -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