Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: using certloader.ClientConfigBuilder to prepare tls.Config #151

Merged
merged 1 commit into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"google.golang.org/grpc"

"github.com/cilium/cilium/api/v1/flow"
"github.com/cilium/hubble-ui/backend/logger"
"github.com/cilium/hubble-ui/backend/pkg/logger"
"github.com/cilium/hubble-ui/backend/proto/ui"
)

Expand Down
1 change: 1 addition & 0 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/cilium/hubble v0.6.1
github.com/golang/protobuf v1.5.0
github.com/google/gops v0.3.17
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.7.0
google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.26.0
Expand Down
1 change: 1 addition & 0 deletions backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
Expand Down
56 changes: 56 additions & 0 deletions backend/internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package config

import (
"crypto/tls"
"fmt"

"github.com/pkg/errors"

"github.com/cilium/cilium/pkg/crypto/certloader"
"github.com/cilium/hubble-ui/backend/pkg/logger"
)

var (
log = logger.New("config")

CACertLoadError = errors.New("failed to read CA certificate")
CACertInvalidError = errors.New("CA certificate is not properly PEM-encoded")
)

const (
TLSAddrPrefix = "tls://"
)

type Config struct {
// The address of hubble-relay instance
RelayAddr string

// The port which will be used to listen to on grpc server setup
UIServerPort string

TLSToRelayEnabled bool
// The meaning of this flags is the same as in
// https://github.com/cilium/hubble/blob/master/cmd/common/config/flags.go
TLSToRelayAllowInsecure bool
TLSRelayServerName string
TLSRelayCACertFiles []string
TLSRelayClientCertFile string
TLSRelayClientKeyFile string

relayClientConfig certloader.ClientConfigBuilder
}

func (cfg *Config) UIServerListenAddr() string {
return fmt.Sprintf("0.0.0.0:%s", cfg.UIServerPort)
}

func (cfg *Config) AsRelayClientTLSConfig() (*tls.Config, error) {
if cfg.relayClientConfig == nil {
return nil, errors.New("hubble-ui backend is running with TLS disabled")
}

return cfg.relayClientConfig.ClientConfig(&tls.Config{
InsecureSkipVerify: cfg.TLSToRelayAllowInsecure,
ServerName: cfg.TLSRelayServerName,
}), nil
}
108 changes: 108 additions & 0 deletions backend/internal/config/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package config

import (
"os"
"strconv"
"strings"

"github.com/cilium/cilium/pkg/crypto/certloader"
"github.com/cilium/hubble-ui/backend/internal/msg"
"github.com/cilium/hubble-ui/backend/pkg/logger"
)

const (
UIServerDefaultPort = "8090"
)

func Init() (*Config, error) {
cfg := &Config{}

setupRelayAddr(cfg)
setupUIServerPort(cfg)

if err := setupTLSOptions(cfg); err != nil {
return nil, err
}

return cfg, nil
}

func setupRelayAddr(cfg *Config) {
relayAddr, ok := os.LookupEnv("FLOWS_API_ADDR")
if !ok {
relayAddr = "localhost:50051"
log.Warnf(msg.ServerSetupUsingDefRelayAddr, relayAddr)
}

cfg.RelayAddr = relayAddr
}

func setupUIServerPort(cfg *Config) {
port, ok := os.LookupEnv("EVENTS_SERVER_PORT")
if !ok {
port = UIServerDefaultPort
log.Warnf(msg.ServerSetupUsingDefPort, port)
}

cfg.UIServerPort = port
}

