mirror of
https://github.com/Threnklyn/wg-ui.git
synced 2026-05-18 12:53:30 +02:00
Initial implementation of wireguard configuration
This commit is contained in:
@@ -0,0 +1 @@
|
||||
wireguard-ui
|
||||
@@ -0,0 +1,13 @@
|
||||
module github.com/embarkstudios/wireguard-ui
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
|
||||
github.com/mdlayher/wireguardctrl v0.0.0-20190419142446-a4a944b88a6b
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
github.com/vishvananda/netlink v1.0.0
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/mdlayher/genetlink v0.0.0-20190419142426-b806ce69960a h1:tIPUNU99ot2Tko8SorsytkeFC0to6pRJB6koxswpeB8=
|
||||
github.com/mdlayher/genetlink v0.0.0-20190419142426-b806ce69960a/go.mod h1:J+g63IQCVwjKLOxodrxOylt23f7d5vVB9rgNh+T13Uk=
|
||||
github.com/mdlayher/netlink v0.0.0-20190419142405-71c9566a34ae h1:Ec6B7pKh4YZyKI9VtTeZmN1GGLvAIT/fs2votDcWnMU=
|
||||
github.com/mdlayher/netlink v0.0.0-20190419142405-71c9566a34ae/go.mod h1:TR9n0u8mie4+iszGTMjP6QRwUZQNynkhDbXTLF6DUi4=
|
||||
github.com/mdlayher/wireguardctrl v0.0.0-20190419142446-a4a944b88a6b h1:3EhP8SsJHU7mbXm4iWtO57HR2LI48KaCuSfDhAywrBg=
|
||||
github.com/mdlayher/wireguardctrl v0.0.0-20190419142446-a4a944b88a6b/go.mod h1:3oz/rt7iwoq/LQa+QaFheGKzGZvc+vlmaBvtxeh6Jtc=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
|
||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk=
|
||||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba h1:h0zCzEL5UW1mERvwTN6AXcc75PpLkY6OcReia6Dq1BM=
|
||||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be h1:mI+jhqkn68ybP0ORJqunXn+fq+Eeb4hHKqLQcFICjAc=
|
||||
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
logLevel = kingpin.Flag("log-level", "The level of logging").Default("info").Enum("debug", "info", "warn", "error", "panic", "fatal")
|
||||
)
|
||||
|
||||
func main() {
|
||||
kingpin.HelpFlag.Short('h')
|
||||
kingpin.CommandLine.DefaultEnvars()
|
||||
kingpin.Parse()
|
||||
switch strings.ToLower(*logLevel) {
|
||||
case "debug":
|
||||
log.SetLevel(log.DebugLevel)
|
||||
case "warn":
|
||||
log.SetLevel(log.WarnLevel)
|
||||
case "error":
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
case "panic":
|
||||
log.SetLevel(log.PanicLevel)
|
||||
default:
|
||||
log.SetLevel(log.InfoLevel)
|
||||
}
|
||||
|
||||
log.Info("Starting")
|
||||
|
||||
server := NewServer()
|
||||
err := server.Start()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/mdlayher/wireguardctrl"
|
||||
"github.com/mdlayher/wireguardctrl/wgtypes"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
listenAddr = kingpin.Flag("listen-address", "Address to listen to").Default(":8080").String()
|
||||
wgLinkName = kingpin.Flag("wg-device-name", "Wireguard network device name").Default("wg0").String()
|
||||
wgListenPort = kingpin.Flag("wg-listen-port", "Wireguard UDP port to listen to").Default("51820").Int()
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
mux *http.ServeMux
|
||||
storage *Storage
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
type WgLink struct {
|
||||
attrs *netlink.LinkAttrs
|
||||
}
|
||||
|
||||
func (w *WgLink) Attrs() *netlink.LinkAttrs {
|
||||
return w.attrs
|
||||
}
|
||||
|
||||
func (w *WgLink) Type() string {
|
||||
return "wireguard"
|
||||
}
|
||||
|
||||
func NewServer() *Server {
|
||||
storage := NewStorage()
|
||||
|
||||
server := &Server{
|
||||
mux: http.NewServeMux(),
|
||||
storage: storage,
|
||||
config: storage.GetServerConfig(),
|
||||
}
|
||||
|
||||
server.mux.HandleFunc("/", server.Hello)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *Server) initInterface() error {
|
||||
attrs := netlink.NewLinkAttrs()
|
||||
attrs.Name = *wgLinkName
|
||||
|
||||
link := WgLink{
|
||||
attrs: &attrs,
|
||||
}
|
||||
|
||||
err := netlink.LinkAdd(&link)
|
||||
if os.IsExist(err) {
|
||||
log.Infof("Wireguard interface %s already exists. Reusing.", *wgLinkName)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wg, err := wireguardctrl.New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := wgtypes.ParseKey(s.config.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := wgtypes.Config{
|
||||
PrivateKey: &key,
|
||||
ListenPort: wgListenPort,
|
||||
}
|
||||
wg.ConfigureDevice(*wgLinkName, cfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
err := s.initInterface()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.WithField("listenAddr", *listenAddr).Info("Starting server")
|
||||
return http.ListenAndServe(*listenAddr, s.mux)
|
||||
}
|
||||
|
||||
func (s *Server) Hello(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("Hello World"))
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/mdlayher/wireguardctrl/wgtypes"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
dataDir = kingpin.Flag("data-dir", "Directory used for storage").Default("/var/lib/wireguard-ui").String()
|
||||
)
|
||||
|
||||
type ServerConfig struct {
|
||||
PrivateKey string
|
||||
PublicKey string
|
||||
}
|
||||
|
||||
type UserConfig struct {
|
||||
Name string
|
||||
Devices []DeviceConfig
|
||||
}
|
||||
|
||||
type DeviceConfig struct {
|
||||
PublicKey string
|
||||
}
|
||||
|
||||
type Storage struct {
|
||||
serverConfigPath string
|
||||
}
|
||||
|
||||
func NewStorage() *Storage {
|
||||
err := os.MkdirAll(*dataDir, 0700)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("Error initializing data directory: %s", *dataDir)
|
||||
}
|
||||
|
||||
s := Storage{
|
||||
serverConfigPath: path.Join(*dataDir, "config.json"),
|
||||
}
|
||||
log.Debug("Storage initialized: ", *dataDir)
|
||||
return &s
|
||||
}
|
||||
|
||||
func NewServerConfig() *ServerConfig {
|
||||
key, err := wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
cfg := ServerConfig{
|
||||
PrivateKey: key.String(),
|
||||
PublicKey: key.PublicKey().String(),
|
||||
}
|
||||
|
||||
return &cfg
|
||||
}
|
||||
|
||||
func (cfg *ServerConfig) WriteServerConfig(path string) error {
|
||||
data, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(path, data, 0600)
|
||||
}
|
||||
|
||||
func (s *Storage) GetServerConfig() *ServerConfig {
|
||||
config := NewServerConfig()
|
||||
|
||||
f, err := os.Open(s.serverConfigPath)
|
||||
if err == nil {
|
||||
if err = json.NewDecoder(f).Decode(config); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Debug("Read server config from file: ", s.serverConfigPath)
|
||||
} else if os.IsNotExist(err) {
|
||||
log.Debug("No config found. Creating new: ", s.serverConfigPath)
|
||||
err = config.WriteServerConfig(s.serverConfigPath)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Debug("Configuration loaded with public key: ", config.PublicKey)
|
||||
return config
|
||||
}
|
||||
Reference in New Issue
Block a user