satellite/api: configuration option to set additional node tag authorities
Change-Id: Iba387e37cb586ce1378668c99beb3b4db8a9064d
This commit is contained in:
parent
034542db8f
commit
2ed08922d9
@ -8,7 +8,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
|
||||
"github.com/spacemonkeygo/monkit/v3"
|
||||
"github.com/zeebo/errs"
|
||||
@ -327,9 +329,10 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
|
||||
Version: *pbVersion,
|
||||
}
|
||||
|
||||
var authority nodetag.Authority
|
||||
peerIdentity := full.PeerIdentity()
|
||||
authority = append(authority, signing.SigneeFromPeerIdentity(peerIdentity))
|
||||
authority, err := loadAuthorities(full.PeerIdentity(), config.TagAuthorities)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer.Contact.Service = contact.NewService(peer.Log.Named("contact:service"), self, peer.Overlay.Service, peer.DB.PeerIdentities(), peer.Dialer, authority, config.Contact)
|
||||
peer.Contact.Endpoint = contact.NewEndpoint(peer.Log.Named("contact:endpoint"), peer.Contact.Service)
|
||||
@ -678,6 +681,28 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
|
||||
return peer, nil
|
||||
}
|
||||
|
||||
func loadAuthorities(peerIdentity *identity.PeerIdentity, authorityLocations string) (nodetag.Authority, error) {
|
||||
var authority nodetag.Authority
|
||||
authority = append(authority, signing.SigneeFromPeerIdentity(peerIdentity))
|
||||
for _, cert := range strings.Split(authorityLocations, ",") {
|
||||
cert = strings.TrimSpace(cert)
|
||||
if cert == "" {
|
||||
continue
|
||||
}
|
||||
cert = strings.TrimSpace(cert)
|
||||
raw, err := os.ReadFile(cert)
|
||||
if err != nil {
|
||||
return nil, errs.New("Couldn't load identity for node tag authority from %s: %v", cert, err)
|
||||
}
|
||||
pi, err := identity.PeerIdentityFromPEM(raw)
|
||||
if err != nil {
|
||||
return nil, errs.New("Node tag authority file %s couldn't be loaded as peer identity: %v", cert, err)
|
||||
}
|
||||
authority = append(authority, signing.SigneeFromPeerIdentity(pi))
|
||||
}
|
||||
return authority, nil
|
||||
}
|
||||
|
||||
// Run runs satellite until it's either closed or it errors.
|
||||
func (peer *API) Run(ctx context.Context) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
74
satellite/api_test.go
Normal file
74
satellite/api_test.go
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2023 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package satellite
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"storj.io/common/identity/testidentity"
|
||||
"storj.io/common/pb"
|
||||
"storj.io/common/storj"
|
||||
"storj.io/common/testcontext"
|
||||
)
|
||||
|
||||
const certExample = `
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYjCCAQegAwIBAgIQILox8KzJildxdqYqBIdPYTAKBggqhkjOPQQDAjAQMQ4w
|
||||
DAYDVQQKEwVTdG9yajAiGA8wMDAxMDEwMTAwMDAwMFoYDzAwMDEwMTAxMDAwMDAw
|
||||
WjAQMQ4wDAYDVQQKEwVTdG9yajBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKrU
|
||||
7UPNIbn7Ll6XTRlLTJF+CBmssEHC9EJDCE5nFUUdPJ7XTlwY5pIAHthW2SN1wIF7
|
||||
riWBVOqZMhW/7nxy8NmjPzA9MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr
|
||||
BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAKBggqhkjOPQQDAgNJADBG
|
||||
AiEAjuL/DcSXUp1WMJXb0YfDG3choj5efMfq2EeB7MnsTR0CIQDOtGUIvTjB+CzJ
|
||||
wyxU+oxqT796GNVeYMyearuQ1QZCJw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBcDCCARWgAwIBAgIQVJK5KKSuzc5UYE/Mz0F1AjAKBggqhkjOPQQDAjAQMQ4w
|
||||
DAYDVQQKEwVTdG9yajAiGA8wMDAxMDEwMTAwMDAwMFoYDzAwMDEwMTAxMDAwMDAw
|
||||
WjAQMQ4wDAYDVQQKEwVTdG9yajBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKz1
|
||||
EFtvbYmWiJlVu2r6UyZKMFiczHWmpUhPU2vPcVFPQ+hLsbDRa8dFTzmoqQ5HWAov
|
||||
RL64plhFJDUR2lYZvKujTTBLMA4GA1UdDwEB/wQEAwICBDAPBgNVHRMBAf8EBTAD
|
||||
AQH/MB0GA1UdDgQWBBQ9Qt80xie1vPyCQ4RU+nFnjQe1djAJBgSINwIBBAEAMAoG
|
||||
CCqGSM49BAMCA0kAMEYCIQCkvgnd51j1QEdvtIEQGZGHGAE3n7a7bhJ1MK+WBaiu
|
||||
LgIhALqIm7uONq0H1xQEtV2nnGFUHC6v+6tIOu2Z7W92DSzb
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
// generated with 'tag-signer sign --node-id 1AujhDBDBhfYUhEH8cpFMymPu5yLYkQBCfFYbdSN5AVL5Bu6W9 --identity-dir `pwd` foo=bar' using the key of the cert, above.
|
||||
const signedTag = "CqIBCjQKIBaACbi52g7o8pQaX+hkw6TJNDHJ0UVqSLQtibPHoqkAEgoKA2ZvbxIDYmFyGKWoiaYGGiAJ20r8flrnkM9YBpKEvXmeXhYLfwx/HUEwu9Lv4QzaACJIMEYCIQCHk1wkMPYB6ZkmGGSU9M2p0E+WdjXCzxy4Kx2+gUP9wgIhALvcaTIgHCFOsc9gjGhSA0wS8L+cXaXQQPvq2nFapiLc"
|
||||
|
||||
func TestLoadAuthorities(t *testing.T) {
|
||||
selfIdentity := testidentity.MustPregeneratedIdentity(0, storj.LatestIDVersion())
|
||||
t.Run("real cert", func(t *testing.T) {
|
||||
certPath := filepath.Join(t.TempDir(), "identity.cert")
|
||||
err := os.WriteFile(certPath, []byte(certExample), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
a, err := loadAuthorities(selfIdentity.PeerIdentity(), certPath+","+certPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
decoded, err := base64.StdEncoding.DecodeString(signedTag)
|
||||
require.NoError(t, err)
|
||||
|
||||
tags := &pb.SignedNodeTagSets{}
|
||||
err = proto.Unmarshal(decoded, tags)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, tags.Tags, 1)
|
||||
_, err = a.Verify(testcontext.New(t), tags.Tags[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
})
|
||||
t.Run("invalid file", func(t *testing.T) {
|
||||
_, err := loadAuthorities(selfIdentity.PeerIdentity(), "none")
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
}
|
@ -220,6 +220,8 @@ type Config struct {
|
||||
Analytics analytics.Config
|
||||
|
||||
PieceTracker piecetracker.Config
|
||||
|
||||
TagAuthorities string `help:"comma-separated paths of additional cert files, used to validate signed node tags"`
|
||||
}
|
||||
|
||||
func setupMailService(log *zap.Logger, config Config) (*mailservice.Service, error) {
|
||||
|
3
scripts/testdata/satellite-config.yaml.lock
vendored
3
scripts/testdata/satellite-config.yaml.lock
vendored
@ -1111,6 +1111,9 @@ server.private-address: 127.0.0.1:7778
|
||||
# length of time a node can go without contacting satellite before being disqualified
|
||||
# stray-nodes.max-duration-without-contact: 720h0m0s
|
||||
|
||||
# comma-separated paths of additional cert files, used to validate signed node tags
|
||||
# tag-authorities: ""
|
||||
|
||||
# as of system interval
|
||||
# tally.as-of-system-interval: -5m0s
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user