func setupTLSOptions(cfg *Config) error {
tlsEnabledStr, _ := os.LookupEnv("TLS_TO_RELAY_ENABLED")
tlsServerName, _ := os.LookupEnv("TLS_RELAY_SERVER_NAME")
tlsAllowInsecureStr, _ := os.LookupEnv("TLS_TO_RELAY_ALLOW_INSECURE")
tlsCACertFiles, _ := os.LookupEnv("TLS_RELAY_CA_CERT_FILES")
tlsClientCertFile, _ := os.LookupEnv("TLS_RELAY_CLIENT_CERT_FILE")
tlsClientKeyFile, _ := os.LookupEnv("TLS_RELAY_CLIENT_KEY_FILE")

cfg.TLSRelayServerName = tlsServerName

tlsAllowInsecure, _ := strconv.ParseBool(tlsAllowInsecureStr)
if tlsAllowInsecure {
log.Warnf(msg.ServerSetupTLSAllowInsecureDef, tlsAllowInsecure)
}

tlsToRelayEnabled, _ := strconv.ParseBool(tlsEnabledStr)

cfg.TLSToRelayEnabled = tlsToRelayEnabled
cfg.TLSToRelayAllowInsecure = tlsAllowInsecure
cfg.TLSRelayCACertFiles = make([]string, 0)
for _, caCertPath := range strings.Split(tlsCACertFiles, ",") {
trimmed := strings.TrimSpace(caCertPath)
if len(trimmed) == 0 {
continue
}

cfg.TLSRelayCACertFiles = append(cfg.TLSRelayCACertFiles, trimmed)
}

cfg.TLSRelayClientCertFile = tlsClientCertFile
cfg.TLSRelayClientKeyFile = tlsClientKeyFile

tlsState := "disabled"
if tlsToRelayEnabled {
tlsState = "enabled"
}

log.Infof(msg.ServerSetupTLSInitState, tlsState)

if !tlsToRelayEnabled {
return nil
}

relayClientConfig, err := certloader.NewWatchedClientConfig(
logger.New("tls-config-watcher"),
cfg.TLSRelayCACertFiles,
cfg.TLSRelayClientCertFile,
cfg.TLSRelayClientKeyFile,
)

if err != nil {
return err
}

cfg.relayClientConfig = relayClientConfig
log.Infof(msg.ServerSetupTLSInitWithNCACerts, len(cfg.TLSRelayCACertFiles))

return nil
}
22 changes: 22 additions & 0 deletions backend/internal/grpc/tls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package grpc

import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

"github.com/cilium/hubble-ui/backend/internal/config"
)

