Merge pull request #4 from getlantern/amnezia

Added support for AmneziaWG
This commit is contained in:
Ilya Yakelzon 2025-03-10 15:58:32 +01:00 committed by GitHub
commit 285af41309
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 95 additions and 6 deletions

View File

@ -35,6 +35,31 @@ icon: material/new-box
} }
``` ```
!!! question "Since sing-box 1.xx.0"
#### Advanced security (AmneziaWG)
To activate advanced security mode for WireGuard (powered by AmneziaWG), please add the following fields to the configuration:
```json5
{
...
"private_key": "....",
"jc": 0, // JunkPacketCount
"jmin": 0, // JunkPacketMinSize
"jmax": 0, // JunkPacketMaxSize
"s1": 0, // InitPacketJunkSize
"s2": 0, // ResponsePacketJunkSize
"h1": 0, // InitPacketMagicHeader
"h2": 0, // ResponsePacketMagicHeader
"h3": 0, // UnderloadPacketMagicHeader
"h4": 0, // TransportPacketMagicHeader
}
```
Setting any of these values with a non-zero value will activate the corresponding security feature.
If neither of these values is set, the default WireGuard security will be used.
!!! note "" !!! note ""
You can ignore the JSON Array [] tag when the content is only one item You can ignore the JSON Array [] tag when the content is only one item

8
go.mod
View File

