Skip to content

Commit

Permalink
[FAB-8350] Support different listener for admin server
Browse files Browse the repository at this point in the history
The peer's admin server shares the listener with the endorser one.

This doesn't make much sense because the admin service might be deployed
in a setup where it should only be accessible to peer administrators and
not to clients, and also  - mutual TLS is used, then it also accepts
TLS client certificates issued by CAs of other organizations which
share a channel with the peer's organization.

This change set makes it so that the admin server can have its own listener.
By default - it still registers to the peer's gRPC service.

However, if the listen address is specified in the core.yaml and it's port
differs from the port of the peer service - it creates its own gRPC
service and attaches to it instead of the peer's.

Change-Id: I69c132348da17cdd6e4e4f9b31ba5c59d6a3f1cb
Signed-off-by: yacovm <yacovm@il.ibm.com>
  • Loading branch information
yacovm committed Mar 31, 2018
1 parent 25e7786 commit 1f2503f
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 9 deletions.
60 changes: 51 additions & 9 deletions peer/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,8 @@ func serve(args []string) error {

logger.Debugf("Running peer")

// Register the Admin server
localMSP := mgmt.GetLocalMSP()
mspID := viper.GetString("peer.localMspId")
pp := cauthdsl.NewPolicyProvider(localMSP)
adminPolicy, _, err := pp.NewPolicy(utils.MarshalOrPanic(cauthdsl.SignedByAnyAdmin([]string{mspID})))
if err != nil {
logger.Panicf("Failed creating admin policy: +%v", err)
}
pb.RegisterAdminServer(peerServer.Server(), admin.NewAdminServer(adminPolicy))
// Start the Admin server
startAdminServer(listenAddr, peerServer.Server())

privDataDist := func(channel string, txID string, privateData *rwset.TxPvtReadWriteSet) error {
return service.GetGossipService().DistributePrivateData(channel, txID, privateData)
Expand Down Expand Up @@ -565,6 +558,55 @@ func createEventHubServer(serverConfig comm.ServerConfig) (*comm.GRPCServer, err
return grpcServer, nil
}

func adminHasSeparateListener(peerListenAddr string, adminListenAddress string) bool {
// By default, admin listens on the same port as the peer data service
if adminListenAddress == "" {
return false
}
_, peerPort, err := net.SplitHostPort(peerListenAddr)
if err != nil {
logger.Panicf("Failed parsing peer listen address")
}

_, adminPort, err := net.SplitHostPort(adminListenAddress)
if err != nil {
logger.Panicf("Failed parsing admin listen address")
}
// Admin service has a separate listener in case it doesn't match the peer's
// configured service
return adminPort != peerPort
}

func startAdminServer(peerListenAddr string, peerServer *grpc.Server) {
adminListenAddress := viper.GetString("peer.adminService.listenAddress")
separateLsnrForAdmin := adminHasSeparateListener(peerListenAddr, adminListenAddress)
localMSP := mgmt.GetLocalMSP()
mspID := viper.GetString("peer.localMspId")
pp := cauthdsl.NewPolicyProvider(localMSP)
adminPolicy, _, err := pp.NewPolicy(utils.MarshalOrPanic(cauthdsl.SignedByAnyAdmin([]string{mspID})))
if err != nil {
logger.Panicf("Failed creating admin policy: +%v", err)
}
gRPCService := peerServer
if separateLsnrForAdmin {
logger.Info("Creating gRPC server for admin service on", adminListenAddress)
serverConfig, err := peer.GetServerConfig()
if err != nil {
logger.Fatalf("Error loading secure config for admin service (%s)", err)
}
adminServer, err := peer.NewPeerServer(adminListenAddress, serverConfig)
if err != nil {
logger.Fatalf("Failed to create admin server (%s)", err)
}
gRPCService = adminServer.Server()
defer func() {
go adminServer.Start()
}()
}

pb.RegisterAdminServer(gRPCService, admin.NewAdminServer(adminPolicy))
}

func initializeEventsServerConfig(mutualTLS bool) *producer.EventsServerConfig {
extract := func(msg proto.Message) []byte {
evt, isEvent := msg.(*pb.Event)
Expand Down
16 changes: 16 additions & 0 deletions peer/node/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,22 @@ func TestWritePid(t *testing.T) {
}
}

func TestAdminHasSeparateListener(t *testing.T) {
assert.False(t, adminHasSeparateListener("0.0.0.0:7051", ""))

assert.Panics(t, func() {
adminHasSeparateListener("foo", "blabla")
})

assert.Panics(t, func() {
adminHasSeparateListener("0.0.0.0:7051", "blabla")
})

assert.False(t, adminHasSeparateListener("0.0.0.0:7051", "0.0.0.0:7051"))
assert.False(t, adminHasSeparateListener("0.0.0.0:7051", "127.0.0.1:7051"))
assert.True(t, adminHasSeparateListener("0.0.0.0:7051", "0.0.0.0:7055"))
}

func TestHandlerMap(t *testing.T) {
config1 := `
peer:
Expand Down
10 changes: 10 additions & 0 deletions sampleconfig/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,16 @@ peer:
enabled: false
listenAddress: 0.0.0.0:6060

# The admin service is used for administrative operations such as
# control over log module severity, etc.
# Only peer administrators can use the service.
adminService:
# The interface and port on which the admin server will listen on.
# If this is commented out, or the port number is equal to the port
# of the peer listen address - the admin service is attached to the
# peer's service (defaults to 7051).
#listenAddress: 0.0.0.0:7055

# Handlers defines custom handlers that can filter and mutate
# objects passing within the peer, such as:
# Auth filter - reject or forward proposals from clients
Expand Down

0 comments on commit 1f2503f

Please sign in to comment.