Skip to content

Commit

Permalink
Added route management based off peer allowed ips
Browse files Browse the repository at this point in the history
  • Loading branch information
UnAfraid committed Sep 8, 2023
1 parent 533aa5b commit a820c1b
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 18 deletions.
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ module github.com/UnAfraid/wg-ui
go 1.21

require (
github.com/99designs/gqlgen v0.17.36
github.com/99designs/gqlgen v0.17.37
github.com/UnAfraid/searchindex v0.0.0-20230707222905-bbf56d7105a6
github.com/go-chi/chi/v5 v5.0.10
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/google/uuid v1.3.1
github.com/gorilla/websocket v1.5.0
github.com/graph-gophers/dataloader/v7 v7.1.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/rs/cors v1.9.0
github.com/rs/cors v1.10.0
github.com/sirupsen/logrus v1.9.3
github.com/vektah/gqlparser/v2 v2.5.8
github.com/vishvananda/netlink v1.1.0
github.com/vektah/gqlparser/v2 v2.5.9
github.com/vishvananda/netlink v1.2.1-beta.2
go.etcd.io/bbolt v1.3.7
go.uber.org/automaxprocs v1.5.3
golang.org/x/crypto v0.13.0
Expand Down
25 changes: 11 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go=
github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4=
github.com/99designs/gqlgen v0.17.37 h1:PDUH/4AhEYmXb9b1AfxX2JY+myp5TIaoSjNEY7ugt/4=
github.com/99designs/gqlgen v0.17.37/go.mod h1:eov4+h4V+M6snvxWsGsUZskjv9r0vuIrSE7qjMkJYig=
github.com/UnAfraid/searchindex v0.0.0-20230707222905-bbf56d7105a6 h1:QApMS8Er+YY4CELLYfWngiWiT37O06Q0/beviYeIHbA=
github.com/UnAfraid/searchindex v0.0.0-20230707222905-bbf56d7105a6/go.mod h1:i0ERwbL7iSvPKgEXjW8ooFCNMpO/fXq/btcH5f+1sEk=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
Expand Down Expand Up @@ -36,7 +36,6 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand All @@ -57,26 +56,25 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/cors v1.10.0 h1:62NOS1h+r8p1mW6FM0FSB0exioXLhd/sh15KpjWBZ+8=
github.com/rs/cors v1.10.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4=
github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vektah/gqlparser/v2 v2.5.9 h1:bFju9t/E8shqIcDGayKdpl6OHBplFZEeYac9SALiRZE=
github.com/vektah/gqlparser/v2 v2.5.9/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc=
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
Expand All @@ -93,7 +91,8 @@ golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -106,10 +105,8 @@ golang.zx2c4.com/wireguard v0.0.0-20230704135630-469159ecf7d1/go.mod h1:tqur9Lnf
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=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
113 changes: 113 additions & 0 deletions pkg/wg/interface_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package wg
import (
"errors"
"fmt"
"net"
"os"
"slices"
"strings"

"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
)

Expand Down Expand Up @@ -66,6 +68,117 @@ func configureInterface(name string, address string, mtu int) error {
return nil
}

func configureRoutes(name string, allowedIPs []net.IPNet) error {
link, err := netlink.LinkByName(name)
if err != nil {
if os.IsNotExist(err) || errors.As(err, &netlink.LinkNotFoundError{}) {
return nil
}
return fmt.Errorf("failed to find link by name: %w", err)
}

routes, err := netlink.RouteList(link, netFamilyAll)
if err != nil {
return fmt.Errorf("failed to get routes: %w", err)
}

routesToAdd, routesToUpdate, routesToRemove := computeRoutes(link, routes, allowedIPs)

for i, route := range routesToAdd {
if err = netlink.RouteAdd(routesToAdd[i]); err != nil {
return fmt.Errorf("failed to add route for %s - %w", route.Dst.String(), err)
}

logrus.
WithField("name", link.Attrs().Name).
WithField("route", route.Dst.String()).
Debug("route added")
}

for i, route := range routesToUpdate {
if err = netlink.RouteReplace(routesToAdd[i]); err != nil {
return fmt.Errorf("failed to replace route for %s - %w", route.Dst.String(), err)
}

logrus.
WithField("name", link.Attrs().Name).
WithField("route", route.Dst.String()).
Debug("route replaced")
}

for i, route := range routesToRemove {
if err = netlink.RouteDel(routesToAdd[i]); err != nil {
return fmt.Errorf("failed to delete route for %s - %w", route.Dst.String(), err)
}

logrus.
WithField("name", link.Attrs().Name).
WithField("route", route.Dst.String()).
Debug("route deleted")
}
return nil
}

func computeRoutes(link netlink.Link, existingRoutes []netlink.Route, allowedIPs []net.IPNet) ([]*netlink.Route, []*netlink.Route, []*netlink.Route) {
var routesToAdd []*netlink.Route
var routesToUpdate []*netlink.Route
var routesToRemove []*netlink.Route
for i, allowedIP := range allowedIPs {
var existingRoute *netlink.Route
for _, route := range existingRoutes {
if route.Dst != nil && route.Dst.IP.Equal(allowedIP.IP) && slices.Equal(route.Dst.Mask, allowedIP.Mask) {
existingRoute = &existingRoutes[i]
break
}
}
if existingRoute != nil {
var update bool
if existingRoute.Scope != netlink.SCOPE_LINK {
existingRoute.Scope = netlink.SCOPE_LINK
update = true
}

if existingRoute.Protocol != netlink.RouteProtocol(3) {
existingRoute.Protocol = netlink.RouteProtocol(3)
update = true
}

if existingRoute.Type != 1 {
existingRoute.Type = 1
update = true
}

if update {
routesToUpdate = append(routesToUpdate, existingRoute)
}
continue
}

routesToAdd = append(routesToAdd, &netlink.Route{
LinkIndex: link.Attrs().Index,
Scope: netlink.SCOPE_LINK,
Dst: &allowedIP,
Protocol: netlink.RouteProtocol(3),
Type: 1,
})
}

for i, existingRoute := range existingRoutes {
var exists bool
for _, allowedIP := range allowedIPs {
exists = existingRoute.Dst != nil && existingRoute.Dst.IP.Equal(allowedIP.IP) && slices.Equal(existingRoute.Dst.Mask, allowedIP.Mask)
if exists {
break
}
}
if !exists {
routesToRemove = append(routesToRemove, &existingRoutes[i])
}
}

return routesToAdd, routesToUpdate, routesToRemove
}

func deleteInterface(name string) error {
link, err := netlink.LinkByName(name)
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions pkg/wg/interface_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
package wg

import (
"net"

"github.com/UnAfraid/wg-ui/pkg/server"
)

func configureInterface(name string, address string, mtu int) error {
return nil
}

func configureRoutes(name string, allowedIPs []net.IPNet) error {
return nil
}

func deleteInterface(name string) error {
return nil
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/wg/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,19 @@ func (s *service) StopServer(ctx context.Context, serverId string) (*server.Serv
return s.serverService.UpdateServer(ctx, serverId, updateServerOptions, updateServerFieldMask, "")
}

func (s *service) getAllowedIPs(name string) ([]net.IPNet, error) {
currentDevice, err := s.client.Device(name)
if err != nil {
return nil, fmt.Errorf("failed to open wireguard device: %w", err)
}

var allowedIPs []net.IPNet
for _, p := range currentDevice.Peers {
allowedIPs = append(allowedIPs, p.AllowedIPs...)
}
return allowedIPs, nil
}

func (s *service) ConfigureWireGuard(name string, privateKey string, listenPort *int, firewallMark *int, peers []*peer.Peer) error {
currentDevice, err := s.client.Device(name)
if err != nil {
Expand Down Expand Up @@ -657,6 +670,15 @@ func (s *service) configureWireguard(name string, privateKey string, listenPort
return fmt.Errorf("failed to configure device: %w", err)
}

allowedIPs, err := s.getAllowedIPs(name)
if err != nil {
return fmt.Errorf("failed to get allowed ips: %w", err)
}

if err := configureRoutes(name, allowedIPs); err != nil {
return fmt.Errorf("failed to configure routes: %w", err)
}

return nil
}

Expand Down

0 comments on commit a820c1b

Please sign in to comment.