Skip to content

Commit 47c10c6

Browse files
committed
add source
1 parent eafc31f commit 47c10c6

22 files changed

+1313
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.idea
2+
/sample
3+
/build
4+
/test
5+
/dist

.goreleaser.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
project_name: tinc-boot
2+
builds:
3+
- main: ./cmd/tinc-boot/main.go
4+
binary: tinc-boot
5+
env:
6+
- CGO_ENABLED=0
7+
goarch:
8+
- amd64
9+
- 386
10+
- arm
11+
- arm64
12+
goarm:
13+
- 5
14+
- 6
15+
- 7
16+
goos:
17+
- linux
18+
gcflags:
19+
- all=-trimpath={{.Env.GOPATH}}
20+
flags:
21+
- -trimpath
22+
archives:
23+
- replacements:
24+
Linux: linux
25+
386: i386
26+
format: tar.gz
27+
checksum:
28+
name_template: 'checksums.txt'
29+
snapshot:
30+
name_template: "{{ .Tag }}-next"
31+
changelog:
32+
sort: asc
33+
filters:
34+
exclude:
35+
- '^docs:'
36+
- '^test:'

README.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Overview
2+
3+
Idea to create a easy-to-use wrapper over [tinc vpn](https://www.tinc-vpn.org).
4+
5+
Tinc VPN - is full-mesh, auto-healing, time-proofed VPN system without single point of failure, with high-throughput and
6+
serious cryptography.
7+
All nodes in a Tinc network are fully equal. New nodes discovering full topology through any entry point.
8+
Node may interact with each other even if they don't have direct connections.
9+
10+
Tinc is a great and have a lot of features. It's ideal for a complicated situations (China, Russia and others).
11+
I really admire the project.
12+
13+
![transit](https://user-images.githubusercontent.com/6597086/65304801-1b4ae480-dbb4-11e9-933f-b890242358ab.png)
14+
15+
**But...** it's pain to configure and maintain.
16+
17+
Pain to create a new node. Pain to add new node to network.
18+
19+
Minimal configuration for a first public node:
20+
21+
* 2 files (tinc.conf, hostfile),
22+
* 1 script (tinc-up),
23+
* 2 directories (net, hosts),
24+
* 1 command execution (key generation).
25+
26+
(let's not count service initialization and other common stuff)
27+
28+
Second node adds key exchange (+1 operation if we will use `rsync`, or +2 operations if manually).
29+
30+
![second_node](https://user-images.githubusercontent.com/6597086/65304124-72e85080-dbb2-11e9-939f-6359095dbe54.png)
31+
32+
Next new public nodes require increasing number of additional operations (+N operations, where N is a number of public nodes).
33+
34+
![third_node](https://user-images.githubusercontent.com/6597086/65304303-df634f80-dbb2-11e9-8b9a-32bd4c6b9c46.png)
35+
36+
37+
> To be honest, to just to connect to the network an only single key exchange operation required: with any public node.
38+
> Than tincd will discover all other nodes.
39+
>
40+
> **But** after your node disconnect/reboot and in case of death of your entry node you will be no more able to connect
41+
> to other alive nodes (because they don't know your key and your node don't know theirs).
42+
43+
44+
45+
**Tinc-boot** - is a all-in-one tool with zero dependency (except `tinc` of course), that aims to achieve:
46+
47+
1. one-line node initialization
48+
2. automatic keys distribution
49+
3. simplified procedure to add new node to existent net
50+
51+
52+
## Installation
53+
54+
* (recommended) look at releases page and download
55+
* build from source `go get -v github.com/reddec/tinc-boot/cmd/...`
56+
57+
### Build requirements
58+
59+
* go 1.13+
60+
61+
## Runtime requirements
62+
63+
* Linux
64+
* `tincd 1.10.xx`
65+
* `bash`
66+
* (recommended) `systemd`
67+
68+
## Tested operation systems
69+
70+
* Ubuntu 18.04 x64
71+
* Archlinux (Q1 2019) x64
72+
* Manjaro (Q1 2019) x64
73+
74+
Should work on all major linux systems, except generated helpers useful only for systemd-based OS.
75+
76+
77+
# Quick start
78+
79+
Download/build binary to `/usr/local/bin/tinc-boot`.
80+
81+
## First node
82+
83+
```
84+
sudo tinc-boot gen --standalone -a <PUBLIC ADDRESS>
85+
```
86+
87+
and follow recommendations
88+
89+
### Explanation
90+
91+
* `--standalone` means that it's a first node, no need for keys exchange
92+
* `-a <address>` sets public address of node (if exists); could be used several times
93+
94+
Will generate all required files under `/etc/tinc/dnet`.
95+
96+
## Turn node to boot node
97+
98+
```
99+
sudo tinc-boot bootnode --service --dir /etc/tinc/dnet --token <SECRETTOKEN>
100+
```
101+
102+
and follow recommendations
103+
104+
### Explanation
105+
106+
* `--service` generates systemd file to `/etc/systemd/system/tinc-boot-{net}.service`
107+
* `--dir` location of tinc configuration
108+
* `--token` set's authorization token that will be used by clients
109+
110+
## Create another node and join to net
111+
112+
```
113+
sudo tinc-boot gen --token <SECRETTOKEN> <PUBLIC ADDRESS>:8655
114+
```
115+
116+
> Don't forget add `-a <NODE ADDRESS>` if applicable
117+
118+
and follow recommendations
119+
120+
# How it works
121+
122+
TBD
123+
124+
# TODO
125+
126+
* generate script with token to redistribute all-in-one to end-users

_docs/diagrams/second_node.drawio

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile modified="2019-09-20T06:24:34.057Z" host="www.draw.io" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36" etag="o2XcR6PpeDW3ecr9oysl" version="11.2.9" type="device" pages="1"><diagram id="n3g4DslWbVnhe9REuUzu" name="Page-1">zZVNb9swDIZ/jY8rYjtp1mvd9APYhg05tD0KFmerlU1DoWu7v35STH8tc9AORbZLID4kJZHUG3thlNU3RhTpV5SgvWAhay+88oJguVraXweaFqzDixYkRskW+QPYqldguGBaKgm7SSAhalLFFMaY5xDThAljsJqG/UQ9PbUQCRyAbSz0Ib1XklKm/vnF4LgFlaR89Odg3Toy0QVzJbtUSKxGKNx4YWQQqV1ldQTa9a7rS5t3PePtL2Ygp7ckXIrvrw/LmziX6ttdtCqiH1vzKWx3eRG65IJzO0GHnqHhe1PTNQOk7Q2baCjFBHOhNwO9NFjmEtyJC2sNMV8QCwt9C5+AqOFBi5LQopQyzV6oFT249LMVW4+8mVtf1WOj6YycTDNKcubj2Dek7a0ur63PFTXbUkY7LE0MR/rYPU1hEqAjcUE/eCsYwAzsfWyeAS1IvUzvIfjpJn3cMF274AG/Y9j+3LB/H7PWVl5unFWqCLaF2NdeWYFPh8X7gSGoj7fwsGRO6IXO/w+9XKpBbWtG6UhnHfvwJi3/2CT/f1OE/1eK8E+niOCNiph5HqdRRDA37H+oiPBkgrDm8PnZ+0bf8HDzCw==</diagram></mxfile>

_docs/diagrams/third_node.drawio

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile modified="2019-09-20T06:27:46.755Z" host="www.draw.io" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36" etag="hdCTx4tFTckrNGlkylh3" version="11.2.9" type="device" pages="1"><diagram id="n3g4DslWbVnhe9REuUzu" name="Page-1">1VfBctowEP0ajmFkC0N9bAhJO9N20uFQctTgxVYqLI8Qwc7XV8ZryyKYBKYFemG8T6vV6uk9YffoeJk/KJYl32UEoueTKO/Ru57vD4KB+S2BogKGIamAWPGogjwLTPkrIFinrXkEKydRSyk0z1xwLtMU5trBmFJy46YtpHBXzVgMb4DpnIm36C8e6QRRbxjagS/A4wSX/uSPqoElq5NxJ6uERXLTguikR8dKSl09LfMxiJK7mpdq3n3HaNOYglR/ZMIte3ydDR7macR/fB0H2fjnVN1gsy9MrHHDqTnBEvoNBfati5oMiAw3GEqlExnLlImJRW+VXKcRlCsSE9mcb1JmBvQM+AxaF3jQbK2lgRK9FDgKOdezcno/wOipNXKXY+VtUNRBqlUxq9PK4MlWKEM7bRvV86r9lZvqpBShlVyrORzgsZYmUzHoA3lBc/DGMCCXYPox89AtpE+DEZZCv3hBFSoQTPMXt1OG4o6bSk3xR8nNHmyKXCxWprOWQMxDqwcLbWVzhIS8LgntikcIY9pSJJuEa5hmbMvoxlwbrgSwHigN+eGD6SSyuT6QxcaEG+vhEUJJy701to9Yh7ejSdrPknd5o3nH24w4Njufyfy/ZLJh6FNXHuQUk31WihWthKy03GqPB3Hh0NUkHZIdWVUFz25gv0uaFzQwvTL/hns5otdlX3KCfb3z2Tf4oH0PK+OG9ElIQtdKJ/n3rH+S5FoFRNoCal663pOQfbe6UhH574ko+M9es4IuAV3wlvZ2rmka/LNr2oT2U6ni1H5v0skf</diagram></mxfile>

_docs/diagrams/transit.drawio

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile modified="2019-09-20T06:36:35.539Z" host="www.draw.io" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36" etag="7nU4MMjqwcQ3Rq4wiZzN" version="11.2.9" type="device" pages="1"><diagram id="n3g4DslWbVnhe9REuUzu" name="Page-1">7Vlbb9s6DP41eUxgW3Yuj01abwO2gx70Ydujaiu2VsUyZKVJ+utH2fJVXi5t0mbAArQRKYqS+JEUpQzQYrX9JHAaf+MhYQPHCrcDdDtwHNdz4b9i7ArGeGYVjEjQsGDZNeOBvhDNLMXWNCRZS1ByziRN28yAJwkJZIuHheCbttiSs/asKY6IwXgIMDO532koY821x7O64zOhUaynnjqTomOFS2G9kyzGId80WOhugBaCc1m0VtsFYcp2pV2Kcf4fequFCZLIYwbM8f3LD/dTkIT0vy8LL138/yCGWsszZmu94QQQRHrFcleaAVSBxYGYb2IqyUOKA9WzAcyBF8sVA8qGptZHhCTbPy7UrrYPbkP4ikixAxE9ACFtMe0ytqfpTQ3ARLPihulLHtaQR5Xm2irQ0IY5xUjIsFJIhfI2w0whOI8muZAxj3iC2V3NnQu+TkKiZrOAqmW+cp5qE/4iUu50JOC15G0Dky2VP9Twkaepn1qZat9um8SuJBIwQ2OQIn+W+hRRD8upclwmsZA3KoqAETCcZTQo2T5lbczV3vcjDqbiaxGQPaZ2dIhjERG5R87r9yBBGJb0ub2O8/vDxPCHR8aDJ4D1Ax3CbrpD5Rz9DtEGVvAs68BaCAn+RBaccZFvBvm+NbUKLwm7g4HVGPoBHrE/pwytkT0ea9yO9hKt7p5TWHUtwpfLjEjDjapZX+9ZTm86tk23esd0bE/b6RjZH52O3StMx6dEX52Om8m4kZuvJh17bwu+90nHXm/QOFcVNB9fw5hW+hc0lwka++8oYsZX6BDnKGqtv9ch3ppG86GwNbxrCKSqesl6yhmdqsZeO1PZnWtkRxztl4dGsYCz1kWlBa+qMLq6a+rUMJJhnyzGqWrSVf7u0bSIsgUNMLthNEqAJ1XsVtyv+JGwe55RSbnqfeRS8hUIMNUxx8FTlGeBxnVhmX9AJJ/sJkuL9xkVg7gklnSr8sZcr+c2llI97NwoSzh+ECZoRAOeLCnkFzEKYEbHD7HE8KX44Nb+kuEoGyKo7X0EtxMYFdMEDxOsVorZcMMFC8GDpqM0ic4Cuztqh4Azcw3kPdtE3rtYLp+djvw5gO13mX5wW/g34a7QZruArFejR/oCxCYdAr5SYeL465RxHCqwHUtdvn0LDO6Lp2ToetYW/nJozxTUXXSR65noTnrQnVwI3fIBsYGuFDgBxAyQg7V4zs9hu3NLr465RsAb93sLPr5//BHZW8btPbPPeKg6/TA2QepJviXvtU8A2ksqPd07camiWL4ete80ddqKHKujqKgZDEWnHvLdBRuPxYfk3RPlD1QRzrR/3xetIkqcrzaQrKMDqSp+qyfcY0rfc4ff60va9wlT4+nKeWWYulan1nMvE6b27LSw627wUNjZ6Ej9ZT86EMZtdbMD0rZ3ijhyT9KOuk8ub7uYqAKj+m2uEK9/4ER3vwE=</diagram></mxfile>

cmd/tinc-boot/forget/main.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package forget
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"errors"
7+
"github.com/reddec/tinc-boot/types"
8+
"net"
9+
"net/http"
10+
"strconv"
11+
)
12+
13+
type Cmd struct {
14+
Iface string `long:"iface" env:"INTERFACE" description:"RPC interface" required:"yes"`
15+
Port int `long:"port" env:"PORT" description:"RPC port" default:"1655"`
16+
Subnet string `long:"subnet" env:"SUBNET" description:"Subnet address to watch" required:"yes"`
17+
Node string `long:"node" env:"NODE" description:"Subnet owner name" required:"yes"`
18+
}
19+
20+
func (cmd *Cmd) Execute(args []string) error {
21+
rpcAddr, err := cmd.binding()
22+
if err != nil {
23+
return err
24+
}
25+
var subnet = types.Subnet{
26+
Subnet: cmd.Subnet,
27+
Node: cmd.Node,
28+
}
29+
data, err := json.Marshal(subnet)
30+
if err != nil {
31+
return err
32+
}
33+
res, err := http.Post("http://"+rpcAddr+"/rpc/forget", "application/json", bytes.NewBuffer(data))
34+
if err != nil {
35+
return err
36+
}
37+
38+
defer res.Body.Close()
39+
if res.StatusCode != http.StatusNoContent {
40+
return errors.New(res.Status)
41+
}
42+
return nil
43+
}
44+
45+
func (cmd *Cmd) binding() (string, error) {
46+
ief, err := net.InterfaceByName(cmd.Iface)
47+
if err != nil {
48+
return "", err
49+
}
50+
addrs, err := ief.Addrs()
51+
if err != nil {
52+
return "", err
53+
}
54+
return addrs[0].(*net.IPNet).IP.String() + ":" + strconv.Itoa(cmd.Port), nil
55+
}

0 commit comments

Comments
 (0)