Skip to content

Commit b70275e

Browse files
committed
fix : check wireguard kernel setup conditions
1 parent 3b68653 commit b70275e

8 files changed

Lines changed: 96 additions & 66 deletions

File tree

infra/conf/wireguard.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ func (c *WireGuardConfig) Build() (proto.Message, error) {
118118

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

125125
config.IsClient = c.IsClient
126126
if c.IsClient {
127-
if support := wireguard.KernelTunSupported(); c.KernelMode == nil {
127+
if support := wireguard.CheckUnixKernelTunSupported(); c.KernelMode == nil {
128128
config.KernelMode = support
129129
} else if *c.KernelMode && support {
130130
config.KernelMode = true

proxy/wireguard/check_tun_linux_only.go

Lines changed: 0 additions & 12 deletions
This file was deleted.

proxy/wireguard/check_tun_other.go

Lines changed: 0 additions & 7 deletions
This file was deleted.

proxy/wireguard/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (c *DeviceConfig) fallbackIP6() bool {
2525
}
2626

2727
func (c *DeviceConfig) createTun() tunCreator {
28-
if c.KernelMode {
28+
if c.IsClient && c.KernelMode {
2929
return createKernelTun
3030
}
3131
return createGVisorTun

proxy/wireguard/tun_default.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build !linux || android
1+
//go:build !linux
22

33
package wireguard
44

@@ -8,9 +8,5 @@ import (
88
)
99

1010
func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (t Tunnel, err error) {
11-
return nil, errors.New("not implemented")
12-
}
13-
14-
func KernelTunSupported() bool {
15-
return false
11+
return nil, errors.New("not implemented kernel tunnel for non-linux system")
1612
}

proxy/wireguard/tun_linux.go

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build linux && !android
1+
//go:build linux
22

33
package wireguard
44

@@ -8,19 +8,14 @@ import (
88
"fmt"
99
"net"
1010
"net/netip"
11-
"os"
12-
"os/exec"
13-
"strings"
1411

1512
"golang.org/x/sys/unix"
1613

1714
"github.com/sagernet/sing/common/control"
1815
"github.com/vishvananda/netlink"
19-
wgtun "golang.zx2c4.com/wireguard/tun"
20-
"kernel.org/pub/linux/libs/security/libcap/cap"
21-
2216
"github.com/xtls/xray-core/proxy/wireguard/iptables"
2317
iptexec "github.com/xtls/xray-core/proxy/wireguard/iptables/exec"
18+
wgtun "golang.zx2c4.com/wireguard/tun"
2419
)
2520

2621
type deviceNet struct {
@@ -92,7 +87,7 @@ func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
9287
x := prefixes
9388
v4 = &x
9489
}
95-
if v6 == nil && prefixes.Is6() {
90+
if v6 == nil && prefixes.Is6() && CheckUnixKernelIPv6IsEnabled() {
9691
x := prefixes
9792
v6 = &x
9893
}
@@ -244,33 +239,3 @@ func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
244239
out.tun = wgt
245240
return out, nil
246241
}
247-
248-
// KernelTunSupported returns true if kernel tun is supported.
249-
// 1. check if the current process has CAP_NET_ADMIN capability
250-
// 2. check if /proc/sys/net/ipv4/conf/all/src_valid_mark exists and is set to 1
251-
// 3. check if iptables is available
252-
func KernelTunSupported() bool {
253-
orig := cap.GetProc()
254-
c, err := orig.Dup()
255-
if err != nil {
256-
return false
257-
}
258-
on, _ := c.GetFlag(cap.Effective, cap.NET_ADMIN)
259-
if !on {
260-
return false
261-
}
262-
263-
buf, _ := os.ReadFile("/proc/sys/net/ipv4/conf/all/src_valid_mark")
264-
value := strings.TrimSpace(string(buf))
265-
if value != "1" {
266-
return false
267-
}
268-
269-
outCmd := exec.Command("sh", "-c", "command -v iptables")
270-
outBuffer, err := outCmd.CombinedOutput()
271-
if err != nil {
272-
return false
273-
}
274-
iptablesPath := strings.TrimSpace(string(outBuffer))
275-
return iptablesPath != ""
276-
}

proxy/wireguard/wireguard_linux.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//go:build linux
2+
3+
package wireguard
4+
5+
import (
6+
"os"
7+
"os/exec"
8+
"strings"
9+
10+
"kernel.org/pub/linux/libs/security/libcap/cap"
11+
)
12+
13+
func IsLinux() bool {
14+
return true
15+
}
16+
17+
func CheckUnixKernelTunDeviceEnabled() bool {
18+
if _, err := os.Stat("/dev/net/tun"); err != nil {
19+
return false
20+
}
21+
return true
22+
}
23+
24+
func CheckUnixKernelNetAdminCapEnabled() bool {
25+
orig := cap.GetProc()
26+
c, err := orig.Dup()
27+
if err != nil {
28+
return false
29+
}
30+
on, _ := c.GetFlag(cap.Effective, cap.NET_ADMIN)
31+
return on
32+
}
33+
34+
func CheckUnixKernelIPv4SrcValidMarkEnabled() bool {
35+
buf, _ := os.ReadFile("/proc/sys/net/ipv4/conf/all/src_valid_mark")
36+
value := strings.TrimSpace(string(buf))
37+
return value == "1"
38+
}
39+
40+
func CheckUnixKernelIPv6IsEnabled() bool {
41+
buf, _ := os.ReadFile("/proc/sys/net/ipv6/conf/all/disable_ipv6")
42+
value := strings.TrimSpace(string(buf))
43+
return value == "0"
44+
}
45+
46+
// CheckUnixKernelTunSupported returns true if kernel tun is supported.
47+
// 1. check if the current process has CAP_NET_ADMIN capability
48+
// 2. check if /proc/sys/net/ipv4/conf/all/src_valid_mark exists and is set to 1
49+
// 3. check if iptables is available
50+
func CheckUnixKernelTunSupported() bool {
51+
if !CheckUnixKernelTunDeviceEnabled() || !CheckUnixKernelNetAdminCapEnabled() {
52+
return false
53+
}
54+
outCmd := exec.Command("sh", "-c", "command -v iptables")
55+
outBuffer, err := outCmd.CombinedOutput()
56+
if err != nil {
57+
return false
58+
}
59+
iptablesPath := strings.TrimSpace(string(outBuffer))
60+
return iptablesPath != ""
61+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//go:build !linux
2+
3+
package wireguard
4+
5+
func IsLinux() bool {
6+
return false
7+
}
8+
9+
func CheckUnixKernelTunDeviceEnabled() bool {
10+
return true
11+
}
12+
13+
func CheckUnixKernelNetAdminCapEnabled() bool {
14+
return false
15+
}
16+
17+
func CheckUnixKernelIPv6IsEnabled() bool {
18+
return false
19+
}
20+
21+
func CheckUnixKernelIPv4SrcValidMarkEnabled() bool {
22+
return false
23+
}
24+
25+
func CheckUnixKernelTunSupported() bool {
26+
return false
27+
}

0 commit comments

Comments
 (0)