Implement a RouterInfo parameter similar to Tor's MyFamily

Description

Tor has the MyFamily option that operators can set to group their nodes in the consensus, which helps their clients to build circuits through distinct operator groups. But there is no consensus on whether it is beneficial, and the current implementation has an O(n2) space requirement (because every node's descriptor lists every other node in the family).

I am curious as to how beneficial (or otherwise) this would be for I2P. It would only affect usage of peers whose operators choose to configure the setting; for all other peers, the peer selection algorithm would be unchanged.

Open questions:

How would this affect the probability of selecting malicious peers for a tunnel (who would not use the setting honestly)?

What happens if a router only knows peers that are all in the same family? Unlikely, but a possible corner case.

If we did decide this to be a good idea, it would be implemented along the lines of Tor's newer proposal.

After writing the Sybil analysis tool, I now think this is a good idea.

I count at least 13 floodfills that have a common /24 with another, including two pairs with the same IP. Most of them I think I i know who runs them, but not all.

Simply trusting a floodfill more if it has a family name set probably isn't that helpful, but it's useful for quick analysis. The proposal for a family signature in tor 242 linked above is adaptable to our setup but a lot more work. We could start with just the name as set in advanced config, and add the sig stuff later.

We would bundle the family pubkey certs as we do with other certs, but use Ed instead of RSA. We'd probably only need to sign the family name and the router hash, not anything that changed every time, so we'd only have to sign it once, not every time we published our RI. We'd only need to do sig verification in the Sybil checker.

There's a number of things to implement before we can store and distribute Ed pub/priv keys:

EdDSAPrivateKey and EdDSAPublicKey don't have getEncoded() implemented (for PKCS#8 and X.509 respectively). We don't have a real ASN.1 lib so we'd have to do it by hand, going off of the code we have in SigUtil?. Have to find the standard OID and parameter stuff.

We would need decoding methods as well

Java keystore doesn't know about Ed, so we couldn't store our privkeys in there, we'd have to store natively in PKCS#8

sign/verify algorithm would be the signature of the concatenation of (family name in UTF-8, 32-byte binary router hash). This doesn't change per-publish, so the router would only have to generate it once. Verifying routers could cache the verification result.

to set up, set the family name in the router advanced config with netdb.family.name=foo

first router in the family would generate keypair. Distribute privkey to other family members and install before setting the family. Check in pubkey cert to certificates/family. Alternative: Publish pubkey in the RI also. Router would have to store these persistently. First key for a family name wins. Maybe we implement both, so that some names are effectively reserved by having a cert for them.

This prevents any unauthorized routers from joining an existing family.

status:

I've added code to publish the family name, and my floodfills are running that code with the family 'i2p-dev'.

just did some x.509 certificate utility cleanup that I needed and checked that in

I have some untested, un-checkedin code to do signing/verification.

Would appreciate comments from str4d and others on whether we really want to do this. Still just playing around with it.

Enhancement in comment 8 to use our local cert to verify our own family is in 0.9.23-12.

Enhancement / alternative in 4th bullet of comment 6 (publishing pubkey) implemented in bf18831e5b7e3a25f1a9012ae603e3ea61836961 to be 0.9.23-13. This allows all families to be verifed without a local cert. Local certs are still supported and if present are used in preference to the published pubkey. When we have the cert, it can't be spoofed.

<str4d> zzz2, re: MyFamily?, see ​https://trac.torproject.org/projects/tor/ticket/18026 - I need to figure out what Tor is doing and for what reasons
<str4d> No point putting something in that we will later regret
<zzz2> yeah i've seen that. but see ML for recent onionoo changes
<zzz2> seems like they are moving forward with something
<zzz2> they have 350 families in current net
<dg> it's thought that only the good guys will specify MyFamily? so you're more likely to end up with an attacker
<dg> that was the thinking the last time I looked into it, i think it was only a minor part of a sybil paper
<dg> tor have been meaning to kill it for a long time
<zzz2> looks to me like they're going forward with fixing it
<zzz2> if we're going to start serious sybil monitoring, then knowing who the good guys are is important too
<str4d> Thing is, what we currently do as "MyFamily?" isn't quite what Tor does
<str4d> And I'm still getting my head around its implications
<zzz2> right. it's closer to what they're going to do
<zzz2> winter reports 18 sybil attacks in last 5 1/2 years

Persistent objection is that 'only good guys will use family'. However, knowing who the good guys are is extremely valuable when doing Sybil analysis.

The one feature not provided by my implementation is membership in multiple families. My assessment was that it's a needless complication and I couldn't think of a use case.

Pushed my i2p-dev family cert in 0.9.23-23-rc, and that's it for 0.9.23. We can rip it out or redo it in some future release if we want to, but my general proposal has been here for 6 weeks and the code checked in for 5 weeks, without any objection seen, so I consider it done for now.