ooni / probe

OONI Probe network measurement tool for detecting internet censorship
https://ooni.org/install
BSD 3-Clause "New" or "Revised" License
763 stars 142 forks source link

Design a simple credential distribution mechanism for WireGuard experiments #2772

Open ainghazal opened 4 months ago

ainghazal commented 4 months ago

Problem statement

We need a simple way of distributing credentials for probing target WireGuard nodes. We assume we're able to control abuse, for instance by adding firewall rules to the wireguard node restricting what are allowed IP addresses routed from the gateway.

In a recent conversation with @hellais we said that we'd like an implementation that keeps as little state as possible: this means that we can control what information is passed to the clients via the VPN endpoint API, and/or hardcoding tokens on the experiment itself. On the wireguard server, we need to generate the list of public keys (and IP allocations) for the set of allowed Peers -- but we'd rather avoid modifying the configuration file dynamically.

We agree that we can pre-compute a number of public keys (a 32-byte Curve25519 point) on the server; this number needs only to be big enough to practically minimize the likelihood of a "collision" (i.e., two probes attempting to use the same encryption key).

This constrain is given by WireGuard design:

Since a public key uniquely identifies a peer, the outer external 
source IP of an encrypted WireGuard packet is used to identify
the remote endpoint of a peer, enabling peers to roam freely between
different external IPs, between mobile networks for example

Design Discussion

Do note that Curve25519 clamping may need to be accounted for (i.e., different private keys can result in the same public key), although the likelihood of this happening is possibly negligible.

Choice of PRNG

Minor detail (need to benchmark it for practical usage), but we could either iterate through the whole range every time, if using a LCG (as the default PRNG in Go), that will give us O(n) complexity, or perhaps use a generator that allows skip-ahead, and thus O(1).

Priority & Deadlines

This would be the main blocker for distributing wireguard experiments to clients. At this point I'd say we're not on time to make it to the July release, so I would tentatively assign it to the September probe-cli release cycle. For sure testing from VPs can start as soon as I have a prototype ready.

ainghazal commented 4 months ago

@hellais thoughts or preferences?

hellais commented 4 months ago

I think we need to have a call to discuss this. We are currently a full capacity and we should aim for the simplest possible solution. Can do something like a github gist that just has in it the stuff you need and you hardcode that in your experiment? Alternatively would a OONI Run v2 link with custom options be sufficient?

ainghazal commented 4 months ago

fwiw, I got a binary util that can deterministically create server and peer configs given a pre-defined seed (and, implicitly, a chosen CIDR).

working on containerizing and integration tests.

ainghazal commented 4 months ago

would a OONI Run v2 link with custom options be sufficient?

that is already possible in the wireguard experiment. in fact, I had designed the wg MVP to support only an oonirun descriptor to avoid dealing with credential distribution (still, the distributors of the oonirun link should take into account how public the link is, and how many users are likely to attempt the test within the same time range). the scope of this issue is only related to exposing the experiment to the generality of users, so we should be free to drop prio for the time being.