add flag to allow configuration of SSH kex algos
Adds a flag `ssh-kex-algos` which configures the gogit and libgit2 managed clients to use the specified list of kex algos for ssh. If not used the default list in `golang/x/crypto/ssh` is used. Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
This commit is contained in:
parent
362bc56bd7
commit
5c84ea7e96
9
main.go
9
main.go
|
@ -46,6 +46,7 @@ import (
|
|||
"github.com/fluxcd/source-controller/controllers"
|
||||
"github.com/fluxcd/source-controller/internal/cache"
|
||||
"github.com/fluxcd/source-controller/internal/helm"
|
||||
"github.com/fluxcd/source-controller/pkg/git"
|
||||
"github.com/fluxcd/source-controller/pkg/git/libgit2/managed"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
@ -90,6 +91,7 @@ func main() {
|
|||
helmCacheMaxSize int
|
||||
helmCacheTTL string
|
||||
helmCachePurgeInterval string
|
||||
kexAlgos []string
|
||||
)
|
||||
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", envOrDefault("METRICS_ADDR", ":8080"),
|
||||
|
@ -120,6 +122,8 @@ func main() {
|
|||
"The TTL of an index in the cache. Valid time units are ns, us (or µs), ms, s, m, h.")
|
||||
flag.StringVar(&helmCachePurgeInterval, "helm-cache-purge-interval", "1m",
|
||||
"The interval at which the cache is purged. Valid time units are ns, us (or µs), ms, s, m, h.")
|
||||
flag.StringSliceVar(&kexAlgos, "ssh-kex-algos", []string{},
|
||||
"The list of key exchange algorithms to use for ssh connections, arranged from most preferred to the least.")
|
||||
|
||||
clientOptions.BindFlags(flag.CommandLine)
|
||||
logOptions.BindFlags(flag.CommandLine)
|
||||
|
@ -174,6 +178,7 @@ func main() {
|
|||
storageAdvAddr = determineAdvStorageAddr(storageAddr, setupLog)
|
||||
}
|
||||
storage := mustInitStorage(storagePath, storageAdvAddr, setupLog)
|
||||
setPreferredKexAlgos(kexAlgos)
|
||||
|
||||
if err = (&controllers.GitRepositoryReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
|
@ -333,3 +338,7 @@ func envOrDefault(envName, defaultValue string) string {
|
|||
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func setPreferredKexAlgos(algos []string) {
|
||||
git.KexAlgos = algos
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import (
|
|||
"github.com/fluxcd/pkg/ssh/knownhosts"
|
||||
|
||||
"github.com/fluxcd/source-controller/pkg/git"
|
||||
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// transportAuth constructs the transport.AuthMethod for the git.Transport of
|
||||
|
@ -58,7 +60,10 @@ func transportAuth(opts *git.AuthOptions) (transport.AuthMethod, error) {
|
|||
}
|
||||
pk.HostKeyCallback = callback
|
||||
}
|
||||
return pk, nil
|
||||
customPK := &CustomPublicKeys{
|
||||
pk: pk,
|
||||
}
|
||||
return customPK, nil
|
||||
}
|
||||
case "":
|
||||
return nil, fmt.Errorf("no transport type set")
|
||||
|
@ -75,3 +80,28 @@ func caBundle(opts *git.AuthOptions) []byte {
|
|||
}
|
||||
return opts.CAFile
|
||||
}
|
||||
|
||||
// CustomPublicKeys is a wrapper around ssh.PublicKeys to help us
|
||||
// customize the ssh config. It implements ssh.AuthMethod.
|
||||
type CustomPublicKeys struct {
|
||||
pk *ssh.PublicKeys
|
||||
}
|
||||
|
||||
func (a *CustomPublicKeys) Name() string {
|
||||
return a.pk.Name()
|
||||
}
|
||||
|
||||
func (a *CustomPublicKeys) String() string {
|
||||
return a.pk.String()
|
||||
}
|
||||
|
||||
func (a *CustomPublicKeys) ClientConfig() (*gossh.ClientConfig, error) {
|
||||
config, err := a.pk.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(git.KexAlgos) > 0 {
|
||||
config.Config.KeyExchanges = git.KexAlgos
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/fluxcd/source-controller/pkg/git"
|
||||
|
@ -72,6 +71,7 @@ func Test_transportAuth(t *testing.T) {
|
|||
name string
|
||||
opts *git.AuthOptions
|
||||
wantFunc func(g *WithT, t transport.AuthMethod, opts *git.AuthOptions)
|
||||
kexAlgos []string
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
|
@ -128,10 +128,10 @@ func Test_transportAuth(t *testing.T) {
|
|||
Identity: []byte(privateKeyFixture),
|
||||
},
|
||||
wantFunc: func(g *WithT, t transport.AuthMethod, opts *git.AuthOptions) {
|
||||
tt, ok := t.(*ssh.PublicKeys)
|
||||
tt, ok := t.(*CustomPublicKeys)
|
||||
g.Expect(ok).To(BeTrue())
|
||||
g.Expect(tt.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
g.Expect(tt.pk.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.pk.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -143,10 +143,31 @@ func Test_transportAuth(t *testing.T) {
|
|||
Identity: []byte(privateKeyPassphraseFixture),
|
||||
},
|
||||
wantFunc: func(g *WithT, t transport.AuthMethod, opts *git.AuthOptions) {
|
||||
tt, ok := t.(*ssh.PublicKeys)
|
||||
tt, ok := t.(*CustomPublicKeys)
|
||||
g.Expect(ok).To(BeTrue())
|
||||
g.Expect(tt.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
g.Expect(tt.pk.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.pk.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SSH with custom key exchanges",
|
||||
opts: &git.AuthOptions{
|
||||
Transport: git.SSH,
|
||||
Username: "example",
|
||||
Identity: []byte(privateKeyFixture),
|
||||
KnownHosts: []byte(knownHostsFixture),
|
||||
},
|
||||
kexAlgos: []string{"curve25519-sha256", "diffie-hellman-group-exchange-sha256"},
|
||||
wantFunc: func(g *WithT, t transport.AuthMethod, opts *git.AuthOptions) {
|
||||
tt, ok := t.(*CustomPublicKeys)
|
||||
g.Expect(ok).To(BeTrue())
|
||||
g.Expect(tt.pk.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.pk.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
config, err := tt.ClientConfig()
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
g.Expect(config.Config.KeyExchanges).To(Equal(
|
||||
[]string{"curve25519-sha256", "diffie-hellman-group-exchange-sha256"}),
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -168,11 +189,11 @@ func Test_transportAuth(t *testing.T) {
|
|||
KnownHosts: []byte(knownHostsFixture),
|
||||
},
|
||||
wantFunc: func(g *WithT, t transport.AuthMethod, opts *git.AuthOptions) {
|
||||
tt, ok := t.(*ssh.PublicKeys)
|
||||
tt, ok := t.(*CustomPublicKeys)
|
||||
g.Expect(ok).To(BeTrue())
|
||||
g.Expect(tt.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
g.Expect(tt.HostKeyCallback).ToNot(BeNil())
|
||||
g.Expect(tt.pk.User).To(Equal(opts.Username))
|
||||
g.Expect(tt.pk.Signer.PublicKey().Type()).To(Equal("ssh-rsa"))
|
||||
g.Expect(tt.pk.HostKeyCallback).ToNot(BeNil())
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -202,6 +223,10 @@ func Test_transportAuth(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
if len(tt.kexAlgos) > 0 {
|
||||
git.KexAlgos = tt.kexAlgos
|
||||
}
|
||||
|
||||
got, err := transportAuth(tt.opts)
|
||||
if tt.wantErr != nil {
|
||||
g.Expect(err).To(Equal(tt.wantErr))
|
||||
|
|
|
@ -58,6 +58,7 @@ import (
|
|||
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/fluxcd/source-controller/pkg/git"
|
||||
git2go "github.com/libgit2/git2go/v33"
|
||||
)
|
||||
|
||||
|
@ -344,6 +345,9 @@ func cacheKeyAndConfig(remoteAddress string, cred *git2go.Credential) (string, *
|
|||
Auth: []ssh.AuthMethod{ssh.PublicKeys(key)},
|
||||
Timeout: sshConnectionTimeOut,
|
||||
}
|
||||
if len(git.KexAlgos) > 0 {
|
||||
cfg.Config.KeyExchanges = git.KexAlgos
|
||||
}
|
||||
|
||||
return ck, cfg, nil
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@ type AuthOptions struct {
|
|||
CAFile []byte
|
||||
}
|
||||
|
||||
// List of custom key exchange algorithms to be used for ssh connections.
|
||||
var KexAlgos []string
|
||||
|
||||
// Validate the AuthOptions against the defined Transport.
|
||||
func (o AuthOptions) Validate() error {
|
||||
switch o.Transport {
|
||||
|
|
Loading…
Reference in New Issue