2021-05-26 00:48:04 +08:00
|
|
|
package serverctl
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"log"
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
"net"
|
|
|
|
"strconv"
|
|
|
|
"errors"
|
|
|
|
"github.com/vishvananda/netlink"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
"github.com/gravitl/netmaker/servercfg"
|
|
|
|
"github.com/gravitl/netmaker/functions"
|
|
|
|
"github.com/gravitl/netmaker/models"
|
|
|
|
"github.com/gravitl/netmaker/mongoconn"
|
|
|
|
)
|
|
|
|
|
|
|
|
func InitServerWireGuard() error {
|
|
|
|
|
|
|
|
created, err := CreateCommsNetwork()
|
|
|
|
if !created {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
wgconfig := servercfg.GetWGConfig()
|
|
|
|
if !(wgconfig.GRPCWireGuard == "on") {
|
|
|
|
return errors.New("WireGuard not enabled on this server.")
|
|
|
|
}
|
|
|
|
ifaceSettings := netlink.NewLinkAttrs()
|
|
|
|
|
|
|
|
if wgconfig.GRPCWGInterface == "" {
|
|
|
|
return errors.New("No WireGuard Interface Name set.")
|
|
|
|
}
|
|
|
|
ifaceSettings.Name = wgconfig.GRPCWGInterface
|
|
|
|
wglink := &models.WireGuardLink{LinkAttrs: &ifaceSettings}
|
|
|
|
|
|
|
|
err = netlink.LinkAdd(wglink)
|
|
|
|
if err != nil {
|
|
|
|
if os.IsExist(err) {
|
|
|
|
log.Println("interface " + ifaceSettings.Name + " already exists")
|
|
|
|
log.Println("continuing setup using existing interface")
|
|
|
|
} else {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2021-05-28 02:57:59 +08:00
|
|
|
address, err := netlink.ParseAddr(wgconfig.GRPCWGAddress + "/24")
|
2021-05-26 00:48:04 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = netlink.AddrAdd(wglink, address)
|
|
|
|
if err != nil {
|
|
|
|
if os.IsExist(err) {
|
|
|
|
log.Println("address " + wgconfig.GRPCWGAddress + " already exists")
|
|
|
|
log.Println("continuing with existing setup")
|
|
|
|
} else {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
err = netlink.LinkSetUp(wglink)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("could not bring up wireguard interface")
|
|
|
|
return err
|
|
|
|
}
|
2021-05-28 02:57:59 +08:00
|
|
|
var client models.IntClient
|
|
|
|
client.PrivateKey = wgconfig.GRPCWGPrivKey
|
|
|
|
client.PublicKey = wgconfig.GRPCWGPubKey
|
|
|
|
client.ServerEndpoint = wgconfig.GRPCWGEndpoint
|
|
|
|
client.ServerAddress = wgconfig.GRPCWGAddress
|
|
|
|
client.ServerPort = wgconfig.GRPCWGPort
|
|
|
|
client.Address = wgconfig.GRPCWGAddress
|
2021-05-26 00:48:04 +08:00
|
|
|
client.IsServer = "yes"
|
|
|
|
client.Network = "comms"
|
2021-05-30 01:24:13 +08:00
|
|
|
exists, _ := functions.ServerIntClientExists()
|
|
|
|
if exists {
|
|
|
|
|
|
|
|
}
|
2021-05-26 00:48:04 +08:00
|
|
|
err = RegisterServer(client)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-05-30 01:24:13 +08:00
|
|
|
func DeleteServerClient() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-28 02:57:59 +08:00
|
|
|
func RegisterServer(client models.IntClient) error {
|
2021-05-26 00:48:04 +08:00
|
|
|
if client.PrivateKey == "" {
|
|
|
|
privateKey, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
client.PrivateKey = privateKey.String()
|
|
|
|
client.PublicKey = privateKey.PublicKey().String()
|
|
|
|
}
|
|
|
|
|
|
|
|
if client.Address == "" {
|
2021-05-28 02:57:59 +08:00
|
|
|
newAddress, err := functions.UniqueAddress(client.Network)
|
2021-05-26 00:48:04 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-05-28 02:57:59 +08:00
|
|
|
if newAddress == "" {
|
|
|
|
return errors.New("Could not retrieve address")
|
|
|
|
}
|
|
|
|
client.Address = newAddress
|
2021-05-26 00:48:04 +08:00
|
|
|
}
|
|
|
|
if client.Network == "" { client.Network = "comms" }
|
|
|
|
client.ServerKey = client.PublicKey
|
|
|
|
|
2021-05-28 02:57:59 +08:00
|
|
|
collection := mongoconn.Client.Database("netmaker").Collection("intclients")
|
2021-05-26 00:48:04 +08:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
|
|
// insert our network into the network table
|
|
|
|
_, err := collection.InsertOne(ctx, client)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
ReconfigureServerWireGuard()
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReconfigureServerWireGuard() error {
|
|
|
|
server, err := GetServerWGConf()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
serverkey, err := wgtypes.ParseKey(server.PrivateKey)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
serverport, err := strconv.Atoi(servercfg.GetGRPCWGPort())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-05-28 02:57:59 +08:00
|
|
|
peers, err := functions.GetIntPeersList()
|
2021-05-26 00:48:04 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
wgserver, err := wgctrl.New()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
var serverpeers []wgtypes.PeerConfig
|
|
|
|
for _, peer := range peers {
|
|
|
|
|
|
|
|
pubkey, err := wgtypes.ParseKey(peer.PublicKey)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
var peercfg wgtypes.PeerConfig
|
|
|
|
var allowedips []net.IPNet
|
|
|
|
if peer.Address != "" {
|
|
|
|
var peeraddr = net.IPNet{
|
|
|
|
IP: net.ParseIP(peer.Address),
|
2021-05-30 01:22:18 +08:00
|
|
|
Mask: net.CIDRMask(32, 32),
|
2021-05-26 00:48:04 +08:00
|
|
|
}
|
|
|
|
allowedips = append(allowedips, peeraddr)
|
|
|
|
}
|
|
|
|
if peer.Address6 != "" {
|
|
|
|
var addr6 = net.IPNet{
|
|
|
|
IP: net.ParseIP(peer.Address6),
|
|
|
|
Mask: net.CIDRMask(128, 128),
|
|
|
|
}
|
|
|
|
allowedips = append(allowedips, addr6)
|
|
|
|
}
|
|
|
|
peercfg = wgtypes.PeerConfig{
|
|
|
|
PublicKey: pubkey,
|
|
|
|
ReplaceAllowedIPs: true,
|
|
|
|
AllowedIPs: allowedips,
|
|
|
|
}
|
|
|
|
serverpeers = append(serverpeers, peercfg)
|
|
|
|
}
|
|
|
|
|
|
|
|
wgconf := wgtypes.Config{
|
|
|
|
PrivateKey: &serverkey,
|
|
|
|
ListenPort: &serverport,
|
|
|
|
ReplacePeers: true,
|
|
|
|
Peers: serverpeers,
|
|
|
|
}
|
|
|
|
err = wgserver.ConfigureDevice(servercfg.GetGRPCWGInterface(), wgconf)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|