Skip to content
Snippets Groups Projects
Commit 0c889ce5 authored by Martin Stiemerling's avatar Martin Stiemerling :speech_balloon:
Browse files

Resolve "TLS support for gnmi-target"

parent 2013da4c
No related branches found
No related tags found
2 merge requests!30Move from develop to master as default branch,!25Resolve "TLS support for gnmi-target"
......@@ -42,6 +42,11 @@ container: build
container-debug:
docker buildx build --rm -t gnmi-target-debug --load -f ./Dockerfile.debug .
self-certs:
mkdir -p ./artifacts/ssl/private
mkdir -p ./artifacts/ssl/certs
openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout ./artifacts/ssl/private/gnmi-target-selfsigned.key -out ./artifacts/ssl/certs/gnmi-target-selfsigned.crt
# other targets
cross:
go build -o ${OUTPUT}
......
......@@ -8,7 +8,28 @@ To update the generated ygot structs from yang modules you can simply run `make
To use the target: (after the obligatory `go install`) run `gnmi-target start` to start the gNMI server with default configuration (OS client: ubuntu)
To request all data with `gnmiclient`: run `gnmic -a localhost:7030 -u admin -p admsdsdin --insecure get --path "/"`
### Options to start the gNMI target
To start the target with TLS you have to provide a certificate (command line option `--cert <path-to-cert>`) and a private key (command line option `--key <path-to-key>`)
It is recommended to always use TLS.
For testing purposes the Makefile provides the option `make self-certs`. This generates a self-signed certificate and the corresponding private key. They are both stored under the directory `artifacts/ssl` in the source code directory.
However, you can also run the target with not TLS enabled by specifying the command line option `--insecure`.
## Requesting Data from the target
### With TLS and self-signed certificates
To request all data with `gnmiclient` run this command
`gnmic -a localhost:7030 -u admin -p admsdsdin --skip-verify get --path "/"`
### With no TLS
To request all data with `gnmiclient`: run this command
`gnmic -a localhost:7030 -u admin -p admsdsdin --insecure get --path "/"`
---
......
/*
Copyright © 2021 da/net Research Group <danet@h-da.de>
Copyright © 2023 da/net Research Group <danet@h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
......
/*
Copyright © 2021 da/net Research Group <danet@h-da.de>
Copyright © 2023 da/net Research Group <danet@h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
......@@ -41,23 +41,28 @@ import (
)
var (
bindAddress string
configFile string
osclient string
logLevel string
bindAddress string // IP/Port to bind to listen for the gnmi server
configFile string // my config file to use
osclient string // TODO unclear
logLevel string // which loglevel to use
certFile string // the location of the file containing the X.509 certificates for the gnmi server
keyFile string // the location of the file containing the key for the certificates for the gnmi server
insecure *bool // set to true if insecure operations is needed, i.e., do not use TLS
// Below is qkdn specific information
udpQL1AddrString string
ql1Name string
udpQL2AddrString string
ql2Name string
// End of qkdn specific information
)
// startCmd represents the start command
var startCmd = &cobra.Command{
Use: "start",
Short: "Start gnmi server",
Long: `A Linux GNMI target that does GNMI target stuff`,
Long: `A gNMI target`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Startup GNMI Target...")
fmt.Println("Startup of GNMI Target...")
lvl := viper.GetString("logLevel")
// parse string, this is built-in feature of logrus
......@@ -77,7 +82,7 @@ var startCmd = &cobra.Command{
}
gnmitTarget := gnmitarget.NewGnmiTarget(&qkdnBootInfo)
if err := gnmitTarget.Start(viper.GetString("bindAddress")); err != nil {
if err := gnmitTarget.Start(viper.GetString("bindAddress"), viper.GetString("certFile"), viper.GetString("keyFile"), *insecure); err != nil {
logrus.Fatal(err)
}
},
......@@ -88,7 +93,9 @@ func init() {
startCmd.Flags().StringVarP(&configFile, "config", "c", "config/openconfig.json", "system configuration")
startCmd.Flags().StringVarP(&bindAddress, "bind_address", "a", ":7030", "address to bind to")
startCmd.Flags().StringVarP(&logLevel, "log", "l", "info", "loglevel")
startCmd.Flags().Bool("tls", false, "Use Viper for configuration")
insecure = startCmd.Flags().Bool("insecure", false, "If true do not use TLS")
startCmd.Flags().StringVarP(&certFile, "cert", "", "", "location of the cert file")
startCmd.Flags().StringVarP(&keyFile, "key", "", "", "location of the key file")
startCmd.Flags().StringVarP(&osclient, "osclient", "o", "ubuntu", "os client to use by system")
startCmd.Flags().StringVarP(&udpQL1AddrString, "my_QLE_socket", "", "[::1]:50900", "local quantum element's address")
startCmd.Flags().StringVarP(&ql1Name, "my_name", "", "ekms-ql1", "The name of the local quantumlayer")
......@@ -98,7 +105,9 @@ func init() {
viper.BindPFlag("bindAddress", startCmd.Flags().Lookup("bind_address"))
viper.BindPFlag("configFile", startCmd.Flags().Lookup("config"))
viper.BindPFlag("logLevel", startCmd.Flags().Lookup("log"))
viper.BindPFlag("useTLS", startCmd.Flags().Lookup("tls"))
viper.BindPFlag("insecure", startCmd.Flags().Lookup("insecure"))
viper.BindPFlag("certFile", startCmd.Flags().Lookup("cert"))
viper.BindPFlag("keyFile", startCmd.Flags().Lookup("key"))
viper.BindPFlag("osclient", startCmd.Flags().Lookup("osclient"))
viper.BindPFlag("my_QLE_socket", startCmd.Flags().Lookup("my-address"))
viper.BindPFlag("my_name", startCmd.Flags().Lookup("my-name"))
......
......@@ -127,5 +127,10 @@ func (gt *GnmiTarget) InitializeConfig() (ygot.ValidatedGoStruct, error) {
}()
}
return conf, customerrs.CombinedErrListError{Errors: errs}
if len(errs) != 0 {
return conf, customerrs.CombinedErrListError{Errors: errs}
} else {
return conf, nil
}
}
package gnmitarget
import (
"time"
"code.fbi.h-da.de/danet/gnmi-target/etsiqkdnclient"
"code.fbi.h-da.de/danet/gnmi-target/gnmiserver"
not "code.fbi.h-da.de/danet/gnmi-target/notifications"
......@@ -13,6 +11,7 @@ import (
"reflect"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/reflection"
"code.fbi.h-da.de/danet/gnmi-target/modeldata"
......@@ -41,10 +40,7 @@ func NewGnmiTarget(qkdnBootInfo *etsiqkdnclient.EtsiQkdClientInfo) *GnmiTarget {
}
}
func (gt *GnmiTarget) Start(bindAddress string) error {
//NOTE: This sleep is currently just for testing purposes to play around with
//containerlab.
time.Sleep(5 * time.Second)
func (gt *GnmiTarget) Start(bindAddress string, certFile string, keyFile string, insecure bool) error {
schema, err := gnmitargetygot.Schema()
if err != nil {
......@@ -67,6 +63,7 @@ func (gt *GnmiTarget) Start(bindAddress string) error {
}
}
// Initialize ygot structs with the current device configuration
config, err := gt.InitializeConfig()
if err != nil {
log.Error(err)
......@@ -77,21 +74,35 @@ func (gt *GnmiTarget) Start(bindAddress string) error {
log.Fatalf("error in creating GNMI target: %v", err)
}
// Create new GRPC Server without service registert
grpcServer := grpc.NewServer()
var grpcServer *grpc.Server
if insecure == false {
// Setup credentials for secured message transport
grpcCredentials, err := credentials.NewServerTLSFromFile(certFile, keyFile)
if err != nil {
log.Fatalf("error in opening the TLS certificate: %v", err)
}
// Create new GRPC Server without service registered
grpcServer = grpc.NewServer(grpc.Creds(grpcCredentials))
} else {
log.Infof("\n\n*****WARNING*********WARNING*****\nStarting without secured gnmi server!\nAll gnmi transmissions are unencrypted\n*****WARNING*********WARNING*****\n\n")
// Create new GRPC Server without service registered
grpcServer = grpc.NewServer()
}
// Register GNMI Server
pbGNMI.RegisterGNMIServer(grpcServer, gnmiServer)
reflection.Register(grpcServer)
// Start Server
log.Infof("Starting target server to listen on %s", bindAddress)
log.Infof("Starting gnmi-target server to listen on %s", bindAddress)
listener, err := net.Listen("tcp", bindAddress)
if err != nil {
log.Fatalf("Failed to list due to: %v", err)
}
log.Info("Target is starting to serve requests")
log.Info("gnmi-target is ready to serve requests.")
err = grpcServer.Serve(listener)
if err != nil {
log.Fatalf("Failed to serve requests due to: %v", err)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment