Skip to content

Commit

Permalink
Reworked wireguard implementation
Browse files Browse the repository at this point in the history
Added multi-backend support
Linux host only for now
Mikrotik backend pending
  • Loading branch information
UnAfraid committed Oct 22, 2023
1 parent 095fb05 commit b431920
Show file tree
Hide file tree
Showing 38 changed files with 1,243 additions and 1,211 deletions.
4 changes: 4 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Wireguard interface backend
# Default: linux
WG_UI_BACKEND=linux

# The main database file path
# Stores all users and wireguard servers configuration
WG_UI_BOLT_DB_PATH=/var/lib/wg-ui/data.db
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ require (
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.14.0 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231018191413-24ea13351eb7 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.zx2c4.com/wireguard v0.0.0-20231018191413-24ea13351eb7 h1:1+bHXA5s3p7saWQTFJKtQF7WzoU0HEvIe5iUovtpzhU=
golang.zx2c4.com/wireguard v0.0.0-20231018191413-24ea13351eb7/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb h1:c5tyN8sSp8jSDxdCCDXVOpJwYXXhmTkNMt+g0zTSOic=
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
34 changes: 27 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"

Expand All @@ -25,7 +26,9 @@ import (
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/subscription"
"github.com/UnAfraid/wg-ui/pkg/user"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/wireguard"
"github.com/UnAfraid/wg-ui/pkg/wireguard/backend"
"github.com/UnAfraid/wg-ui/pkg/wireguard/linux"
)

const (
Expand Down Expand Up @@ -111,26 +114,43 @@ func main() {
return
}

wgService, err := wg.NewService(serverService, peerService)
if err != nil {
var wireguardBackend backend.Backend

switch strings.ToLower(conf.Backend) {
case "linux":
wireguardBackend, err = linux.NewLinuxBackend()
if err != nil {
logrus.
WithError(err).
Fatal("failed to initialize linux backend for wireguard")
return
}
default:
logrus.
WithError(err).
Fatal("failed to initialize WireGuard service")
Fatal("unsupported wireguard backend")
return
}
defer wgService.Close()

wireguardService := wireguard.NewService(wireguardBackend)
defer func() {
if err := wireguardService.Close(context.Background()); err != nil {
logrus.
WithError(err).
Error("failed to close wireguard service")
}
}()

authService := auth.NewService(jwt.SigningMethodHS256, jwtSecretBytes, jwtSecretBytes, conf.JwtDuration)

manageService := manage.NewService(transactionScoper, userService, serverService, peerService, wgService)
manageService := manage.NewService(transactionScoper, userService, serverService, peerService, wireguardService)

router := api.NewRouter(
conf,
authService,
userService,
serverService,
peerService,
wgService,
manageService,
)

Expand Down
9 changes: 2 additions & 7 deletions pkg/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/user"
"github.com/UnAfraid/wg-ui/pkg/wg"
)

//go:generate go run github.com/99designs/gqlgen --config ../../gqlgen.yml generate
Expand All @@ -23,16 +22,15 @@ func newConfig(
userService user.Service,
serverService server.Service,
peerService peer.Service,
wgService wg.Service,
manageService manage.Service,
) resolver.Config {
return resolver.Config{
Resolvers: &resolverRoot{
queryResolver: query.NewQueryResolver(
wgService,
peerService,
serverService,
userService,
manageService,
),
mutationResolver: mutation.NewMutationResolver(
authService,
Expand All @@ -48,13 +46,10 @@ func newConfig(
peerService,
),
serverResolver: serverResolver.NewServerResolver(
serverService,
peerService,
wgService,
),
peerResolver: peerResolver.NewPeerResolver(
peerService,
wgService,
manageService,
),
},
Directives: directive.NewDirectiveRoot(),
Expand Down
30 changes: 17 additions & 13 deletions pkg/api/internal/model/adapter_foreign.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package model

import (
"net"

"github.com/UnAfraid/wg-ui/pkg/internal/adapt"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/wireguard/backend"
)

func ToForeignInterface(foreignInterface *wg.ForeignInterface) *ForeignInterface {
func ToForeignInterface(foreignInterface *backend.ForeignInterface) *ForeignInterface {
if foreignInterface == nil {
return nil
}
Expand All @@ -17,13 +19,13 @@ func ToForeignInterface(foreignInterface *wg.ForeignInterface) *ForeignInterface
}
}

func ToForeignServer(foreignServer *wg.ForeignServer) *ForeignServer {
func ToForeignServer(foreignServer *backend.ForeignServer) *ForeignServer {
if foreignServer == nil {
return nil
}

return &ForeignServer{
ForeignInterface: ToForeignInterface(foreignServer.ForeignInterface),
ForeignInterface: ToForeignInterface(foreignServer.Interface),
Name: foreignServer.Name,
Type: foreignServer.Type,
PublicKey: foreignServer.PublicKey,
Expand All @@ -33,19 +35,21 @@ func ToForeignServer(foreignServer *wg.ForeignServer) *ForeignServer {
}
}

func ToForeignPeer(foreignPeer *wg.ForeignPeer) *ForeignPeer {
func ToForeignPeer(foreignPeer *backend.Peer) *ForeignPeer {
if foreignPeer == nil {
return nil
}

return &ForeignPeer{
PublicKey: foreignPeer.PublicKey,
Endpoint: foreignPeer.Endpoint,
AllowedIps: foreignPeer.AllowedIPs,
PersistentKeepAliveInterval: int(foreignPeer.PersistentKeepaliveInterval),
LastHandshakeTime: adapt.ToPointer(foreignPeer.LastHandshakeTime),
ReceiveBytes: float64(foreignPeer.ReceiveBytes),
TransmitBytes: float64(foreignPeer.TransmitBytes),
ProtocolVersion: foreignPeer.ProtocolVersion,
PublicKey: foreignPeer.PublicKey,
Endpoint: adapt.ToPointerNilZero(foreignPeer.Endpoint),
AllowedIps: adapt.Array(foreignPeer.AllowedIPs, func(allowedIp net.IPNet) string {
return allowedIp.String()
}),
PersistentKeepAliveInterval: int(foreignPeer.PersistentKeepalive.Seconds()),
LastHandshakeTime: adapt.ToPointer(foreignPeer.Stats.LastHandshakeTime),
ReceiveBytes: float64(foreignPeer.Stats.ReceiveBytes),
TransmitBytes: float64(foreignPeer.Stats.TransmitBytes),
ProtocolVersion: foreignPeer.Stats.ProtocolVersion,
}
}
4 changes: 2 additions & 2 deletions pkg/api/internal/model/adapter_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package model
import (
"github.com/UnAfraid/wg-ui/pkg/internal/adapt"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/wireguard/backend"
)

func CreatePeerInputToCreateOptions(input CreatePeerInput) *peer.CreateOptions {
Expand Down Expand Up @@ -140,7 +140,7 @@ func PeerHookInputToPeerHook(hook *PeerHookInput) *peer.Hook {
}
}

func ToPeerStats(stats *wg.PeerStats) *PeerStats {
func ToPeerStats(stats *backend.PeerStats) *PeerStats {
if stats == nil {
return nil
}
Expand Down
24 changes: 22 additions & 2 deletions pkg/api/internal/mutation/mutation_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,22 @@ func (r *mutationResolver) DeleteServer(ctx context.Context, input model.DeleteS
}

func (r *mutationResolver) StartServer(ctx context.Context, input model.StartServerInput) (*model.StartServerPayload, error) {
user, err := model.ContextToUser(ctx)
if err != nil {
return nil, err
}

userId, err := user.ID.String(model.IdKindUser)
if err != nil {
return nil, err
}

serverId, err := input.ID.String(model.IdKindServer)
if err != nil {
return nil, err
}

srv, err := r.manageService.StartServer(ctx, serverId)
srv, err := r.manageService.StartServer(ctx, serverId, userId)
if err != nil {
return nil, err
}
Expand All @@ -214,12 +224,22 @@ func (r *mutationResolver) StartServer(ctx context.Context, input model.StartSer
}

func (r *mutationResolver) StopServer(ctx context.Context, input model.StopServerInput) (*model.StopServerPayload, error) {
user, err := model.ContextToUser(ctx)
if err != nil {
return nil, err
}

userId, err := user.ID.String(model.IdKindUser)
if err != nil {
return nil, err
}

serverId, err := input.ID.String(model.IdKindServer)
if err != nil {
return nil, err
}

srv, err := r.manageService.StopServer(ctx, serverId)
srv, err := r.manageService.StopServer(ctx, serverId, userId)
if err != nil {
return nil, err
}
Expand Down
14 changes: 5 additions & 9 deletions pkg/api/internal/peer/peer_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@ import (
"github.com/UnAfraid/wg-ui/pkg/api/internal/handler"
"github.com/UnAfraid/wg-ui/pkg/api/internal/model"
"github.com/UnAfraid/wg-ui/pkg/api/internal/resolver"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/manage"
)

type peerResolver struct {
peerService peer.Service
wgService wg.Service
manageService manage.Service
}

func NewPeerResolver(
peerService peer.Service,
wgService wg.Service,
manageService manage.Service,
) resolver.PeerResolver {
return &peerResolver{
wgService: wgService,
peerService: peerService,
manageService: manageService,
}
}

Expand Down Expand Up @@ -66,7 +62,7 @@ func (r *peerResolver) Stats(ctx context.Context, p *model.Peer) (*model.PeerSta
return nil, nil
}

stats, err := r.wgService.PeerStats(server.Name, p.PublicKey)
stats, err := r.manageService.PeerStats(nil, server.Name, p.PublicKey)
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/api/internal/query/query_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@ import (
"github.com/UnAfraid/wg-ui/pkg/api/internal/model"
"github.com/UnAfraid/wg-ui/pkg/api/internal/resolver"
"github.com/UnAfraid/wg-ui/pkg/internal/adapt"
"github.com/UnAfraid/wg-ui/pkg/manage"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/user"
"github.com/UnAfraid/wg-ui/pkg/wg"
)

type queryResolver struct {
wgService wg.Service
peerService peer.Service
serverService server.Service
userService user.Service
manageService manage.Service
}

func NewQueryResolver(
wgService wg.Service,
peerService peer.Service,
serverService server.Service,
userService user.Service,
manageService manage.Service,
) resolver.QueryResolver {
return &queryResolver{
wgService: wgService,
peerService: peerService,
serverService: serverService,
userService: userService,
manageService: manageService,
}
}

Expand Down Expand Up @@ -138,7 +138,7 @@ func (r *queryResolver) Peers(ctx context.Context, query *string) ([]*model.Peer
}

func (r *queryResolver) ForeignServers(ctx context.Context) ([]*model.ForeignServer, error) {
foreignServers, err := r.wgService.ForeignServers(ctx)
foreignServers, err := r.manageService.ForeignServers(ctx)
if err != nil {
return nil, err
}
Expand Down
12 changes: 2 additions & 10 deletions pkg/api/internal/server/server_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,17 @@ import (
"github.com/UnAfraid/wg-ui/pkg/api/internal/resolver"
"github.com/UnAfraid/wg-ui/pkg/internal/adapt"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/wg"
)

type serverResolver struct {
serverService server.Service
peerService peer.Service
wgService wg.Service
peerService peer.Service
}

func NewServerResolver(
serverService server.Service,
peerService peer.Service,
wgService wg.Service,
) resolver.ServerResolver {
return &serverResolver{
serverService: serverService,
peerService: peerService,
wgService: wgService,
peerService: peerService,
}
}

Expand Down
3 changes: 0 additions & 3 deletions pkg/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/user"
"github.com/UnAfraid/wg-ui/pkg/wg"
)

const (
Expand All @@ -42,7 +41,6 @@ func NewRouter(
userService user.Service,
serverService server.Service,
peerService peer.Service,
wgService wg.Service,
manageService manage.Service,
) http.Handler {
corsMiddleware := cors.New(cors.Options{
Expand All @@ -58,7 +56,6 @@ func NewRouter(
userService,
serverService,
peerService,
wgService,
manageService,
)

Expand Down
Loading

0 comments on commit b431920

Please sign in to comment.