From 2aee70995f3a6ecb73936b4a95b0359f4d8cc2d8 Mon Sep 17 00:00:00 2001 From: Vytautas Maciulskis Date: Mon, 9 Sep 2019 17:39:25 +0300 Subject: [PATCH 1/4] mask potential secrets in logging for remote URLs --- daemon/daemon.go | 2 +- daemon/loop.go | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index 9112e9a3a..b6d7409bd 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -542,7 +542,7 @@ func (d *Daemon) NotifyChange(ctx context.Context, change v9.Change) error { switch change.Kind { case v9.GitChange: gitUpdate := change.Source.(v9.GitUpdate) - if gitUpdate.URL != d.Repo.Origin().URL && gitUpdate.Branch != d.GitConfig.Branch { + if gitUpdate.URL != d.Repo.Origin().SafeURL() && gitUpdate.Branch != d.GitConfig.Branch { // It isn't strictly an _error_ to be notified about a repo/branch pair // that isn't ours, but it's worth logging anyway for debugging. d.Logger.Log("msg", "notified about unrelated change", diff --git a/daemon/loop.go b/daemon/loop.go index b25394fb6..3dd052924 100644 --- a/daemon/loop.go +++ b/daemon/loop.go @@ -116,14 +116,13 @@ func (d *Daemon) Loop(stop chan struct{}, wg *sync.WaitGroup, logger log.Logger) cancel() if err != nil { - logger.Log("url", d.Repo.Origin().URL, "err", err) + logger.Log("url", d.Repo.Origin().SafeURL(), "err", err) continue } if invalidCommit.Revision != "" { logger.Log("err", "found invalid GPG signature for commit", "revision", invalidCommit.Revision, "key", invalidCommit.Signature.Key) } - - logger.Log("event", "refreshed", "url", d.Repo.Origin().URL, "branch", d.GitConfig.Branch, "HEAD", newSyncHead) + logger.Log("event", "refreshed", "url", d.Repo.Origin().SafeURL(), "branch", d.GitConfig.Branch, "HEAD", newSyncHead) if newSyncHead != syncHead { syncHead = newSyncHead d.AskForSync() From 45733c07f80d9505937eb818f913eaba159f791a Mon Sep 17 00:00:00 2001 From: Vytautas Maciulskis Date: Mon, 9 Sep 2019 17:42:51 +0300 Subject: [PATCH 2/4] added comment, about NewNopSSHKeyRing usage --- ssh/keyring.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssh/keyring.go b/ssh/keyring.go index 878a14003..e8cb6868e 100644 --- a/ssh/keyring.go +++ b/ssh/keyring.go @@ -11,7 +11,7 @@ type KeyRing interface { type sshKeyRing struct{} // NewNopSSHKeyRing returns a KeyRing that doesn't do anything. -// It is meant for local development purposes when running fluxd outside a Kubernetes container. +// It is meant for local development purposes when running fluxd outside a Kubernetes container or authentication to git done via HTTPS func NewNopSSHKeyRing() KeyRing { return &sshKeyRing{} } From b80bec1ad5d0be9972160cd0a965d654af9e5ced Mon Sep 17 00:00:00 2001 From: Vytautas Maciulskis Date: Mon, 9 Sep 2019 17:49:21 +0300 Subject: [PATCH 3/4] added git-apikey argument: * this argument and logics makes possible to use https transport for git remote. If git-apikey argument is supplied - ssh private/public key generation will be skipped (as key auth is no longer in use) * added logics forces not to use username:password in git-url argument, as apikey better keep separate and treat is as secret, instead of simple configmap added example for git-url, that https transport also can be used --- cmd/fluxd/main.go | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/cmd/fluxd/main.go b/cmd/fluxd/main.go index f12ddddf3..b5a40b963 100644 --- a/cmd/fluxd/main.go +++ b/cmd/fluxd/main.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/http" _ "net/http/pprof" + "net/url" "os" "os/exec" "os/signal" @@ -110,11 +111,12 @@ func main() { kubernetesKubectl = fs.String("kubernetes-kubectl", "", "optional, explicit path to kubectl tool") versionFlag = fs.Bool("version", false, "get version number") // Git repo & key etc. - gitURL = fs.String("git-url", "", "URL of git repo with Kubernetes manifests; e.g., git@github.com:weaveworks/flux-get-started") + gitURL = fs.String("git-url", "", "URL of git repo with Kubernetes manifests; e.g., git@github.com:weaveworks/flux-get-started or https://github.com/fluxcd/flux.git . If specifying HTTPS transport, you can add git-user and git-apikey for authentication") gitBranch = fs.String("git-branch", "master", "branch of git repo to use for Kubernetes manifests") gitPath = fs.StringSlice("git-path", []string{}, "relative paths within the git repo to locate Kubernetes manifests") gitReadonly = fs.Bool("git-readonly", false, fmt.Sprintf("use to prevent Flux from pushing changes to git; implies --sync-state=%s", fluxsync.NativeStateMode)) gitUser = fs.String("git-user", "Weave Flux", "username to use as git committer") + gitAPIKey = fs.String("git-apikey", "", `if set, git-apikey will be used to clone repo and push sync tags only using HTTPS protocol`) gitEmail = fs.String("git-email", "support@weave.works", "email to use as git committer") gitSetAuthor = fs.Bool("git-set-author", false, "if set, the author of git commits will reflect the user who initiated the commit and will differ from the git committer.") gitLabel = fs.String("git-label", "", "label to keep track of sync progress; overrides both --git-sync-tag and --git-notes-ref") @@ -319,7 +321,7 @@ func main() { } } - if *sshKeygenDir == "" { + if *sshKeygenDir == "" && *gitAPIKey == "" { logger.Log("info", fmt.Sprintf("SSH keygen dir (--ssh-keygen-dir) not provided, so using the deploy key volume (--k8s-secret-volume-mount-path=%s); this may cause problems if the deploy key volume is mounted read-only", *k8sSecretVolumeMountPath)) *sshKeygenDir = *k8sSecretVolumeMountPath } @@ -430,7 +432,7 @@ func main() { } clusterVersion = "kubernetes-" + serverVersion.GitVersion - if *k8sInCluster { + if *k8sInCluster && *gitAPIKey == "" { namespace, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") if err != nil { logger.Log("err", err) @@ -596,12 +598,42 @@ func main() { } checkpoint.CheckForUpdates(product, version, checkpointFlags, updateCheckLogger) + if *gitAPIKey != "" { + parsedGitURL, err := url.Parse(*gitURL) + + if err != nil { + logger.Log("err", err) + os.Exit(1) + } + + if parsedGitURL.Scheme != "https" { + logger.Log("err", "git-apikey argument can be used only with HTTPS transport") + os.Exit(1) + } + + if parsedGitURL.User.Username() != "" { + logger.Log("err", "Set git username not in git-url, but use git-user argument instead") + os.Exit(1) + } + + _, passwordExists := parsedGitURL.User.Password() + + if passwordExists { + logger.Log("err", "Set git APIkey not in git-url, but use git-apikey argument instead") + os.Exit(1) + } + + parsedGitURL.User = url.UserPassword(*gitUser, *gitAPIKey) + *gitURL = parsedGitURL.String() + } + gitRemote := git.Remote{URL: *gitURL} gitConfig := git.Config{ Paths: *gitPath, Branch: *gitBranch, NotesRef: *gitNotesRef, UserName: *gitUser, + APIKey: *gitAPIKey, UserEmail: *gitEmail, SigningKey: *gitSigningKey, SetAuthor: *gitSetAuthor, @@ -621,7 +653,7 @@ func main() { } logger.Log( - "url", *gitURL, + "url", gitRemote.SafeURL(), "user", *gitUser, "email", *gitEmail, "signing-key", *gitSigningKey, From 892c88b258f9b0a8d8f5fc80b92e4418f3f83b2f Mon Sep 17 00:00:00 2001 From: Vytautas Maciulskis Date: Mon, 9 Sep 2019 17:50:00 +0300 Subject: [PATCH 4/4] added APIKey element for git.Config --- git/working.go | 1 + 1 file changed, 1 insertion(+) diff --git a/git/working.go b/git/working.go index f3b2f5b70..155cb368b 100644 --- a/git/working.go +++ b/git/working.go @@ -18,6 +18,7 @@ type Config struct { Paths []string // paths within the repo containing files we care about NotesRef string UserName string + APIKey string UserEmail string SigningKey string SetAuthor bool