Skip to content

Commit

Permalink
satellite/contact: accept self signed tags from storagenodes
Browse files Browse the repository at this point in the history
We will accept tags which are signed by node tags.

It is useful to participate in opt-in requirements, as node operators can signal intentions with adding tags.

Strictly speaking this signature is not required (TLS connection already proved the ownership), but it's cheap, and makes the code simple...

Change-Id: Icba3632a6de95d08661debf3e416e22adbb3f018
  • Loading branch information
elek authored and Storj Robot committed May 3, 2024
1 parent 532942c commit c23ba19
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
26 changes: 21 additions & 5 deletions satellite/contact/contact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func TestSatelliteContactEndpoint_WithNodeTags(t *testing.T) {
},
}

unsignedTags := &pb.NodeTagSet{
signedTags, err := nodetag.Sign(ctx, &pb.NodeTagSet{
NodeId: ident.ID.Bytes(),
Tags: []*pb.Tag{
{
Expand All @@ -220,9 +220,18 @@ func TestSatelliteContactEndpoint_WithNodeTags(t *testing.T) {
Value: []byte("bar"),
},
},
}
}, signing.SignerFromFullIdentity(planet.Satellites[0].Identity))
require.NoError(t, err)

signedTags, err := nodetag.Sign(ctx, unsignedTags, signing.SignerFromFullIdentity(planet.Satellites[0].Identity))
selfSignedTag, err := nodetag.Sign(ctx, &pb.NodeTagSet{
NodeId: ident.ID.Bytes(),
Tags: []*pb.Tag{
{
Name: "self",
Value: []byte{1},
},
},
}, signing.SignerFromFullIdentity(planet.StorageNodes[0].Identity))
require.NoError(t, err)

peerCtx := rpcpeer.NewContext(ctx, &peer)
Expand All @@ -236,6 +245,7 @@ func TestSatelliteContactEndpoint_WithNodeTags(t *testing.T) {
SignedTags: &pb.SignedNodeTagSets{
Tags: []*pb.SignedNodeTagSet{
signedTags,
selfSignedTag,
},
},
})
Expand All @@ -244,15 +254,21 @@ func TestSatelliteContactEndpoint_WithNodeTags(t *testing.T) {

tags, err := planet.Satellites[0].DB.OverlayCache().GetNodeTags(ctx, ident.ID)
require.NoError(t, err)
require.Len(t, tags, 2)
require.Len(t, tags, 3)
sort.Slice(tags, func(i, j int) bool {
return tags[i].Name < tags[j].Name
})
require.Equal(t, "foo", tags[0].Name)
require.Equal(t, "bar", string(tags[0].Value))
require.Equal(t, planet.Satellites[0].Identity.ID, tags[0].Signer)

require.Equal(t, "soc", tags[1].Name)
require.Equal(t, "self", tags[1].Name)
require.Equal(t, []byte{1}, tags[1].Value)
require.Equal(t, planet.StorageNodes[0].Identity.ID, tags[1].Signer)

require.Equal(t, "soc", tags[2].Name)
require.Equal(t, []byte{1}, tags[2].Value)
require.Equal(t, planet.Satellites[0].Identity.ID, tags[2].Signer)

})
}
Expand Down
3 changes: 2 additions & 1 deletion satellite/contact/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"storj.io/common/pb"
"storj.io/common/rpc/noise"
"storj.io/common/rpc/rpcstatus"
"storj.io/common/signing"
"storj.io/common/storj"
"storj.io/drpc/drpcctx"
"storj.io/eventkit"
Expand Down Expand Up @@ -114,7 +115,7 @@ func (endpoint *Endpoint) CheckIn(ctx context.Context, req *pb.CheckInRequest) (
req.Operator.WalletFeatures = nil
}
}
err = endpoint.service.processNodeTags(ctx, nodeID, req.SignedTags)
err = endpoint.service.processNodeTags(ctx, nodeID, signing.SigneeFromPeerIdentity(peerID), req.SignedTags)
if err != nil {
endpoint.log.Info("failed to update node tags", zap.String("node address", req.Address), zap.Stringer("Node ID", nodeID), zap.Error(err))
}
Expand Down
5 changes: 3 additions & 2 deletions satellite/contact/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"storj.io/common/rpc"
"storj.io/common/rpc/quic"
"storj.io/common/rpc/rpcstatus"
"storj.io/common/signing"
"storj.io/common/storj"
"storj.io/storj/satellite/nodeselection"
"storj.io/storj/satellite/overlay"
Expand Down Expand Up @@ -145,11 +146,11 @@ func (service *Service) pingNodeQUIC(ctx context.Context, nodeurl storj.NodeURL)
return nil
}

func (service *Service) processNodeTags(ctx context.Context, nodeID storj.NodeID, req *pb.SignedNodeTagSets) error {
func (service *Service) processNodeTags(ctx context.Context, nodeID storj.NodeID, self signing.Signee, req *pb.SignedNodeTagSets) error {
if req != nil {
tags := nodeselection.NodeTags{}
for _, t := range req.Tags {
verifiedTags, signerID, err := verifyTags(ctx, service.nodeTagAuthority, nodeID, t)
verifiedTags, signerID, err := verifyTags(ctx, append(service.nodeTagAuthority, self), nodeID, t)
if err != nil {
service.log.Info("Failed to verify tags.", zap.Error(err), zap.Stringer("NodeID", nodeID))
continue
Expand Down

0 comments on commit c23ba19

Please sign in to comment.