Skip to content

Commit

Permalink
fix : check wireguard kernel setup conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
kunsonx committed Nov 26, 2023
1 parent 3b68653 commit b70275e
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 66 deletions.
4 changes: 2 additions & 2 deletions infra/conf/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ func (c *WireGuardConfig) Build() (proto.Message, error) {

// check device exist for wireguard setup
// module "golang.zx2c4.com/wireguard" only support linux and require /dev/net/tun
if !wireguard.CheckWireGuardDeviceRequire() {
if wireguard.IsLinux() && !wireguard.CheckUnixKernelTunDeviceEnabled() {
return nil, newError("wireguard module require device /dev/net/tun")
}

config.IsClient = c.IsClient
if c.IsClient {
if support := wireguard.KernelTunSupported(); c.KernelMode == nil {
if support := wireguard.CheckUnixKernelTunSupported(); c.KernelMode == nil {
config.KernelMode = support
} else if *c.KernelMode && support {
config.KernelMode = true
Expand Down
12 changes: 0 additions & 12 deletions proxy/wireguard/check_tun_linux_only.go

This file was deleted.

7 changes: 0 additions & 7 deletions proxy/wireguard/check_tun_other.go

This file was deleted.

2 changes: 1 addition & 1 deletion proxy/wireguard/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (c *DeviceConfig) fallbackIP6() bool {
}

func (c *DeviceConfig) createTun() tunCreator {
if c.KernelMode {
if c.IsClient && c.KernelMode {
return createKernelTun
}
return createGVisorTun
Expand Down
8 changes: 2 additions & 6 deletions proxy/wireguard/tun_default.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !linux || android
//go:build !linux

package wireguard

Expand All @@ -8,9 +8,5 @@ import (
)

func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (t Tunnel, err error) {
return nil, errors.New("not implemented")
}

func KernelTunSupported() bool {
return false
return nil, errors.New("not implemented kernel tunnel for non-linux system")
}
41 changes: 3 additions & 38 deletions proxy/wireguard/tun_linux.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build linux && !android
//go:build linux

package wireguard

Expand All @@ -8,19 +8,14 @@ import (
"fmt"
"net"
"net/netip"
"os"
"os/exec"
"strings"

"golang.org/x/sys/unix"

"github.com/sagernet/sing/common/control"
"github.com/vishvananda/netlink"
wgtun "golang.zx2c4.com/wireguard/tun"
"kernel.org/pub/linux/libs/security/libcap/cap"

"github.com/xtls/xray-core/proxy/wireguard/iptables"
iptexec "github.com/xtls/xray-core/proxy/wireguard/iptables/exec"
wgtun "golang.zx2c4.com/wireguard/tun"
)

type deviceNet struct {
Expand Down Expand Up @@ -92,7 +87,7 @@ func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
x := prefixes
v4 = &x
}
if v6 == nil && prefixes.Is6() {
if v6 == nil && prefixes.Is6() && CheckUnixKernelIPv6IsEnabled() {
x := prefixes
v6 = &x
}
Expand Down Expand Up @@ -244,33 +239,3 @@ func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
out.tun = wgt
return out, nil
}

// KernelTunSupported returns true if kernel tun is supported.
// 1. check if the current process has CAP_NET_ADMIN capability
// 2. check if /proc/sys/net/ipv4/conf/all/src_valid_mark exists and is set to 1
// 3. check if iptables is available
func KernelTunSupported() bool {
orig := cap.GetProc()
c, err := orig.Dup()
if err != nil {
return false
}
on, _ := c.GetFlag(cap.Effective, cap.NET_ADMIN)
if !on {
return false
}

buf, _ := os.ReadFile("/proc/sys/net/ipv4/conf/all/src_valid_mark")
value := strings.TrimSpace(string(buf))
if value != "1" {
return false
}

outCmd := exec.Command("sh", "-c", "command -v iptables")
outBuffer, err := outCmd.CombinedOutput()
if err != nil {
return false
}
iptablesPath := strings.TrimSpace(string(outBuffer))
return iptablesPath != ""
}
61 changes: 61 additions & 0 deletions proxy/wireguard/wireguard_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//go:build linux

package wireguard

import (
"os"
"os/exec"
"strings"

"kernel.org/pub/linux/libs/security/libcap/cap"
)

func IsLinux() bool {
return true
}

func CheckUnixKernelTunDeviceEnabled() bool {
if _, err := os.Stat("/dev/net/tun"); err != nil {
return false
}
return true
}

func CheckUnixKernelNetAdminCapEnabled() bool {
orig := cap.GetProc()
c, err := orig.Dup()
if err != nil {
return false
}
on, _ := c.GetFlag(cap.Effective, cap.NET_ADMIN)
return on
}

func CheckUnixKernelIPv4SrcValidMarkEnabled() bool {
buf, _ := os.ReadFile("/proc/sys/net/ipv4/conf/all/src_valid_mark")
value := strings.TrimSpace(string(buf))
return value == "1"
}

func CheckUnixKernelIPv6IsEnabled() bool {
buf, _ := os.ReadFile("/proc/sys/net/ipv6/conf/all/disable_ipv6")
value := strings.TrimSpace(string(buf))
return value == "0"
}

// CheckUnixKernelTunSupported returns true if kernel tun is supported.
// 1. check if the current process has CAP_NET_ADMIN capability
// 2. check if /proc/sys/net/ipv4/conf/all/src_valid_mark exists and is set to 1
// 3. check if iptables is available
func CheckUnixKernelTunSupported() bool {
if !CheckUnixKernelTunDeviceEnabled() || !CheckUnixKernelNetAdminCapEnabled() {
return false
}
outCmd := exec.Command("sh", "-c", "command -v iptables")
outBuffer, err := outCmd.CombinedOutput()
if err != nil {
return false
}
iptablesPath := strings.TrimSpace(string(outBuffer))
return iptablesPath != ""
}
27 changes: 27 additions & 0 deletions proxy/wireguard/wireguard_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//go:build !linux

package wireguard

func IsLinux() bool {
return false
}

func CheckUnixKernelTunDeviceEnabled() bool {
return true
}

func CheckUnixKernelNetAdminCapEnabled() bool {
return false
}

func CheckUnixKernelIPv6IsEnabled() bool {
return false
}

func CheckUnixKernelIPv4SrcValidMarkEnabled() bool {
return false
}

func CheckUnixKernelTunSupported() bool {
return false
}

0 comments on commit b70275e

Please sign in to comment.