sargassum-world / latreutes

Desktop application for connecting to ZeroTier networks
Apache License 2.0
1 stars 1 forks source link

Add a way for devices to attest to their generation of "join form" submissions #13

Open ethanjli opened 3 years ago

ethanjli commented 3 years ago

In #12, no mechanism is specified for checking the validity of "join form" submissions - instead, the network administrator must check out-of-band that the information is valid, and that the device operator agrees with the contents of the "join form". It will be much easier and smoother to add devices to the network if some of this can be driven by the operator of the device which is being added to the network.

ethanjli commented 3 years ago

Here are possible approaches for confirming with the device operator (via the device) that they produced the "join form" submission. This allows us to protect against other people trying to impersonate the device operator (specifically making "join form submissions" without coordinating with the device operator), so we can be sure that the "join form" submission actually belongs to the device it says it belongs to. However, it doesn't allow us to confirm who the device operator is or whether they are someone we want on the network. The identity and trustworthiness of the device operator would have to be determined out-of-band anyways.

Run a server on the joining device

If the joining device runs a server, then the network host's server can directly talk to it over a secured, private route from the assigned IPv6 address and and ask it to confirm that the "join form" submission's information is correct.

Challenges:

Temporary network and API endpoint on the network host

For every join "join form" submission (which is uniquely identified by a triple of the network ID and the node ID), the network host provisions a unique temporary network for the joining device to join, with the joining device's node ID already whitelisted; then the network announces the network ID as well as the IPv6 address to connect to, which serves an API endpoint available only on that private network. The network host can then monitor the network, and once the joining device has joined, the device accesses the API endpoint to review the "join form" submission and verify that the joining device's operator produced the "join form" submission.

Challenges:

Temporary network on the joining device

The network host's server knows the Node ID of the joining device. If the joining device provisions its own unique temporary network and provides the network ID in the "join form" submission, and whitelists the network host's node ID (which can be extracted from the network ID), then the network host's server can try to join; if it's accepted, then the network host can be sure that the "join form" submission came from someone who operates the joining device (or who can eavesdrop on the list of joined networks on the joining device). So the temporary network's network ID and configuration acts as a proof that the "join form"'s submitter has control over or privileged visibility into the joining device. Afterwards, the joining device's temporary network should be destroyed. There should be a way to ensure that the "join form" submission can't be tampered with - i.e. an attacker leaving the joining device's temporary network unchanged while changing other fields.

This would be vulnerable to an attack where the joining device provisions a new temporary network for the network host to join, and then the attacker gains knowledge of that network ID and makes a "join form" submission using it. This could happen through a few attacks:

Temporary network on the network host

As a response to every "join form" submission, the network host provisions a unique temporary network for the joining device to join within n minutes and replies to the "join form" submission with the network ID. If the joining device joins that network within that duration, then the network host takes that as proof that whoever made the "join form" submission also controls the joining device. This is probably the simplest approach, and it's the most similar to device pairing protocols (e.g. a user tries to log in to a mobile messaging app from the desktop, then the desktop asks the user to open a QR code from their phone).

If needed, each temporary network ID can also be given a human-readable heroku-style hostname for someone to join manually, though I don't think this would ever actually be needed.

Attacks: