Skip to content

Commit

Permalink
Merge pull request #2513 from openziti/ops-verify-login
Browse files Browse the repository at this point in the history
refinements to ops verify-traffic to integrate and work with ziti edge login
  • Loading branch information
dovholuknf authored Oct 31, 2024
2 parents 6c3eeac + 03eed34 commit 3a0fd6a
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 90 deletions.
2 changes: 1 addition & 1 deletion controller/oidc_auth/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ type HybridStorage struct {
serviceUsers cmap.ConcurrentMap[string, *Client]

startOnce sync.Once
issuer string
//linter issue issuer string
config *Config

keys cmap.ConcurrentMap[string, *pubKey]
Expand Down
57 changes: 57 additions & 0 deletions internal/rest/mgmt/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ package mgmt

import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"github.com/openziti/edge-api/rest_management_api_client"
rest_mgmt "github.com/openziti/edge-api/rest_management_api_client/current_api_session"
"github.com/openziti/edge-api/rest_management_api_client/identity"
"github.com/openziti/edge-api/rest_management_api_client/service"
"github.com/openziti/edge-api/rest_management_api_client/service_policy"
"github.com/openziti/edge-api/rest_model"
"github.com/openziti/edge-api/rest_util"
"github.com/openziti/ziti/ziti/util"
log "github.com/sirupsen/logrus"
"net/http"
"os"
"time"
)

