Skip to content

Commit

Permalink
Liqonet: wireguard userspace golang
Browse files Browse the repository at this point in the history
  • Loading branch information
cheina97 authored and adamjensenbot committed Aug 21, 2023
1 parent 09378c5 commit 3715d0d
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 31 deletions.
27 changes: 12 additions & 15 deletions build/liqonet/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
FROM rust:1.70.0 as rustBuilder
FROM golang:1.20 as goBuilder-wg

ARG VERSION=0.5.2

RUN git clone https://github.com/cloudflare/boringtun.git

WORKDIR /boringtun

RUN cargo build --bin boringtun-cli --release
ARG VERSION=0.0.20230223

# change with "go install git.zx2c4.com/wireguard-go"
# waiting for https://github.com/WireGuard/wireguard-go/pull/87 to be merged
RUN git clone -b ${VERSION} https://git.zx2c4.com/wireguard-go
WORKDIR /go/wireguard-go
RUN CGO_ENABLED=0 make

FROM golang:1.20 as goBuilder
WORKDIR /tmp/builder
Expand All @@ -20,15 +19,13 @@ COPY . ./
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -ldflags="-s -w" ./cmd/liqonet


FROM debian:11.7-slim
FROM alpine:3.15

RUN apt-get update && \
apt-get install -y iproute2 iptables bash wireguard-tools tcpdump conntrack curl iputils-ping && \
apt-get clean autoclean && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
RUN apk update && \
apk add iptables bash wireguard-tools tcpdump conntrack-tools curl && \
rm -rf /var/cache/apk/*

COPY --from=goBuilder /tmp/builder/liqonet /usr/bin/liqonet
COPY --from=rustBuilder /boringtun/target/release/boringtun-cli /usr/bin/boringtun-cli
COPY --from=goBuilder-wg /go/wireguard-go/wireguard-go /usr/bin/wireguard-go

ENTRYPOINT [ "/usr/bin/liqonet" ]
52 changes: 36 additions & 16 deletions pkg/liqonet/tunnel/wireguard/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
k8s "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"

Expand All @@ -46,6 +47,7 @@ import (
"github.com/liqotech/liqo/pkg/liqonet/tunnel/metrics"
"github.com/liqotech/liqo/pkg/liqonet/tunnel/resolver"
liqonetutils "github.com/liqotech/liqo/pkg/liqonet/utils"
"github.com/liqotech/liqo/pkg/liqonet/utils/signals"
)

// Registering the driver as available.
Expand Down Expand Up @@ -109,6 +111,7 @@ type Wireguard struct {

// NewDriver creates a new WireGuard driver.
func NewDriver(k8sClient k8s.Interface, namespace string, config tunnel.Config) (tunnel.Driver, error) {
ctx, _ := signals.NotifyContextPosix(context.Background(), signals.ShutdownSignals...)
var err error
w := Wireguard{
connections: make(map[string]*netv1alpha1.Connection),
Expand All @@ -125,9 +128,10 @@ func NewDriver(k8sClient k8s.Interface, namespace string, config tunnel.Config)
if err != nil {
return nil, err
}
if err = w.setWGLink(); err != nil {
if err = w.setWGLink(ctx); err != nil {
return nil, fmt.Errorf("failed to setup %s link: %w", liqoconst.DriverName, err)
}
klog.Infof("Wireguard driver initialized with %s implementation", w.Implementation)
// create controller.
if w.client, err = wgctrl.New(); err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -351,8 +355,22 @@ func (w *Wireguard) Close() error {
return fmt.Errorf("failed to delete existng WireGuard device: %w", err)
}

// runWgUserCmd runs the wg command with the given arguments.
func runWgUserCmd(cmd *exec.Cmd) {
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
if err != nil {
outStr, errStr := stdout.String(), stderr.String()
fmt.Printf("out:\n%s\nerr:\n%s\n", outStr, errStr)
klog.Fatalf("failed to run '%s': %w", cmd.String(), err)
}
}
}

// Create new wg link.
func (w *Wireguard) setWGLink() error {
func (w *Wireguard) setWGLink(ctx context.Context) error {
var err error
// delete existing wg device if needed.
if link, err := netlink.LinkByName(liqoconst.DeviceName); err == nil {
Expand All @@ -370,27 +388,29 @@ func (w *Wireguard) setWGLink() error {
LinkType: "wireguard",
}

if err = netlink.LinkAdd(link); err != nil && !errors.Is(err, unix.EOPNOTSUPP) {
return fmt.Errorf("failed to add wireguard device %q: %w", liqoconst.DeviceName, err)
if w.Implementation == Kernel {
if err = netlink.LinkAdd(link); err != nil && !errors.Is(err, unix.EOPNOTSUPP) {
return fmt.Errorf("failed to add wireguard device %q: %w", liqoconst.DeviceName, err)
}
}
if errors.Is(err, unix.EOPNOTSUPP) || w.Implementation == Userspace {
klog.Warningf("wireguard kernel module not present, falling back to the userspace implementation")

// Enforce the userspace implementation to show it in metrics.
w.Implementation = Userspace

cmd := exec.Command("/usr/bin/boringtun-cli", liqoconst.DeviceName, "--disable-drop-privileges") //nolint:gosec //we leave it as it is
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
outStr, errStr := stdout.String(), stderr.String()
fmt.Printf("out:\n%s\nerr:\n%s\n", outStr, errStr)
return fmt.Errorf("failed to add wireguard devices '%s': %w", liqoconst.DeviceName, err)
}
if w.link, err = netlink.LinkByName(liqoconst.DeviceName); err != nil {
return fmt.Errorf("failed to get wireguard device '%s': %w", liqoconst.DeviceName, err)
cmd := exec.Command("/usr/bin/wireguard-go", "-f", liqoconst.DeviceName) //nolint:gosec //we leave it as it is
go runWgUserCmd(cmd)

if err := wait.PollUntilContextTimeout(ctx, time.Second, 10*time.Second, true, func(context.Context) (done bool, err error) {
klog.Info("Waiting for wireguard device to be created")
if w.link, err = netlink.LinkByName(liqoconst.DeviceName); err != nil {
klog.Errorf("failed to get wireguard device '%s': %s", liqoconst.DeviceName, err)
return false, nil
}
return true, nil
}); err != nil {
return fmt.Errorf("failed to create wireguard device %q: %w", liqoconst.DeviceName, err)
}
}
w.link = link
Expand Down

0 comments on commit 3715d0d

Please sign in to comment.