func TransportSecurityToRelay(cfg *config.Config) (grpc.DialOption, error) {
if !cfg.TLSToRelayEnabled {
return grpc.WithInsecure(), nil
}

tlsConfig, err := cfg.AsRelayClientTLSConfig()
if err != nil {
return nil, err
}

creds := credentials.NewTLS(tlsConfig)
return grpc.WithTransportCredentials(creds), nil
}
23 changes: 14 additions & 9 deletions backend/internal/msg/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@ const (
ZeroIdentityInSourceOrDest = "invalid (zero) identity in source / dest services\n"
PrintZeroIdentityFlowJson = "zero identity flow json: %v\n"

ServerSetupGRPCClientError = "failed to setup grpc client: %v\n"
ServerSetupK8sClientsetError = "failed to create k8s clientset: %v\n"
ServerSetupNoRelayAddrError = "hubble-relay addr is empty, flows fetching is impossible\n"
ServerSetupRelayClientReady = "hubble-relay grpc client created (hubble-relay addr: %s)\n"
ServerSetupRunError = "failed to run server: %v\n"
ServerSetupUsingDefRelayAddr = "hubble-relay addr is set to default (%s)\n"
ServerSetupUsingDefPort = "server port is set to default (%s)\n"
ServerSetupListenError = "failed to listen: %v\n"
ServerSetupListeningAt = "listening at: %s\n"
ServerSetupGRPCClientError = "failed to setup grpc client: %v\n"
ServerSetupK8sClientsetError = "failed to create k8s clientset: %v\n"
ServerSetupNoRelayAddrError = "hubble-relay addr is empty, flows fetching is impossible\n"
ServerSetupRelayClientReady = "hubble-relay grpc client created (hubble-relay addr: %s)\n"
ServerSetupRunError = "failed to run server: %v\n"
ServerSetupUsingDefRelayAddr = "hubble-relay addr is set to default (%s)\n"
ServerSetupUsingDefPort = "server port is set to default (%s)\n"
ServerSetupListenError = "failed to listen: %v\n"
ServerSetupListeningAt = "listening at: %s\n"
ServerSetupConfigInitError = "failed to initialize hubble-ui backend: %s\n"
ServerSetupTLSAllowInsecureDef = "TLSAllowInsecure option set to: %v\n"
ServerSetupTLSInitWithNCACerts = "initialized with %d CA certificates\n"
ServerSetupTLSInitState = "initialized with TLS %s\n"
ServerSetupRelayClientError = "failed to create a hubble-relay client from user context %v\n"

SendConnStateError = "failed to send connection state (%s) to the client: %v\n"
SendK8sUnavailableNotifError = "failed to send k8s unavailable notification: %v\n"
Expand Down
46 changes: 27 additions & 19 deletions backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net"
"os"
"strconv"

// "github.com/cilium/cilium/pkg/logging"
// "github.com/cilium/cilium/pkg/logging/logfields"
Expand All @@ -13,8 +14,9 @@ import (
"google.golang.org/grpc"

"github.com/cilium/hubble-ui/backend/client"
"github.com/cilium/hubble-ui/backend/internal/config"
"github.com/cilium/hubble-ui/backend/internal/msg"
"github.com/cilium/hubble-ui/backend/logger"
"github.com/cilium/hubble-ui/backend/pkg/logger"
"github.com/cilium/hubble-ui/backend/server"
)

Expand Down Expand Up @@ -48,19 +50,9 @@ func setupListener() net.Listener {
return listener
}

func getObserverAddr() string {
observerAddr, ok := os.LookupEnv("FLOWS_API_ADDR")
if !ok {
observerAddr = "0.0.0.0:50051"
log.Warnf(msg.ServerSetupUsingDefRelayAddr, observerAddr)
}

return observerAddr
}

func runServer() {
observerAddr := getObserverAddr()
srv := server.New(observerAddr)
func runServer(cfg *config.Config) {
// observerAddr := getObserverAddr()
srv := server.New(cfg)

if err := srv.Run(); err != nil {
log.Errorf(msg.ServerSetupRunError, err)
Expand All @@ -74,8 +66,8 @@ func runServer() {
grpcServer.Serve(listener)
}

func runClient() {
addr := getServerAddr()
func runClient(cfg *config.Config) {
addr := cfg.UIServerListenAddr()
log.Infof("connecting to server: %s\n", addr)

cl := client.New(addr)
Expand All @@ -91,25 +83,41 @@ func getMode() string {
return "server"
}

func main() {
func runGops() {
if enabled, _ := strconv.ParseBool(os.Getenv("GOPS_ENABLED")); !enabled {
return
}

gopsPort := "0"
if gopsPortEnv := os.Getenv("GOPS_PORT"); gopsPortEnv != "" {
gopsPort = gopsPortEnv
}
// Open socket for using gops to get stacktraces of the agent.
addr := fmt.Sprintf("127.0.0.1:%s", gopsPort)
addrField := logrus.Fields{"address": addr}

if err := gops.Listen(gops.Options{
Addr: addr,
ReuseSocketAddrAndPort: true,
}); err != nil {
log.WithError(err).WithFields(addrField).Fatal("Cannot start gops server")
}

log.WithFields(addrField).Info("Started gops server")
}

func main() {
runGops()

cfg, err := config.Init()
if err != nil {
log.Errorf(msg.ServerSetupConfigInitError, err.Error())
os.Exit(1)
}

if mode := getMode(); mode == "server" {
runServer()
runServer(cfg)
} else {
runClient()
runClient(cfg)
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion backend/server/get-events.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (srv *UIServer) GetEvents(
var flowCancel func()

if eventsRequested.FlowsRequired() {
flowCancel, flowResponses, flowErrors = srv.GetFlows(req)
flowCancel, flowResponses, flowErrors = srv.GetFlows(stream.Context(), req)
defer flowCancel()
}

Expand Down
12 changes: 10 additions & 2 deletions backend/server/get-flows.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import (
"github.com/cilium/hubble-ui/backend/server/helpers"
)

func (srv *UIServer) GetFlows(req *ui.GetEventsRequest) (
func (srv *UIServer) GetFlows(
streamContext context.Context, req *ui.GetEventsRequest,
) (
context.CancelFunc, chan *ui.GetEventsResponse, chan error,
) {
// TODO: handle context cancellation
Expand All @@ -33,7 +35,13 @@ func (srv *UIServer) GetFlows(req *ui.GetEventsRequest) (
retry := func(attempt int) error {
log.Infof(msg.GetFlowsConnectingToRelay, attempt)

fs, err := srv.hubbleClient.GetFlows(ctx, flowsRequest)
client, err := srv.GetHubbleClientFromContext(streamContext)
if err != nil {
log.Errorf(msg.ServerSetupRelayClientError, err)
return err
}

fs, err := client.hubble.GetFlows(ctx, flowsRequest)
if err != nil {
log.Errorf(msg.GetFlowsConnectionAttemptError, attempt, err)
return err
Expand Down
Loading