mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-29 16:58:34 +00:00
WireGuard Inbound (User-space WireGuard server) (#2477)
* feat: wireguard inbound * feat(command): generate wireguard compatible keypair * feat(wireguard): connection idle timeout * fix(wireguard): close endpoint after connection closed * fix(wireguard): resolve conflicts * feat(wireguard): set cubic as default cc algorithm in gVisor TUN * chore(wireguard): resolve conflict * chore(wireguard): remove redurant code * chore(wireguard): remove redurant code * feat: rework server for gvisor tun * feat: keep user-space tun as an option * fix: exclude android from native tun build * feat: auto kernel tun * fix: build * fix: regulate function name & fix test
This commit is contained in:
parent
f1c81557dc
commit
0ac7da2fc8
17 changed files with 1049 additions and 500 deletions
|
@ -13,7 +13,7 @@ type WireGuardPeerConfig struct {
|
|||
PublicKey string `json:"publicKey"`
|
||||
PreSharedKey string `json:"preSharedKey"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
KeepAlive int `json:"keepAlive"`
|
||||
KeepAlive uint32 `json:"keepAlive"`
|
||||
AllowedIPs []string `json:"allowedIPs,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,11 @@ func (c *WireGuardPeerConfig) Build() (proto.Message, error) {
|
|||
var err error
|
||||
config := new(wireguard.PeerConfig)
|
||||
|
||||
config.PublicKey, err = parseWireGuardKey(c.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if c.PublicKey != "" {
|
||||
config.PublicKey, err = parseWireGuardKey(c.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if c.PreSharedKey != "" {
|
||||
|
@ -31,13 +33,11 @@ func (c *WireGuardPeerConfig) Build() (proto.Message, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
config.PreSharedKey = "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
|
||||
config.Endpoint = c.Endpoint
|
||||
// default 0
|
||||
config.KeepAlive = int32(c.KeepAlive)
|
||||
config.KeepAlive = c.KeepAlive
|
||||
if c.AllowedIPs == nil {
|
||||
config.AllowedIps = []string{"0.0.0.0/0", "::0/0"}
|
||||
} else {
|
||||
|
@ -48,11 +48,14 @@ func (c *WireGuardPeerConfig) Build() (proto.Message, error) {
|
|||
}
|
||||
|
||||
type WireGuardConfig struct {
|
||||
IsClient bool `json:""`
|
||||
|
||||
KernelMode *bool `json:"kernelMode"`
|
||||
SecretKey string `json:"secretKey"`
|
||||
Address []string `json:"address"`
|
||||
Peers []*WireGuardPeerConfig `json:"peers"`
|
||||
MTU int `json:"mtu"`
|
||||
NumWorkers int `json:"workers"`
|
||||
MTU int32 `json:"mtu"`
|
||||
NumWorkers int32 `json:"workers"`
|
||||
Reserved []byte `json:"reserved"`
|
||||
DomainStrategy string `json:"domainStrategy"`
|
||||
}
|
||||
|
@ -87,11 +90,11 @@ func (c *WireGuardConfig) Build() (proto.Message, error) {
|
|||
if c.MTU == 0 {
|
||||
config.Mtu = 1420
|
||||
} else {
|
||||
config.Mtu = int32(c.MTU)
|
||||
config.Mtu = c.MTU
|
||||
}
|
||||
// these a fallback code exists in github.com/nanoda0523/wireguard-go code,
|
||||
// these a fallback code exists in wireguard-go code,
|
||||
// we don't need to process fallback manually
|
||||
config.NumWorkers = int32(c.NumWorkers)
|
||||
config.NumWorkers = c.NumWorkers
|
||||
|
||||
if len(c.Reserved) != 0 && len(c.Reserved) != 3 {
|
||||
return nil, newError(`"reserved" should be empty or 3 bytes`)
|
||||
|
@ -113,22 +116,42 @@ func (c *WireGuardConfig) Build() (proto.Message, error) {
|
|||
return nil, newError("unsupported domain strategy: ", c.DomainStrategy)
|
||||
}
|
||||
|
||||
config.IsClient = c.IsClient
|
||||
if c.KernelMode != nil {
|
||||
config.KernelMode = *c.KernelMode
|
||||
if config.KernelMode && !wireguard.KernelTunSupported() {
|
||||
newError("kernel mode is not supported on your OS or permission is insufficient").AtWarning().WriteToLog()
|
||||
}
|
||||
} else {
|
||||
config.KernelMode = wireguard.KernelTunSupported()
|
||||
if config.KernelMode {
|
||||
newError("kernel mode is enabled as it's supported and permission is sufficient").AtDebug().WriteToLog()
|
||||
}
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func parseWireGuardKey(str string) (string, error) {
|
||||
if len(str) != 64 {
|
||||
// may in base64 form
|
||||
dat, err := base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
return "", err
|
||||
var err error
|
||||
|
||||
if len(str)%2 == 0 {
|
||||
_, err = hex.DecodeString(str)
|
||||
if err == nil {
|
||||
return str, nil
|
||||
}
|
||||
if len(dat) != 32 {
|
||||
return "", newError("key should be 32 bytes: " + str)
|
||||
}
|
||||
return hex.EncodeToString(dat), err
|
||||
} else {
|
||||
// already hex form
|
||||
return str, nil
|
||||
}
|
||||
|
||||
var dat []byte
|
||||
str = strings.TrimSuffix(str, "=")
|
||||
if strings.ContainsRune(str, '+') || strings.ContainsRune(str, '/') {
|
||||
dat, err = base64.RawStdEncoding.DecodeString(str)
|
||||
} else {
|
||||
dat, err = base64.RawURLEncoding.DecodeString(str)
|
||||
}
|
||||
if err == nil {
|
||||
return hex.EncodeToString(dat), nil
|
||||
}
|
||||
|
||||
return "", newError("failed to deserialize key").Base(err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue