mirror of
https://github.com/vx3r/wg-gen-web.git
synced 2024-12-18 00:13:23 +00:00
go fmt / badges
This commit is contained in:
parent
024d2b4ebb
commit
9b6d610a9c
@ -2,6 +2,13 @@
|
||||
|
||||
Simple Web based configuration generator for [WireGuard](https://wireguard.com).
|
||||
|
||||
---
|
||||
|
||||
<p align="left">
|
||||
<a href="https://goreportcard.com/report/github.com/vx3r/wg-gen-web"><img src="https://goreportcard.com/badge/github.com/vx3r/wg-gen-web" alt="Go Report Card"></a>
|
||||
<a href="https://gitlab.127-0-0-1.fr/vx3r/wg-gen-web/commits/master"><img src="https://gitlab.127-0-0-1.fr/vx3r/wg-gen-web/badges/master/pipeline.svg" alt="Gitlab CI / CD"></a>
|
||||
</p>
|
||||
|
||||
## Whay another one ?
|
||||
|
||||
All WireGuard UI implementation are trying to manage the WireGuard by applying configurations or creation network rules.
|
||||
|
24
api/api.go
24
api/api.go
@ -29,7 +29,6 @@ func ApplyRoutes(r *gin.Engine) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func createClient(c *gin.Context) {
|
||||
var data model.Client
|
||||
|
||||
@ -136,19 +135,18 @@ func configClient(c *gin.Context) {
|
||||
c.Header("Content-Disposition", "attachment; filename=wg0.conf")
|
||||
c.Data(http.StatusOK, "application/config", configData)
|
||||
return
|
||||
} else {
|
||||
// return config as png qrcode
|
||||
png, err := qrcode.Encode(string(configData), qrcode.Medium, 220)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"err": err,
|
||||
}).Error("failed to create qrcode")
|
||||
c.AbortWithStatus(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
c.Data(http.StatusOK, "image/png", png)
|
||||
}
|
||||
// return config as png qrcode
|
||||
png, err := qrcode.Encode(string(configData), qrcode.Medium, 220)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"err": err,
|
||||
}).Error("failed to create qrcode")
|
||||
c.AbortWithStatus(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
c.Data(http.StatusOK, "image/png", png)
|
||||
return
|
||||
}
|
||||
|
||||
func readServer(c *gin.Context) {
|
||||
@ -185,4 +183,4 @@ func updateServer(c *gin.Context) {
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, client)
|
||||
}
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -11,6 +11,5 @@ require (
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200114203027-fcfc50b29cbb
|
||||
)
|
||||
|
7
go.sum
7
go.sum
@ -39,10 +39,8 @@ github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdA
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0 h1:vySPY5Oxnn/8lxAPn2cK6kAzcZzYJl3KriSLO46OT18=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -70,16 +68,14 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -88,7 +84,6 @@ golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -2,15 +2,16 @@ package model
|
||||
|
||||
import "time"
|
||||
|
||||
// client structure
|
||||
type Client struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Enable bool `json:"enable"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
AllowedIPs string `json:"allowedIPs"`
|
||||
Address string `json:"address"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Enable bool `json:"enable"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
AllowedIPs string `json:"allowedIPs"`
|
||||
Address string `json:"address"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
}
|
||||
|
@ -2,16 +2,17 @@ package model
|
||||
|
||||
import "time"
|
||||
|
||||
// server structure
|
||||
type Server struct {
|
||||
Name string `json:"name"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Address string `json:"address"`
|
||||
ListenPort int `json:"listenPort"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
PresharedKey string `json:"presharedKey"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
PersistentKeepalive int `json:"persistentKeepalive"`
|
||||
Dns string `json:"dns"`
|
||||
Name string `json:"name"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Address string `json:"address"`
|
||||
ListenPort int `json:"listenPort"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
PresharedKey string `json:"presharedKey"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
PersistentKeepalive int `json:"persistentKeepalive"`
|
||||
Dns string `json:"dns"`
|
||||
}
|
||||
|
@ -16,6 +16,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
* Create client with all necessary data
|
||||
*/
|
||||
func CreateClient(client *model.Client) (*model.Client, error) {
|
||||
u := uuid.NewV4()
|
||||
client.Id = u.String()
|
||||
@ -37,10 +40,10 @@ func CreateClient(client *model.Client) (*model.Client, error) {
|
||||
for _, client := range clients {
|
||||
ips := strings.Split(client.Address, ",")
|
||||
for i := range ips {
|
||||
if util.IsIPv6(ips[i]){
|
||||
ips[i] = strings.ReplaceAll(strings.TrimSpace(ips[i]), "/128","")
|
||||
if util.IsIPv6(ips[i]) {
|
||||
ips[i] = strings.ReplaceAll(strings.TrimSpace(ips[i]), "/128", "")
|
||||
} else {
|
||||
ips[i] = strings.ReplaceAll(strings.TrimSpace(ips[i]), "/32","")
|
||||
ips[i] = strings.ReplaceAll(strings.TrimSpace(ips[i]), "/32", "")
|
||||
}
|
||||
}
|
||||
reserverIps = append(reserverIps, ips...)
|
||||
@ -56,7 +59,7 @@ func CreateClient(client *model.Client) (*model.Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if util.IsIPv6(ip){
|
||||
if util.IsIPv6(ip) {
|
||||
ip = ip + "/128"
|
||||
} else {
|
||||
ip = ip + "/32"
|
||||
@ -64,7 +67,7 @@ func CreateClient(client *model.Client) (*model.Client, error) {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
client.Address = strings.Join(ips, ",")
|
||||
|
||||
|
||||
client.Created = time.Now().UTC()
|
||||
client.Updated = client.Created
|
||||
|
||||
@ -82,6 +85,9 @@ func CreateClient(client *model.Client) (*model.Client, error) {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Read client by id
|
||||
*/
|
||||
func ReadClient(id string) (*model.Client, error) {
|
||||
v, err := deserialize(id)
|
||||
if err != nil {
|
||||
@ -92,6 +98,9 @@ func ReadClient(id string) (*model.Client, error) {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Get client config ion wg format
|
||||
*/
|
||||
func ReadClientConfig(id string) ([]byte, error) {
|
||||
client, err := ReadClient(id)
|
||||
if err != nil {
|
||||
@ -111,6 +120,9 @@ func ReadClientConfig(id string) ([]byte, error) {
|
||||
return configDataWg.Bytes(), nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Update client preserve keys
|
||||
*/
|
||||
func UpdateClient(Id string, client *model.Client) (*model.Client, error) {
|
||||
v, err := deserialize(Id)
|
||||
if err != nil {
|
||||
@ -141,6 +153,9 @@ func UpdateClient(Id string, client *model.Client) (*model.Client, error) {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete client from disk
|
||||
*/
|
||||
func DeleteClient(id string) error {
|
||||
path := filepath.Join(os.Getenv("WG_CONF_DIR"), id)
|
||||
err := os.Remove(path)
|
||||
@ -152,6 +167,9 @@ func DeleteClient(id string) error {
|
||||
return generateWgConfig()
|
||||
}
|
||||
|
||||
/*
|
||||
* Read all clients
|
||||
*/
|
||||
func ReadClients() ([]*model.Client, error) {
|
||||
clients := make([]*model.Client, 0)
|
||||
|
||||
@ -253,6 +271,7 @@ func UpdateServer(server *model.Server) (*model.Server, error) {
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Write object to disk
|
||||
*/
|
||||
@ -270,6 +289,7 @@ func serialize(id string, c interface{}) error {
|
||||
// data modified, dump new config
|
||||
return generateWgConfig()
|
||||
}
|
||||
|
||||
/*
|
||||
* Read client from disc
|
||||
*/
|
||||
@ -282,6 +302,7 @@ func deserializeClient(data []byte) (*model.Client, error) {
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Read server from disc
|
||||
*/
|
||||
@ -307,6 +328,7 @@ func deserialize(id string) (interface{}, error) {
|
||||
|
||||
return deserializeClient(b)
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Wireguard interface configuration
|
||||
*/
|
||||
@ -332,4 +354,4 @@ func generateWgConfig() error {
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
12
util/tpl.go
12
util/tpl.go
@ -40,6 +40,7 @@ AllowedIPs = {{.Address}}
|
||||
{{end}}`
|
||||
)
|
||||
|
||||
// dump client wg config with go template
|
||||
func DumpClient(client *model.Client, server *model.Server) (bytes.Buffer, error) {
|
||||
var tplBuff bytes.Buffer
|
||||
|
||||
@ -57,6 +58,7 @@ func DumpClient(client *model.Client, server *model.Server) (bytes.Buffer, error
|
||||
})
|
||||
}
|
||||
|
||||
// dump server wg config with go template
|
||||
func DumpServerWg(clients []*model.Client, server *model.Server) (bytes.Buffer, error) {
|
||||
var tplBuff bytes.Buffer
|
||||
|
||||
@ -66,17 +68,17 @@ func DumpServerWg(clients []*model.Client, server *model.Server) (bytes.Buffer,
|
||||
}
|
||||
|
||||
return dump(t, struct {
|
||||
Clients []*model.Client
|
||||
Server *model.Server
|
||||
Clients []*model.Client
|
||||
Server *model.Server
|
||||
ServerAdresses []string
|
||||
}{
|
||||
ServerAdresses: strings.Split(server.Address, ","),
|
||||
Clients: clients,
|
||||
Server: server,
|
||||
Clients: clients,
|
||||
Server: server,
|
||||
})
|
||||
}
|
||||
|
||||
func dump(tpl *template.Template , data interface{}) (bytes.Buffer, error) {
|
||||
func dump(tpl *template.Template, data interface{}) (bytes.Buffer, error) {
|
||||
var tplBuff bytes.Buffer
|
||||
|
||||
err := tpl.Execute(&tplBuff, data)
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// read file content
|
||||
func ReadFile(path string) (bytes []byte, err error) {
|
||||
bytes, err = ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
@ -17,6 +18,7 @@ func ReadFile(path string) (bytes []byte, err error) {
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
// write content to file
|
||||
func WriteFile(path string, bytes []byte) (err error) {
|
||||
err = ioutil.WriteFile(path, bytes, 0644)
|
||||
if err != nil {
|
||||
@ -26,6 +28,7 @@ func WriteFile(path string, bytes []byte) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// check if file exists
|
||||
func FileExists(name string) bool {
|
||||
info, err := os.Stat(name)
|
||||
if os.IsNotExist(err) {
|
||||
@ -34,6 +37,7 @@ func FileExists(name string) bool {
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
// check if directory exists
|
||||
func DirectoryExists(name string) bool {
|
||||
info, err := os.Stat(name)
|
||||
if os.IsNotExist(err) {
|
||||
@ -42,6 +46,7 @@ func DirectoryExists(name string) bool {
|
||||
return info.IsDir()
|
||||
}
|
||||
|
||||
// search for an available in cidr against a list of reserved ips
|
||||
func GetAvailableIp(cidr string, reserved []string) (string, error) {
|
||||
addresses, err := GetAllAddressesFromCidr(cidr)
|
||||
if err != nil {
|
||||
@ -64,6 +69,7 @@ func GetAvailableIp(cidr string, reserved []string) (string, error) {
|
||||
return "", errors.New("no more available address from cidr")
|
||||
}
|
||||
|
||||
// get all ip addresses from cidr
|
||||
func GetAllAddressesFromCidr(cidr string) ([]string, error) {
|
||||
ip, ipnet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
@ -88,6 +94,7 @@ func inc(ip net.IP) {
|
||||
}
|
||||
}
|
||||
|
||||
// check if given ip is IPv6
|
||||
func IsIPv6(address string) bool {
|
||||
return strings.Count(address, ":") >= 2
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user