Compare commits
32 Commits
v0.1.0-bet
...
v0.2.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
842b143a48 | ||
|
|
1323a74db0 | ||
|
|
74485d3b13 | ||
|
|
bef3b3392b | ||
|
|
fcea3c99d4 | ||
|
|
96799a25b5 | ||
|
|
07291cdb93 | ||
|
|
21139938c1 | ||
|
|
5cf2d0a6a9 | ||
|
|
8551afe04e | ||
|
|
1685817171 | ||
|
|
e17f662683 | ||
|
|
a764fb870c | ||
|
|
cabff941ac | ||
|
|
b5f35dfb5e | ||
|
|
1d426b7f81 | ||
|
|
e4f9406d44 | ||
|
|
7c79ff62ee | ||
|
|
32c369257b | ||
|
|
08dd719aa1 | ||
|
|
84c714dd93 | ||
|
|
996c8d7c62 | ||
|
|
25e68ce493 | ||
|
|
4881dcbd51 | ||
|
|
d505f70972 | ||
|
|
6a80684378 | ||
|
|
2624a7c4e6 | ||
|
|
9a412e7bf1 | ||
|
|
b5d1690129 | ||
|
|
d4bec15ca3 | ||
|
|
3212aca7c7 | ||
|
|
b97a2251d3 |
33
.github/workflows/release.yml
vendored
@@ -51,28 +51,15 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
||||
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||
|
||||
-
|
||||
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
|
||||
@@ -13,13 +13,18 @@ builds:
|
||||
- arm
|
||||
- amd64
|
||||
- arm64
|
||||
- mips
|
||||
gomips:
|
||||
- hardfloat
|
||||
- softfloat
|
||||
ignore:
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} -X main.builtBy=goreleaser
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
tags:
|
||||
- load_wintun_from_rsrc
|
||||
|
||||
@@ -32,6 +37,9 @@ builds:
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} -X main.builtBy=goreleaser
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
|
||||
- id: wiretrustee-signal
|
||||
dir: signal
|
||||
@@ -42,28 +50,40 @@ builds:
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} -X main.builtBy=goreleaser
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
archives:
|
||||
- builds:
|
||||
- wiretrustee
|
||||
nfpms:
|
||||
- maintainer: Wiretrustee <wiretrustee@wiretrustee.com>
|
||||
description: Wiretrustee project.
|
||||
- maintainer: Wiretrustee <dev@wiretrustee.com>
|
||||
description: Wiretrustee client.
|
||||
homepage: https://wiretrustee.com/
|
||||
id: deb
|
||||
builds:
|
||||
- wiretrustee
|
||||
formats:
|
||||
- deb
|
||||
- rpm
|
||||
contents:
|
||||
- src: release_files/wiretrustee.service
|
||||
dst: /lib/systemd/system/wiretrustee.service
|
||||
|
||||
- src: release_files/wiretrustee.json
|
||||
dst: /etc/wiretrustee/wiretrustee.json
|
||||
type: "config|noreplace"
|
||||
|
||||
scripts:
|
||||
postinstall: "release_files/post_install.sh"
|
||||
preremove: "release_files/pre_remove.sh"
|
||||
replacements:
|
||||
arm6: armf
|
||||
|
||||
- maintainer: Wiretrustee <dev@wiretrustee.com>
|
||||
description: Wiretrustee client.
|
||||
homepage: https://wiretrustee.com/
|
||||
id: rpm
|
||||
builds:
|
||||
- wiretrustee
|
||||
formats:
|
||||
- rpm
|
||||
|
||||
scripts:
|
||||
postinstall: "release_files/post_install.sh"
|
||||
preremove: "release_files/pre_remove.sh"
|
||||
dockers:
|
||||
- image_templates:
|
||||
- wiretrustee/signal:{{ .Version }}-amd64
|
||||
@@ -196,4 +216,20 @@ brews:
|
||||
homepage: https://wiretrustee.com/
|
||||
license: "BSD3"
|
||||
test: |
|
||||
system "#{bin}/{{ .ProjectName }} -h"
|
||||
system "#{bin}/{{ .ProjectName }} -h"
|
||||
|
||||
uploads:
|
||||
- name: debian
|
||||
ids:
|
||||
- deb
|
||||
mode: archive
|
||||
target: https://pkgs.wiretrustee.com/debian/pool/{{ .ArtifactName }};deb.distribution=stable;deb.component=main;deb.architecture={{ .Arch }}{{ if .Arm }}{{ .Arm }}{{ end }}
|
||||
username: dev@wiretrustee.com
|
||||
method: PUT
|
||||
- name: yum
|
||||
ids:
|
||||
- rpm
|
||||
mode: archive
|
||||
target: https://pkgs.wiretrustee.com/yum/{{ .Arch }}{{ if .Arm }}{{ .Arm }}{{ end }}
|
||||
username: dev@wiretrustee.com
|
||||
method: PUT
|
||||
204
README.md
@@ -1,15 +1,50 @@
|
||||
# Wiretrustee
|
||||
<div align="center">
|
||||
|
||||
A WireGuard®-based mesh network that connects your devices into a single private network.
|
||||
<p align="center">
|
||||
<img width="250" src="docs/media/logo-full.png"/>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img src="https://img.shields.io/badge/license-BSD--3-blue" />
|
||||
<img src="https://img.shields.io/docker/pulls/wiretrustee/management" />
|
||||
<img src="https://badgen.net/badge/Open%20Source%3F/Yes%21/blue?icon=github" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
<strong>
|
||||
Start using Wiretrustee at <a href="https://app.wiretrustee.com/">app.wiretrustee.com</a>
|
||||
<br/>
|
||||
See <a href="docs/README.md">Documentation</a>
|
||||
<br/>
|
||||
Join our <a href="https://join.slack.com/t/wiretrustee/shared_invite/zt-vrahf41g-ik1v7fV8du6t0RwxSrJ96A">Slack channel</a>
|
||||
<br/>
|
||||
|
||||
</strong>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
**Wiretrustee is an open-source VPN platform built on top of WireGuard® making it easy to create secure private networks for your organization or home.**
|
||||
|
||||
It requires zero configuration effort leaving behind the hassle of opening ports, complex firewall rules, vpn gateways, and so forth.
|
||||
|
||||
There is no centralized VPN server with Wiretrustee - your computers, devices, machines, and servers connect to each other directly over a fast encrypted tunnel.
|
||||
|
||||
### Secure peer-to-peer VPN in minutes
|
||||
<p float="left" align="middle">
|
||||
<img src="docs/media/peerA.gif" width="400"/>
|
||||
<img src="docs/media/peerB.gif" width="400"/>
|
||||
</p>
|
||||
|
||||
**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)
|
||||
|
||||
Please don't use the hosted demonstration version for production purposes.
|
||||
Hosted demo version:
|
||||
[https://app.wiretrustee.com/](https://app.wiretrustee.com/peers).
|
||||
|
||||
[UI Dashboard Repo](https://github.com/wiretrustee/wiretrustee-dashboard)
|
||||
|
||||
|
||||
### Why using Wiretrustee?
|
||||
|
||||
* Connect multiple devices to each other via a secure peer-to-peer Wireguard VPN tunnel. At home, the office, or anywhere else.
|
||||
@@ -25,8 +60,6 @@ Please don't use the hosted demonstration version for production purposes.
|
||||
* Works on ARM devices (e.g. Raspberry Pi).
|
||||
* 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).
|
||||
@@ -44,116 +77,119 @@ Please don't use the hosted demonstration version for production purposes.
|
||||
|
||||
### Client Installation
|
||||
#### Linux
|
||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases)
|
||||
2. Download the latest release (**Switch VERSION to the latest**):
|
||||
|
||||
**Debian packages**
|
||||
```shell
|
||||
wget https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_linux_amd64.deb
|
||||
```
|
||||
3. Install the package
|
||||
```shell
|
||||
sudo dpkg -i wiretrustee_<VERSION>_linux_amd64.deb
|
||||
```
|
||||
**Fedora/Centos packages**
|
||||
```shell
|
||||
wget https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_linux_amd64.rpm
|
||||
```
|
||||
3. Install the package
|
||||
```shell
|
||||
sudo rpm -i wiretrustee_<VERSION>_linux_amd64.rpm
|
||||
```
|
||||
**APT/Debian**
|
||||
1. Add the repository:
|
||||
```shell
|
||||
sudo apt-get update
|
||||
sudo apt-get install ca-certificates curl gnupg -y
|
||||
curl -L https://pkgs.wiretrustee.com/debian/public.key | sudo apt-key add -
|
||||
echo 'deb https://pkgs.wiretrustee.com/debian stable main' | sudo tee /etc/apt/sources.list.d/wiretrustee.list
|
||||
```
|
||||
2. Install the package
|
||||
```shell
|
||||
sudo apt-get update
|
||||
sudo apt-get install wiretrustee
|
||||
```
|
||||
**RPM/Red hat**
|
||||
1. Add the repository:
|
||||
```shell
|
||||
cat <<EOF | sudo tee /etc/yum.repos.d/wiretrustee.repo
|
||||
[Wiretrustee]
|
||||
name=Wiretrustee
|
||||
baseurl=https://pkgs.wiretrustee.com/yum/
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
gpgkey=https://pkgs.wiretrustee.com/yum/repodata/repomd.xml.key
|
||||
repo_gpgcheck=1
|
||||
EOF
|
||||
```
|
||||
2. Install the package
|
||||
```shell
|
||||
sudo yum install wiretrustee
|
||||
```
|
||||
#### MACOS
|
||||
**Brew install**
|
||||
1. Download and install Brew at https://brew.sh/
|
||||
2. Install the client
|
||||
```shell
|
||||
brew install wiretrustee/client/wiretrustee
|
||||
```
|
||||
```shell
|
||||
brew install wiretrustee/client/wiretrustee
|
||||
```
|
||||
**Installation from binary**
|
||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases/latest)
|
||||
2. Download the latest release (**Switch VERSION to the latest**):
|
||||
```shell
|
||||
curl -o ./wiretrustee_<VERSION>_darwin_amd64.tar.gz https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
||||
```
|
||||
```shell
|
||||
curl -o ./wiretrustee_<VERSION>_darwin_amd64.tar.gz https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
||||
```
|
||||
3. Decompress
|
||||
```shell
|
||||
tar xcf ./wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
||||
sudo mv wiretrusee /usr/local/bin/wiretrustee
|
||||
chmod +x /usr/local/bin/wiretrustee
|
||||
```
|
||||
```shell
|
||||
tar xcf ./wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
||||
sudo mv wiretrusee /usr/local/bin/wiretrustee
|
||||
chmod +x /usr/local/bin/wiretrustee
|
||||
```
|
||||
After that you may need to add /usr/local/bin in your MAC's PATH environment variable:
|
||||
````shell
|
||||
export PATH=$PATH:/usr/local/bin
|
||||
````
|
||||
````shell
|
||||
export PATH=$PATH:/usr/local/bin
|
||||
````
|
||||
|
||||
#### Windows
|
||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases/latest)
|
||||
2. Download the latest Windows release installer ```wiretrustee_installer_<VERSION>_windows_amd64.exe``` (**Switch VERSION to the latest**):
|
||||
3. Proceed with installation steps
|
||||
4. This will install the client in the C:\\Program Files\\Wiretrustee and add the client service
|
||||
5. After installing you can follow the [Client Configuration](#Client-Configuration) steps.
|
||||
5. After installing, you can follow the [Client Configuration](#Client-Configuration) steps.
|
||||
> To uninstall the client and service, you can use Add/Remove programs
|
||||
|
||||
### Client Configuration
|
||||
1. Login to the Management Service. You need to have a `setup key` in hand (see ).
|
||||
|
||||
For **Unix** systems:
|
||||
```shell
|
||||
sudo wiretrustee login --setup-key <SETUP KEY>
|
||||
```
|
||||
For **Windows** systems:
|
||||
```shell
|
||||
.\wiretrustee.exe login --setup-key <SETUP KEY>
|
||||
```
|
||||
```shell
|
||||
sudo wiretrustee up --setup-key <SETUP KEY>
|
||||
```
|
||||
For **Windows** systems, start powershell as administrator and:
|
||||
```shell
|
||||
wiretrustee up --setup-key <SETUP KEY>
|
||||
```
|
||||
|
||||
Alternatively, if you are hosting your own Management Service provide `--management-url` property pointing to your Management Service:
|
||||
```shell
|
||||
sudo wiretrustee login --setup-key <SETUP KEY> --management-url https://localhost:33073
|
||||
```
|
||||
```shell
|
||||
sudo wiretrustee up --setup-key <SETUP KEY> --management-url https://localhost:33073
|
||||
```
|
||||
|
||||
You could also omit `--setup-key` property. In this case the tool will prompt it the key.
|
||||
> You could also omit `--setup-key` property. In this case the tool will prompt it the key.
|
||||
|
||||
2. Start Wiretrustee:
|
||||
|
||||
For **MACOS** you will just start the service:
|
||||
````shell
|
||||
sudo wiretrustee up
|
||||
# or
|
||||
sudo wiretrustee up & # to run it in background
|
||||
````
|
||||
2. Check your IP:
|
||||
For **MACOS** you will just start the service:
|
||||
````shell
|
||||
sudo ipconfig getifaddr utun100
|
||||
````
|
||||
For **Linux** systems:
|
||||
```shell
|
||||
sudo systemctl restart wiretrustee.service
|
||||
sudo systemctl status wiretrustee.service
|
||||
```
|
||||
```shell
|
||||
ip addr show wt0
|
||||
```
|
||||
For **Windows** systems:
|
||||
```shell
|
||||
.\wiretrustee.exe service start
|
||||
```
|
||||
> You may need to run Powershell as Administrator
|
||||
```shell
|
||||
netsh interface ip show config name="wt0"
|
||||
```
|
||||
|
||||
3. Check your IP:
|
||||
For **MACOS** you will just start the service:
|
||||
````shell
|
||||
sudo ipconfig getifaddr utun100
|
||||
````
|
||||
For **Linux** systems:
|
||||
```shell
|
||||
ip addr show wt0
|
||||
```
|
||||
For **Windows** systems:
|
||||
```shell
|
||||
netsh interface ip show config name="wt0"
|
||||
```
|
||||
3. Repeat on other machines.
|
||||
|
||||
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).
|
||||
|
||||
@@ -152,6 +152,5 @@ func promptPeerSetupKey() (string, error) {
|
||||
return "", s.Err()
|
||||
}
|
||||
|
||||
func init() {
|
||||
loginCmd.PersistentFlags().StringVar(&setupKey, "setup-key", "", "Setup key obtained from the Management Service Dashboard (used to register peer)")
|
||||
}
|
||||
//func init() {
|
||||
//}
|
||||
|
||||
@@ -2,11 +2,13 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,15 +24,15 @@ var (
|
||||
defaultLogFile string
|
||||
logFile string
|
||||
managementURL string
|
||||
|
||||
rootCmd = &cobra.Command{
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "wiretrustee",
|
||||
Short: "",
|
||||
Long: "",
|
||||
}
|
||||
|
||||
// Execution control channel for stopCh signal
|
||||
stopCh chan int
|
||||
stopCh chan int
|
||||
cleanupCh chan struct{}
|
||||
)
|
||||
|
||||
// Execute executes the root command.
|
||||
@@ -40,6 +42,7 @@ func Execute() error {
|
||||
func init() {
|
||||
|
||||
stopCh = make(chan int)
|
||||
cleanupCh = make(chan struct{})
|
||||
|
||||
defaultConfigPath = "/etc/wiretrustee/config.json"
|
||||
defaultLogFile = "/var/log/wiretrustee/client.log"
|
||||
@@ -52,9 +55,11 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringVar(&configPath, "config", defaultConfigPath, "Wiretrustee config file location")
|
||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "sets Wiretrustee log level")
|
||||
rootCmd.PersistentFlags().StringVar(&logFile, "log-file", defaultLogFile, "sets Wiretrustee log path. If console is specified the the log will be output to stdout")
|
||||
rootCmd.PersistentFlags().StringVar(&setupKey, "setup-key", "", "Setup key obtained from the Management Service Dashboard (used to register peer)")
|
||||
rootCmd.AddCommand(serviceCmd)
|
||||
rootCmd.AddCommand(upCmd)
|
||||
rootCmd.AddCommand(loginCmd)
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service
|
||||
serviceCmd.AddCommand(installCmd, uninstallCmd) // service installer commands are subcommands of service
|
||||
}
|
||||
@@ -62,10 +67,10 @@ func init() {
|
||||
// SetupCloseHandler handles SIGTERM signal and exits with success
|
||||
func SetupCloseHandler() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
go func() {
|
||||
for range c {
|
||||
fmt.Println("\r- Ctrl+C pressed in Terminal")
|
||||
log.Info("shutdown signal received")
|
||||
stopCh <- 0
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -1,26 +1,58 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/kardianos/service"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wiretrustee/wiretrustee/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (p *program) Start(s service.Service) error {
|
||||
|
||||
var backOff = &backoff.ExponentialBackOff{
|
||||
InitialInterval: time.Second,
|
||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||
Multiplier: backoff.DefaultMultiplier,
|
||||
MaxInterval: 30 * time.Second,
|
||||
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
||||
Stop: backoff.Stop,
|
||||
Clock: backoff.SystemClock,
|
||||
}
|
||||
|
||||
// Start should not block. Do the actual work async.
|
||||
log.Info("starting service") //nolint
|
||||
go func() {
|
||||
err := upCmd.RunE(p.cmd, p.args)
|
||||
if err != nil {
|
||||
return
|
||||
operation := func() error {
|
||||
err := runClient()
|
||||
if err != nil {
|
||||
log.Warnf("retrying Wiretrustee client app due to error: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err := backoff.Retry(operation, backOff)
|
||||
if err != nil {
|
||||
log.Errorf("exiting client retry loop due to unrecoverable error: %s", err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *program) Stop(s service.Service) error {
|
||||
stopCh <- 1
|
||||
go func() {
|
||||
stopCh <- 1
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-cleanupCh:
|
||||
case <-time.After(time.Second * 10):
|
||||
log.Warnf("failed waiting for service cleanup, terminating")
|
||||
}
|
||||
log.Info("stopped Wiretrustee service") //nolint
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -30,6 +62,14 @@ var (
|
||||
Short: "runs wiretrustee as service",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
SetupCloseHandler()
|
||||
|
||||
prg := &program{
|
||||
cmd: cmd,
|
||||
args: args,
|
||||
@@ -54,19 +94,24 @@ var (
|
||||
startCmd = &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "starts wiretrustee service",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return err
|
||||
}
|
||||
s, err := newSVC(&program{}, newSVCConfig())
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
err = s.Start()
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
cmd.Printf("Wiretrustee service has been started")
|
||||
cmd.Println("Wiretrustee service has been started")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -76,7 +121,10 @@ var (
|
||||
Use: "stop",
|
||||
Short: "stops wiretrustee service",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
s, err := newSVC(&program{}, newSVCConfig())
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
@@ -87,7 +135,7 @@ var (
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
}
|
||||
cmd.Printf("Wiretrustee service has been stopped")
|
||||
cmd.Println("Wiretrustee service has been stopped")
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -97,7 +145,10 @@ var (
|
||||
Use: "restart",
|
||||
Short: "restarts wiretrustee service",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
s, err := newSVC(&program{}, newSVCConfig())
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
@@ -108,7 +159,7 @@ var (
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
}
|
||||
cmd.Printf("Wiretrustee service has been restarted")
|
||||
cmd.Println("Wiretrustee service has been restarted")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ var (
|
||||
installCmd = &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "installs wiretrustee service",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
svcConfig := newSVCConfig()
|
||||
|
||||
@@ -30,15 +30,16 @@ var (
|
||||
s, err := newSVC(&program{}, svcConfig)
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.Install()
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
cmd.Printf("Wiretrustee service has been installed")
|
||||
cmd.Println("Wiretrustee service has been installed")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -60,7 +61,7 @@ var (
|
||||
cmd.PrintErrln(err)
|
||||
return
|
||||
}
|
||||
cmd.Printf("Wiretrustee has been uninstalled")
|
||||
cmd.Println("Wiretrustee has been uninstalled")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
189
client/cmd/up.go
@@ -2,13 +2,13 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/kardianos/service"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||
mgm "github.com/wiretrustee/wiretrustee/management/client"
|
||||
mgmProto "github.com/wiretrustee/wiretrustee/management/proto"
|
||||
signal "github.com/wiretrustee/wiretrustee/signal/client"
|
||||
"github.com/wiretrustee/wiretrustee/util"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -17,97 +17,45 @@ import (
|
||||
var (
|
||||
upCmd = &cobra.Command{
|
||||
Use: "up",
|
||||
Short: "start wiretrustee",
|
||||
Short: "install, login and start wiretrustee client",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
|
||||
err := loginCmd.RunE(cmd, args)
|
||||
if err != nil {
|
||||
log.Errorf("failed initializing log %v", err)
|
||||
return err
|
||||
}
|
||||
if logFile == "console" {
|
||||
return runClient()
|
||||
}
|
||||
|
||||
s, err := newSVC(&program{}, newSVCConfig())
|
||||
if err != nil {
|
||||
cmd.PrintErrln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := internal.ReadConfig(managementURL, configPath)
|
||||
srvStatus, err := s.Status()
|
||||
if err != nil {
|
||||
log.Errorf("failed reading config %s %v", configPath, err)
|
||||
return err
|
||||
if err == service.ErrNotInstalled {
|
||||
log.Infof("%s. Installing it now", err.Error())
|
||||
e := installCmd.RunE(cmd, args)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
} else {
|
||||
log.Warnf("failed retrieving service status: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
//validate our peer's Wireguard PRIVATE key
|
||||
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
||||
if err != nil {
|
||||
log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error())
|
||||
return err
|
||||
if srvStatus == service.StatusRunning {
|
||||
stopCmd.Run(cmd, args)
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
mgmTlsEnabled := false
|
||||
if config.ManagementURL.Scheme == "https" {
|
||||
mgmTlsEnabled = true
|
||||
}
|
||||
|
||||
// connect (just a connection, no stream yet) and login to Management Service to get an initial global Wiretrustee config
|
||||
mgmClient, loginResp, err := connectToManagement(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// with the global Wiretrustee config in hand connect (just a connection, no stream yet) Signal
|
||||
signalClient, err := connectToSignal(ctx, loginResp.GetWiretrusteeConfig(), myPrivateKey)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
engineConfig, err := createEngineConfig(myPrivateKey, config, loginResp.GetWiretrusteeConfig(), loginResp.GetPeerConfig())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// create start the Wiretrustee Engine that will connect to the Signal and Management streams and manage connections to remote peers.
|
||||
engine := internal.NewEngine(signalClient, mgmClient, engineConfig, cancel)
|
||||
err = engine.Start()
|
||||
if err != nil {
|
||||
log.Errorf("error while starting Wiretrustee Connection Engine: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
SetupCloseHandler()
|
||||
|
||||
select {
|
||||
case <-stopCh:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
log.Infof("receive signal to stop running")
|
||||
err = mgmClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Management Service client %v", err)
|
||||
return err
|
||||
}
|
||||
err = signalClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Signal Service client %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = engine.Stop()
|
||||
if err != nil {
|
||||
log.Errorf("failed stopping engine %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return startCmd.RunE(cmd, args)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
// createEngineConfig converts configuration received from Management Service to EngineConfig
|
||||
func createEngineConfig(key wgtypes.Key, config *internal.Config, wtConfig *mgmProto.WiretrusteeConfig, peerConfig *mgmProto.PeerConfig) (*internal.EngineConfig, error) {
|
||||
func createEngineConfig(key wgtypes.Key, config *internal.Config, peerConfig *mgmProto.PeerConfig) (*internal.EngineConfig, error) {
|
||||
iFaceBlackList := make(map[string]struct{})
|
||||
for i := 0; i < len(config.IFaceBlackList); i += 2 {
|
||||
iFaceBlackList[config.IFaceBlackList[i]] = struct{}{}
|
||||
@@ -163,7 +111,88 @@ func connectToManagement(ctx context.Context, managementAddr string, ourPrivateK
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("peer logged in to Management Service %s", managementAddr)
|
||||
log.Debugf("peer logged in to Management Service %s", managementAddr)
|
||||
|
||||
return client, loginResp, nil
|
||||
}
|
||||
|
||||
func runClient() error {
|
||||
config, err := internal.ReadConfig(managementURL, configPath)
|
||||
if err != nil {
|
||||
log.Errorf("failed reading config %s %v", configPath, err)
|
||||
return err
|
||||
}
|
||||
|
||||
//validate our peer's Wireguard PRIVATE key
|
||||
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
||||
if err != nil {
|
||||
log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error())
|
||||
return err
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
mgmTlsEnabled := false
|
||||
if config.ManagementURL.Scheme == "https" {
|
||||
mgmTlsEnabled = true
|
||||
}
|
||||
|
||||
// connect (just a connection, no stream yet) and login to Management Service to get an initial global Wiretrustee config
|
||||
mgmClient, loginResp, err := connectToManagement(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// with the global Wiretrustee config in hand connect (just a connection, no stream yet) Signal
|
||||
signalClient, err := connectToSignal(ctx, loginResp.GetWiretrusteeConfig(), myPrivateKey)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
peerConfig := loginResp.GetPeerConfig()
|
||||
|
||||
engineConfig, err := createEngineConfig(myPrivateKey, config, peerConfig)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// create start the Wiretrustee Engine that will connect to the Signal and Management streams and manage connections to remote peers.
|
||||
engine := internal.NewEngine(signalClient, mgmClient, engineConfig, cancel, ctx)
|
||||
err = engine.Start()
|
||||
if err != nil {
|
||||
log.Errorf("error while starting Wiretrustee Connection Engine: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Wiretrustee engine started, my IP is: ", peerConfig.Address)
|
||||
|
||||
select {
|
||||
case <-stopCh:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
err = mgmClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Management Service client %v", err)
|
||||
return err
|
||||
}
|
||||
err = signalClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Signal Service client %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = engine.Stop()
|
||||
if err != nil {
|
||||
log.Errorf("failed stopping engine %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("stopped Wiretrustee client")
|
||||
cleanupCh <- struct{}{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wiretrustee/wiretrustee/iface"
|
||||
mgmt "github.com/wiretrustee/wiretrustee/management/server"
|
||||
"github.com/wiretrustee/wiretrustee/util"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -37,24 +34,6 @@ func TestUp_Start(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestUp_ShouldFail_On_NoConfig(t *testing.T) {
|
||||
|
||||
tempDir := t.TempDir()
|
||||
confPath := tempDir + "/config.json"
|
||||
mgmtURL := fmt.Sprintf("http://%s", mgmAddr)
|
||||
rootCmd.SetArgs([]string{
|
||||
"up",
|
||||
"--config",
|
||||
confPath,
|
||||
"--management-url",
|
||||
mgmtURL,
|
||||
})
|
||||
err := rootCmd.Execute()
|
||||
if err == nil || !errors.Is(err, os.ErrNotExist) {
|
||||
t.Errorf("expecting login command to fail on absence of config")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUp(t *testing.T) {
|
||||
|
||||
defer iface.Close()
|
||||
@@ -65,24 +44,17 @@ func TestUp(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
rootCmd.SetArgs([]string{
|
||||
"login",
|
||||
"up",
|
||||
"--config",
|
||||
confPath,
|
||||
"--setup-key",
|
||||
"A2C8E62B-38F5-4553-B31E-DD66C696CEBB",
|
||||
"--management-url",
|
||||
mgmtURL.String(),
|
||||
})
|
||||
err = rootCmd.Execute()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
rootCmd.SetArgs([]string{
|
||||
"up",
|
||||
"--config",
|
||||
confPath,
|
||||
"--log-file",
|
||||
"console",
|
||||
})
|
||||
go func() {
|
||||
err = rootCmd.Execute()
|
||||
|
||||
14
client/cmd/version.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package cmd
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
var (
|
||||
Version string
|
||||
versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "prints wiretrustee version",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Println(Version)
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -166,7 +166,7 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
||||
select {
|
||||
case remoteAuth := <-conn.remoteAuthChannel:
|
||||
|
||||
log.Infof("got a connection confirmation from peer %s", conn.Config.RemoteWgKey.String())
|
||||
log.Debugf("got a connection confirmation from peer %s", conn.Config.RemoteWgKey.String())
|
||||
|
||||
err = conn.agent.GatherCandidates()
|
||||
if err != nil {
|
||||
@@ -186,8 +186,11 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
useProxy := useProxy(pair)
|
||||
|
||||
// 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) {
|
||||
if !useProxy {
|
||||
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)
|
||||
err = conn.wgProxy.StartLocal(fmt.Sprintf("%s:%d", pair.Remote.Address(), iface.WgPort))
|
||||
if err != nil {
|
||||
@@ -195,19 +198,17 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Infof("establishing secure tunnel to peer %s via selected candidate pair %s", conn.Config.RemoteWgKey.String(), pair)
|
||||
log.Debugf("establishing secure tunnel to peer %s via selected candidate pair %s", conn.Config.RemoteWgKey.String(), pair)
|
||||
err = conn.wgProxy.Start(remoteConn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if pair.Remote.Type() == ice.CandidateTypeRelay || pair.Local.Type() == ice.CandidateTypeRelay {
|
||||
log.Infof("using relay with peer %s", conn.Config.RemoteWgKey)
|
||||
}
|
||||
relayed := pair.Remote.Type() == ice.CandidateTypeRelay || pair.Local.Type() == ice.CandidateTypeRelay
|
||||
|
||||
conn.Status = StatusConnected
|
||||
log.Infof("opened connection to peer %s", conn.Config.RemoteWgKey.String())
|
||||
log.Infof("opened connection to peer %s [localProxy=%v, relayed=%v]", conn.Config.RemoteWgKey.String(), useProxy, relayed)
|
||||
case <-conn.closeCond.C:
|
||||
conn.Status = StatusDisconnected
|
||||
return fmt.Errorf("connection to peer %s has been closed", conn.Config.RemoteWgKey.String())
|
||||
@@ -271,7 +272,7 @@ func (conn *Connection) Close() error {
|
||||
var err error
|
||||
conn.closeCond.Do(func() {
|
||||
|
||||
log.Warnf("closing connection to peer %s", conn.Config.RemoteWgKey.String())
|
||||
log.Debugf("closing connection to peer %s", conn.Config.RemoteWgKey.String())
|
||||
|
||||
if a := conn.agent; a != nil {
|
||||
e := a.Close()
|
||||
|
||||
@@ -57,6 +57,8 @@ type Engine struct {
|
||||
TURNs []*ice.URL
|
||||
|
||||
cancel context.CancelFunc
|
||||
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Peer is an instance of the Connection Peer
|
||||
@@ -66,7 +68,7 @@ type Peer struct {
|
||||
}
|
||||
|
||||
// NewEngine creates a new Connection Engine
|
||||
func NewEngine(signalClient *signal.Client, mgmClient *mgm.Client, config *EngineConfig, cancel context.CancelFunc) *Engine {
|
||||
func NewEngine(signalClient *signal.Client, mgmClient *mgm.Client, config *EngineConfig, cancel context.CancelFunc, ctx context.Context) *Engine {
|
||||
return &Engine{
|
||||
signal: signalClient,
|
||||
mgmClient: mgmClient,
|
||||
@@ -77,17 +79,25 @@ func NewEngine(signalClient *signal.Client, mgmClient *mgm.Client, config *Engin
|
||||
STUNs: []*ice.URL{},
|
||||
TURNs: []*ice.URL{},
|
||||
cancel: cancel,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Engine) Stop() error {
|
||||
err := e.removeAllPeerConnections()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("removing Wiretrustee interface %s", e.config.WgIface)
|
||||
err := iface.Close()
|
||||
err = iface.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Wiretrustee interface %s %v", e.config.WgIface, err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("stopped Wiretrustee Engine")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -127,7 +137,7 @@ func (e *Engine) Start() error {
|
||||
|
||||
// initializePeer peer agent attempt to open connection
|
||||
func (e *Engine) initializePeer(peer Peer) {
|
||||
var backOff = &backoff.ExponentialBackOff{
|
||||
var backOff = backoff.WithContext(&backoff.ExponentialBackOff{
|
||||
InitialInterval: backoff.DefaultInitialInterval,
|
||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||
Multiplier: backoff.DefaultMultiplier,
|
||||
@@ -135,13 +145,14 @@ func (e *Engine) initializePeer(peer Peer) {
|
||||
MaxElapsedTime: time.Duration(0), //never stop
|
||||
Stop: backoff.Stop,
|
||||
Clock: backoff.SystemClock,
|
||||
}
|
||||
}, e.ctx)
|
||||
|
||||
operation := func() error {
|
||||
_, err := e.openPeerConnection(e.wgPort, e.config.WgPrivateKey, peer)
|
||||
e.peerMux.Lock()
|
||||
defer e.peerMux.Unlock()
|
||||
if _, ok := e.conns[peer.WgPubKey]; !ok {
|
||||
log.Infof("removing connection attempt with Peer: %v, not retrying", peer.WgPubKey)
|
||||
log.Debugf("removed connection attempt to peer: %v, not retrying", peer.WgPubKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -172,6 +183,19 @@ func (e *Engine) removePeerConnections(peers []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) removeAllPeerConnections() error {
|
||||
log.Debugf("removing all peer connections")
|
||||
e.peerMux.Lock()
|
||||
defer e.peerMux.Unlock()
|
||||
for peer := range e.conns {
|
||||
err := e.removePeerConnection(peer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// removePeerConnection closes existing peer connection and removes peer
|
||||
func (e *Engine) removePeerConnection(peerKey string) error {
|
||||
conn, exists := e.conns[peerKey]
|
||||
@@ -179,6 +203,7 @@ func (e *Engine) removePeerConnection(peerKey string) error {
|
||||
delete(e.conns, peerKey)
|
||||
return conn.Close()
|
||||
}
|
||||
log.Infof("removed connection to peer %s", peerKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -310,7 +335,7 @@ func (e *Engine) receiveManagementEvents() {
|
||||
e.cancel()
|
||||
return
|
||||
}
|
||||
log.Infof("connected to Management Service updates stream")
|
||||
log.Debugf("stopped receiving updates from Management Service")
|
||||
}()
|
||||
log.Debugf("connecting to Management Service updates stream")
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func (p *WgProxy) proxyToRemotePeer(remoteConn *ice.Conn) {
|
||||
for {
|
||||
select {
|
||||
case <-p.close:
|
||||
log.Infof("stopped proxying from remote peer %s due to closed connection", p.remoteKey)
|
||||
log.Debugf("stopped proxying from remote peer %s due to closed connection", p.remoteKey)
|
||||
return
|
||||
default:
|
||||
n, err := p.wgConn.Read(buf)
|
||||
@@ -113,7 +113,7 @@ func (p *WgProxy) proxyToLocalWireguard(remoteConn *ice.Conn) {
|
||||
for {
|
||||
select {
|
||||
case <-p.close:
|
||||
log.Infof("stopped proxying from remote peer %s due to closed connection", p.remoteKey)
|
||||
log.Debugf("stopped proxying from remote peer %s due to closed connection", p.remoteKey)
|
||||
return
|
||||
default:
|
||||
n, err := remoteConn.Read(buf)
|
||||
|
||||
@@ -5,7 +5,11 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var version = "development"
|
||||
|
||||
func main() {
|
||||
|
||||
cmd.Version = version
|
||||
if err := cmd.Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
105
docs/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
### Table of contents
|
||||
|
||||
* [About Wiretrustee](#about-wiretrustee)
|
||||
* [Why not just Wireguard?](#why-not-just-wireguard)
|
||||
* [Wiretrustee vs. Traditional VPN](#wiretrustee-vs-traditional-vpn)
|
||||
* [High-level technology overview](#high-level-technology-overview)
|
||||
* [Getting started](#getting-started)
|
||||
|
||||
### About Wiretrustee
|
||||
|
||||
Wiretrustee is an open-source VPN platform built on top of [WireGuard®](https://www.wireguard.com/) making it easy to create secure private networks for your organization or home.
|
||||
|
||||
It requires zero configuration effort leaving behind the hassle of opening ports, complex firewall rules, vpn gateways, and so forth.
|
||||
|
||||
There is no centralized VPN server with Wiretrustee - your computers, devices, machines, and servers connect to each other directly over a fast encrypted tunnel.
|
||||
|
||||
It literally takes less than 5 minutes to provision a secure peer-to-peer VPN with Wiretrustee. Check our [Quickstart Guide Video](https://www.youtube.com/watch?v=cWTsGUJAUaU) to see the setup in action.
|
||||
|
||||
### Why not just Wireguard?
|
||||
|
||||
WireGuard is a modern and extremely fast VPN tunnel utilizing state-of-the-art [cryptography](https://www.wireguard.com/protocol/)
|
||||
and Wiretrustee uses Wireguard to establish a secure tunnel between machines.
|
||||
|
||||
Built with simplicity in mind, Wireguard ensures that traffic between two machines is encrypted and flowing, however, it requires a few things to be done beforehand.
|
||||
|
||||
First, in order to connect, the machines have to be configured.
|
||||
On each machine, you need to generate private and public keys and prepare a WireGuard configuration file.
|
||||
The configuration also includes a private IP address that should be unique per machine.
|
||||
|
||||
Secondly, to accept the incoming traffic, the machines have to trust each other.
|
||||
The generated public keys have to be pre-shared on the machines.
|
||||
This works similarly to SSH with its authorised_keys file.
|
||||
|
||||
Lastly, the connectivity between the machines has to be ensured.
|
||||
To make machines reach one another, you are required to set a WireGuard endpoint property which indicates the IP address and port of the remote machine to connect to.
|
||||
On many occasions, machines are hidden behind firewalls and NAT devices,
|
||||
meaning that you may need to configure a port forwarding or open holes in your firewall to ensure the machines are reachable.
|
||||
|
||||
The undertakings mentioned above might not be complicated if you have just a few machines, but the complexity grows as the number of machines increases.
|
||||
|
||||
Wiretrustee simplifies the setup by automatically generating private and public keys, assigning unique private IP addresses, and takes care of sharing public keys between the machines.
|
||||
It is worth mentioning that the private key never leaves the machine.
|
||||
So only the machine that owns the key can decrypt traffic addressed to it.
|
||||
The same applies also to the relayed traffic mentioned below.
|
||||
|
||||
Furthermore, Wiretrustee ensures connectivity by leveraging advanced [NAT traversal techniques](https://en.wikipedia.org/wiki/NAT_traversal)
|
||||
and removing the necessity of port forwarding, opening holes in the firewall, and having a public static IP address.
|
||||
In cases when a direct peer-to-peer connection isn't possible all traffic is relayed securely between peers.
|
||||
Wiretrustee also monitors the connection health and restarts broken connections.
|
||||
|
||||
There are a few more things that we are working on to make secure private networks simple. A few examples are ACLs, MFA and activity monitoring.
|
||||
|
||||
Check out the WireGuard [Quick Start](https://www.wireguard.com/quickstart/) guide to learn more about configuring "plain" WireGuard without Wiretrustee.
|
||||
|
||||
### Wiretrustee vs. Traditional VPN
|
||||
|
||||
In the traditional VPN model, everything converges on a centralized, protected network where all the clients are connecting to a central VPN server.
|
||||
|
||||
An increasing amount of connections can easily overload the VPN server.
|
||||
Even a short downtime of a server can cause expensive system disruptions, and a remote team's inability to work.
|
||||
|
||||
Centralized VPNs imply all the traffic going through the central server causing network delays and increased traffic usage.
|
||||
|
||||
Such systems require an experienced team to set up and maintain.
|
||||
Configuring firewalls, setting up NATs, SSO integration, and managing access control lists can be a nightmare.
|
||||
|
||||
Traditional centralized VPNs are often compared to a [castle-and-moat](https://en.wikipedia.org/wiki/Moat) model
|
||||
in which once accessed, user is trusted and can access critical infrastructure and resources without any restrictions.
|
||||
|
||||
Wiretrustee decentralizes networks using direct point-to-point connections, as opposed to traditional models.
|
||||
Consequently, network performance is increased since traffic flows directly between the machines bypassing VPN servers or gateways.
|
||||
To achieve this, Wiretrustee client applications employ signalling servers to find other machines and negotiate connections.
|
||||
These are similar to the signaling servers used in [WebRTC](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Signaling_and_video_calling#the_signaling_server)
|
||||
|
||||
Thanks to [NAT traversal techniques](https://en.wikipedia.org/wiki/NAT_traversal),
|
||||
outlined in the [Why not just Wireguard?](#why-not-just-wireguard) section above,
|
||||
Wiretrustee installation doesn't require complex network and firewall configuration.
|
||||
It just works, minimising the maintenance effort.
|
||||
|
||||
Finally, each machine or device in the Wiretrustee network verifies incoming connections accepting only the trusted ones.
|
||||
This is ensured by Wireguard's [Crypto Routing concept](https://www.wireguard.com/#cryptokey-routing).
|
||||
|
||||
### High-level technology 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 [app.wiretrustee.com](https://app.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 |
BIN
docs/media/logo-full.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/media/logo.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/media/peerA.gif
Normal file
|
After Width: | Height: | Size: 409 KiB |
BIN
docs/media/peerB.gif
Normal file
|
After Width: | Height: | Size: 526 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://app.wiretrustee.com/](https://app.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.
|
||||
96
docs/self-hosting.md
Normal file
@@ -0,0 +1,96 @@
|
||||
### 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).
|
||||
|
||||
### Step-by-step video guide on YouTube:
|
||||
|
||||
[](https://youtu.be/Ofpgx5WhT0k "Wiretrustee Self-Hosting Guide")
|
||||
|
||||
### 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, 10000, 3478``` (Dashboard, Management HTTP API, Management gRpc API, Signal gRpc, 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 generating a new certificate.
|
||||
|
||||
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
|
||||
2
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/kardianos/service v1.2.0
|
||||
github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7
|
||||
github.com/onsi/ginkgo v1.16.4
|
||||
github.com/onsi/gomega v1.13.0
|
||||
github.com/pion/ice/v2 v2.1.7
|
||||
|
||||
4
go.sum
@@ -146,8 +146,8 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kardianos/service v1.2.0 h1:bGuZ/epo3vrt8IPC7mnKQolqFeYJb7Cs8Rk4PSOBB/g=
|
||||
github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||
github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7 h1:oohm9Rk9JAxxmp2NLZa7Kebgz9h4+AJDcc64txg3dQ0=
|
||||
github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
||||
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:
|
||||
61
infrastructure_files/docker-compose.yml.tmpl
Normal file
@@ -0,0 +1,61 @@
|
||||
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
|
||||
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")
|
||||
|
||||
@@ -45,7 +45,7 @@ func NewClient(ctx context.Context, addr string, ourPrivateKey wgtypes.Key, tlsE
|
||||
}))
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("failed creating connection to Management Srvice %v", err)
|
||||
log.Errorf("failed creating connection to Management Service %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ func (c *Client) Close() error {
|
||||
}
|
||||
|
||||
//defaultBackoff is a basic backoff mechanism for general issues
|
||||
func defaultBackoff() backoff.BackOff {
|
||||
return &backoff.ExponentialBackOff{
|
||||
func defaultBackoff(ctx context.Context) backoff.BackOff {
|
||||
return backoff.WithContext(&backoff.ExponentialBackOff{
|
||||
InitialInterval: 800 * time.Millisecond,
|
||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||
Multiplier: backoff.DefaultMultiplier,
|
||||
@@ -74,14 +74,14 @@ func defaultBackoff() backoff.BackOff {
|
||||
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
||||
Stop: backoff.Stop,
|
||||
Clock: backoff.SystemClock,
|
||||
}
|
||||
}, ctx)
|
||||
}
|
||||
|
||||
// Sync wraps the real client's Sync endpoint call and takes care of retries and encryption/decryption of messages
|
||||
// Blocking request. The result will be sent via msgHandler callback function
|
||||
func (c *Client) Sync(msgHandler func(msg *proto.SyncResponse) error) error {
|
||||
|
||||
var backOff = defaultBackoff()
|
||||
var backOff = defaultBackoff(c.ctx)
|
||||
|
||||
operation := func() error {
|
||||
|
||||
@@ -114,7 +114,7 @@ func (c *Client) Sync(msgHandler func(msg *proto.SyncResponse) error) error {
|
||||
|
||||
err := backoff.Retry(operation, backOff)
|
||||
if err != nil {
|
||||
log.Errorf("exiting Management Service connection retry loop due to unrecoverable error %s ", err)
|
||||
log.Warnf("exiting Management Service connection retry loop due to unrecoverable error: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ func (c *Client) receiveEvents(stream proto.ManagementService_SyncClient, server
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("disconnected from Management Service sync stream: %v", err)
|
||||
log.Warnf("disconnected from Management Service sync stream: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func (c *Client) receiveEvents(stream proto.ManagementService_SyncClient, server
|
||||
|
||||
err = msgHandler(decryptedResp)
|
||||
if err != nil {
|
||||
log.Errorf("failed handling an update message received from Management Service %v", err.Error())
|
||||
log.Errorf("failed handling an update message received from Management Service: %v", err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,30 +12,27 @@ fi
|
||||
cleanInstall() {
|
||||
printf "\033[32m Post Install of an clean install\033[0m\n"
|
||||
# Step 3 (clean install), enable the service in the proper way for this platform
|
||||
if [ "${use_systemctl}" = "True" ]; then
|
||||
printf "\033[32m Reload the service unit from disk\033[0m\n"
|
||||
systemctl daemon-reload ||:
|
||||
printf "\033[32m Unmask the service\033[0m\n"
|
||||
systemctl unmask wiretrustee ||:
|
||||
printf "\033[32m Set the preset flag for the service unit\033[0m\n"
|
||||
systemctl preset wiretrustee ||:
|
||||
printf "\033[32m Set the enabled flag for the service unit\033[0m\n"
|
||||
systemctl enable wiretrustee ||:
|
||||
systemctl restart wiretrustee ||:
|
||||
fi
|
||||
/usr/local/bin/wiretrustee service install
|
||||
/usr/local/bin/wiretrustee service start
|
||||
}
|
||||
|
||||
upgrade() {
|
||||
printf "\033[32m Post Install of an upgrade\033[0m\n"
|
||||
if [ "${use_systemctl}" = "True" ]; then
|
||||
printf "\033[32m Reload the service unit from disk\033[0m\n"
|
||||
systemctl daemon-reload ||:
|
||||
printf "\033[32m Restarting the service\033[0m\n"
|
||||
systemctl restart wiretrustee ||:
|
||||
printf "\033[32m Stopping the service\033[0m\n"
|
||||
systemctl stop wiretrustee 2> /dev/null || true
|
||||
fi
|
||||
if [ -e /lib/systemd/system/wiretrustee.service ]; then
|
||||
rm -f /lib/systemd/system/wiretrustee.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
# will trow an error until everyone upgrade
|
||||
/usr/local/bin/wiretrustee service uninstall 2> /dev/null || true
|
||||
/usr/local/bin/wiretrustee service install
|
||||
/usr/local/bin/wiretrustee service start
|
||||
}
|
||||
|
||||
# Step 2, check if this is a clean install or an upgrade
|
||||
# Check if this is a clean install or an upgrade
|
||||
action="$1"
|
||||
if [ "$1" = "configure" ] && [ -z "$2" ]; then
|
||||
# Alpine linux does not pass args, and deb passes $1=configure
|
||||
@@ -50,12 +47,9 @@ case "$action" in
|
||||
cleanInstall
|
||||
;;
|
||||
"2" | "upgrade")
|
||||
printf "\033[32m Post Install of an upgrade\033[0m\n"
|
||||
upgrade
|
||||
;;
|
||||
*)
|
||||
# $1 == version being installed
|
||||
printf "\033[32m install\033[0m"
|
||||
cleanInstall
|
||||
;;
|
||||
esac
|
||||
43
release_files/pre_remove.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
# decide if we should use systemd or init/upstart
|
||||
use_systemctl="True"
|
||||
systemd_version=0
|
||||
if ! command -V systemctl >/dev/null 2>&1; then
|
||||
use_systemctl="False"
|
||||
else
|
||||
systemd_version=$(systemctl --version | head -1 | sed 's/systemd //g')
|
||||
fi
|
||||
|
||||
remove() {
|
||||
printf "\033[32m Pre uninstall\033[0m\n"
|
||||
|
||||
if [ "${use_systemctl}" = "True" ]; then
|
||||
printf "\033[32m Stopping the service\033[0m\n"
|
||||
systemctl stop wiretrustee || true
|
||||
|
||||
if [ -e /lib/systemd/system/wiretrustee.service ]; then
|
||||
rm -f /lib/systemd/system/wiretrustee.service
|
||||
systemctl daemon-reload || true
|
||||
fi
|
||||
|
||||
fi
|
||||
printf "\033[32m Uninstalling the service\033[0m\n"
|
||||
/usr/local/bin/wiretrustee service uninstall || true
|
||||
|
||||
|
||||
if [ "${use_systemctl}" = "True" ]; then
|
||||
printf "\n\033[32m running daemon reload\033[0m\n"
|
||||
systemctl daemon-reload || true
|
||||
fi
|
||||
}
|
||||
|
||||
action="$1"
|
||||
|
||||
case "$action" in
|
||||
"0" | "remove")
|
||||
remove
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"PrivateKey": "",
|
||||
"Peers": [
|
||||
{
|
||||
"WgPubKey": "",
|
||||
"WgAllowedIps": ""
|
||||
}
|
||||
],
|
||||
"StunTurnURLs": [
|
||||
{
|
||||
"Scheme": 1,
|
||||
"Host": "",
|
||||
"Port": 3468,
|
||||
"Username": "",
|
||||
"Password": "",
|
||||
"Proto": 1
|
||||
},
|
||||
{
|
||||
"Scheme": 3,
|
||||
"Host": "",
|
||||
"Port": 3468,
|
||||
"Username": "",
|
||||
"Password": "",
|
||||
"Proto": 1
|
||||
}
|
||||
],
|
||||
"SignalAddr": "",
|
||||
"WgAddr": "",
|
||||
"WgIface": ""
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
[Unit]
|
||||
Description=Wiretrustee Service
|
||||
After=multi-user.target network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/wiretrustee up --config /etc/wiretrustee/config.json --log-level debug
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -76,8 +76,8 @@ func NewClient(ctx context.Context, addr string, key wgtypes.Key, tlsEnabled boo
|
||||
}
|
||||
|
||||
//defaultBackoff is a basic backoff mechanism for general issues
|
||||
func defaultBackoff() backoff.BackOff {
|
||||
return &backoff.ExponentialBackOff{
|
||||
func defaultBackoff(ctx context.Context) backoff.BackOff {
|
||||
return backoff.WithContext(&backoff.ExponentialBackOff{
|
||||
InitialInterval: 800 * time.Millisecond,
|
||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||
Multiplier: backoff.DefaultMultiplier,
|
||||
@@ -85,7 +85,8 @@ func defaultBackoff() backoff.BackOff {
|
||||
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
||||
Stop: backoff.Stop,
|
||||
Clock: backoff.SystemClock,
|
||||
}
|
||||
}, ctx)
|
||||
|
||||
}
|
||||
|
||||
// Receive Connects to the Signal Exchange message stream and starts receiving messages.
|
||||
@@ -96,12 +97,13 @@ func (c *Client) Receive(msgHandler func(msg *proto.Message) error) {
|
||||
c.connWg.Add(1)
|
||||
go func() {
|
||||
|
||||
var backOff = defaultBackoff()
|
||||
var backOff = defaultBackoff(c.ctx)
|
||||
|
||||
operation := func() error {
|
||||
|
||||
err := c.connect(c.key.PublicKey().String(), msgHandler)
|
||||
if err != nil {
|
||||
log.Warnf("disconnected from the Signal Exchange due to an error %s. Retrying ... ", err)
|
||||
log.Warnf("disconnected from the Signal Exchange due to an error: %v", err)
|
||||
c.connWg.Add(1)
|
||||
return err
|
||||
}
|
||||
@@ -112,7 +114,7 @@ func (c *Client) Receive(msgHandler func(msg *proto.Message) error) {
|
||||
|
||||
err := backoff.Retry(operation, backOff)
|
||||
if err != nil {
|
||||
log.Errorf("error while communicating with the Signal Exchange %s ", err)
|
||||
log.Errorf("exiting Signal Service connection retry loop due to unrecoverable error: %s", err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||