libp2p / go-libp2p-pubsub

The PubSub implementation for go-libp2p
https://github.com/libp2p/specs/tree/master/pubsub
Other
309 stars 178 forks source link

How to write a validator or peer filter that blocks by IP addresses? #531

Closed estebanabaroa closed 1 year ago

estebanabaroa commented 1 year ago

Sorry if this is documented somewhere or if there's a better place to ask this question but I couldn't find it. I wrote a custom default validator function like this:

func validate(ctx context.Context, peerId peer.ID, pubsubMessage *pubsub.Message) bool {
    message, err := cborDecode(pubsubMessage.Data)
    ...
}

I'm trying to validate if an IP address (not a peer ID) has sent some message in the past that is now in retrospect considered invalid. I dont want to just block peer IDs since someone can generate infinite IDs.

It seems peer.ID and pubsub.Message don't have the IP address, so how would you recommend I access it? My plan is to fork kubo and add my custom validator there, so the pubsub would be instanciated by kubo.

vyzo commented 1 year ago

If your validator has access to the Peerstore through the host, then it can query it for the known peer adresses.

That's probably your best option.

estebanabaroa commented 1 year ago

If your validator has access to the Peerstore through the host, then it can query it for the known peer adresses.

Thanks I figured out how to use the peerstore

type Validator struct {
    host host.Host
}

func (validator Validator) Validate(ctx context.Context, peerId peer.ID, pubsubMessage *pubsub.Message) bool {
    peerMultiAddresses := validator.host.Peerstore().Addrs(peerId)
    // ...
}

host, _ := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"))
validator := Validator{host}
ps, _ := pubsub.NewGossipSub(ctx, host, pubsub.WithDefaultValidator(validator.Validate))

Also I see in the readme that there's AppSpecificScore https://pkg.go.dev/github.com/libp2p/go-libp2p-pubsub#PeerScoreParams, instead of manually blocking IP addresses, would it be better to lower the score of a peer? Would a peer with a low score automatically get their IP blocked eventually? Also how do I manually lower a peer's score during validation, I'm not finding an API for it.

vyzo commented 1 year ago

Yes, using the app specific score can be used as a soft blocking mechanism. If a peer is negatively scored, it wont be part of the mesh. And if its score is even lower (see the threshold values in the spec) we can stop publishing to it and even completely ignore its messages.

One caveat is that the app specific score function should be fast, the score function gets called a lot internally.

vyzo commented 1 year ago

Note: You cant explicitly lower a peer's score by hand, you'd have to do it through the app specific score. See also the tracer api.