Expand Down Expand Up @@ -80,4 +88,53 @@ func ServicePolicyFromFilter(client *rest_management_api_client.ZitiEdgeManageme

func NameFilter(name string) string {
return `name="` + name + `"`
}

func NewClient() (*rest_management_api_client.ZitiEdgeManagement, error) {
cachedCreds, _, loadErr := util.LoadRestClientConfig()
if loadErr != nil {
return nil, loadErr
}

cachedId := cachedCreds.EdgeIdentities[cachedCreds.Default] //only support default for now
if cachedId == nil {
return nil, errors.New("no identity found")
}

caPool := x509.NewCertPool()
if _, cacertErr := os.Stat(cachedId.CaCert); cacertErr == nil {
rootPemData, err := os.ReadFile(cachedId.CaCert)
if err != nil {
return nil, err
}
caPool.AppendCertsFromPEM(rootPemData)
} else {
return nil, errors.New("CA cert file not found in config file")
}

tlsConfig := &tls.Config{
RootCAs: caPool,
}

transport := &http.Transport{
TLSClientConfig: tlsConfig,
}

// Assign the transport to the default HTTP client
http.DefaultClient = &http.Client{
Transport: transport,
}
c, e := rest_util.NewEdgeManagementClientWithToken(http.DefaultClient, cachedId.Url, cachedId.Token)
if e != nil {
return nil, e
}

apiSessionParams := &rest_mgmt.GetCurrentAPISessionParams{
Context: context.Background(),
}
_, authErr := c.CurrentAPISession.GetCurrentAPISession(apiSessionParams, nil)
if authErr != nil {
return nil, errors.New("client not authenticated. login with 'ziti edge login' before executing")
}
return c, nil
}
4 changes: 2 additions & 2 deletions ziti/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ func NewCmdRoot(in io.Reader, out, err io.Writer, cmd *cobra.Command) *cobra.Com
opsCommands.AddCommand(database.NewCmdDb(out, err))
opsCommands.AddCommand(NewCmdLogFormat(out, err))
opsCommands.AddCommand(NewUnwrapIdentityFileCommand(out, err))
opsCommands.AddCommand(verify.NewVerifyNetwork())
opsCommands.AddCommand(verify.NewVerifyTraffic())
opsCommands.AddCommand(verify.NewVerifyNetwork(out, err))
opsCommands.AddCommand(verify.NewVerifyTraffic(out, err))

groups := templates.CommandGroups{
{
Expand Down
38 changes: 21 additions & 17 deletions ziti/cmd/edge/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ type LoginOptions struct {
FileCertCreds *edge_apis.IdentityCredentials
}

func AddLoginFlags(cmd *cobra.Command, options *LoginOptions) {
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)

cmd.Flags().StringVarP(&options.Username, "username", "u", "", "username to use for authenticating to the Ziti Edge Controller ")
cmd.Flags().StringVarP(&options.Password, "password", "p", "", "password to use for authenticating to the Ziti Edge Controller, if -u is supplied and -p is not, a value will be prompted for")
cmd.Flags().StringVarP(&options.Token, "token", "t", "", "if an api token has already been acquired, it can be set in the config with this option. This will set the session to read only by default")
cmd.Flags().StringVarP(&options.CaCert, "ca", "", "", "additional root certificates used by the Ziti Edge Controller")
cmd.Flags().BoolVar(&options.ReadOnly, "read-only", false, "marks this login as read-only. Note: this is not a guarantee that nothing can be changed on the server. Care should still be taken!")
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", false, "If set, responds to prompts with yes. This will result in untrusted certs being accepted or updated.")
cmd.Flags().BoolVar(&options.IgnoreConfig, "ignore-config", false, "If set, does not use value from the config file for hostname or username. Values must be entered or will be prompted for.")
cmd.Flags().StringVarP(&options.ClientCert, "client-cert", "c", "", "A certificate used to authenticate")
cmd.Flags().StringVarP(&options.ClientKey, "client-key", "k", "", "The key to use with certificate authentication")
cmd.Flags().StringVarP(&options.ExtJwt, "ext-jwt", "e", "", "A file containing a JWT from an external provider to be used for authentication")
cmd.Flags().StringVarP(&options.File, "file", "f", "", "An identity file to use for authentication")

options.AddCommonFlags(cmd)
}

// NewLoginCmd creates the command
func NewLoginCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &LoginOptions{
Expand All @@ -77,23 +96,8 @@ func NewLoginCmd(out io.Writer, errOut io.Writer) *cobra.Command {
},
SuggestFor: []string{},
}

// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)

cmd.Flags().StringVarP(&options.Username, "username", "u", "", "username to use for authenticating to the Ziti Edge Controller ")
cmd.Flags().StringVarP(&options.Password, "password", "p", "", "password to use for authenticating to the Ziti Edge Controller, if -u is supplied and -p is not, a value will be prompted for")
cmd.Flags().StringVarP(&options.Token, "token", "t", "", "if an api token has already been acquired, it can be set in the config with this option. This will set the session to read only by default")
cmd.Flags().StringVarP(&options.CaCert, "ca", "", "", "additional root certificates used by the Ziti Edge Controller")
cmd.Flags().BoolVar(&options.ReadOnly, "read-only", false, "marks this login as read-only. Note: this is not a guarantee that nothing can be changed on the server. Care should still be taken!")
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", false, "If set, responds to prompts with yes. This will result in untrusted certs being accepted or updated.")
cmd.Flags().BoolVar(&options.IgnoreConfig, "ignore-config", false, "If set, does not use value from the config file for hostname or username. Values must be entered or will be prompted for.")
cmd.Flags().StringVarP(&options.ClientCert, "client-cert", "c", "", "A certificate used to authenticate")
cmd.Flags().StringVarP(&options.ClientKey, "client-key", "k", "", "The key to use with certificate authentication")
cmd.Flags().StringVarP(&options.ExtJwt, "ext-jwt", "e", "", "A file containing a JWT from an external provider to be used for authentication")
cmd.Flags().StringVarP(&options.File, "file", "f", "", "An identity file to use for authentication")

options.AddCommonFlags(cmd)

AddLoginFlags(cmd, options)

return cmd
}
Expand Down
7 changes: 0 additions & 7 deletions ziti/cmd/verify/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ import (
"runtime"
)

type controller struct {
user string
pass string
host string
port string
}

func configureLogFormat(level logrus.Level) {
logrus.SetLevel(level)
logrus.SetFormatter(&logrus.TextFormatter{
Expand Down
3 changes: 2 additions & 1 deletion ziti/cmd/verify/ops_verify_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package verify

import (
"fmt"
"io"
"net"
"os"
"strings"
Expand Down Expand Up @@ -48,7 +49,7 @@ type stringMapList []interface{}

type StringMap map[string]interface{}

func NewVerifyNetwork() *cobra.Command {
func NewVerifyNetwork(_ io.Writer, _ io.Writer) *cobra.Command {
n := &network{}

cmd := &cobra.Command{
Expand Down
78 changes: 16 additions & 62 deletions ziti/cmd/verify/ops_verify_traffic.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ package verify
import (
"bufio"
"context"
"crypto/x509"
"fmt"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/foundation/v2/term"
"github.com/openziti/ziti/ziti/cmd/edge"
"github.com/sirupsen/logrus"
"io"
"net"
"os"
"strings"
"sync"
"time"
Expand All @@ -37,15 +36,14 @@ import (
"github.com/openziti/edge-api/rest_management_api_client/service_policy"
"github.com/openziti/edge-api/rest_management_api_client/terminator"
"github.com/openziti/edge-api/rest_model"
"github.com/openziti/edge-api/rest_util"
"github.com/openziti/sdk-golang/ziti"
"github.com/openziti/sdk-golang/ziti/enroll"
"github.com/openziti/ziti/internal/rest/mgmt"
)


type traffic struct {
controller
loginOpts edge.LoginOptions
prefix string
mode string
cleanup bool
Expand All @@ -60,7 +58,7 @@ type traffic struct {
dialSPName string
}

func NewVerifyTraffic() *cobra.Command {
func NewVerifyTraffic(out io.Writer, errOut io.Writer) *cobra.Command {
t := &traffic{}
cmd := &cobra.Command{
Use: "verify-traffic",
Expand Down Expand Up @@ -97,9 +95,16 @@ func NewVerifyTraffic() *cobra.Command {
t.clientIdName = t.prefix + ".client"
t.bindSPName = t.prefix + ".bind"
t.dialSPName = t.prefix + ".dial"
client, err := t.newMgmtClient()
client, err := mgmt.NewClient()
if err != nil {
log.Fatal(err)
loginErr := t.loginOpts.Run()
if loginErr != nil {
log.Fatal(err)
}
client, err = mgmt.NewClient()
if err != nil {
log.Fatal(err)
}
}
t.client = client
if t.cleanup {
Expand All @@ -125,13 +130,11 @@ func NewVerifyTraffic() *cobra.Command {
cmd.Flags().StringVarP(&t.prefix, "prefix", "x", "", "[optional] The prefix to apply to generated objects, necessary when not using the 'both' role.")
cmd.Flags().StringVarP(&t.mode, "mode", "m", "", "[optional, default 'both'] The mode to perform: server, client, both.")
cmd.Flags().BoolVar(&t.cleanup, "cleanup", false, "Whether to perform cleanup.")
cmd.Flags().BoolVar(&t.verbose, "verbose", false, "Show additional output.")
cmd.Flags().BoolVar(&t.allowMultipleServers, "allow-multiple-servers", false, "Whether to allows the same server multiple times.")

cmd.Flags().StringVarP(&t.user, "username", "u", "", "username to use for authenticating to the Ziti Edge Controller ")
cmd.Flags().StringVarP(&t.pass, "password", "p", "", "password to use for authenticating to the Ziti Edge Controller, if -u is supplied and -p is not, a value will be prompted for")
cmd.Flags().StringVar(&t.host, "host", "", "the controller host")
cmd.Flags().StringVar(&t.port, "port", "", "the controller port")
edge.AddLoginFlags(cmd, &t.loginOpts)
t.loginOpts.Out = out
t.loginOpts.Err = errOut

return cmd
}
Expand Down Expand Up @@ -269,55 +272,6 @@ func waitForTerminator(client *rest_management_api_client.ZitiEdgeManagement, se
return false
}

func (t *traffic) newMgmtClient() (*rest_management_api_client.ZitiEdgeManagement, error) {
if t.user == "" {
t.user = os.Getenv("ZITI_USER")
if t.user == "" {
log.Info("user not supplied nor ZITI_USER set. defaulting to admin")
t.user = "admin"
}
}
if t.host == "" {
t.host = os.Getenv("ZITI_CTRL_EDGE_ADVERTISED_ADDRESS")
if t.host == "" {
log.Info("host not supplied nor ZITI_CTRL_EDGE_ADVERTISED_ADDRESS set. defaulting to localhost")
t.host = "localhost"
}
}
if t.port == "" {
t.port = os.Getenv("ZITI_CTRL_EDGE_ADVERTISED_PORT")
if t.port == "" {
log.Info("port not supplied nor ZITI_CTRL_EDGE_ADVERTISED_PORT set. defaulting to 1280")
t.port = "1280"
}
}

if t.pass == "" {
p := os.Getenv("ZITI_PWD")
t.pass = p
if t.pass == "" {
pass, err := term.PromptPassword("Enter password: ", false)
if err != nil {
log.Fatal(err)
}
t.pass = pass
}
}

ctrlAddress := "https://" + t.host + ":" + t.port

log.Infof("connecting with user %s to %s", t.user, ctrlAddress)
caCerts, err := rest_util.GetControllerWellKnownCas(ctrlAddress)
if err != nil {
log.Fatal(err)
}
caPool := x509.NewCertPool()
for _, ca := range caCerts {
caPool.AddCert(ca)
}
return rest_util.NewEdgeManagementClientWithUpdb(t.user, t.pass, ctrlAddress, caPool)
}

func createIdentity(client *rest_management_api_client.ZitiEdgeManagement, name string, roleAttributes rest_model.Attributes) *identity.CreateIdentityCreated {
falseVar := false
usrType := rest_model.IdentityTypeUser
Expand Down

0 comments on commit 3a0fd6a

Please sign in to comment.