mirror of
https://github.com/h44z/wg-portal.git
synced 2025-10-07 08:56:18 +00:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e0968b3239 | ||
|
e1db939a18 | ||
|
92d09535bc |
18
README.md
18
README.md
@@ -9,11 +9,11 @@
|
|||||||
[](https://hub.docker.com/r/h44z/wg-portal/)
|
[](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.
|
|||||||

|

|
||||||
|
|
||||||
## 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
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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
|
||||||
|
@@ -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()
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
var Version = "testbuild"
|
var Version = "testbuild"
|
||||||
var DatabaseVersion = "1.0.7"
|
var DatabaseVersion = "1.0.8"
|
||||||
|
@@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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}}
|
||||||
|
Reference in New Issue
Block a user