feat(wireguard): amneziawg implementation (#3150)

This commit is contained in:
Zhurik
2026-03-11 16:55:28 +03:00
committed by GitHub
parent f4eeffe79a
commit e6fc792f4f
20 changed files with 635 additions and 68 deletions
@@ -69,6 +69,38 @@ func (s *Source) Get(key string) (value string, isSet bool) {
return strPtrToStringIsSet(s.lazyLoadWireguardConf().EndpointIP)
case "wireguard_endpoint_port":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().EndpointPort)
case "wireguard_jc":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.Jc)
case "wireguard_jmin":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.Jmin)
case "wireguard_jmax":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.Jmax)
case "wireguard_s1":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S1)
case "wireguard_s2":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S2)
case "wireguard_s3":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S3)
case "wireguard_s4":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S4)
case "wireguard_h1":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H1)
case "wireguard_h2":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H2)
case "wireguard_h3":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H3)
case "wireguard_h4":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H4)
case "wireguard_i1":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I1)
case "wireguard_i2":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I2)
case "wireguard_i3":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I3)
case "wireguard_i4":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I4)
case "wireguard_i5":
return strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I5)
}
value, isSet, err := ReadFromFile(path)
@@ -25,13 +25,54 @@ func (s *Source) lazyLoadWireguardConf() WireguardConfig {
return s.cached.wireguardConf
}
type amneziaWgConfig struct {
Jc *string
Jmin *string
Jmax *string
S1 *string
S2 *string
S3 *string
S4 *string
H1 *string
H2 *string
H3 *string
H4 *string
I1 *string
I2 *string
I3 *string
I4 *string
I5 *string
}
func parseWireguardAmneziaInterfaceSection(interfaceSection *ini.Section) amneziaWgConfig {
return amneziaWgConfig{
Jc: getINIKeyFromSection(interfaceSection, "Jc"),
Jmin: getINIKeyFromSection(interfaceSection, "Jmin"),
Jmax: getINIKeyFromSection(interfaceSection, "Jmax"),
S1: getINIKeyFromSection(interfaceSection, "S1"),
S2: getINIKeyFromSection(interfaceSection, "S2"),
S3: getINIKeyFromSection(interfaceSection, "S3"),
S4: getINIKeyFromSection(interfaceSection, "S4"),
H1: getINIKeyFromSection(interfaceSection, "H1"),
H2: getINIKeyFromSection(interfaceSection, "H2"),
H3: getINIKeyFromSection(interfaceSection, "H3"),
H4: getINIKeyFromSection(interfaceSection, "H4"),
I1: getINIKeyFromSection(interfaceSection, "I1"),
I2: getINIKeyFromSection(interfaceSection, "I2"),
I3: getINIKeyFromSection(interfaceSection, "I3"),
I4: getINIKeyFromSection(interfaceSection, "I4"),
I5: getINIKeyFromSection(interfaceSection, "I5"),
}
}
type WireguardConfig struct {
PrivateKey *string
PreSharedKey *string
Addresses *string
PublicKey *string
EndpointIP *string
EndpointPort *string
PrivateKey *string
PreSharedKey *string
Addresses *string
PublicKey *string
EndpointIP *string
EndpointPort *string
AmneziaParams amneziaWgConfig
}
var regexINISectionNotExist = regexp.MustCompile(`^section ".+" does not exist$`)
@@ -48,6 +89,7 @@ func ParseWireguardConf(path string) (config WireguardConfig, err error) {
interfaceSection, err := iniFile.GetSection("Interface")
if err == nil {
config.PrivateKey, config.Addresses = parseWireguardInterfaceSection(interfaceSection)
config.AmneziaParams = parseWireguardAmneziaInterfaceSection(interfaceSection)
} else if !regexINISectionNotExist.MatchString(err.Error()) {
// can never happen
return WireguardConfig{}, fmt.Errorf("getting interface section: %w", err)
@@ -97,9 +97,10 @@ func Test_parseWireguardInterfaceSection(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
iniData string
privateKey *string
addresses *string
iniData string
privateKey *string
addresses *string
amneziaParams amneziaWgConfig
}{
"no_fields": {
iniData: `[Interface]`,
@@ -115,9 +116,17 @@ PrivateKey = x
[Interface]
PrivateKey = QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8=
Address = 10.38.22.35/32
Jc = 4
H1 = 721391205
I1 = <b 0x1234>
`,
privateKey: ptrTo("QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8="),
addresses: ptrTo("10.38.22.35/32"),
amneziaParams: amneziaWgConfig{
Jc: ptrTo("4"),
H1: ptrTo("721391205"),
I1: ptrTo("<b 0x1234>"),
},
},
}
@@ -131,9 +140,11 @@ Address = 10.38.22.35/32
require.NoError(t, err)
privateKey, addresses := parseWireguardInterfaceSection(iniSection)
amneziaWgConfig := parseWireguardAmneziaInterfaceSection(iniSection)
assert.Equal(t, testCase.privateKey, privateKey)
assert.Equal(t, testCase.addresses, addresses)
assert.Equal(t, testCase.amneziaParams, amneziaWgConfig)
})
}
}
@@ -83,6 +83,11 @@ func (s *Source) Get(key string) (value string, isSet bool) {
return strPtrToStringIsSet(s.lazyLoadWireguardConf().EndpointPort)
}
value, isSet, matched := s.getAmneziaWg(key)
if matched {
return value, isSet
}
value, isSet, err := files.ReadFromFile(path)
if err != nil {
s.warner.Warnf("skipping %s: reading file: %s", path, err)
@@ -104,3 +109,43 @@ func (s *Source) KeyTransform(key string) string {
return key
}
}
func (s *Source) getAmneziaWg(key string) (value string, isSet, matched bool) {
switch key {
case "wireguard_jc":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.Jc)
case "wireguard_jmin":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.Jmin)
case "wireguard_jmax":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.Jmax)
case "wireguard_s1":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S1)
case "wireguard_s2":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S2)
case "wireguard_s3":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S3)
case "wireguard_s4":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.S4)
case "wireguard_h1":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H1)
case "wireguard_h2":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H2)
case "wireguard_h3":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H3)
case "wireguard_h4":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.H4)
case "wireguard_i1":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I1)
case "wireguard_i2":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I2)
case "wireguard_i3":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I3)
case "wireguard_i4":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I4)
case "wireguard_i5":
value, isSet = strPtrToStringIsSet(s.lazyLoadWireguardConf().AmneziaParams.I5)
default:
return "", false, false
}
return value, isSet, true
}