mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-01 14:46:41 +00:00
Compare commits
20 Commits
v0.1.0-bet
...
v0.2.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b2c26847b | ||
|
|
595ea0d4f8 | ||
|
|
f714868fdd | ||
|
|
81821a1f39 | ||
|
|
842b143a48 | ||
|
|
1323a74db0 | ||
|
|
74485d3b13 | ||
|
|
bef3b3392b | ||
|
|
fcea3c99d4 | ||
|
|
96799a25b5 | ||
|
|
07291cdb93 | ||
|
|
21139938c1 | ||
|
|
5cf2d0a6a9 | ||
|
|
8551afe04e | ||
|
|
1685817171 | ||
|
|
e17f662683 | ||
|
|
a764fb870c | ||
|
|
cabff941ac | ||
|
|
b5f35dfb5e | ||
|
|
1d426b7f81 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -51,6 +51,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_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 }}
|
||||||
|
|
||||||
-
|
-
|
||||||
name: Trigger Windows binaries sign pipeline
|
name: Trigger Windows binaries sign pipeline
|
||||||
|
|||||||
@@ -13,13 +13,18 @@ builds:
|
|||||||
- arm
|
- arm
|
||||||
- amd64
|
- amd64
|
||||||
- arm64
|
- arm64
|
||||||
|
- mips
|
||||||
|
gomips:
|
||||||
|
- hardfloat
|
||||||
|
- softfloat
|
||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
|
||||||
goarch: arm64
|
|
||||||
- goos: windows
|
- goos: windows
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
- goos: windows
|
- goos: windows
|
||||||
goarch: arm
|
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:
|
tags:
|
||||||
- load_wintun_from_rsrc
|
- load_wintun_from_rsrc
|
||||||
|
|
||||||
@@ -32,6 +37,9 @@ builds:
|
|||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
- arm64
|
- 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
|
- id: wiretrustee-signal
|
||||||
dir: signal
|
dir: signal
|
||||||
@@ -42,28 +50,38 @@ builds:
|
|||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
- arm64
|
- arm64
|
||||||
|
ldflags:
|
||||||
|
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} -X main.builtBy=goreleaser
|
||||||
|
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||||
archives:
|
archives:
|
||||||
- builds:
|
- builds:
|
||||||
- wiretrustee
|
- wiretrustee
|
||||||
nfpms:
|
nfpms:
|
||||||
- maintainer: Wiretrustee <wiretrustee@wiretrustee.com>
|
- maintainer: Wiretrustee <dev@wiretrustee.com>
|
||||||
description: Wiretrustee project.
|
description: Wiretrustee client.
|
||||||
homepage: https://wiretrustee.com/
|
homepage: https://wiretrustee.com/
|
||||||
|
id: deb
|
||||||
builds:
|
builds:
|
||||||
- wiretrustee
|
- wiretrustee
|
||||||
formats:
|
formats:
|
||||||
- deb
|
- 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:
|
scripts:
|
||||||
postinstall: "release_files/post_install.sh"
|
postinstall: "release_files/post_install.sh"
|
||||||
|
preremove: "release_files/pre_remove.sh"
|
||||||
|
|
||||||
|
- 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:
|
dockers:
|
||||||
- image_templates:
|
- image_templates:
|
||||||
- wiretrustee/signal:{{ .Version }}-amd64
|
- wiretrustee/signal:{{ .Version }}-amd64
|
||||||
@@ -197,3 +215,19 @@ brews:
|
|||||||
license: "BSD3"
|
license: "BSD3"
|
||||||
test: |
|
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 }}
|
||||||
|
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
|
||||||
194
README.md
194
README.md
@@ -1,18 +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).
|
**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:
|
Hosted demo version:
|
||||||
[https://beta.wiretrustee.com/](https://beta.wiretrustee.com/peers).
|
[https://app.wiretrustee.com/](https://app.wiretrustee.com/peers).
|
||||||
|
|
||||||
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)
|
[UI Dashboard Repo](https://github.com/wiretrustee/wiretrustee-dashboard)
|
||||||
|
|
||||||
|
|
||||||
### Why using Wiretrustee?
|
### 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.
|
* Connect multiple devices to each other via a secure peer-to-peer Wireguard VPN tunnel. At home, the office, or anywhere else.
|
||||||
@@ -28,8 +60,6 @@ Please don't use the hosted demonstration version for production purposes. We ap
|
|||||||
* Works on ARM devices (e.g. Raspberry Pi).
|
* Works on ARM devices (e.g. Raspberry Pi).
|
||||||
* Open-source (including Management Service)
|
* Open-source (including Management Service)
|
||||||
|
|
||||||
### Secure peer-to-peer VPN in minutes
|
|
||||||

|
|
||||||
|
|
||||||
### A bit on Wiretrustee internals
|
### 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).
|
* Wiretrustee features a Management Service that offers peer IP management and network updates distribution (e.g. when new peer joins the network).
|
||||||
@@ -45,116 +75,106 @@ Please don't use the hosted demonstration version for production purposes. We ap
|
|||||||
- [Public Roadmap](https://github.com/wiretrustee/wiretrustee/projects/2)
|
- [Public Roadmap](https://github.com/wiretrustee/wiretrustee/projects/2)
|
||||||
- [Public Roadmap Progress Tracking](https://github.com/wiretrustee/wiretrustee/projects/1)
|
- [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
|
### Client Installation
|
||||||
#### Linux
|
#### Linux
|
||||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases)
|
|
||||||
2. Download the latest release (**Switch VERSION to the latest**):
|
|
||||||
|
|
||||||
**Debian packages**
|
**APT/Debian**
|
||||||
```shell
|
1. Add the repository:
|
||||||
wget https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_linux_amd64.deb
|
```shell
|
||||||
```
|
sudo apt-get update
|
||||||
3. Install the package
|
sudo apt-get install ca-certificates curl gnupg -y
|
||||||
```shell
|
curl -L https://pkgs.wiretrustee.com/debian/public.key | sudo apt-key add -
|
||||||
sudo dpkg -i wiretrustee_<VERSION>_linux_amd64.deb
|
echo 'deb https://pkgs.wiretrustee.com/debian stable main' | sudo tee /etc/apt/sources.list.d/wiretrustee.list
|
||||||
```
|
```
|
||||||
**Fedora/Centos packages**
|
2. Install the package
|
||||||
```shell
|
```shell
|
||||||
wget https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_linux_amd64.rpm
|
sudo apt-get update
|
||||||
```
|
sudo apt-get install wiretrustee
|
||||||
3. Install the package
|
```
|
||||||
```shell
|
**RPM/Red hat**
|
||||||
sudo rpm -i wiretrustee_<VERSION>_linux_amd64.rpm
|
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
|
#### MACOS
|
||||||
**Brew install**
|
**Brew install**
|
||||||
1. Download and install Brew at https://brew.sh/
|
1. Download and install Brew at https://brew.sh/
|
||||||
2. Install the client
|
2. Install the client
|
||||||
```shell
|
```shell
|
||||||
brew install wiretrustee/client/wiretrustee
|
brew install wiretrustee/client/wiretrustee
|
||||||
```
|
```
|
||||||
**Installation from binary**
|
**Installation from binary**
|
||||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases/latest)
|
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases/latest)
|
||||||
2. Download the latest release (**Switch VERSION to the latest**):
|
2. Download the latest release (**Switch VERSION to the latest**):
|
||||||
```shell
|
```shell
|
||||||
curl -o ./wiretrustee_<VERSION>_darwin_amd64.tar.gz https://github.com/wiretrustee/wiretrustee/releases/download/v<VERSION>/wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
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
|
3. Decompress
|
||||||
```shell
|
```shell
|
||||||
tar xcf ./wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
tar xcf ./wiretrustee_<VERSION>_darwin_amd64.tar.gz
|
||||||
sudo mv wiretrusee /usr/local/bin/wiretrustee
|
sudo mv wiretrusee /usr/local/bin/wiretrustee
|
||||||
chmod +x /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:
|
After that you may need to add /usr/local/bin in your MAC's PATH environment variable:
|
||||||
````shell
|
````shell
|
||||||
export PATH=$PATH:/usr/local/bin
|
export PATH=$PATH:/usr/local/bin
|
||||||
````
|
````
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases/latest)
|
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**):
|
2. Download the latest Windows release installer ```wiretrustee_installer_<VERSION>_windows_amd64.exe``` (**Switch VERSION to the latest**):
|
||||||
3. Proceed with installation steps
|
3. Proceed with installation steps
|
||||||
4. This will install the client in the C:\\Program Files\\Wiretrustee and add the client service
|
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
|
> To uninstall the client and service, you can use Add/Remove programs
|
||||||
|
|
||||||
### Client Configuration
|
### Client Configuration
|
||||||
1. Login to the Management Service. You need to have a `setup key` in hand (see ).
|
1. Login to the Management Service. You need to have a `setup key` in hand (see ).
|
||||||
|
|
||||||
For **Unix** systems:
|
For **Unix** systems:
|
||||||
```shell
|
```shell
|
||||||
sudo wiretrustee login --setup-key <SETUP KEY>
|
sudo wiretrustee up --setup-key <SETUP KEY>
|
||||||
```
|
```
|
||||||
For **Windows** systems:
|
For **Windows** systems, start powershell as administrator and:
|
||||||
```shell
|
```shell
|
||||||
.\wiretrustee.exe login --setup-key <SETUP KEY>
|
wiretrustee up --setup-key <SETUP KEY>
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, if you are hosting your own Management Service provide `--management-url` property pointing to your Management Service:
|
Alternatively, if you are hosting your own Management Service provide `--management-url` property pointing to your Management Service:
|
||||||
```shell
|
```shell
|
||||||
sudo wiretrustee login --setup-key <SETUP KEY> --management-url https://localhost:33073
|
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:
|
2. Check your IP:
|
||||||
````shell
|
For **MACOS** you will just start the service:
|
||||||
sudo wiretrustee up
|
````shell
|
||||||
# or
|
sudo ipconfig getifaddr utun100
|
||||||
sudo wiretrustee up & # to run it in background
|
````
|
||||||
````
|
|
||||||
For **Linux** systems:
|
For **Linux** systems:
|
||||||
```shell
|
```shell
|
||||||
sudo systemctl restart wiretrustee.service
|
ip addr show wt0
|
||||||
sudo systemctl status wiretrustee.service
|
```
|
||||||
```
|
|
||||||
For **Windows** systems:
|
For **Windows** systems:
|
||||||
```shell
|
```shell
|
||||||
.\wiretrustee.exe service start
|
netsh interface ip show config name="wt0"
|
||||||
```
|
```
|
||||||
> You may need to run Powershell as Administrator
|
|
||||||
|
|
||||||
3. Check your IP:
|
3. Repeat on other machines.
|
||||||
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"
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Repeat on other machines.
|
|
||||||
|
|
||||||
### Running Dashboard, 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
|
Wiretrustee uses [Auth0](https://auth0.com) for user authentication and authorization, therefore you will need to create a free account
|
||||||
|
|||||||
@@ -152,6 +152,5 @@ func promptPeerSetupKey() (string, error) {
|
|||||||
return "", s.Err()
|
return "", s.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
//func init() {
|
||||||
loginCmd.PersistentFlags().StringVar(&setupKey, "setup-key", "", "Setup key obtained from the Management Service Dashboard (used to register peer)")
|
//}
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/wiretrustee/wiretrustee/client/internal"
|
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -22,15 +24,15 @@ var (
|
|||||||
defaultLogFile string
|
defaultLogFile string
|
||||||
logFile string
|
logFile string
|
||||||
managementURL string
|
managementURL string
|
||||||
|
rootCmd = &cobra.Command{
|
||||||
rootCmd = &cobra.Command{
|
|
||||||
Use: "wiretrustee",
|
Use: "wiretrustee",
|
||||||
Short: "",
|
Short: "",
|
||||||
Long: "",
|
Long: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execution control channel for stopCh signal
|
// Execution control channel for stopCh signal
|
||||||
stopCh chan int
|
stopCh chan int
|
||||||
|
cleanupCh chan struct{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Execute executes the root command.
|
// Execute executes the root command.
|
||||||
@@ -40,6 +42,7 @@ func Execute() error {
|
|||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
stopCh = make(chan int)
|
stopCh = make(chan int)
|
||||||
|
cleanupCh = make(chan struct{})
|
||||||
|
|
||||||
defaultConfigPath = "/etc/wiretrustee/config.json"
|
defaultConfigPath = "/etc/wiretrustee/config.json"
|
||||||
defaultLogFile = "/var/log/wiretrustee/client.log"
|
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(&configPath, "config", defaultConfigPath, "Wiretrustee config file location")
|
||||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "sets Wiretrustee log level")
|
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(&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(serviceCmd)
|
||||||
rootCmd.AddCommand(upCmd)
|
rootCmd.AddCommand(upCmd)
|
||||||
rootCmd.AddCommand(loginCmd)
|
rootCmd.AddCommand(loginCmd)
|
||||||
|
rootCmd.AddCommand(versionCmd)
|
||||||
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service
|
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service
|
||||||
serviceCmd.AddCommand(installCmd, uninstallCmd) // service installer 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
|
// SetupCloseHandler handles SIGTERM signal and exits with success
|
||||||
func SetupCloseHandler() {
|
func SetupCloseHandler() {
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt)
|
signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
for range c {
|
for range c {
|
||||||
fmt.Println("\r- Ctrl+C pressed in Terminal")
|
log.Info("shutdown signal received")
|
||||||
stopCh <- 0
|
stopCh <- 0
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -1,26 +1,58 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/cenkalti/backoff/v4"
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/wiretrustee/wiretrustee/util"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *program) Start(s service.Service) error {
|
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.
|
// Start should not block. Do the actual work async.
|
||||||
log.Info("starting service") //nolint
|
log.Info("starting service") //nolint
|
||||||
go func() {
|
go func() {
|
||||||
err := upCmd.RunE(p.cmd, p.args)
|
operation := func() error {
|
||||||
if err != nil {
|
err := runClient()
|
||||||
return
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *program) Stop(s service.Service) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +62,14 @@ var (
|
|||||||
Short: "runs wiretrustee as service",
|
Short: "runs wiretrustee as service",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
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{
|
prg := &program{
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
args: args,
|
args: args,
|
||||||
@@ -54,19 +94,24 @@ var (
|
|||||||
startCmd = &cobra.Command{
|
startCmd = &cobra.Command{
|
||||||
Use: "start",
|
Use: "start",
|
||||||
Short: "starts wiretrustee service",
|
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())
|
s, err := newSVC(&program{}, newSVCConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln(err)
|
cmd.PrintErrln(err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
err = s.Start()
|
err = s.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln(err)
|
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",
|
Use: "stop",
|
||||||
Short: "stops wiretrustee service",
|
Short: "stops wiretrustee service",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
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())
|
s, err := newSVC(&program{}, newSVCConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln(err)
|
cmd.PrintErrln(err)
|
||||||
@@ -87,7 +135,7 @@ var (
|
|||||||
cmd.PrintErrln(err)
|
cmd.PrintErrln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd.Printf("Wiretrustee service has been stopped")
|
cmd.Println("Wiretrustee service has been stopped")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -97,7 +145,10 @@ var (
|
|||||||
Use: "restart",
|
Use: "restart",
|
||||||
Short: "restarts wiretrustee service",
|
Short: "restarts wiretrustee service",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
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())
|
s, err := newSVC(&program{}, newSVCConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln(err)
|
cmd.PrintErrln(err)
|
||||||
@@ -108,7 +159,7 @@ var (
|
|||||||
cmd.PrintErrln(err)
|
cmd.PrintErrln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd.Printf("Wiretrustee service has been restarted")
|
cmd.Println("Wiretrustee service has been restarted")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ var (
|
|||||||
installCmd = &cobra.Command{
|
installCmd = &cobra.Command{
|
||||||
Use: "install",
|
Use: "install",
|
||||||
Short: "installs wiretrustee service",
|
Short: "installs wiretrustee service",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
svcConfig := newSVCConfig()
|
svcConfig := newSVCConfig()
|
||||||
|
|
||||||
@@ -30,15 +30,16 @@ var (
|
|||||||
s, err := newSVC(&program{}, svcConfig)
|
s, err := newSVC(&program{}, svcConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln(err)
|
cmd.PrintErrln(err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Install()
|
err = s.Install()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrln(err)
|
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)
|
cmd.PrintErrln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd.Printf("Wiretrustee has been uninstalled")
|
cmd.Println("Wiretrustee has been uninstalled")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
193
client/cmd/up.go
193
client/cmd/up.go
@@ -2,13 +2,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/kardianos/service"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/wiretrustee/wiretrustee/client/internal"
|
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||||
mgm "github.com/wiretrustee/wiretrustee/management/client"
|
mgm "github.com/wiretrustee/wiretrustee/management/client"
|
||||||
mgmProto "github.com/wiretrustee/wiretrustee/management/proto"
|
mgmProto "github.com/wiretrustee/wiretrustee/management/proto"
|
||||||
signal "github.com/wiretrustee/wiretrustee/signal/client"
|
signal "github.com/wiretrustee/wiretrustee/signal/client"
|
||||||
"github.com/wiretrustee/wiretrustee/util"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@@ -17,97 +17,45 @@ import (
|
|||||||
var (
|
var (
|
||||||
upCmd = &cobra.Command{
|
upCmd = &cobra.Command{
|
||||||
Use: "up",
|
Use: "up",
|
||||||
Short: "start wiretrustee",
|
Short: "install, login and start wiretrustee client",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
err := util.InitLog(logLevel, logFile)
|
|
||||||
|
err := loginCmd.RunE(cmd, args)
|
||||||
if err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := internal.ReadConfig(managementURL, configPath)
|
srvStatus, err := s.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed reading config %s %v", configPath, err)
|
if err == service.ErrNotInstalled {
|
||||||
return err
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if srvStatus == service.StatusRunning {
|
||||||
//validate our peer's Wireguard PRIVATE key
|
stopCmd.Run(cmd, args)
|
||||||
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())
|
return startCmd.RunE(cmd, args)
|
||||||
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
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// createEngineConfig converts configuration received from Management Service to EngineConfig
|
// 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{})
|
iFaceBlackList := make(map[string]struct{})
|
||||||
for i := 0; i < len(config.IFaceBlackList); i += 2 {
|
for i := 0; i < len(config.IFaceBlackList); i += 2 {
|
||||||
iFaceBlackList[config.IFaceBlackList[i]] = struct{}{}
|
iFaceBlackList[config.IFaceBlackList[i]] = struct{}{}
|
||||||
@@ -163,7 +111,92 @@ 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
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
cleanupCh <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Info("stopped Wiretrustee client")
|
||||||
|
|
||||||
|
return ctx.Err()
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/wiretrustee/wiretrustee/iface"
|
"github.com/wiretrustee/wiretrustee/iface"
|
||||||
mgmt "github.com/wiretrustee/wiretrustee/management/server"
|
mgmt "github.com/wiretrustee/wiretrustee/management/server"
|
||||||
"github.com/wiretrustee/wiretrustee/util"
|
"github.com/wiretrustee/wiretrustee/util"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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) {
|
func TestUp(t *testing.T) {
|
||||||
|
|
||||||
defer iface.Close()
|
defer iface.Close()
|
||||||
@@ -65,24 +44,17 @@ func TestUp(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rootCmd.SetArgs([]string{
|
rootCmd.SetArgs([]string{
|
||||||
"login",
|
"up",
|
||||||
"--config",
|
"--config",
|
||||||
confPath,
|
confPath,
|
||||||
"--setup-key",
|
"--setup-key",
|
||||||
"A2C8E62B-38F5-4553-B31E-DD66C696CEBB",
|
"A2C8E62B-38F5-4553-B31E-DD66C696CEBB",
|
||||||
"--management-url",
|
"--management-url",
|
||||||
mgmtURL.String(),
|
mgmtURL.String(),
|
||||||
})
|
"--log-file",
|
||||||
err = rootCmd.Execute()
|
"console",
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rootCmd.SetArgs([]string{
|
|
||||||
"up",
|
|
||||||
"--config",
|
|
||||||
confPath,
|
|
||||||
})
|
})
|
||||||
go func() {
|
go func() {
|
||||||
err = rootCmd.Execute()
|
err = rootCmd.Execute()
|
||||||
|
|||||||
14
client/cmd/version.go
Normal file
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)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -128,6 +128,8 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
|||||||
a, err := ice.NewAgent(&ice.AgentConfig{
|
a, err := ice.NewAgent(&ice.AgentConfig{
|
||||||
// MulticastDNSMode: ice.MulticastDNSModeQueryAndGather,
|
// MulticastDNSMode: ice.MulticastDNSModeQueryAndGather,
|
||||||
NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4},
|
NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4},
|
||||||
|
PortMin: 57830,
|
||||||
|
PortMax: 57830,
|
||||||
Urls: conn.Config.StunTurnURLS,
|
Urls: conn.Config.StunTurnURLS,
|
||||||
CandidateTypes: []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay},
|
CandidateTypes: []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay},
|
||||||
InterfaceFilter: func(s string) bool {
|
InterfaceFilter: func(s string) bool {
|
||||||
@@ -160,13 +162,13 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn.Status = StatusConnecting
|
conn.Status = StatusConnecting
|
||||||
log.Infof("trying to connect to peer %s", conn.Config.RemoteWgKey.String())
|
log.Debugf("trying to connect to peer %s", conn.Config.RemoteWgKey.String())
|
||||||
|
|
||||||
// wait until credentials have been sent from the remote peer (will arrive via a signal server)
|
// wait until credentials have been sent from the remote peer (will arrive via a signal server)
|
||||||
select {
|
select {
|
||||||
case remoteAuth := <-conn.remoteAuthChannel:
|
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()
|
err = conn.agent.GatherCandidates()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -186,8 +188,11 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.
|
// 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)
|
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))
|
err = conn.wgProxy.StartLocal(fmt.Sprintf("%s:%d", pair.Remote.Address(), iface.WgPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -195,19 +200,17 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} 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)
|
err = conn.wgProxy.Start(remoteConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pair.Remote.Type() == ice.CandidateTypeRelay || pair.Local.Type() == ice.CandidateTypeRelay {
|
relayed := pair.Remote.Type() == ice.CandidateTypeRelay || pair.Local.Type() == ice.CandidateTypeRelay
|
||||||
log.Infof("using relay with peer %s", conn.Config.RemoteWgKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.Status = StatusConnected
|
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:
|
case <-conn.closeCond.C:
|
||||||
conn.Status = StatusDisconnected
|
conn.Status = StatusDisconnected
|
||||||
return fmt.Errorf("connection to peer %s has been closed", conn.Config.RemoteWgKey.String())
|
return fmt.Errorf("connection to peer %s has been closed", conn.Config.RemoteWgKey.String())
|
||||||
@@ -271,7 +274,7 @@ func (conn *Connection) Close() error {
|
|||||||
var err error
|
var err error
|
||||||
conn.closeCond.Do(func() {
|
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 {
|
if a := conn.agent; a != nil {
|
||||||
e := a.Close()
|
e := a.Close()
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ type Engine struct {
|
|||||||
TURNs []*ice.URL
|
TURNs []*ice.URL
|
||||||
|
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
|
||||||
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peer is an instance of the Connection Peer
|
// Peer is an instance of the Connection Peer
|
||||||
@@ -66,7 +68,7 @@ type Peer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewEngine creates a new Connection Engine
|
// 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{
|
return &Engine{
|
||||||
signal: signalClient,
|
signal: signalClient,
|
||||||
mgmClient: mgmClient,
|
mgmClient: mgmClient,
|
||||||
@@ -77,17 +79,25 @@ func NewEngine(signalClient *signal.Client, mgmClient *mgm.Client, config *Engin
|
|||||||
STUNs: []*ice.URL{},
|
STUNs: []*ice.URL{},
|
||||||
TURNs: []*ice.URL{},
|
TURNs: []*ice.URL{},
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) Stop() error {
|
func (e *Engine) Stop() error {
|
||||||
|
err := e.removeAllPeerConnections()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Debugf("removing Wiretrustee interface %s", e.config.WgIface)
|
log.Debugf("removing Wiretrustee interface %s", e.config.WgIface)
|
||||||
err := iface.Close()
|
err = iface.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed closing Wiretrustee interface %s %v", e.config.WgIface, err)
|
log.Errorf("failed closing Wiretrustee interface %s %v", e.config.WgIface, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Infof("stopped Wiretrustee Engine")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +137,7 @@ func (e *Engine) Start() error {
|
|||||||
|
|
||||||
// initializePeer peer agent attempt to open connection
|
// initializePeer peer agent attempt to open connection
|
||||||
func (e *Engine) initializePeer(peer Peer) {
|
func (e *Engine) initializePeer(peer Peer) {
|
||||||
var backOff = &backoff.ExponentialBackOff{
|
var backOff = backoff.WithContext(&backoff.ExponentialBackOff{
|
||||||
InitialInterval: backoff.DefaultInitialInterval,
|
InitialInterval: backoff.DefaultInitialInterval,
|
||||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||||
Multiplier: backoff.DefaultMultiplier,
|
Multiplier: backoff.DefaultMultiplier,
|
||||||
@@ -135,19 +145,20 @@ func (e *Engine) initializePeer(peer Peer) {
|
|||||||
MaxElapsedTime: time.Duration(0), //never stop
|
MaxElapsedTime: time.Duration(0), //never stop
|
||||||
Stop: backoff.Stop,
|
Stop: backoff.Stop,
|
||||||
Clock: backoff.SystemClock,
|
Clock: backoff.SystemClock,
|
||||||
}
|
}, e.ctx)
|
||||||
|
|
||||||
operation := func() error {
|
operation := func() error {
|
||||||
_, err := e.openPeerConnection(e.wgPort, e.config.WgPrivateKey, peer)
|
_, err := e.openPeerConnection(e.wgPort, e.config.WgPrivateKey, peer)
|
||||||
e.peerMux.Lock()
|
e.peerMux.Lock()
|
||||||
defer e.peerMux.Unlock()
|
defer e.peerMux.Unlock()
|
||||||
if _, ok := e.conns[peer.WgPubKey]; !ok {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnln(err)
|
log.Warnln(err)
|
||||||
log.Warnln("retrying connection because of error: ", err.Error())
|
log.Debugf("retrying connection because of error: %s", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -172,6 +183,19 @@ func (e *Engine) removePeerConnections(peers []string) error {
|
|||||||
return nil
|
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
|
// removePeerConnection closes existing peer connection and removes peer
|
||||||
func (e *Engine) removePeerConnection(peerKey string) error {
|
func (e *Engine) removePeerConnection(peerKey string) error {
|
||||||
conn, exists := e.conns[peerKey]
|
conn, exists := e.conns[peerKey]
|
||||||
@@ -179,6 +203,7 @@ func (e *Engine) removePeerConnection(peerKey string) error {
|
|||||||
delete(e.conns, peerKey)
|
delete(e.conns, peerKey)
|
||||||
return conn.Close()
|
return conn.Close()
|
||||||
}
|
}
|
||||||
|
log.Infof("removed connection to peer %s", peerKey)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +335,7 @@ func (e *Engine) receiveManagementEvents() {
|
|||||||
e.cancel()
|
e.cancel()
|
||||||
return
|
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")
|
log.Debugf("connecting to Management Service updates stream")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (p *WgProxy) proxyToRemotePeer(remoteConn *ice.Conn) {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-p.close:
|
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
|
return
|
||||||
default:
|
default:
|
||||||
n, err := p.wgConn.Read(buf)
|
n, err := p.wgConn.Read(buf)
|
||||||
@@ -113,7 +113,7 @@ func (p *WgProxy) proxyToLocalWireguard(remoteConn *ice.Conn) {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-p.close:
|
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
|
return
|
||||||
default:
|
default:
|
||||||
n, err := remoteConn.Read(buf)
|
n, err := remoteConn.Read(buf)
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var version = "development"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
cmd.Version = version
|
||||||
if err := cmd.Execute(); err != nil {
|
if err := cmd.Execute(); err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,86 @@
|
|||||||
## Introduction
|
### Table of contents
|
||||||
|
|
||||||
Wiretrustee is a WireGuard®-based platform that connects your devices securely into a peer-to-peer private network.
|
* [About Wiretrustee](#about-wiretrustee)
|
||||||
|
* [Why Wireguard with Wiretrustee?](#why-wireguard-with-wiretrustee)
|
||||||
|
* [Wiretrustee vs. Traditional VPN](#wiretrustee-vs-traditional-vpn)
|
||||||
|
* [High-level technology overview](#high-level-technology-overview)
|
||||||
|
* [Getting started](#getting-started)
|
||||||
|
|
||||||
It simplifies VPN creation and management for your organization without the hassle of opening ports, complex firewall rules, and so forth.
|
### About Wiretrustee
|
||||||
|
|
||||||
It literally takes less than 5 minutes to provision a secure peer-to-peer VPN with 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.
|
||||||
|
|
||||||
### High-level overview
|
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 Wireguard with Wiretrustee?
|
||||||
|
|
||||||
|
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-wireguard-with-wiretrustee) 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).
|
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">
|
<p align="center">
|
||||||
@@ -24,8 +98,7 @@ There are 2 ways of getting started with Wiretrustee:
|
|||||||
- use Cloud Managed version
|
- use Cloud Managed version
|
||||||
- self-hosting
|
- 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.
|
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.
|
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).
|
If you don't want to use the managed version, check out our [Self-hosting Guide](../docs/self-hosting.md).
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 42 KiB |
BIN
docs/media/logo-full.png
Normal file
BIN
docs/media/logo-full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/media/logo.png
Normal file
BIN
docs/media/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/media/peerA.gif
Normal file
BIN
docs/media/peerA.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 409 KiB |
BIN
docs/media/peerB.gif
Normal file
BIN
docs/media/peerB.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 526 KiB |
@@ -8,7 +8,7 @@ This guide describes how to create secure VPN and connect 2 machines peer-to-pee
|
|||||||
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).
|
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.
|
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)
|
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)
|
You can use your email and password to sign-up or any available social login option (e.g., GitHub account)
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ We focused on connectivity instead.
|
|||||||
|
|
||||||
If you would like to learn more about the architecture please refer to the [Wiretrustee Architecture section](architecture.md).
|
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
|
### Requirements
|
||||||
|
|
||||||
- Virtual machine offered by any cloud provider (e.g., AWS, DigitalOcean, Hetzner, Google Cloud, Azure ...).
|
- Virtual machine offered by any cloud provider (e.g., AWS, DigitalOcean, Hetzner, Google Cloud, Azure ...).
|
||||||
- Any Linux OS.
|
- Any Linux OS.
|
||||||
- Docker Compose installed (see [Install Docker Compose](https://docs.docker.com/compose/install/)).
|
- Docker Compose installed (see [Install Docker Compose](https://docs.docker.com/compose/install/)).
|
||||||
- Domain name pointing to the public IP address of your server.
|
- 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.
|
- 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 :)
|
- Maybe a cup of coffee or tea :)
|
||||||
|
|
||||||
### Step-by-step guide
|
### Step-by-step guide
|
||||||
@@ -68,7 +72,7 @@ For this tutorial we will be using domain ```test.wiretrustee.com``` which point
|
|||||||
* set the property in the ```setup.env``` file.
|
* set the property in the ```setup.env``` file.
|
||||||
6. Configure ```WIRETRUSTEE_LETSENCRYPT_EMAIL``` property.
|
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.
|
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:
|
7. Make sure all the properties set in the ```setup.env``` file and run:
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
|||||||
github.com/golang/protobuf v1.5.2
|
github.com/golang/protobuf v1.5.2
|
||||||
github.com/google/uuid v1.2.0
|
github.com/google/uuid v1.2.0
|
||||||
github.com/gorilla/mux v1.8.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/ginkgo v1.16.4
|
||||||
github.com/onsi/gomega v1.13.0
|
github.com/onsi/gomega v1.13.0
|
||||||
github.com/pion/ice/v2 v2.1.7
|
github.com/pion/ice/v2 v2.1.7
|
||||||
|
|||||||
4
go.sum
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/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/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/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.1-0.20210728001519-a323c3813bc7 h1:oohm9Rk9JAxxmp2NLZa7Kebgz9h4+AJDcc64txg3dQ0=
|
||||||
github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
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/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
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=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ services:
|
|||||||
# command: ["--letsencrypt-domain", "$WIRETRUSTEE_DOMAIN", "--log-file", "console"]
|
# command: ["--letsencrypt-domain", "$WIRETRUSTEE_DOMAIN", "--log-file", "console"]
|
||||||
# Management
|
# Management
|
||||||
management:
|
management:
|
||||||
# image: wiretrustee/management:latest
|
image: wiretrustee/management:latest
|
||||||
image: wiretrustee/management:v0.1.0-beta.2-SNAPSHOT-39d450b-amd64
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- dashboard
|
- dashboard
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func NewClient(ctx context.Context, addr string, ourPrivateKey wgtypes.Key, tlsE
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
if err != nil {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ func (c *Client) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//defaultBackoff is a basic backoff mechanism for general issues
|
//defaultBackoff is a basic backoff mechanism for general issues
|
||||||
func defaultBackoff() backoff.BackOff {
|
func defaultBackoff(ctx context.Context) backoff.BackOff {
|
||||||
return &backoff.ExponentialBackOff{
|
return backoff.WithContext(&backoff.ExponentialBackOff{
|
||||||
InitialInterval: 800 * time.Millisecond,
|
InitialInterval: 800 * time.Millisecond,
|
||||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||||
Multiplier: backoff.DefaultMultiplier,
|
Multiplier: backoff.DefaultMultiplier,
|
||||||
@@ -74,14 +74,14 @@ func defaultBackoff() backoff.BackOff {
|
|||||||
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
||||||
Stop: backoff.Stop,
|
Stop: backoff.Stop,
|
||||||
Clock: backoff.SystemClock,
|
Clock: backoff.SystemClock,
|
||||||
}
|
}, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync wraps the real client's Sync endpoint call and takes care of retries and encryption/decryption of messages
|
// 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
|
// Blocking request. The result will be sent via msgHandler callback function
|
||||||
func (c *Client) Sync(msgHandler func(msg *proto.SyncResponse) error) error {
|
func (c *Client) Sync(msgHandler func(msg *proto.SyncResponse) error) error {
|
||||||
|
|
||||||
var backOff = defaultBackoff()
|
var backOff = defaultBackoff(c.ctx)
|
||||||
|
|
||||||
operation := func() error {
|
operation := func() error {
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ func (c *Client) Sync(msgHandler func(msg *proto.SyncResponse) error) error {
|
|||||||
|
|
||||||
err := backoff.Retry(operation, backOff)
|
err := backoff.Retry(operation, backOff)
|
||||||
if err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ func (c *Client) receiveEvents(stream proto.ManagementService_SyncClient, server
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ func (c *Client) receiveEvents(stream proto.ManagementService_SyncClient, server
|
|||||||
|
|
||||||
err = msgHandler(decryptedResp)
|
err = msgHandler(decryptedResp)
|
||||||
if err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,30 +12,27 @@ fi
|
|||||||
cleanInstall() {
|
cleanInstall() {
|
||||||
printf "\033[32m Post Install of an clean install\033[0m\n"
|
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
|
# Step 3 (clean install), enable the service in the proper way for this platform
|
||||||
if [ "${use_systemctl}" = "True" ]; then
|
/usr/local/bin/wiretrustee service install
|
||||||
printf "\033[32m Reload the service unit from disk\033[0m\n"
|
/usr/local/bin/wiretrustee service start
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
upgrade() {
|
upgrade() {
|
||||||
printf "\033[32m Post Install of an upgrade\033[0m\n"
|
printf "\033[32m Post Install of an upgrade\033[0m\n"
|
||||||
if [ "${use_systemctl}" = "True" ]; then
|
if [ "${use_systemctl}" = "True" ]; then
|
||||||
printf "\033[32m Reload the service unit from disk\033[0m\n"
|
printf "\033[32m Stopping the service\033[0m\n"
|
||||||
systemctl daemon-reload ||:
|
systemctl stop wiretrustee 2> /dev/null || true
|
||||||
printf "\033[32m Restarting the service\033[0m\n"
|
|
||||||
systemctl restart wiretrustee ||:
|
|
||||||
fi
|
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"
|
action="$1"
|
||||||
if [ "$1" = "configure" ] && [ -z "$2" ]; then
|
if [ "$1" = "configure" ] && [ -z "$2" ]; then
|
||||||
# Alpine linux does not pass args, and deb passes $1=configure
|
# Alpine linux does not pass args, and deb passes $1=configure
|
||||||
@@ -50,12 +47,9 @@ case "$action" in
|
|||||||
cleanInstall
|
cleanInstall
|
||||||
;;
|
;;
|
||||||
"2" | "upgrade")
|
"2" | "upgrade")
|
||||||
printf "\033[32m Post Install of an upgrade\033[0m\n"
|
|
||||||
upgrade
|
upgrade
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# $1 == version being installed
|
|
||||||
printf "\033[32m install\033[0m"
|
|
||||||
cleanInstall
|
cleanInstall
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
43
release_files/pre_remove.sh
Normal file
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
|
//defaultBackoff is a basic backoff mechanism for general issues
|
||||||
func defaultBackoff() backoff.BackOff {
|
func defaultBackoff(ctx context.Context) backoff.BackOff {
|
||||||
return &backoff.ExponentialBackOff{
|
return backoff.WithContext(&backoff.ExponentialBackOff{
|
||||||
InitialInterval: 800 * time.Millisecond,
|
InitialInterval: 800 * time.Millisecond,
|
||||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||||
Multiplier: backoff.DefaultMultiplier,
|
Multiplier: backoff.DefaultMultiplier,
|
||||||
@@ -85,7 +85,8 @@ func defaultBackoff() backoff.BackOff {
|
|||||||
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
MaxElapsedTime: 24 * 3 * time.Hour, //stop after 3 days trying
|
||||||
Stop: backoff.Stop,
|
Stop: backoff.Stop,
|
||||||
Clock: backoff.SystemClock,
|
Clock: backoff.SystemClock,
|
||||||
}
|
}, ctx)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive Connects to the Signal Exchange message stream and starts receiving messages.
|
// 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)
|
c.connWg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
|
||||||
var backOff = defaultBackoff()
|
var backOff = defaultBackoff(c.ctx)
|
||||||
|
|
||||||
operation := func() error {
|
operation := func() error {
|
||||||
|
|
||||||
err := c.connect(c.key.PublicKey().String(), msgHandler)
|
err := c.connect(c.key.PublicKey().String(), msgHandler)
|
||||||
if err != nil {
|
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)
|
c.connWg.Add(1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -112,7 +114,7 @@ func (c *Client) Receive(msgHandler func(msg *proto.Message) error) {
|
|||||||
|
|
||||||
err := backoff.Retry(operation, backOff)
|
err := backoff.Retry(operation, backOff)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
Reference in New Issue
Block a user