Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial Windows support #26

Merged
merged 7 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
project_name: wiretrustee
builds:
- env: [CGO_ENABLED=0]

goos:
- linux
- darwin
- windows
goarch:
- arm
- amd64
- arm64
ignore:
- goos: darwin
goarch: arm64
- goos: windows
goarch: arm64
- goos: windows
goarch: arm
tags:
- load_wintun_from_rsrc
nfpms:
- maintainer: Wiretrustee <wiretrustee@wiretrustee.com>
description: Wiretrustee project.
Expand Down
9 changes: 4 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ require (
github.com/spf13/cobra v1.1.3
github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/tools v0.1.1 // indirect
golang.zx2c4.com/wireguard v0.0.20201118
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210506160403-92e472f520a5
golang.zx2c4.com/wireguard/windows v0.3.14
google.golang.org/grpc v1.32.0
)
87 changes: 61 additions & 26 deletions go.sum

Large diffs are not rendered by default.

33 changes: 8 additions & 25 deletions iface/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package iface

import (
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/ipc"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
Expand All @@ -23,38 +22,36 @@ var tunIface tun.Device
// Will reuse an existing one.
func Create(iface string, address string) error {
var err error

tunIface, err = tun.CreateTUN(iface, defaultMTU)
if err != nil {
return err
}

// We need to create a wireguard-go device and listen to configuration requests
tunDevice := device.NewDevice(tunIface, device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
tunDevice.Up()
tunSock, err := ipc.UAPIOpen(iface)
tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
err = tunDevice.Up()
if err != nil {
return err
}
uapi, err := ipc.UAPIListen(iface, tunSock)
uapi, err := getUAPI(iface)
if err != nil {
return err
}

go func() {
for {
conn, err := uapi.Accept()
uapiConn, err := uapi.Accept()
if err != nil {
log.Debugln(err)
return
}
go tunDevice.IpcHandle(conn)
go tunDevice.IpcHandle(uapiConn)
}
}()

log.Debugln("UAPI listener started")

err = assignAddr(iface, address)
err = assignAddr(address, tunIface)
if err != nil {
return err
}
Expand Down Expand Up @@ -176,7 +173,7 @@ func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.
log.Debugf("got Wireguard device %s", iface)

//parse allowed ips
ipNet, err := netlink.ParseIPNet(allowedIps)
_, ipNet, err := net.ParseCIDR(allowedIps)
if err != nil {
return err
}
Expand Down Expand Up @@ -259,17 +256,3 @@ func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error

return nil
}

type wgLink struct {
attrs *netlink.LinkAttrs
}

// Attrs returns the Wireguard's default attributes
func (w *wgLink) Attrs() *netlink.LinkAttrs {
return w.attrs
}

// Type returns the interface type
func (w *wgLink) Type() string {
return "wireguard"
}
8 changes: 5 additions & 3 deletions iface/iface_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package iface

import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/tun"
"net"
"os/exec"
"strings"
Expand All @@ -12,15 +13,16 @@ import (
//)

// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
func assignAddr(iface string, address string) error {
func assignAddr(address string, tunDevice tun.Device) error {
ifaceName, err := tunDevice.Name()
ip := strings.Split(address, "/")
cmd := exec.Command("ifconfig", iface, "inet", address, ip[0])
cmd := exec.Command("ifconfig", ifaceName, "inet", address, ip[0])
if out, err := cmd.CombinedOutput(); err != nil {
log.Infoln("Command: %v failed with output %s and error: ", cmd.String(), out)
return err
}
_, resolvedNet, err := net.ParseCIDR(address)
err = addRoute(iface, resolvedNet)
err = addRoute(ifaceName, resolvedNet)
if err != nil {
log.Infoln("Adding route failed with error:", err)
}
Expand Down
30 changes: 25 additions & 5 deletions iface/iface_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package iface
import (
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"golang.zx2c4.com/wireguard/tun"

"os"
)

Expand All @@ -11,23 +13,41 @@ import (
//)

// assignAddr Adds IP address to the tunnel interface
func assignAddr(iface string, address string) error {
func assignAddr(address string, tunDevice tun.Device) error {
var err error
attrs := netlink.NewLinkAttrs()
attrs.Name = iface
attrs.Name, err = tunDevice.Name()
if err != nil {
return err
}

link := wgLink{
attrs: &attrs,
}

log.Debugf("adding address %s to interface: %s", address, iface)
log.Debugf("adding address %s to interface: %s", address, attrs.Name)
addr, _ := netlink.ParseAddr(address)
err := netlink.AddrAdd(&link, addr)
err = netlink.AddrAdd(&link, addr)
if os.IsExist(err) {
log.Infof("interface %s already has the address: %s", iface, address)
log.Infof("interface %s already has the address: %s", attrs.Name, address)
} else if err != nil {
return err
}
// On linux, the link must be brought up
err = netlink.LinkSetUp(&link)
return err
}

type wgLink struct {
attrs *netlink.LinkAttrs
}

// Attrs returns the Wireguard's default attributes
func (w *wgLink) Attrs() *netlink.LinkAttrs {
return w.attrs
}

// Type returns the interface type
func (w *wgLink) Type() string {
return "wireguard"
}
17 changes: 17 additions & 0 deletions iface/iface_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// +build linux darwin

package iface

import (
"golang.zx2c4.com/wireguard/ipc"
"net"
)

// getUAPI returns a Listener
func getUAPI(iface string) (net.Listener, error) {
tunSock, err := ipc.UAPIOpen(iface)
if err != nil {
return nil, err
}
return ipc.UAPIListen(iface, tunSock)
}
36 changes: 36 additions & 0 deletions iface/iface_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package iface

import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/ipc"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"net"
)

// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
func assignAddr(address string, tunDevice tun.Device) error {
ifaceName, err := tunDevice.Name()
nativeTunDevice := tunDevice.(*tun.NativeTun)
luid := winipcfg.LUID(nativeTunDevice.LUID())

ip, ipnet, _ := net.ParseCIDR(address)

log.Debugf("adding address %s to interface: %s", address, ifaceName)
err = luid.SetIPAddresses([]net.IPNet{{ip, ipnet.Mask}})
if err != nil {
return err
}

log.Debugf("adding Routes to interface: %s", ifaceName)
err = luid.SetRoutes([]*winipcfg.RouteData{{*ipnet, ipnet.IP, 0}})
if err != nil {
return err
}
return nil
}

// getUAPI returns a Listener
func getUAPI(iface string) (net.Listener, error) {
return ipc.UAPIListen(iface)
}
Binary file added resources_amd64.syso
Binary file not shown.