mirror of https://github.com/h44z/wg-portal.git
				
				
				
			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) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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}} | ||||||
|  | @ -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