@ -1,6 +1,8 @@
module github.com/sagernet/sing-box module github.com/sagernet/sing-box
go 1.23.1 go 1.23.6
toolchain go1.24.0
require ( require (
github.com/anytls/sing-anytls v0.0.5 github.com/anytls/sing-anytls v0.0.5
@ -123,6 +125,7 @@ require (
github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 // indirect github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 // indirect
github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 // indirect github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 // indirect
github.com/tcnksm/go-httpstat v0.2.0 // indirect github.com/tcnksm/go-httpstat v0.2.0 // indirect
github.com/tevino/abool/v2 v2.1.0 // indirect
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect
github.com/vishvananda/netns v0.0.4 // indirect github.com/vishvananda/netns v0.0.4 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
@ -143,3 +146,6 @@ require (
) )
//replace github.com/sagernet/sing => ../sing //replace github.com/sagernet/sing => ../sing
// TODO: if github.com/getlantern/wireguard-go gets merged, remove this line
replace github.com/sagernet/wireguard-go => github.com/getlantern/wireguard-go v0.0.1-beta.5.0.20250303165430-793006c422ec

6
go.sum
View File

@ -44,6 +44,8 @@ github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1t
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gaissmai/bart v0.11.1 h1:5Uv5XwsaFBRo4E5VBcb9TzY8B7zxFf+U7isDxqOrRfc= github.com/gaissmai/bart v0.11.1 h1:5Uv5XwsaFBRo4E5VBcb9TzY8B7zxFf+U7isDxqOrRfc=
github.com/gaissmai/bart v0.11.1/go.mod h1:KHeYECXQiBjTzQz/om2tqn3sZF1J7hw9m6z41ftj3fg= github.com/gaissmai/bart v0.11.1/go.mod h1:KHeYECXQiBjTzQz/om2tqn3sZF1J7hw9m6z41ftj3fg=
github.com/getlantern/wireguard-go v0.0.1-beta.5.0.20250303165430-793006c422ec h1:jXekDkSozctYj5JQlV1mCsIW+qHpIkgSFhOIpgRSB1I=
github.com/getlantern/wireguard-go v0.0.1-beta.5.0.20250303165430-793006c422ec/go.mod h1:akc2Wh+rX9bFFNnHJGsQ8VIV3eJI1LXJYgx2Y+8lcW8=
github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I=
github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo=
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8= github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
@ -204,8 +206,6 @@ github.com/sagernet/tailscale v1.79.0-mod.1 h1:wIuAH7VqBYJNk0h2+bTyk4F0OlSqHvyLD
github.com/sagernet/tailscale v1.79.0-mod.1/go.mod h1:RKY5WjYLj3JJ7VO/8ZCw8eAFa4+kWU6A1Ftdk84uB14= github.com/sagernet/tailscale v1.79.0-mod.1/go.mod h1:RKY5WjYLj3JJ7VO/8ZCw8eAFa4+kWU6A1Ftdk84uB14=
github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8= github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8=
github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM= github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM=
github.com/sagernet/wireguard-go v0.0.1-beta.5 h1:aBEsxJUMEONwOZqKPIkuAcv4zJV5p6XlzEN04CF0FXc=
github.com/sagernet/wireguard-go v0.0.1-beta.5/go.mod h1:jGXij2Gn2wbrWuYNUmmNhf1dwcZtvyAvQoe8Xd8MbUo=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
@ -236,6 +236,8 @@ github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk=
github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0= github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0=
github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8=
github.com/tevino/abool/v2 v2.1.0 h1:7w+Vf9f/5gmKT4m4qkayb33/92M+Um45F2BkHOR+L/c=
github.com/tevino/abool/v2 v2.1.0/go.mod h1:+Lmlqk6bHDWHqN1cbxqhwEAwMPXgc8I1SDEamtseuXY=
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e h1:BA9O3BmlTmpjbvajAwzWx4Wo2TRVdpPXZEeemGQcajw= github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e h1:BA9O3BmlTmpjbvajAwzWx4Wo2TRVdpPXZEeemGQcajw=
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=

View File

@ -6,6 +6,29 @@ import (
"github.com/sagernet/sing/common/json/badoption" "github.com/sagernet/sing/common/json/badoption"
) )
/*
WireGuardAdvancedSecurityOptions provides advanced security options for WireGuard required to activate AmneziaWG.
In AmneziaWG, random bytes are appended to every auth packet to alter their size.
Thus, "init and response handshake packets" have added "junk" at the beginning of their data, the size of which
is determined by the values S1 and S2.
By default, the initiating handshake packet has a fixed size (148 bytes). After adding the junk, its size becomes 148 bytes + S1.
AmneziaWG also incorporates another trick for more reliable masking. Before initiating a session, Amnezia sends a
certain number of "junk" packets to thoroughly confuse DPI systems. The number of these packets and their
minimum and maximum byte sizes can also be adjusted in the settings, using parameters Jc, Jmin, and Jmax.
*/
type WireGuardAdvancedSecurityOptions struct {
JunkPacketCount int `json:"junk_packet_count,omitempty"` // jc
JunkPacketMinSize int `json:"junk_packet_min_size,omitempty"` // jmin
JunkPacketMaxSize int `json:"junk_packet_max_size,omitempty"` // jmax
InitPacketJunkSize int `json:"init_packet_junk_size,omitempty"` // s1
ResponsePacketJunkSize int `json:"response_packet_junk_size,omitempty"` // s2
InitPacketMagicHeader uint32 `json:"init_packet_magic_header,omitempty"` // h1
ResponsePacketMagicHeader uint32 `json:"response_packet_magic_header,omitempty"` // h2
UnderloadPacketMagicHeader uint32 `json:"underload_packet_magic_header,omitempty"` // h3
TransportPacketMagicHeader uint32 `json:"transport_packet_magic_header,omitempty"` // h4
}
type WireGuardEndpointOptions struct { type WireGuardEndpointOptions struct {
System bool `json:"system,omitempty"` System bool `json:"system,omitempty"`
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
@ -16,6 +39,7 @@ type WireGuardEndpointOptions struct {
Peers []WireGuardPeer `json:"peers,omitempty"` Peers []WireGuardPeer `json:"peers,omitempty"`
UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"` UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"`
Workers int `json:"workers,omitempty"` Workers int `json:"workers,omitempty"`
WireGuardAdvancedSecurityOptions
DialerOptions DialerOptions
} }

View File

@ -104,7 +104,8 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
Reserved: it.Reserved, Reserved: it.Reserved,
} }
}), }),
Workers: options.Workers, Workers: options.Workers,
WireGuardAdvancedSecurityOptions: options.WireGuardAdvancedSecurityOptions,
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -1,6 +1,6 @@
module test module test
go 1.23.1 go 1.23.6
toolchain go1.24.0 toolchain go1.24.0
@ -30,7 +30,7 @@ require (
github.com/akutz/memconn v0.1.0 // indirect github.com/akutz/memconn v0.1.0 // indirect
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/anytls/sing-anytls v0.0.2 // indirect github.com/anytls/sing-anytls v0.0.5 // indirect
github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect
github.com/caddyserver/certmagic v0.21.7 // indirect github.com/caddyserver/certmagic v0.21.7 // indirect
github.com/caddyserver/zerossl v0.1.3 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect

View File

@ -14,6 +14,7 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/anytls/sing-anytls v0.0.2 h1:25azSh0o/LMcIkhS4ZutgRTIGwh8O3wuOhsThVM9K9o= github.com/anytls/sing-anytls v0.0.2 h1:25azSh0o/LMcIkhS4ZutgRTIGwh8O3wuOhsThVM9K9o=
github.com/anytls/sing-anytls v0.0.2/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8= github.com/anytls/sing-anytls v0.0.2/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
github.com/anytls/sing-anytls v0.0.5/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg= github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg=

View File

@ -47,6 +47,33 @@ func NewEndpoint(options EndpointOptions) (*Endpoint, error) {
if options.ListenPort != 0 { if options.ListenPort != 0 {
ipcConf += "\nlisten_port=" + F.ToString(options.ListenPort) ipcConf += "\nlisten_port=" + F.ToString(options.ListenPort)
} }
if options.JunkPacketCount > 0 {
ipcConf += "\njc=" + F.ToString(options.JunkPacketCount)
}
if options.JunkPacketMinSize > 0 {
ipcConf += "\njmin=" + F.ToString(options.JunkPacketMinSize)
}
if options.JunkPacketMaxSize > 0 {
ipcConf += "\njmax=" + F.ToString(options.JunkPacketMaxSize)
}
if options.InitPacketJunkSize > 0 {
ipcConf += "\ns1=" + F.ToString(options.InitPacketJunkSize)
}
if options.ResponsePacketJunkSize > 0 {
ipcConf += "\ns2=" + F.ToString(options.ResponsePacketJunkSize)
}
if options.InitPacketMagicHeader > 0 {
ipcConf += "\nh1=" + F.ToString(options.InitPacketMagicHeader)
}
if options.ResponsePacketMagicHeader > 0 {
ipcConf += "\nh2=" + F.ToString(options.ResponsePacketMagicHeader)
}
if options.UnderloadPacketMagicHeader > 0 {
ipcConf += "\nh3=" + F.ToString(options.UnderloadPacketMagicHeader)
}
if options.TransportPacketMagicHeader > 0 {
ipcConf += "\nh4=" + F.ToString(options.TransportPacketMagicHeader)
}
var peers []peerConfig var peers []peerConfig
for peerIndex, rawPeer := range options.Peers { for peerIndex, rawPeer := range options.Peers {
peer := peerConfig{ peer := peerConfig{
@ -255,5 +282,6 @@ func (c peerConfig) GenerateIpcLines() string {
if c.keepalive > 0 { if c.keepalive > 0 {
ipcLines += "\npersistent_keepalive_interval=" + F.ToString(c.keepalive) ipcLines += "\npersistent_keepalive_interval=" + F.ToString(c.keepalive)
} }
return ipcLines return ipcLines
} }

View File

@ -2,6 +2,7 @@ package wireguard
import ( import (
"context" "context"
"github.com/sagernet/sing-box/option"
"net/netip" "net/netip"
"time" "time"
@ -27,6 +28,7 @@ type EndpointOptions struct {
ResolvePeer func(domain string) (netip.Addr, error) ResolvePeer func(domain string) (netip.Addr, error)
Peers []PeerOptions Peers []PeerOptions
Workers int Workers int
option.WireGuardAdvancedSecurityOptions
} }
type PeerOptions struct { type PeerOptions struct {