Compare commits

...

3 Commits

Author SHA1 Message Date
Christoph Haas
e0968b3239 support AllowIPs for peers in server config (#24) 2021-06-18 14:13:44 +02:00
Christoph Haas
e1db939a18 update readme to clarify some things 2021-06-18 14:12:22 +02:00
Christoph Haas
92d09535bc fix foreign key problem (#23) 2021-06-08 16:17:30 +02:00
7 changed files with 37 additions and 14 deletions

View File

@@ -9,11 +9,11 @@
[![Docker Pulls](https://img.shields.io/docker/pulls/h44z/wg-portal.svg)](https://hub.docker.com/r/h44z/wg-portal/) [![Docker Pulls](https://img.shields.io/docker/pulls/h44z/wg-portal.svg)](https://hub.docker.com/r/h44z/wg-portal/)
A simple, web based configuration portal for [WireGuard](https://wireguard.com). A simple, web based configuration portal for [WireGuard](https://wireguard.com).
The portal uses the WireGuard [wgctrl](https://github.com/WireGuard/wgctrl-go) library to manage the VPN The portal uses the WireGuard [wgctrl](https://github.com/WireGuard/wgctrl-go) library to manage existing VPN
interface. This allows for seamless activation or deactivation of new users, without disturbing existing VPN interfaces. This allows for seamless activation or deactivation of new users, without disturbing existing VPN
connections. connections.
The configuration portal currently supports using SQLite, MySQL as a user source for authentication and profile data. The configuration portal currently supports using SQLite and MySQL as a user source for authentication and profile data.
It also supports LDAP (Active Directory or OpenLDAP) as authentication provider. It also supports LDAP (Active Directory or OpenLDAP) as authentication provider.
## Features ## Features
@@ -35,6 +35,8 @@ It also supports LDAP (Active Directory or OpenLDAP) as authentication provider.
![Screenshot](screenshot.png) ![Screenshot](screenshot.png)
## Setup ## Setup
Make sure that your host system has at least one WireGuard interface (for example wg0) available.
If you did not start up a WireGuard interface yet, take a look at [wg-quick](https://manpages.debian.org/unstable/wireguard-tools/wg-quick.8.en.html) in order to get started.
### Docker ### Docker
The easiest way to run WireGuard Portal is to use the Docker image provided. The easiest way to run WireGuard Portal is to use the Docker image provided.
@@ -81,7 +83,7 @@ services:
- LDAP_ADMIN_GROUP=CN=WireGuardAdmins,OU=Users,DC=COMPANY,DC=LOCAL - LDAP_ADMIN_GROUP=CN=WireGuardAdmins,OU=Users,DC=COMPANY,DC=LOCAL
``` ```
Please note that mapping ```/etc/wireguard``` to ```/etc/wireguard``` inside the docker, will erase your host's current configuration. Please note that mapping ```/etc/wireguard``` to ```/etc/wireguard``` inside the docker, will erase your host's current configuration.
If needed, please make sure to backup your files from ```/etc/wireguard```. If needed, please make sure to back up your files from ```/etc/wireguard```.
For a full list of configuration options take a look at the source file [internal/server/configuration.go](internal/server/configuration.go#L56). For a full list of configuration options take a look at the source file [internal/server/configuration.go](internal/server/configuration.go#L56).
### Standalone ### Standalone
@@ -200,10 +202,10 @@ The API is documented using OpenAPI 2.0, the Swagger UI can be found
under the URL `http://<your wg-portal ip/domain>/swagger/index.html`. under the URL `http://<your wg-portal ip/domain>/swagger/index.html`.
## What is out of scope ## What is out of scope
* Creating or removing WireGuard (wgX) interfaces.
* Generation or application of any `iptables` or `nftables` rules * Generation or application of any `iptables` or `nftables` rules.
* Setting up or changing IP-addresses of the WireGuard interface on operating systems other than linux * Setting up or changing IP-addresses of the WireGuard interface on operating systems other than linux.
* Importing private keys of an existing WireGuard setup * Importing private keys of an existing WireGuard setup.
## Application stack ## Application stack

View File

@@ -82,6 +82,12 @@
<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-group col-md-12">
<label for="server_AllowedIPSrv">Extra Allowed IPs (Server sided)</label>
<input type="text" name="allowedipSrv" class="form-control" id="server_AllowedIPSrv" value="{{.Peer.AllowedIPsSrvStr}}">
</div>
</div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12 global-config"> <div class="form-group col-md-12 global-config">
<label for="server_DNS">Client DNS Servers</label> <label for="server_DNS">Client DNS Servers</label>

View File

@@ -29,6 +29,13 @@ func init() {
return nil return nil
}, },
}) })
migrations = append(migrations, Migration{
version: "1.0.8",
migrateFn: func(db *gorm.DB) error {
logrus.Infof("upgraded database format to version 1.0.8")
return nil
},
})
} }
type SupportedDatabase string type SupportedDatabase string

View File

@@ -64,6 +64,7 @@ func (s *Server) PostAdminEditPeer(c *gin.Context) {
// Clean list input // Clean list input
formPeer.IPsStr = common.ListToString(common.ParseStringList(formPeer.IPsStr)) formPeer.IPsStr = common.ListToString(common.ParseStringList(formPeer.IPsStr))
formPeer.AllowedIPsStr = common.ListToString(common.ParseStringList(formPeer.AllowedIPsStr)) formPeer.AllowedIPsStr = common.ListToString(common.ParseStringList(formPeer.AllowedIPsStr))
formPeer.AllowedIPsSrvStr = common.ListToString(common.ParseStringList(formPeer.AllowedIPsSrvStr))
disabled := c.PostForm("isdisabled") != "" disabled := c.PostForm("isdisabled") != ""
now := time.Now() now := time.Now()
@@ -121,6 +122,7 @@ func (s *Server) PostAdminCreatePeer(c *gin.Context) {
// Clean list input // Clean list input
formPeer.IPsStr = common.ListToString(common.ParseStringList(formPeer.IPsStr)) formPeer.IPsStr = common.ListToString(common.ParseStringList(formPeer.IPsStr))
formPeer.AllowedIPsStr = common.ListToString(common.ParseStringList(formPeer.AllowedIPsStr)) formPeer.AllowedIPsStr = common.ListToString(common.ParseStringList(formPeer.AllowedIPsStr))
formPeer.AllowedIPsSrvStr = common.ListToString(common.ParseStringList(formPeer.AllowedIPsSrvStr))
disabled := c.PostForm("isdisabled") != "" disabled := c.PostForm("isdisabled") != ""
now := time.Now() now := time.Now()

View File

@@ -1,4 +1,4 @@
package server package server
var Version = "testbuild" var Version = "testbuild"
var DatabaseVersion = "1.0.7" var DatabaseVersion = "1.0.8"

View File

@@ -64,7 +64,6 @@ func init() {
type Peer struct { type Peer struct {
Peer *wgtypes.Peer `gorm:"-" json:"-"` // WireGuard peer Peer *wgtypes.Peer `gorm:"-" json:"-"` // WireGuard peer
Device *Device `gorm:"foreignKey:DeviceName" binding:"-" json:"-"` // linked WireGuard device
Config string `gorm:"-" json:"-"` Config string `gorm:"-" json:"-"`
UID string `form:"uid" binding:"required,alphanum" json:"-"` // uid for html identification UID string `form:"uid" binding:"required,alphanum" json:"-"` // uid for html identification
@@ -83,6 +82,7 @@ type Peer struct {
PublicKey string `gorm:"primaryKey" form:"pubkey" binding:"required,base64"` // the public key of the peer itself 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
AllowedIPsSrvStr string `form:"allowedipSrv" binding:"cidrlist"` // a comma separated list of IPs that are used in the server 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"`
@@ -124,6 +124,10 @@ func (p Peer) GetAllowedIPs() []string {
return common.ParseStringList(p.AllowedIPsStr) return common.ParseStringList(p.AllowedIPsStr)
} }
func (p Peer) GetAllowedIPsSrv() []string {
return common.ParseStringList(p.AllowedIPsSrvStr)
}
func (p Peer) GetConfig(dev *Device) wgtypes.PeerConfig { func (p Peer) GetConfig(dev *Device) wgtypes.PeerConfig {
publicKey, _ := wgtypes.ParseKey(p.PublicKey) publicKey, _ := wgtypes.ParseKey(p.PublicKey)
@@ -154,6 +158,7 @@ func (p Peer) GetConfig(dev *Device) wgtypes.PeerConfig {
peerAllowedIPs = p.GetAllowedIPs() peerAllowedIPs = p.GetAllowedIPs()
case DeviceTypeServer: case DeviceTypeServer:
peerAllowedIPs = p.GetIPAddresses() peerAllowedIPs = p.GetIPAddresses()
peerAllowedIPs = append(peerAllowedIPs, p.GetAllowedIPsSrv()...)
} }
for _, ip := range peerAllowedIPs { for _, ip := range peerAllowedIPs {
_, ipNet, err := net.ParseCIDR(ip) _, ipNet, err := net.ParseCIDR(ip)
@@ -236,6 +241,7 @@ const (
type Device struct { type Device struct {
Interface *wgtypes.Device `gorm:"-" json:"-"` Interface *wgtypes.Device `gorm:"-" json:"-"`
Peers []Peer `gorm:"foreignKey:DeviceName" binding:"-" json:"-"` // linked WireGuard peers
Type DeviceType `form:"devicetype" binding:"required,oneof=client server"` Type DeviceType `form:"devicetype" binding:"required,oneof=client server"`
DeviceName string `form:"device" gorm:"primaryKey" binding:"required,alphanum"` DeviceName string `form:"device" gorm:"primaryKey" binding:"required,alphanum"`
@@ -375,7 +381,7 @@ func NewPeerManager(db *gorm.DB, wg *Manager) (*PeerManager, error) {
} }
} }
if err := pm.db.AutoMigrate(&Peer{}, &Device{}); err != nil { if err := pm.db.AutoMigrate(&Device{}, &Peer{}); err != nil {
return nil, errors.WithMessage(err, "failed to migrate peer database") return nil, errors.WithMessage(err, "failed to migrate peer database")
} }

View File

@@ -61,7 +61,7 @@ PublicKey = {{ .PublicKey }}
PresharedKey = {{ .PresharedKey }} PresharedKey = {{ .PresharedKey }}
{{- end}} {{- end}}
{{- if eq $.Interface.Type "server"}} {{- if eq $.Interface.Type "server"}}
AllowedIPs = {{ .IPsStr }} AllowedIPs = {{ .IPsStr }}{{if ne .AllowedIPsSrvStr ""}}, {{ .AllowedIPsSrvStr }}{{end}}
{{- end}} {{- end}}
{{- if eq $.Interface.Type "client"}} {{- if eq $.Interface.Type "client"}}
{{- if .AllowedIPsStr}} {{- if .AllowedIPsStr}}