riccardom
cb2deee354
Discriminate initial from rekey failure
2026-07-31 10:49:27 +02:00
riccardom
824055c1c7
pqkem: strict (fail-closed) mode + wire status Quantum resistance
...
Strict mode (NB_PQ_MLKEM_STRICT, default off) closes the initial PQ-vulnerable
window (NET-1408): when enabled, conn.presharedKey programs a per-conn random
sentinel PSK until the ML-KEM exchange derives the real one, so no session can form
on a non-PQ key (the real PSK is pushed via SetPresharedKey once it converges).
Default stays opportunistic.
Also surface PQ status: the peer 'Quantum resistance' flag (RosenpassEnabled) is now
true when an ML-KEM PSK has been derived for the peer, not only for Rosenpass.
2026-07-31 10:49:27 +02:00
riccardom
5fbd6fdc69
pqkem: rotate PSK in kernel mode instead of skipping
...
The idle-gate reads LastActivities, which only tracks per-peer data in userspace;
in kernel mode it is empty, so the gate treated every kernel peer as idle and
disabled data-path rotation entirely. Detect the bind via IsUserspaceBind and, in
kernel mode, report zero activity age (always 'active') so rotation runs on every
rekey. Lazy back-to-idle is already limited in kernel; the eBPF WG-activity
detection will later supply a real signal that excludes handshake/pqkem traffic.
2026-07-31 10:49:27 +02:00
riccardom
5369fbcae2
pqkem: derive PSK with HKDF-SHA256
...
Replace the raw SHA-256 concat combiner with HKDF-SHA256 (crypto/hkdf, Go 1.24):
IKM = ML-KEM_ss || X25519_ss (draft-ietf-tls-ecdhe-mlkem order), salt = the
domain-separation label, info = full transcript (offer || answer) || canonicalised
peer identities. Keeps the transcript + identity binding while using a proper KDF.
2026-07-31 10:49:27 +02:00
riccardom
ba2d9abbdc
Don't rotate PQ keys if data path is idle for ~90s (less than a WG handhshake time
2026-07-31 10:49:27 +02:00
riccardom
46c12f3d01
Adds log tracepoints
...
- Add a trace slog level (NB_PQ_MLKEM_LOG_LEVEL=trace) and move the verbose
per-exchange lifecycle logs (offer/answer/PSK/ack/rotation) to it, so debug
stays quiet and troubleshooting is opt-in.
- Stop logging the raw preshared key; drop the temporary pqkem-dbg OnRemoteOffer/
OnRemoteAnswer probes.
- Demote the per-handshake conn log to trace.
2026-07-31 10:23:07 +02:00
riccardom
af56ae716b
Fixes second answer dropped (the one carrying the PQ KEM data)
...
Prevents dropping concurrent answer / offer carrying the PQ ML-KEM data
2026-07-28 14:31:14 +02:00
riccardom
4e3805f535
Renames SetRemotePort to SetRemoteAddr
2026-07-27 17:09:36 +02:00
riccardom
80c7bb195e
pqkem: clock data-path PSK rotation from WireGuard handshakes
...
Source OnDataPathRekeyed from the WGWatcher's per-handshake callback
(onWGCheckSuccess), which fires only on a fresh handshake, and OnDataPathDown
from the handshake-timeout path. A fresh handshake clocks the next chained
KEM exchange pushed over the data-path UDP transport.
2026-07-27 17:09:36 +02:00
riccardom
cac03bd80c
pqkem: register data-path endpoint from signalling
...
Learn the peer's data-path endpoint from the signalling offer/answer: its WG
overlay IP combined with the advertised pq UDP port (SetRemotePort -> AddPeer).
Registering here is safe before the tunnel is up because sends only ever fire
once it is (clocked by OnDataPathRekeyed). RemovePeer is wired at peer teardown
(engine.removePeer), not on transient disconnect.
2026-07-27 17:09:36 +02:00
riccardom
2681f5f8e6
pqkem: apply derived PSK at WG peer-config time (pull) + keep push for rekey
2026-07-27 17:09:36 +02:00
riccardom
905b7f7914
pqkem: carry KEM offer/answer over the signalling exchange
2026-07-27 17:09:36 +02:00
riccardom
20ae4325ff
pqkem: dedicated slog logger via NB_PQ_MLKEM_LOG_LEVEL
2026-07-27 17:09:36 +02:00
riccardom
4189937ac6
Homogeneous logs prefix
2026-07-27 17:09:36 +02:00
riccardom
1bccd71954
Bit of renaming
...
peer -> peerAddrs
have types for remoteID and localID
t.Close log error
Manager SetTransport -> Start
2026-07-27 17:09:36 +02:00
riccardom
f91e1e34ce
Typo
2026-07-27 17:09:36 +02:00
riccardom
d544bfa15e
Race fix
2026-07-27 17:09:36 +02:00
riccardom
a9fb4e9f0a
Makes Transport just a UDP socket.
...
Manager owns maps for remoteID <-> remote UDP addr
Engine talks to manager only
2026-07-27 17:09:36 +02:00
riccardom
9074f36761
Adds transport
2026-07-27 17:09:36 +02:00
riccardom
a165eec3ba
Communicate the port over the signal exchange
2026-07-27 17:09:36 +02:00
riccardom
4e7cbe2ef8
Ensure iface is up and with overlay ip assigned to get a valid UDP port
2026-07-27 17:09:36 +02:00
riccardom
8157b6d78f
Adds real callback setter for PSK on ready
2026-07-27 17:09:36 +02:00
riccardom
b132eff867
Initializes PQ ML-KEM manager
2026-07-27 17:09:35 +02:00
riccardom
e98019bafc
Adds no-op Transports and callbacks
2026-07-27 17:09:35 +02:00
riccardom
f4fddce174
Added enabled env var
2026-07-27 17:09:35 +02:00
riccardom
94adc454c1
Adds MLKEM Payload placeholder to client internals
2026-07-27 17:09:35 +02:00
riccardom
80f415519b
Invert order of keys as per draft
2026-07-27 17:09:35 +02:00
riccardom
2e7436f49b
Protocol update
2026-07-27 17:09:35 +02:00
riccardom
010f5281ce
Removes confirm. Uses next offer to deliver confirmation/ack of previous round
...
We clock the next Offer initiation to the OnDataPathRekeyed, so we have 2 minutes
ahead of us to do our attempts and stuff before to give up.
On failure, we will know because we will not receive a new answer.. but more importantly
the wg handshake will fail :D
2026-07-27 17:09:35 +02:00
riccardom
e88fc05575
Leave signal offer/answer as a pull/push operation not as an actual transport
2026-07-27 17:09:35 +02:00
riccardom
7d2c71f84f
Assume two transports: initial "signal" (control plane) one (no data path established yet) + data path one
...
Define OnDataPathRekeyed event to transition from control plane path to data plane path over the WG tunnel.
Keep confirm ALWAYS on NEW established WG tunnel (posthandshake with rekeying). We keep an active method
irrelevant of the WG handshake (we might decide that the indirect wg handshake is sufficient in the future).
Optimistic commit on responder(when sending answer), while on initiator we set it on getting the answer
2026-07-27 17:09:35 +02:00
riccardom
3e4652e528
Epurate wg refs
2026-07-27 17:09:35 +02:00
riccardom
46d4e4585d
Collapse Driver and Manager in one.
...
- Have just one manager => one lock
- Session state is needed in driver to => we have it available now.
- Isomorphically align to rosenpass components and functionality
File Role rosenpass equivalent
kem.go primitive pure X25519MLKEM768 crypto.go/handshake
message.go Offer/Answer/Confirm + Encode/Decode messages.go
manager.go Manager stateful, single lock server logic
callbacks.go WGCallbackHandler (seam output) Handler
Transport (interfaccia) seam trasporto pluggable Conn
2026-07-27 17:09:35 +02:00
riccardom
9edf2f4dea
[squash] isInitial and answered can be inferred without state variables
2026-07-27 17:09:35 +02:00
riccardom
43d43e2a97
Manages convergence
2026-07-27 17:09:35 +02:00
riccardom
bca463d4c8
Models reattempts
2026-07-27 17:09:35 +02:00
riccardom
3ad12f0e58
Reuse answer, don't calculate again
2026-07-27 17:09:35 +02:00
riccardom
85df3abf0f
Adds driver to glue together manager and outside world
2026-07-27 17:09:35 +02:00
riccardom
34f5756117
Defines event callbacks
2026-07-27 17:09:35 +02:00
riccardom
b728542d40
Admits possible errors on Encode
2026-07-27 17:09:35 +02:00
riccardom
b95e1aafe3
Bench key material boilerplate time/allocs
...
CGO_ENABLED=1 go test ./client/internal/pqkem/ -run '^$' -bench . -benchmem 2>&1 | grep -E "Benchmark|ns/op|PASS|ok" | head -20
BenchmarkX25519Keygen-14 33795 34966 ns/op 224 B/op 5 allocs/op
BenchmarkX25519ECDH-14 33855 33973 ns/op 32 B/op 1 allocs/op
BenchmarkMLKEMKeygen-14 21817 67778 ns/op 8200 B/op 2 allocs/op
BenchmarkMLKEMEncaps-14 29918 43235 ns/op 1216 B/op 2 allocs/op
BenchmarkMLKEMDecaps-14 26048 56291 ns/op 64 B/op 2 allocs/op
PASS
ok github.com/netbirdio/netbird/client/internal/pqkem 9.751s
Shell cwd was reset to /home/riccardo/Desktop/Personal/netbirdio/netbird
2026-07-27 17:09:35 +02:00
riccardom
35ec435658
Pure mechanics of manager
2026-07-27 17:09:35 +02:00
riccardom
49922a8831
Messages definition
2026-07-27 17:09:35 +02:00
riccardom
3e7f52d80b
ML-KEM encapsulate/decapsulate module
2026-07-27 17:09:35 +02:00
Misha Bragin
1816a020c4
[management, proxy] Add Claude Opus 5 ( #6895 )
2026-07-27 16:15:36 +02:00
Zoltan Papp
aa13928b76
[client] Export agent version info for iOS ( #6918 )
...
## Describe your changes
Export agent version info for iOS
## Issue ticket number and link
## Stack
<!-- branch-stack -->
### Checklist
- [ ] Is it a bug fix
- [ ] Is a typo/documentation fix
- [ ] Is a feature enhancement
- [x] It is a refactor
- [ ] Created tests that fail without the change (if possible)
- [ ] This change does **not** modify the public API, gRPC protocols,
functionality behavior, CLI / service flags, or introduce a new feature
— **OR** I have discussed it with the NetBird team beforehand (link the
issue / Slack thread in the description). See
[CONTRIBUTING.md](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTING.md#discuss-changes-with-the-netbird-team-first ).
> By submitting this pull request, you confirm that you have read and
agree to the terms of the [Contributor License
Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md ).
## Documentation
Select exactly one:
- [ ] I added/updated documentation for this change
- [x] Documentation is **not needed** for this change (explain why)
### Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
https://github.com/netbirdio/docs/pull/__
<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/netbirdio/codesmith/netbird/pr/6918 "><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg "><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg "><img
alt="View with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg "></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787750541&installation_model_id=427504&pr_number=6918&repository=netbirdio%2Fnetbird&return_to=https%3A%2F%2Fgithub.com%2Fnetbirdio%2Fnetbird%2Fpull%2F6918&signature=c2de74d89c36b01aac5866422b0be0b7525f7c6e26e46174efc280339eb864b6 "><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg "><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg "><img
alt="Autofix with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg "></picture></a>
<sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you
need. Autofix is disabled.</sup>
<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
2026-07-27 15:53:09 +02:00
Viktor Liu
d681670a9d
[misc] Restore the rootless-latest docker tag ( #6914 )
2026-07-27 12:07:58 +02:00
Maycon Santos
4f6247b5c3
[management, proxy] Add prompt-cache token and cost accounting to agent network usage ( #6900 )
...
Co-authored-by: braginini <bangvalo@gmail.com >
2026-07-26 21:42:41 +02:00
Riccardo Manfrin
1e5b0a5c89
[client] Make Test_ConnectPeers deterministic under Docker/eBPF kernel / Darwin CI ( #6884 )
...
## Describe your changes
Make `Test_ConnectPeers` deterministic. Two issues, both surfaced once
the
privileged suite moved into a `--privileged` Docker container (#6425 ):
1. The peers used `getLocalIP()` as their WireGuard endpoint, i.e. the
host's
routable NIC IP (the docker bridge IP `172.17.0.2` in CI). That address
might
not hairpin reliably inside the container, so the handshake
intermittently
timed out (flaky). Use loopback (`127.1.0.x`) instead — always
self-reachable.
2. On a Linux runner with the WG kernel module the iface uses the eBPF
proxy
factory. Its manager is a singleton with one shared XDP program +
settings
map, so bringing up the two ifaces makes the second factory overwrite
the
first's `wg_port`/`proxy_port` and the handshake is dropped. The test is
incompatible with the eBPF factory, so disable it via
`NB_DISABLE_EBPF_WG_PROXY` (peers then handshake directly over
loopback).
Running the suite across all three modes (eBPF / UDP proxy / ICE bind)
would
need a larger refactor.
Also fixes a typo in the `ErrSharedSockStopped` message (`socked` →
`socket`).
## Issue ticket number and link
No public issue — CI flakiness follow-up to #6871 on `Test_ConnectPeers`
(https://github.com/netbirdio/netbird/blob/main/client/iface/iface_test.go ).
## Stack
<!-- branch-stack -->
### Checklist
- [x] Is it a bug fix
- [ ] Is a typo/documentation fix
- [ ] Is a feature enhancement
- [ ] It is a refactor
- [ ] Created tests that fail without the change (if possible)
> By submitting this pull request, you confirm that you have read and
agree to the terms of the [Contributor License
Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md ).
## Documentation
Select exactly one:
- [ ] I added/updated documentation for this change
- [x] Documentation is **not needed** for this change (explain why)
Test-only change (plus a log-string typo). No public API, CLI, config,
or
behavior change.
### Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
N/A
<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/netbirdio/codesmith/netbird/pr/6884 "><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg "><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg "><img
alt="View with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg "></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787485967&installation_model_id=427504&pr_number=6884&repository=netbirdio%2Fnetbird&return_to=https%3A%2F%2Fgithub.com%2Fnetbirdio%2Fnetbird%2Fpull%2F6884&signature=09fb996715d039bd02775a140e8cc03deca5cb42540790b82a744527264a30ad "><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg "><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg "><img
alt="Autofix with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg "></picture></a>
<sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you
need. Autofix is disabled.</sup>
<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Corrected the “shared socket stopped” error message for clearer
output.
* **Tests**
* Improved peer connection test reliability in privileged CI by
disabling the eBPF WireGuard proxy and using fixed loopback UDP
endpoints for deterministic setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 15:23:22 +02:00
Riccardo Manfrin
b65ec8b68a
[client] Restores lost backup.Reset from #4935 ( #6883 )
...
## Describe your changes
Restore the management gRPC client's backoff reset after a stream
connects.
This is a regression: PR #4935 originally added this reset; it was then
lost in
commit `58daa674e` during the `withMgmtStream` refactor (Sync/Job
unification).
Compared to before the reset was done AFTER receiveEvents, whereas
now it's done before.
Now should cover for Sync and Job (which didn't exist in #4935 . Hold for
long living stream that breaks.
Reset prevents two things
1. long living conns going wrong from waiting a long backoff time window
before to drive reconn
2. past MaxElapsedTime (3months) long lived conns failures from being
treated as "unrecoverable" (hence triggering an full restart of the
engine)
## Issue ticket number and link
Internal support case (customer agents lost data-plane connectivity
during a
management maintenance/release window). No public issue. Regression
introduced
in commit `58daa674e`, which removed the `backOff.Reset()` added by PR
#4935 .
## Stack
<!-- branch-stack -->
### Checklist
- [x] Is it a bug fix
- [ ] Is a typo/documentation fix
- [ ] Is a feature enhancement
- [ ] It is a refactor
- [ ] Created tests that fail without the change (if possible)
> By submitting this pull request, you confirm that you have read and
agree to the terms of the [Contributor License
Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md ).
## Documentation
Select exactly one:
- [ ] I added/updated documentation for this change
- [x] Documentation is **not needed** for this change (explain why)
Internal reconnection-behavior fix in the management gRPC client. No
public
NetBird CLI, API, or configuration surface changes.
### Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
N/A
<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/netbirdio/codesmith/netbird/pr/6883 "><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg "><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg "><img
alt="View with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg "></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787484622&installation_model_id=427504&pr_number=6883&repository=netbirdio%2Fnetbird&return_to=https%3A%2F%2Fgithub.com%2Fnetbirdio%2Fnetbird%2Fpull%2F6883&signature=525b08edbcb94ee6f4ae4226fb1fe8ddb829caa7d4489e8efa639770af9dccdf "><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg "><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg "><img
alt="Autofix with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg "></picture></a>
<sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you
need. Autofix is disabled.</sup>
<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved management stream retry behavior.
* Retry delays now reset after a stream is successfully established,
helping subsequent connection attempts recover more quickly.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-24 13:53:53 +02:00