Hello, relay operators!
I'm hoping to get some feedback from relay operators, particularly
those who use the MyFamily option, about the best way to deploy
proposal 321. You can read the proposal at:
https://gitlab.torproject.org/tpo/core/torspec/-/blob/master/proposals/321-happy-families.md
The main idea of this proposal is to provide an easier way for
relays to declare that they are in the same family. With proposal
321, each relay in the same family uses a cryptographic certificate
to prove that it is in the same family as the others.
(That's just a summary; see the full proposal at the link above for
a write up of how it works, an a description of backwards
compatibility issues.)
Now, my question is, how can we make this approach as usable as possible?
There are several different ways that we could have it work in practice:
Option 1:
Every family would have a shared secret. This would be a
random file that you'd have to copy to every relay in the family
when you set it up. The relays would use this shared secret to
derive a shared private key.
If this file is ever exposed (for example, if a relay is
compromised), you'd need to make a new one, and copy it to every
relay in the family. (Otherwise, an attacker could claim to be
in your family.)
We could provide a convenient function to make a new secure
shared secret, something like:
$ tor --new-family-secret <filename>
Option 2:
As above, except instead of the shared secret, it would be a
shared ed25519 private key for the family. This would be an
ed25519 private key that would have to be copied to every relay
in the family.
If this key is ever exposed (For example, if one relay in the
family is compromised), you'll need to make a new one, and copy
it to every relay in the family. (Otherwise, an attacker could
claim to be in your family.)
We'd provide a command to generate new keys; it would look
something like:
$ tor --new-family-key <keyfile>
Option 3:
Offline certificate generation with separate distribution. In
this scheme, there would be an ed25519 private key for the
family, but you wouldn't have to copy it to the relays. Instead,
you'd have to generate certificates from the private key offline,
and then copy those certificates to the relays. They would have
a lifetime of N days; you'd need to make new certificates every N
days.
If a relay's certificate is exposed, you don't need to generate
new certificates for the other relays. You just stop generating
certificates for that one relay.
If the offline private key were ever exposed, you'd have to
generate a new one, and a new set of certificates.
The interface would probably look something like:
$ tor --new-family-key <keyfile>
$ tor --make-family-certs --key <keyfile> --members \
<family_list_file> --out <certfile> --lifetime <n days>
Then you'd do something like:
$ for member in $(cat family_hostnames); do
scp <certfile> member:/srv/tor/tor-family-cert
done
Option 3 requires regular updates to all the relays in the family,
which makes it cumbersome. Its advantage is that if a relay is
compromised, you don't need to re-key the family.
Options 1 and 2 are less secure, since you have to re-key your whole
family if the key is ever compromised. But they have the advantage
that they don't take any maintenance in the regular case.
Option 1 is a little more convenient than option 2, since you can
use any old random file. But that makes it more error prone: if
somebody chooses an insecure password as their random file, an
attacker could guess it and become a family member.
So...
If all three of these options were available, which of these would
you choose? Is there anything else that we could do to make this
system simpler or easier to use?
If I'm left to my own devices, I will probably just implement option
2 for now, but leave the door open for option 3 in the future.
best wishes,
--
Nick