mirror of
https://github.com/DJSundog/wg-portal.git
synced 2024-11-27 00:53:51 -05:00
WIP: support different interface types: update config templates
This commit is contained in:
parent
aa17303cec
commit
3bfcbe0209
@ -26,6 +26,9 @@
|
|||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<input type="hidden" name="_csrf" value="{{.Csrf}}">
|
<input type="hidden" name="_csrf" value="{{.Csrf}}">
|
||||||
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
||||||
|
<input type="hidden" name="devicetype" value="{{.Device.Type}}">
|
||||||
|
<input type="hidden" name="device" value="{{.Device.DeviceName}}">
|
||||||
|
<input type="hidden" name="endpointpubkey" value="{{.Device.PublicKey}}">
|
||||||
{{if .EditableKeys}}
|
{{if .EditableKeys}}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
@ -74,22 +77,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="server_AllowedIP">Allowed IPs</label>
|
<label for="server_AllowedIP">Allowed IPs</label>
|
||||||
<input type="text" name="allowedip" class="form-control" id="server_AllowedIP" value="{{.Peer.AllowedIPsStr}}">
|
<input type="text" name="allowedip" class="form-control" id="server_AllowedIP" value="{{.Peer.AllowedIPsStr}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="server_DNS">Client DNS Servers</label>
|
<label for="server_DNS">Client DNS Servers</label>
|
||||||
<input type="text" name="dns" class="form-control" id="server_DNS" value="{{.Peer.DNSStr}}">
|
<input type="text" name="dns" class="form-control" id="server_DNS" value="{{.Peer.DNSStr}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-6">
|
||||||
<label for="server_PersistentKeepalive">Persistent Keepalive</label>
|
<label for="server_PersistentKeepalive">Persistent Keepalive</label>
|
||||||
<input type="number" name="keepalive" class="form-control" id="server_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}">
|
<input type="number" name="keepalive" class="form-control" id="server_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="server_MTU">Client MTU</label>
|
||||||
|
<input type="number" name="mtu" class="form-control" id="server_MTU" placeholder="0" value="{{.Peer.MTU}}">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -127,6 +134,8 @@
|
|||||||
<input type="hidden" name="_csrf" value="{{.Csrf}}">
|
<input type="hidden" name="_csrf" value="{{.Csrf}}">
|
||||||
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
||||||
<input type="hidden" name="mail" value="{{.AdminEmail}}">
|
<input type="hidden" name="mail" value="{{.AdminEmail}}">
|
||||||
|
<input type="hidden" name="devicetype" value="{{.Device.Type}}">
|
||||||
|
<input type="hidden" name="device" value="{{.Device.DeviceName}}">
|
||||||
{{if .EditableKeys}}
|
{{if .EditableKeys}}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
@ -136,7 +145,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group required col-md-12">
|
||||||
<label for="client_PublicKey">Public Key</label>
|
<label for="client_PublicKey">Peer Public Key</label>
|
||||||
<input type="text" name="pubkey" class="form-control" id="client_PublicKey" value="{{.Peer.PublicKey}}">
|
<input type="text" name="pubkey" class="form-control" id="client_PublicKey" value="{{.Peer.PublicKey}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -170,12 +179,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group required col-md-12">
|
||||||
|
<label for="client_EndpointPublicKey">Endpoint Public Key</label>
|
||||||
|
<input type="text" name="endpointpubkey" class="form-control" id="client_EndpointPublicKey" value="{{.Peer.EndpointPublicKey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-12">
|
||||||
<label for="client_AllowedIP">Allowed IPs</label>
|
<label for="client_AllowedIP">Allowed IPs</label>
|
||||||
<input type="text" name="allowedip" class="form-control" id="client_AllowedIP" value="{{.Peer.AllowedIPsStr}}">
|
<input type="text" name="allowedip" class="form-control" id="client_AllowedIP" value="{{.Peer.AllowedIPsStr}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="client_PersistentKeepalive">Persistent Keepalive</label>
|
<label for="client_PersistentKeepalive">Persistent Keepalive</label>
|
||||||
<input type="number" name="keepalive" class="form-control" id="client_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}">
|
<input type="number" name="keepalive" class="form-control" id="client_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}">
|
||||||
</div>
|
</div>
|
||||||
@ -209,6 +224,8 @@
|
|||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<input type="hidden" name="_csrf" value="{{.Csrf}}">
|
<input type="hidden" name="_csrf" value="{{.Csrf}}">
|
||||||
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
<input type="hidden" name="uid" value="{{.Peer.UID}}">
|
||||||
|
<input type="hidden" name="devicetype" value="{{.Device.Type}}">
|
||||||
|
<input type="hidden" name="device" value="{{.Device.DeviceName}}">
|
||||||
{{if .EditableKeys}}
|
{{if .EditableKeys}}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
@ -251,34 +268,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="custom_Endpoint">Endpoint Address</label>
|
<label for="custom_Endpoint">Endpoint Address</label>
|
||||||
<input type="text" name="endpoint" class="form-control" id="custom_Endpoint" value="{{.Peer.Endpoint}}">
|
<input type="text" name="endpoint" class="form-control" id="custom_Endpoint" value="{{.Peer.Endpoint}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group required col-md-12">
|
||||||
|
<label for="custom_EndpointPublicKey">Endpoint Public Key</label>
|
||||||
|
<input type="text" name="endpointpubkey" class="form-control" id="custom_EndpointPublicKey" value="{{.Peer.EndpointPublicKey}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-12">
|
||||||
<label for="custom_IP">Peer IP Address</label>
|
<label for="custom_IP">Peer IP Address</label>
|
||||||
<input type="text" name="ip" class="form-control" id="custom_IP" value="{{.Peer.IPsStr}}">
|
<input type="text" name="ip" class="form-control" id="custom_IP" value="{{.Peer.IPsStr}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="custom_AllowedIP">Allowed IPs</label>
|
<label for="custom_AllowedIP">Allowed IPs</label>
|
||||||
<input type="text" name="allowedip" class="form-control" id="custom_AllowedIP" value="{{.Peer.AllowedIPsStr}}">
|
<input type="text" name="allowedip" class="form-control" id="custom_AllowedIP" value="{{.Peer.AllowedIPsStr}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="custom_DNS">Peer DNS Servers</label>
|
<label for="custom_DNS">Peer DNS Servers</label>
|
||||||
<input type="text" name="dns" class="form-control" id="custom_DNS" value="{{.Peer.DNSStr}}">
|
<input type="text" name="dns" class="form-control" id="custom_DNS" value="{{.Peer.DNSStr}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group required col-md-12">
|
<div class="form-group col-md-6">
|
||||||
<label for="custom_PersistentKeepalive">Persistent Keepalive</label>
|
<label for="custom_PersistentKeepalive">Persistent Keepalive</label>
|
||||||
<input type="number" name="keepalive" class="form-control" id="custom_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}">
|
<input type="number" name="keepalive" class="form-control" id="custom_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="custom_MTU">Client MTU</label>
|
||||||
|
<input type="number" name="mtu" class="form-control" id="custom_MTU" placeholder="0" value="{{.Peer.MTU}}">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
@ -264,7 +264,7 @@
|
|||||||
<label for="custom_ListenPort">Listen port</label>
|
<label for="custom_ListenPort">Listen port</label>
|
||||||
<input type="number" name="port" class="form-control" id="custom_ListenPort" placeholder="51820" value="{{.Device.ListenPort}}">
|
<input type="number" name="port" class="form-control" id="custom_ListenPort" placeholder="51820" value="{{.Device.ListenPort}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group required col-md-6">
|
||||||
<label for="custom_IPs">Interface IP address</label>
|
<label for="custom_IPs">Interface IP address</label>
|
||||||
<input type="text" name="ip" class="form-control" id="custom_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}">
|
<input type="text" name="ip" class="form-control" id="custom_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}">
|
||||||
</div>
|
</div>
|
||||||
|
4
go.mod
4
go.mod
@ -6,7 +6,7 @@ require (
|
|||||||
github.com/gin-contrib/sessions v0.0.3
|
github.com/gin-contrib/sessions v0.0.3
|
||||||
github.com/gin-gonic/gin v1.6.3
|
github.com/gin-gonic/gin v1.6.3
|
||||||
github.com/go-ldap/ldap/v3 v3.2.4
|
github.com/go-ldap/ldap/v3 v3.2.4
|
||||||
github.com/go-playground/validator/v10 v10.2.0
|
github.com/go-playground/validator/v10 v10.4.1
|
||||||
github.com/gorilla/sessions v1.2.1 // indirect
|
github.com/gorilla/sessions v1.2.1 // indirect
|
||||||
github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible
|
github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible
|
||||||
github.com/kelseyhightower/envconfig v1.4.0
|
github.com/kelseyhightower/envconfig v1.4.0
|
||||||
@ -17,7 +17,7 @@ require (
|
|||||||
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
|
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
|
||||||
github.com/toorop/gin-logrus v0.0.0-20200831135515-d2ee50d38dae
|
github.com/toorop/gin-logrus v0.0.0-20200831135515-d2ee50d38dae
|
||||||
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca
|
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||||
gorm.io/driver/mysql v1.0.4
|
gorm.io/driver/mysql v1.0.4
|
||||||
|
@ -7,13 +7,13 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/h44z/wg-portal/internal/common"
|
"github.com/h44z/wg-portal/internal/common"
|
||||||
@ -42,7 +42,6 @@ var cidrList validator.Func = func(fl validator.FieldLevel) bool {
|
|||||||
|
|
||||||
var ipList validator.Func = func(fl validator.FieldLevel) bool {
|
var ipList validator.Func = func(fl validator.FieldLevel) bool {
|
||||||
ipListStr := fl.Field().String()
|
ipListStr := fl.Field().String()
|
||||||
|
|
||||||
ipList := common.ParseStringList(ipListStr)
|
ipList := common.ParseStringList(ipListStr)
|
||||||
for i := range ipList {
|
for i := range ipList {
|
||||||
ip := net.ParseIP(ipList[i])
|
ip := net.ParseIP(ipList[i])
|
||||||
@ -66,13 +65,14 @@ func init() {
|
|||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
Peer *wgtypes.Peer `gorm:"-"` // WireGuard peer
|
Peer *wgtypes.Peer `gorm:"-"` // WireGuard peer
|
||||||
Device *Device `gorm:"foreignKey:DeviceName"` // linked WireGuard device
|
Device *Device `gorm:"foreignKey:DeviceName" binding:"-"` // linked WireGuard device
|
||||||
Config string `gorm:"-"`
|
Config string `gorm:"-"`
|
||||||
|
|
||||||
UID string `form:"uid" binding:"alphanum"` // uid for html identification
|
UID string `form:"uid" binding:"required,alphanum"` // uid for html identification
|
||||||
DeviceName string `gorm:"index"`
|
DeviceName string `gorm:"index" form:"device" binding:"required"`
|
||||||
|
DeviceType DeviceType `gorm:"-" form:"devicetype" binding:"required,oneof=client server custom"`
|
||||||
Identifier string `form:"identifier" binding:"required,max=64"` // Identifier AND Email make a WireGuard peer unique
|
Identifier string `form:"identifier" binding:"required,max=64"` // Identifier AND Email make a WireGuard peer unique
|
||||||
Email string `gorm:"index" form:"mail" binding:"omitempty,email"`
|
Email string `gorm:"index" form:"mail" binding:"required,email"`
|
||||||
IgnoreGlobalSettings bool `form:"ignoreglobalsettings"`
|
IgnoreGlobalSettings bool `form:"ignoreglobalsettings"`
|
||||||
|
|
||||||
IsOnline bool `gorm:"-"`
|
IsOnline bool `gorm:"-"`
|
||||||
@ -81,16 +81,19 @@ type Peer struct {
|
|||||||
LastHandshakeTime string `gorm:"-"`
|
LastHandshakeTime string `gorm:"-"`
|
||||||
|
|
||||||
// Core WireGuard Settings
|
// Core WireGuard Settings
|
||||||
PublicKey string `gorm:"primaryKey" form:"pubkey" binding:"required,base64"`
|
PublicKey string `gorm:"primaryKey" form:"pubkey" binding:"required,base64"` // the public key of the peer itself
|
||||||
PresharedKey string `form:"presharedkey" binding:"omitempty,base64"`
|
PresharedKey string `form:"presharedkey" binding:"omitempty,base64"`
|
||||||
AllowedIPsStr string `form:"allowedip" binding:"cidrlist"` // a comma separated list of IPs that are used in the client config file
|
AllowedIPsStr string `form:"allowedip" binding:"cidrlist"` // a comma separated list of IPs that are used in the client config file
|
||||||
Endpoint string `form:"endpoint" binding:"omitempty,hostname_port"`
|
Endpoint string `form:"endpoint" binding:"omitempty,hostname_port"`
|
||||||
PersistentKeepalive int `form:"keepalive" binding:"gte=0"`
|
PersistentKeepalive int `form:"keepalive" binding:"gte=0"`
|
||||||
|
|
||||||
// Misc. WireGuard Settings
|
// Misc. WireGuard Settings
|
||||||
|
EndpointPublicKey string `form:"endpointpubkey" binding:"required,base64"` // the public key of the remote endpoint
|
||||||
PrivateKey string `form:"privkey" binding:"omitempty,base64"`
|
PrivateKey string `form:"privkey" binding:"omitempty,base64"`
|
||||||
IPsStr string `form:"ip" binding:"cidrlist"` // a comma separated list of IPs of the client
|
IPsStr string `form:"ip" binding:"cidrlist,required_if=devicetype server"` // a comma separated list of IPs of the client
|
||||||
DNSStr string `form:"dns" binding:"iplist"` // comma separated list of the DNS servers for the client
|
DNSStr string `form:"dns" binding:"iplist"` // comma separated list of the DNS servers for the client
|
||||||
|
// Global Device Settings (can be ignored, only make sense if device is in server mode)
|
||||||
|
Mtu int `form:"mtu" binding:"gte=0,lte=1500"`
|
||||||
|
|
||||||
DeactivatedAt *time.Time
|
DeactivatedAt *time.Time
|
||||||
CreatedBy string
|
CreatedBy string
|
||||||
@ -131,40 +134,49 @@ func (p Peer) GetConfig() wgtypes.PeerConfig {
|
|||||||
presharedKey = &presharedKeyTmp
|
presharedKey = &presharedKeyTmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var endpoint *net.UDPAddr
|
||||||
|
if p.Endpoint != "" {
|
||||||
|
addr, err := net.ResolveUDPAddr("udp", p.Endpoint)
|
||||||
|
if err == nil {
|
||||||
|
endpoint = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var keepAlive *time.Duration
|
||||||
|
if p.PersistentKeepalive != 0 {
|
||||||
|
keepAliveDuration := time.Duration(p.PersistentKeepalive) * time.Second
|
||||||
|
keepAlive = &keepAliveDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
peerAllowedIPs := p.GetAllowedIPs()
|
||||||
|
allowedIPs := make([]net.IPNet, len(peerAllowedIPs))
|
||||||
|
for i, ip := range peerAllowedIPs {
|
||||||
|
_, ipNet, err := net.ParseCIDR(ip)
|
||||||
|
if err == nil {
|
||||||
|
allowedIPs[i] = *ipNet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cfg := wgtypes.PeerConfig{
|
cfg := wgtypes.PeerConfig{
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
Remove: false,
|
Remove: false,
|
||||||
UpdateOnly: false,
|
UpdateOnly: false,
|
||||||
PresharedKey: presharedKey,
|
PresharedKey: presharedKey,
|
||||||
Endpoint: nil,
|
Endpoint: endpoint,
|
||||||
PersistentKeepaliveInterval: nil,
|
PersistentKeepaliveInterval: keepAlive,
|
||||||
ReplaceAllowedIPs: true,
|
ReplaceAllowedIPs: true,
|
||||||
AllowedIPs: make([]net.IPNet, len(p.GetIPAddresses())),
|
AllowedIPs: allowedIPs,
|
||||||
}
|
|
||||||
for i, ip := range p.GetIPAddresses() {
|
|
||||||
_, ipNet, err := net.ParseCIDR(ip)
|
|
||||||
if err == nil {
|
|
||||||
cfg.AllowedIPs[i] = *ipNet
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Peer) GetConfigFile(device Device) ([]byte, error) {
|
func (p Peer) GetConfigFile(device Device) ([]byte, error) {
|
||||||
tpl, err := template.New("client").Funcs(template.FuncMap{"StringsJoin": strings.Join}).Parse(ClientCfgTpl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to parse client template")
|
|
||||||
}
|
|
||||||
|
|
||||||
var tplBuff bytes.Buffer
|
var tplBuff bytes.Buffer
|
||||||
|
|
||||||
err = tpl.Execute(&tplBuff, struct {
|
err := templateCache.ExecuteTemplate(&tplBuff, "peer.tpl", gin.H{
|
||||||
Client Peer
|
"Peer": p,
|
||||||
Server Device
|
"Interface": device,
|
||||||
}{
|
|
||||||
Client: p,
|
|
||||||
Server: device,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to execute client template")
|
return nil, errors.Wrap(err, "failed to execute client template")
|
||||||
@ -192,26 +204,6 @@ func (p Peer) IsValid() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Peer) ToMap() map[string]string {
|
|
||||||
out := make(map[string]string)
|
|
||||||
|
|
||||||
v := reflect.ValueOf(p)
|
|
||||||
if v.Kind() == reflect.Ptr {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
typ := v.Type()
|
|
||||||
for i := 0; i < v.NumField(); i++ {
|
|
||||||
// gets us a StructField
|
|
||||||
fi := typ.Field(i)
|
|
||||||
if tagv := fi.Tag.Get("form"); tagv != "" {
|
|
||||||
// set key of map to value in struct field
|
|
||||||
out[tagv] = v.Field(i).String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Peer) GetConfigFileName() string {
|
func (p Peer) GetConfigFileName() string {
|
||||||
reg := regexp.MustCompile("[^a-zA-Z0-9_-]+")
|
reg := regexp.MustCompile("[^a-zA-Z0-9_-]+")
|
||||||
return reg.ReplaceAllString(strings.ReplaceAll(p.Identifier, " ", "-"), "") + ".conf"
|
return reg.ReplaceAllString(strings.ReplaceAll(p.Identifier, " ", "-"), "") + ".conf"
|
||||||
@ -238,7 +230,7 @@ type Device struct {
|
|||||||
|
|
||||||
// Core WireGuard Settings (Interface section)
|
// Core WireGuard Settings (Interface section)
|
||||||
PrivateKey string `form:"privkey" binding:"required,base64"`
|
PrivateKey string `form:"privkey" binding:"required,base64"`
|
||||||
ListenPort int `form:"port" binding:"gt=0,lt=65535"`
|
ListenPort int `form:"port" binding:"omitempty,gt=0,lt=65535,required_if=devicetype server"`
|
||||||
FirewallMark int32 `form:"firewallmark" binding:"gte=0"`
|
FirewallMark int32 `form:"firewallmark" binding:"gte=0"`
|
||||||
// Misc. WireGuard Settings
|
// Misc. WireGuard Settings
|
||||||
PublicKey string `form:"pubkey" binding:"required,base64"`
|
PublicKey string `form:"pubkey" binding:"required,base64"`
|
||||||
@ -253,7 +245,7 @@ type Device struct {
|
|||||||
SaveConfig bool `form:"saveconfig"` // if set to `true', the configuration is saved from the current state of the interface upon shutdown, wg-quick addition
|
SaveConfig bool `form:"saveconfig"` // if set to `true', the configuration is saved from the current state of the interface upon shutdown, wg-quick addition
|
||||||
|
|
||||||
// Settings that are applied to all peer by default
|
// Settings that are applied to all peer by default
|
||||||
DefaultEndpoint string `form:"endpoint" binding:"omitempty,hostname_port"`
|
DefaultEndpoint string `form:"endpoint" binding:"omitempty,hostname_port,required_if=devicetype server"`
|
||||||
DefaultAllowedIPsStr string `form:"allowedip" binding:"cidrlist"` // comma separated list of IPs that are used in the client config file
|
DefaultAllowedIPsStr string `form:"allowedip" binding:"cidrlist"` // comma separated list of IPs that are used in the client config file
|
||||||
DefaultPersistentKeepalive int `form:"keepalive" binding:"gte=0"`
|
DefaultPersistentKeepalive int `form:"keepalive" binding:"gte=0"`
|
||||||
|
|
||||||
@ -317,28 +309,23 @@ func (d Device) GetConfig() wgtypes.Config {
|
|||||||
privateKey = &pKey
|
privateKey = &pKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fwMark := int(d.FirewallMark)
|
||||||
|
|
||||||
cfg := wgtypes.Config{
|
cfg := wgtypes.Config{
|
||||||
PrivateKey: privateKey,
|
PrivateKey: privateKey,
|
||||||
ListenPort: &d.ListenPort,
|
ListenPort: &d.ListenPort,
|
||||||
|
FirewallMark: &fwMark,
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Device) GetConfigFile(peers []Peer) ([]byte, error) {
|
func (d Device) GetConfigFile(peers []Peer) ([]byte, error) {
|
||||||
tpl, err := template.New("server").Funcs(template.FuncMap{"StringsJoin": strings.Join}).Parse(DeviceCfgTpl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to parse server template")
|
|
||||||
}
|
|
||||||
|
|
||||||
var tplBuff bytes.Buffer
|
var tplBuff bytes.Buffer
|
||||||
|
|
||||||
err = tpl.Execute(&tplBuff, struct {
|
err := templateCache.ExecuteTemplate(&tplBuff, "interface.tpl", gin.H{
|
||||||
Clients []Peer
|
"Peers": peers,
|
||||||
Server Device
|
"Interface": d,
|
||||||
}{
|
|
||||||
Clients: peers,
|
|
||||||
Server: d,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to execute server template")
|
return nil, errors.Wrap(err, "failed to execute server template")
|
||||||
|
@ -1,53 +1,20 @@
|
|||||||
package wireguard
|
package wireguard
|
||||||
|
|
||||||
var (
|
import (
|
||||||
ClientCfgTpl = `#{{ .Client.Identifier }}
|
"embed"
|
||||||
[Interface]
|
"html/template"
|
||||||
Address = {{ .Client.IPsStr }}
|
"strings"
|
||||||
PrivateKey = {{ .Client.PrivateKey }}
|
|
||||||
{{- if .Server.DNSStr}}
|
|
||||||
DNS = {{ .Server.DNSStr }}
|
|
||||||
{{- end}}
|
|
||||||
{{- if ne .Server.Mtu 0}}
|
|
||||||
MTU = {{.Server.Mtu}}
|
|
||||||
{{- end}}
|
|
||||||
|
|
||||||
[Peer]
|
|
||||||
PublicKey = {{ .Server.PublicKey }}
|
|
||||||
{{- if .Client.PresharedKey}}
|
|
||||||
PresharedKey = {{ .Client.PresharedKey }}
|
|
||||||
{{- end}}
|
|
||||||
AllowedIPs = {{ .Client.AllowedIPsStr }}
|
|
||||||
Endpoint = {{ .Server.Endpoint }}
|
|
||||||
{{- if and (ne .Server.PersistentKeepalive 0) (not .Client.IgnorePersistentKeepalive)}}
|
|
||||||
PersistentKeepalive = {{.Server.PersistentKeepalive}}
|
|
||||||
{{- end}}
|
|
||||||
`
|
|
||||||
DeviceCfgTpl = `# AUTOGENERATED FILE - DO NOT EDIT
|
|
||||||
# Updated: {{ .Server.UpdatedAt }} / Created: {{ .Server.CreatedAt }}
|
|
||||||
[Interface]
|
|
||||||
{{- range .Server.IPs}}
|
|
||||||
Address = {{ . }}
|
|
||||||
{{- end}}
|
|
||||||
ListenPort = {{ .Server.ListenPort }}
|
|
||||||
PrivateKey = {{ .Server.PrivateKey }}
|
|
||||||
{{- if ne .Server.Mtu 0}}
|
|
||||||
MTU = {{.Server.Mtu}}
|
|
||||||
{{- end}}
|
|
||||||
PreUp = {{ .Server.PreUp }}
|
|
||||||
PostUp = {{ .Server.PostUp }}
|
|
||||||
PreDown = {{ .Server.PreDown }}
|
|
||||||
PostDown = {{ .Server.PostDown }}
|
|
||||||
|
|
||||||
{{range .Clients}}
|
|
||||||
{{if not .DeactivatedAt -}}
|
|
||||||
# {{.Identifier}} / {{.Email}} / Updated: {{.UpdatedAt}} / Created: {{.CreatedAt}}
|
|
||||||
[Peer]
|
|
||||||
PublicKey = {{ .PublicKey }}
|
|
||||||
{{- if .PresharedKey}}
|
|
||||||
PresharedKey = {{ .PresharedKey }}
|
|
||||||
{{- end}}
|
|
||||||
AllowedIPs = {{ StringsJoin .IPs ", " }}
|
|
||||||
{{- end}}
|
|
||||||
{{end}}`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed tpl/*
|
||||||
|
var Templates embed.FS
|
||||||
|
|
||||||
|
var templateCache *template.Template
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
templateCache, err = template.New("server").Funcs(template.FuncMap{"StringsJoin": strings.Join}).ParseFS(Templates, "tpl/*.tpl")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
58
internal/wireguard/tpl/interface.tpl
Normal file
58
internal/wireguard/tpl/interface.tpl
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# AUTOGENERATED FILE - DO NOT EDIT
|
||||||
|
# -WGP- Interface: {{ .Interface.DeviceName }} / Updated: {{ .Interface.UpdatedAt }} / Created: {{ .Interface.CreatedAt }}
|
||||||
|
# -WGP- Interface display name: {{ .Interface.DisplayName }}
|
||||||
|
# -WGP- Interface mode: {{ .Interface.Type }}
|
||||||
|
# -WGP- PublicKey = {{ .Interface.PublicKey }}
|
||||||
|
|
||||||
|
[Interface]
|
||||||
|
|
||||||
|
# Core settings
|
||||||
|
PrivateKey = {{ .Interface.PrivateKey }}
|
||||||
|
Address = {{ .Interface.IPsStr }}
|
||||||
|
|
||||||
|
# Misc. settings
|
||||||
|
{{- if ne .Interface.ListenPort 0}}
|
||||||
|
ListenPort = {{ .Interface.ListenPort }}
|
||||||
|
{{- end}}
|
||||||
|
{{- if ne .Interface.Mtu 0}}
|
||||||
|
MTU = {{.Interface.Mtu}}
|
||||||
|
{{- end}}
|
||||||
|
{{- if ne .Interface.FirewallMark 0}}
|
||||||
|
FwMark = {{.Interface.FirewallMark}}
|
||||||
|
{{- end}}
|
||||||
|
{{- if ne .Interface.RoutingTable ""}}
|
||||||
|
Table = {{.Interface.RoutingTable}}
|
||||||
|
{{- end}}
|
||||||
|
{{- if .Interface.SaveConfig}}
|
||||||
|
SaveConfig = true
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
# Interface hooks
|
||||||
|
PreUp = {{ .Interface.PreUp }}
|
||||||
|
PostUp = {{ .Interface.PostUp }}
|
||||||
|
PreDown = {{ .Interface.PreDown }}
|
||||||
|
PostDown = {{ .Interface.PostDown }}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Peers
|
||||||
|
#
|
||||||
|
|
||||||
|
{{range .Peers}}
|
||||||
|
{{- if not .DeactivatedAt}}
|
||||||
|
# -WGP- Peer: {{.Identifier}} / Updated: {{.UpdatedAt}} / Created: {{.CreatedAt}}
|
||||||
|
# -WGP- Peer email: {{.Email}}
|
||||||
|
# -WGP- PrivateKey: {{.PrivateKey}}
|
||||||
|
[Peer]
|
||||||
|
PublicKey = {{ .PublicKey }}
|
||||||
|
{{- if .PresharedKey}}
|
||||||
|
PresharedKey = {{ .PresharedKey }}
|
||||||
|
{{- end}}
|
||||||
|
AllowedIPs = {{ .AllowedIPsStr }}
|
||||||
|
{{- if ne .Endpoint ""}}
|
||||||
|
Endpoint = {{ .Endpoint }}
|
||||||
|
{{- end}}
|
||||||
|
{{- if ne .PersistentKeepalive 0}}
|
||||||
|
PersistentKeepalive = {{ .PersistentKeepalive }}
|
||||||
|
{{- end}}
|
||||||
|
{{- end}}
|
||||||
|
{{end}}
|
28
internal/wireguard/tpl/peer.tpl
Normal file
28
internal/wireguard/tpl/peer.tpl
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# AUTOGENERATED FILE - PROVIDED BY WIREGUARD PORTAL
|
||||||
|
# WireGuard configuration: {{ .Peer.Identifier }}
|
||||||
|
# -WGP- PublicKey: {{ .Peer.PublicKey }}
|
||||||
|
|
||||||
|
[Interface]
|
||||||
|
|
||||||
|
# Core settings
|
||||||
|
PrivateKey = {{ .Peer.PrivateKey }}
|
||||||
|
Address = {{ .Peer.IPsStr }}
|
||||||
|
|
||||||
|
# Misc. settings
|
||||||
|
{{- if .Peer.DNSStr}}
|
||||||
|
DNS = {{ .Peer.DNSStr }}
|
||||||
|
{{- end}}
|
||||||
|
{{- if ne .Peer.Mtu 0}}
|
||||||
|
MTU = {{.Peer.Mtu}}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = {{ .Peer.EndpointPublicKey }}
|
||||||
|
Endpoint = {{ .Server.Endpoint }}
|
||||||
|
AllowedIPs = {{ .Peer.AllowedIPsStr }}
|
||||||
|
{{- if .Peer.PresharedKey}}
|
||||||
|
PresharedKey = {{ .Peer.PresharedKey }}
|
||||||
|
{{- end}}
|
||||||
|
{{- if ne .Peer.PersistentKeepalive 0}}
|
||||||
|
PersistentKeepalive = {{.Peer.PersistentKeepalive}}
|
||||||
|
{{- end}}
|
Loading…
Reference in New Issue
Block a user