Skip to content

Commit 1f2503f

Browse files
committed
[FAB-8350] Support different listener for admin server
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>
1 parent 25e7786 commit 1f2503f

File tree

3 files changed

+77
-9
lines changed

3 files changed

+77
-9
lines changed

peer/node/start.go

+51-9
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,8 @@ func serve(args []string) error {
201201

202202
logger.Debugf("Running peer")
203203

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

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

561+
func adminHasSeparateListener(peerListenAddr string, adminListenAddress string) bool {
562+
// By default, admin listens on the same port as the peer data service
563+
if adminListenAddress == "" {
564+
return false
565+
}
566+
_, peerPort, err := net.SplitHostPort(peerListenAddr)
567+
if err != nil {
568+
logger.Panicf("Failed parsing peer listen address")
569+
}
570+
571+
_, adminPort, err := net.SplitHostPort(adminListenAddress)
572+
if err != nil {
573+
logger.Panicf("Failed parsing admin listen address")
574+
}
575+
// Admin service has a separate listener in case it doesn't match the peer's
576+
// configured service
577+
return adminPort != peerPort
578+
}
579+
580+
func startAdminServer(peerListenAddr string, peerServer *grpc.Server) {
581+
adminListenAddress := viper.GetString("peer.adminService.listenAddress")
582+
separateLsnrForAdmin := adminHasSeparateListener(peerListenAddr, adminListenAddress)
583+
localMSP := mgmt.GetLocalMSP()
584+
mspID := viper.GetString("peer.localMspId")
585+
pp := cauthdsl.NewPolicyProvider(localMSP)
586+
adminPolicy, _, err := pp.NewPolicy(utils.MarshalOrPanic(cauthdsl.SignedByAnyAdmin([]string{mspID})))
587+
if err != nil {
588+
logger.Panicf("Failed creating admin policy: +%v", err)
589+
}
590+
gRPCService := peerServer
591+
if separateLsnrForAdmin {
592+
logger.Info("Creating gRPC server for admin service on", adminListenAddress)
593+
serverConfig, err := peer.GetServerConfig()
594+
if err != nil {
595+
logger.Fatalf("Error loading secure config for admin service (%s)", err)
596+
}
597+
adminServer, err := peer.NewPeerServer(adminListenAddress, serverConfig)
598+
if err != nil {
599+
logger.Fatalf("Failed to create admin server (%s)", err)
600+
}
601+
gRPCService = adminServer.Server()
602+
defer func() {
603+
go adminServer.Start()
604+
}()
605+
}
606+
607+
pb.RegisterAdminServer(gRPCService, admin.NewAdminServer(adminPolicy))
608+
}
609+
568610
func initializeEventsServerConfig(mutualTLS bool) *producer.EventsServerConfig {
569611
extract := func(msg proto.Message) []byte {
570612
evt, isEvent := msg.(*pb.Event)

peer/node/start_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ func TestWritePid(t *testing.T) {
121121
}
122122
}
123123

124+
func TestAdminHasSeparateListener(t *testing.T) {
125+
assert.False(t, adminHasSeparateListener("0.0.0.0:7051", ""))
126+
127+
assert.Panics(t, func() {
128+
adminHasSeparateListener("foo", "blabla")
129+
})
130+
131+
assert.Panics(t, func() {
132+
adminHasSeparateListener("0.0.0.0:7051", "blabla")
133+
})
134+
135+
assert.False(t, adminHasSeparateListener("0.0.0.0:7051", "0.0.0.0:7051"))
136+
assert.False(t, adminHasSeparateListener("0.0.0.0:7051", "127.0.0.1:7051"))
137+
assert.True(t, adminHasSeparateListener("0.0.0.0:7051", "0.0.0.0:7055"))
138+
}
139+
124140
func TestHandlerMap(t *testing.T) {
125141
config1 := `
126142
peer:

sampleconfig/core.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,16 @@ peer:
342342
enabled: false
343343
listenAddress: 0.0.0.0:6060
344344

345+
# The admin service is used for administrative operations such as
346+
# control over log module severity, etc.
347+
# Only peer administrators can use the service.
348+
adminService:
349+
# The interface and port on which the admin server will listen on.
350+
# If this is commented out, or the port number is equal to the port
351+
# of the peer listen address - the admin service is attached to the
352+
# peer's service (defaults to 7051).
353+
#listenAddress: 0.0.0.0:7055
354+
345355
# Handlers defines custom handlers that can filter and mutate
346356
# objects passing within the peer, such as:
347357
# Auth filter - reject or forward proposals from clients

0 commit comments

Comments
 (0)