fix(amneziawg): let a cleared header protection key reach a running device

amneziawg-go reads an absent UAPI line as "keep the current value", and
addressFingerprint keys only on the addresses and MTU, so an obfuscation-only
edit reconfigures in place rather than rebuilding. Clearing headerProtectionKey
therefore never took effect: the device kept protecting headers with the old
key. The stale key also keeps the S1-S4 minimum in force, so lowering S3/S4 in
the same edit made every later IpcSet fail with -22 — after replace_peers had
already dropped the peers.

Send the all-zero key when the field is empty, which is how the UAPI expresses
"disabled"; an empty value would be rejected, since it decodes to zero bytes.
This commit is contained in:
Sanaei
2026-09-09 00:57:24 +02:00
parent efc603f59c
commit cfd596a489
2 changed files with 52 additions and 3 deletions
+6 -2
View File
@@ -205,13 +205,17 @@ func buildUAPIConfig(inst amneziawg.Instance, opts DeviceOptions) (string, error
writeOptionalLine(&b, "i4", o.I4)
writeOptionalLine(&b, "i5", o.I5)
// An omitted line means "unchanged" to amneziawg-go, so a cleared key can
// only reach a live device as the all-zero one that disables the feature.
hpHex := strings.Repeat("0", 64)
if opts.HeaderProtectionKey != "" {
hpHex, err := wireguard.KeyToHex(opts.HeaderProtectionKey)
var err error
hpHex, err = wireguard.KeyToHex(opts.HeaderProtectionKey)
if err != nil {
return "", fmt.Errorf("invalid header protection key: %w", err)
}
fmt.Fprintf(&b, "header_protection_key=%s\n", hpHex)
}
fmt.Fprintf(&b, "header_protection_key=%s\n", hpHex)
if opts.ContentPaddingAddition != "" {
fmt.Fprintf(&b, "content_padding_addition=%s\n", opts.ContentPaddingAddition)
}