diff --git a/storagenode/contact/contact_test.go b/storagenode/contact/contact_test.go index 44eea8720..61ec3bef5 100644 --- a/storagenode/contact/contact_test.go +++ b/storagenode/contact/contact_test.go @@ -4,13 +4,17 @@ package contact_test import ( + "crypto/tls" + "crypto/x509" "testing" "time" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" + "storj.io/common/identity/testidentity" "storj.io/common/pb" + "storj.io/common/rpc/rpcpeer" "storj.io/common/testcontext" "storj.io/storj/private/testplanet" ) @@ -102,6 +106,34 @@ func TestServicePingSatellites(t *testing.T) { }) } +func TestEndpointPingNode_UnTrust(t *testing.T) { + testplanet.Run(t, testplanet.Config{ + SatelliteCount: 1, StorageNodeCount: 1, UplinkCount: 0, + }, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) { + node := planet.StorageNodes[0] + node.Contact.Chore.Pause(ctx) + + // make sure a trusted satellite is able to ping node + info, err := planet.Satellites[0].Overlay.Service.Get(ctx, node.ID()) + require.NoError(t, err) + require.Equal(t, node.ID(), info.Id) + + // an untrusted peer shouldn't be able to ping node successfully + ident, err := testidentity.NewTestIdentity(ctx) + require.NoError(t, err) + + state := tls.ConnectionState{ + PeerCertificates: []*x509.Certificate{ident.Leaf, ident.CA}, + } + peerCtx := rpcpeer.NewContext(ctx, &rpcpeer.Peer{ + Addr: node.Server.Addr(), + State: state, + }) + _, err = node.Contact.Endpoint.PingNode(peerCtx, &pb.ContactPingRequest{}) + require.Error(t, err) + }) +} + func TestLocalAndUpdateSelf(t *testing.T) { testplanet.Run(t, testplanet.Config{ SatelliteCount: 1, StorageNodeCount: 1, UplinkCount: 0, diff --git a/storagenode/contact/endpoint.go b/storagenode/contact/endpoint.go index 6aefb503d..231e82e66 100644 --- a/storagenode/contact/endpoint.go +++ b/storagenode/contact/endpoint.go @@ -14,6 +14,7 @@ import ( "storj.io/common/pb" "storj.io/common/rpc/rpcpeer" "storj.io/common/rpc/rpcstatus" + "storj.io/storj/storagenode/trust" ) // Endpoint implements the contact service Endpoints. @@ -23,6 +24,8 @@ type Endpoint struct { pb.DRPCContactUnimplementedServer log *zap.Logger pingStats *PingStats + + trust *trust.Pool } // PingStats contains information regarding when the node was last pinged. @@ -32,10 +35,11 @@ type PingStats struct { } // NewEndpoint returns a new contact service endpoint. -func NewEndpoint(log *zap.Logger, pingStats *PingStats) *Endpoint { +func NewEndpoint(log *zap.Logger, trust *trust.Pool, pingStats *PingStats) *Endpoint { return &Endpoint{ log: log, pingStats: pingStats, + trust: trust, } } @@ -50,6 +54,10 @@ func (endpoint *Endpoint) PingNode(ctx context.Context, req *pb.ContactPingReque if err != nil { return nil, rpcstatus.Error(rpcstatus.Unauthenticated, err.Error()) } + if err := endpoint.trust.VerifySatelliteID(ctx, peerID.ID); err != nil { + return nil, rpcstatus.Error(rpcstatus.Unauthenticated, err.Error()) + } + endpoint.log.Debug("pinged", zap.Stringer("by", peerID.ID), zap.Stringer("srcAddr", peer.Addr)) endpoint.pingStats.WasPinged(time.Now()) return &pb.ContactPingResponse{}, nil diff --git a/storagenode/peer.go b/storagenode/peer.go index d00c6dc95..4b201ba49 100644 --- a/storagenode/peer.go +++ b/storagenode/peer.go @@ -420,7 +420,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten Close: peer.Contact.Chore.Close, }) - peer.Contact.Endpoint = contact.NewEndpoint(peer.Log.Named("contact:endpoint"), peer.Contact.PingStats) + peer.Contact.Endpoint = contact.NewEndpoint(peer.Log.Named("contact:endpoint"), peer.Storage2.Trust, peer.Contact.PingStats) if err := pb.DRPCRegisterContact(peer.Server.DRPC(), peer.Contact.Endpoint); err != nil { return nil, errs.Combine(err, peer.Close()) }