2020-03-02 01:45:14 +01:00
|
|
|
package dsnet
|
|
|
|
|
2020-03-02 20:13:47 +01:00
|
|
|
import (
|
2020-03-05 21:43:31 +01:00
|
|
|
"fmt"
|
2020-03-05 21:46:28 +01:00
|
|
|
"os"
|
2020-03-03 22:28:06 +01:00
|
|
|
"text/template"
|
2020-03-07 22:57:00 +01:00
|
|
|
"time"
|
2020-03-02 20:13:47 +01:00
|
|
|
)
|
|
|
|
|
2020-10-26 23:47:48 +01:00
|
|
|
const wgQuickPeerConf = `[Interface]
|
2020-10-27 22:03:45 +01:00
|
|
|
{{ if gt (.DsnetConfig.Network.IPNet.IP | len) 0 -}}
|
2020-10-27 00:37:19 +01:00
|
|
|
Address={{ .Peer.IP }}/{{ .CidrSize }}
|
2020-10-27 22:03:45 +01:00
|
|
|
{{ end -}}
|
|
|
|
{{ if gt (.DsnetConfig.Network6.IPNet.IP | len) 0 -}}
|
2020-10-27 00:37:19 +01:00
|
|
|
Address={{ .Peer.IP6 }}/{{ .CidrSize6 }}
|
2020-10-27 22:03:45 +01:00
|
|
|
{{ end -}}
|
2020-10-19 01:04:05 +02:00
|
|
|
PrivateKey={{ .Peer.PrivateKey.Key }}
|
|
|
|
{{- if .DsnetConfig.DNS }}
|
2020-10-25 23:55:18 +01:00
|
|
|
DNS={{ .DsnetConfig.DNS }}
|
2020-10-19 01:04:05 +02:00
|
|
|
{{ end }}
|
|
|
|
|
|
|
|
[Peer]
|
|
|
|
PublicKey={{ .DsnetConfig.PrivateKey.PublicKey.Key }}
|
|
|
|
PresharedKey={{ .Peer.PresharedKey.Key }}
|
2020-10-26 19:27:35 +01:00
|
|
|
{{ if gt (.DsnetConfig.ExternalIP | len) 0 -}}
|
2020-10-19 01:04:05 +02:00
|
|
|
Endpoint={{ .DsnetConfig.ExternalIP }}:{{ .DsnetConfig.ListenPort }}
|
2020-10-26 19:27:35 +01:00
|
|
|
{{ else -}}
|
|
|
|
Endpoint={{ .DsnetConfig.ExternalIP6 }}:{{ .DsnetConfig.ListenPort }}
|
|
|
|
{{ end -}}
|
2020-10-19 01:04:05 +02:00
|
|
|
PersistentKeepalive={{ .Keepalive }}
|
2020-10-27 01:00:38 +01:00
|
|
|
{{ if gt (.DsnetConfig.Network.IPNet.IP | len) 0 -}}
|
|
|
|
AllowedIPs={{ .DsnetConfig.Network }}
|
2020-10-26 18:58:15 +01:00
|
|
|
{{ end -}}
|
2020-10-27 01:00:38 +01:00
|
|
|
{{ if gt (.DsnetConfig.Network6.IPNet.IP | len) 0 -}}
|
|
|
|
AllowedIPs={{ .DsnetConfig.Network6 }}
|
2020-10-26 18:58:15 +01:00
|
|
|
{{ end -}}
|
|
|
|
{{ range .DsnetConfig.Networks -}}
|
|
|
|
AllowedIPs={{ . }}
|
|
|
|
{{ end -}}
|
2020-10-19 01:04:05 +02:00
|
|
|
`
|
|
|
|
|
2020-10-19 04:37:21 +02:00
|
|
|
// TODO use random wg0-wg999 to hopefully avoid conflict by default?
|
2020-10-19 18:49:36 +02:00
|
|
|
const vyattaPeerConf = `configure
|
2020-10-27 22:03:45 +01:00
|
|
|
{{ if gt (.DsnetConfig.Network.IPNet.IP | len) 0 -}}
|
2020-10-27 00:37:19 +01:00
|
|
|
set interfaces wireguard wg0 address {{ .Peer.IP }}/{{ .CidrSize }}
|
2020-10-27 22:03:45 +01:00
|
|
|
{{ end -}}
|
|
|
|
{{ if gt (.DsnetConfig.Network6.IPNet.IP | len) 0 -}}
|
2020-10-27 00:37:19 +01:00
|
|
|
set interfaces wireguard wg0 address {{ .Peer.IP6 }}/{{ .CidrSize6 }}
|
2020-10-27 22:03:45 +01:00
|
|
|
{{ end -}}
|
2020-10-19 18:52:54 +02:00
|
|
|
set interfaces wireguard wg0 route-allowed-ips true
|
|
|
|
set interfaces wireguard wg0 private-key {{ .Peer.PrivateKey.Key }}
|
2020-10-27 22:03:45 +01:00
|
|
|
set interfaces wireguard wg0 description {{ .DsnetConfig.InterfaceName }}
|
2020-10-19 01:04:05 +02:00
|
|
|
{{- if .DsnetConfig.DNS }}
|
|
|
|
#set service dns forwarding name-server {{ .DsnetConfig.DNS }}
|
|
|
|
{{ end }}
|
|
|
|
|
2020-10-26 22:39:55 +01:00
|
|
|
{{ if gt (.DsnetConfig.ExternalIP | len) 0 -}}
|
2020-10-19 18:52:54 +02:00
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} endpoint {{ .DsnetConfig.ExternalIP }}:{{ .DsnetConfig.ListenPort }}
|
2020-10-26 22:39:55 +01:00
|
|
|
{{ else -}}
|
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} endpoint {{ .DsnetConfig.ExternalIP6 }}:{{ .DsnetConfig.ListenPort }}
|
|
|
|
{{ end -}}
|
2020-10-19 04:17:06 +02:00
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} persistent-keepalive {{ .Keepalive }}
|
2020-10-19 20:25:56 +02:00
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} preshared-key {{ .Peer.PresharedKey.Key }}
|
2020-10-27 01:00:38 +01:00
|
|
|
{{ if gt (.DsnetConfig.Network.IPNet.IP | len) 0 -}}
|
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} allowed-ips {{ .DsnetConfig.Network }}
|
2020-10-26 18:58:15 +01:00
|
|
|
{{ end -}}
|
2020-10-27 01:00:38 +01:00
|
|
|
{{ if gt (.DsnetConfig.Network6.IPNet.IP | len) 0 -}}
|
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} allowed-ips {{ .DsnetConfig.Network6 }}
|
2020-10-26 18:58:15 +01:00
|
|
|
{{ end -}}
|
|
|
|
{{ range .DsnetConfig.Networks -}}
|
|
|
|
set interfaces wireguard wg0 peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} allowed-ips {{ . }}
|
|
|
|
{{ end -}}
|
2020-10-19 01:04:05 +02:00
|
|
|
commit; save
|
|
|
|
`
|
|
|
|
|
2020-03-03 23:33:48 +01:00
|
|
|
func Add() {
|
2020-03-14 15:51:49 +01:00
|
|
|
if len(os.Args) != 3 {
|
2020-03-05 23:13:09 +01:00
|
|
|
// TODO non-red
|
|
|
|
ExitFail("Hostname argument required: dsnet add <hostname>")
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO maybe accept flags to avoid prompt and allow programmatic use?
|
2020-03-03 23:33:48 +01:00
|
|
|
// TODO accept existing pubkey
|
2020-03-02 04:08:28 +01:00
|
|
|
conf := MustLoadDsnetConfig()
|
|
|
|
|
2020-03-05 23:13:09 +01:00
|
|
|
hostname := os.Args[2]
|
2020-03-03 23:33:48 +01:00
|
|
|
owner := MustPromptString("owner", true)
|
|
|
|
description := MustPromptString("Description", true)
|
|
|
|
//publicKey := MustPromptString("PublicKey (optional)", false)
|
|
|
|
ConfirmOrAbort("\nDo you want to add the above configuration?")
|
|
|
|
|
2020-03-05 21:43:31 +01:00
|
|
|
// newline (not on stdout) to separate config
|
|
|
|
fmt.Fprintln(os.Stderr)
|
|
|
|
|
2020-03-02 04:08:28 +01:00
|
|
|
privateKey := GenerateJSONPrivateKey()
|
|
|
|
publicKey := privateKey.PublicKey()
|
|
|
|
|
|
|
|
peer := PeerConfig{
|
2020-03-02 20:03:00 +01:00
|
|
|
Owner: owner,
|
|
|
|
Hostname: hostname,
|
|
|
|
Description: description,
|
2020-03-19 21:12:42 +01:00
|
|
|
Added: time.Now(),
|
2020-03-02 20:03:00 +01:00
|
|
|
PublicKey: publicKey,
|
2020-03-02 23:31:52 +01:00
|
|
|
PrivateKey: privateKey, // omitted from server config JSON!
|
2020-03-02 22:36:41 +01:00
|
|
|
PresharedKey: GenerateJSONKey(),
|
2020-03-04 20:46:39 +01:00
|
|
|
Networks: []JSONIPNet{},
|
2020-03-02 04:08:28 +01:00
|
|
|
}
|
|
|
|
|
2020-10-25 23:27:33 +01:00
|
|
|
if len(conf.Network.IPNet.Mask) > 0 {
|
|
|
|
peer.IP = conf.MustAllocateIP()
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(conf.Network6.IPNet.Mask) > 0 {
|
|
|
|
peer.IP6 = conf.MustAllocateIP6()
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(conf.IP) == 0 && len(conf.IP6) == 0 {
|
|
|
|
ExitFail("No IPv4 or IPv6 network defined in config")
|
|
|
|
}
|
|
|
|
|
2020-03-02 04:08:28 +01:00
|
|
|
conf.MustAddPeer(peer)
|
2020-03-03 22:28:06 +01:00
|
|
|
PrintPeerCfg(peer, conf)
|
2020-03-02 04:08:28 +01:00
|
|
|
conf.MustSave()
|
2020-03-05 21:43:31 +01:00
|
|
|
ConfigureDevice(conf)
|
2020-03-02 01:45:14 +01:00
|
|
|
}
|
2020-03-02 20:57:52 +01:00
|
|
|
|
2020-03-03 22:28:06 +01:00
|
|
|
func PrintPeerCfg(peer PeerConfig, conf *DsnetConfig) {
|
2020-10-19 01:04:05 +02:00
|
|
|
var peerConf string
|
2020-03-02 20:57:52 +01:00
|
|
|
|
2020-10-19 01:04:05 +02:00
|
|
|
switch os.Getenv("DSNET_OUTPUT") {
|
|
|
|
// https://manpages.debian.org/unstable/wireguard-tools/wg-quick.8.en.html
|
|
|
|
case "", "wg-quick":
|
|
|
|
peerConf = wgQuickPeerConf
|
|
|
|
// https://github.com/WireGuard/wireguard-vyatta-ubnt/
|
|
|
|
case "vyatta":
|
|
|
|
peerConf = vyattaPeerConf
|
|
|
|
default:
|
|
|
|
ExitFail("Unrecognised DSNET_OUTPUT type")
|
|
|
|
}
|
2020-03-03 22:28:06 +01:00
|
|
|
|
2020-10-27 00:37:19 +01:00
|
|
|
cidrSize, _ := conf.Network.IPNet.Mask.Size()
|
|
|
|
cidrSize6, _ := conf.Network6.IPNet.Mask.Size()
|
2020-10-19 01:27:39 +02:00
|
|
|
|
2020-03-03 22:28:06 +01:00
|
|
|
t := template.Must(template.New("peerConf").Parse(peerConf))
|
|
|
|
err := t.Execute(os.Stdout, map[string]interface{}{
|
|
|
|
"Peer": peer,
|
|
|
|
"DsnetConfig": conf,
|
2020-03-07 15:36:14 +01:00
|
|
|
"Keepalive": time.Duration(KEEPALIVE).Seconds(),
|
2020-10-27 00:37:19 +01:00
|
|
|
"CidrSize": cidrSize,
|
|
|
|
"CidrSize6": cidrSize6,
|
2020-03-03 22:28:06 +01:00
|
|
|
})
|
|
|
|
check(err)
|
2020-03-02 20:57:52 +01:00
|
|
|
}
|