Compare commits

...

20 Commits

Author SHA1 Message Date
Mikhail Bragin
0b2c26847b fix: return ctx error when UP command exists (#140) 2021-10-26 21:49:05 +02:00
braginini
595ea0d4f8 chore: decrease log verbosity 2021-10-26 10:08:28 +02:00
Maycon Santos
f714868fdd remove arch if and replacement for debian packages (#138) 2021-10-23 10:29:49 +02:00
Mikhail Bragin
81821a1f39 docs: update diagram and Wireguard title (#137)
* docs: update diagram and Wireguard title
2021-10-21 10:06:29 +02:00
mlsmaycon
842b143a48 sync go.sum 2021-10-20 21:57:16 +02:00
Maycon Santos
1323a74db0 fix: avoid failing and extra error messages (#136)
* avoid failing and extra error messages

* avoid extra error messages when executed after pre_remove.sh

* remove extra output and avoid failure on minor errors

* ensure the steps will run only on remove
2021-10-20 11:51:32 +02:00
Mikhail Bragin
74485d3b13 fix: service hanging when error on startup has been encountered (#135) 2021-10-18 13:29:26 +02:00
Mikhail Bragin
bef3b3392b fix: graceful shutdown (#134)
* fix: graceful shutdown

* fix: windows graceful shutdown
2021-10-17 22:15:38 +02:00
Maycon Santos
fcea3c99d4 Enhance up command (#133)
* move setup-key to root command

* up will check login and start service

* update tests to reflect new UP capabilities

* display client IP

* removed unused argument

* install service if not installed

* update post-install and add pre remove script

* improve log messages

* handle service status failures and install service when needed

* removing unused files

* update documentation and description

* add version command

* update service lib version

* using lib constant for not installed services

* match version from goreleaser

* fix: graceful shutdown

* stop only if service is running

* add logs initialization to service controller commands

Co-authored-by: braginini <bangvalo@gmail.com>
2021-10-17 21:34:07 +02:00
Mikhail Bragin
96799a25b5 docs: fix gif size 2021-10-16 16:54:37 +02:00
Mikhail Bragin
07291cdb93 docs: update readme (#132)
* update readme
2021-10-16 16:53:39 +02:00
Mikhail Bragin
21139938c1 docs: highlight Slack channel 2021-10-12 14:37:49 +02:00
Maycon Santos
5cf2d0a6a9 add slack invitation link (#129) 2021-10-12 12:16:09 +02:00
Maycon Santos
8551afe04e enhancement: Support new architectures and auto upload packages to repo (#128)
* adding uploads

* adding uploads

* adding uploads

* adding uploads

* adding uploads

* adding uploads

* use https://pkgs.wiretrustee.com/

* use https://pkgs.wiretrustee.com/

* use https://pkgs.wiretrustee.com/

* set yum id

* secrets for goreleaser uploads

* ensure Github release is enabled
2021-10-12 12:15:45 +02:00
braginini
1685817171 docs: correct installation steps 2021-10-03 18:55:47 +02:00
Mikhail Bragin
e17f662683 docs: update intro (#125)
* docs: update intro
2021-10-03 18:21:41 +02:00
Mikhail Bragin
a764fb870c docs: move intro link up in readme 2021-09-27 09:23:19 +02:00
Mikhail Bragin
cabff941ac docs: add self-hosting video 2021-09-26 16:49:59 +02:00
Mikhail Bragin
b5f35dfb5e docs: replace beta with app.wiretrustee.com (#123)
* docs: replace beta with app.wiretrustee.com

* docs: add Signal port to the list of the open ports

* docs: minor corrections
2021-09-26 11:44:34 +02:00
braginini
1d426b7f81 docs: fix docker-compose management image 2021-09-25 20:17:01 +02:00
31 changed files with 583 additions and 345 deletions

View File

@@ -51,6 +51,8 @@ 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 }}
-
name: Trigger Windows binaries sign pipeline

View File

@@ -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,38 @@ 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"
- 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 +214,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 }}
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
View File

@@ -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).
Hosted demo version:
[https://beta.wiretrustee.com/](https://beta.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/).
[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.
@@ -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).
* Open-source (including Management Service)
### Secure peer-to-peer VPN in minutes
![animation](docs/media/peers.gif)
### A bit on Wiretrustee internals
* Wiretrustee features a Management Service that offers peer IP management and network updates distribution (e.g. when new peer joins the network).
@@ -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 Progress Tracking](https://github.com/wiretrustee/wiretrustee/projects/1)
### Getting started
See [Docs](docs/README.md) for managed and self-hosting guides.
### Client Installation
#### Linux
1. Checkout Wiretrustee [releases](https://github.com/wiretrustee/wiretrustee/releases)
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"
```
4. Repeat on other machines.
3. Repeat on other machines.
### 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

View File

@@ -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() {
//}

View File

@@ -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
}
}()

View File

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

View File

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

View File

@@ -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,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
}
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()
}

View File

@@ -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
View 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)
},
}
)

View File

@@ -128,6 +128,8 @@ func (conn *Connection) Open(timeout time.Duration) error {
a, err := ice.NewAgent(&ice.AgentConfig{
// MulticastDNSMode: ice.MulticastDNSModeQueryAndGather,
NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4},
PortMin: 57830,
PortMax: 57830,
Urls: conn.Config.StunTurnURLS,
CandidateTypes: []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay},
InterfaceFilter: func(s string) bool {
@@ -160,13 +162,13 @@ func (conn *Connection) Open(timeout time.Duration) error {
}
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)
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 +188,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 +200,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 +274,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()

View File

@@ -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,19 +145,20 @@ 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
}
if err != nil {
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 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")
}

View File

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

View File

@@ -5,7 +5,11 @@ import (
"os"
)
var version = "development"
func main() {
cmd.Version = version
if err := cmd.Execute(); err != nil {
os.Exit(1)
}

View File

@@ -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).
<p align="center">
@@ -24,8 +98,7 @@ There are 2 ways of getting started with Wiretrustee:
- use Cloud Managed version
- self-hosting
We recommend starting with the cloud managed version hosted at [beta.wiretrustee.com](https://beta.wiretrustee.com) - the quickest way to get familiar with the system.
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).
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
docs/media/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/media/peerA.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

BIN
docs/media/peerB.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

View File

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

View File

@@ -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).
### Step-by-step video guide on YouTube:
[![IMAGE ALT TEXT](https://img.youtube.com/vi/Ofpgx5WhT0k/0.jpg)](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, 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 :)
### 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.
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:

2
go.mod
View File

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

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

View File

@@ -31,8 +31,7 @@ services:
# command: ["--letsencrypt-domain", "$WIRETRUSTEE_DOMAIN", "--log-file", "console"]
# Management
management:
# image: wiretrustee/management:latest
image: wiretrustee/management:v0.1.0-beta.2-SNAPSHOT-39d450b-amd64
image: wiretrustee/management:latest
restart: unless-stopped
depends_on:
- dashboard

View File

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

View File

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

View 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

View File

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

View File

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

View File

@@ -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
}
}()