fix bug that cause can't login with sshpipe name in kubernetes and add kubernetes pipe management (#82)

* fix kubernetes example wrong link in readme

* fix typo in example deploy file

* fix bug that cause can't login with sshpipe name in kubernetes

* add pipe management in upstream kubernetes

* update errors format
This commit is contained in:
Byron.wang 2022-03-08 04:28:41 +08:00 committed by GitHub
parent cc1fa258c8
commit 1aef76fd7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 49 deletions

2
go.mod
View file

@ -53,11 +53,13 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/imdario/mergo v0.3.5 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/lib/pq v1.1.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect

1
go.sum
View file

@ -205,6 +205,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net"
//"path/filepath"
//"strings"
@ -11,6 +12,7 @@ import (
"golang.org/x/crypto/ssh"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"
//"k8s.io/client-go/util/homedir"
//"k8s.io/client-go/tools/clientcmd"
sshpipeclientset "github.com/pockost/sshpipe-k8s-lib/pkg/client/clientset/versioned"
@ -28,17 +30,16 @@ type pipeConfig struct {
// }
func (p *plugin) getClientSet() (*sshpipeclientset.Clientset, error) {
/*
var kubeconfig string
home := homedir.HomeDir()
kubeconfig = filepath.Join(home, ".kube", "config")
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
return nil, err
}
*/
// var kubeconfig string
// home := homedir.HomeDir()
// kubeconfig = filepath.Join(home, ".kube", "config")
// // use the current context in kubeconfig
// config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
// if err != nil {
// return nil, err
// }
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
@ -53,34 +54,29 @@ func (p *plugin) getClientSet() (*sshpipeclientset.Clientset, error) {
return clientset, nil
}
func (p *plugin) getConfig(clientset *sshpipeclientset.Clientset) ([]pipeConfig, error) {
func (p *plugin) getConfig(clientset *sshpipeclientset.Clientset, sshPipeName string) (pipeConfig, error) {
listOptions := metav1.ListOptions{}
pipes, err := clientset.PockostV1beta1().SshPipes("").List(context.TODO(), listOptions)
if err != nil {
return nil, err
return pipeConfig{}, err
}
if err != nil {
return nil, err
return pipeConfig{}, err
}
var config []pipeConfig
for _, pipe := range pipes.Items {
targetHost := fmt.Sprintf("%s.%s", pipe.Spec.Target.Name, pipe.ObjectMeta.Namespace)
for _, username := range pipe.Spec.Users {
config = append(
config,
pipeConfig{
Username: username,
UpstreamHost: targetHost,
},
)
if pipe.Name == sshPipeName {
targetHost := fmt.Sprintf("%s.%s", pipe.Spec.Target.Name, pipe.ObjectMeta.Namespace)
return pipeConfig{
Username: pipe.Spec.Users[0],
UpstreamHost: targetHost,
}, nil
}
}
return config, nil
return pipeConfig{}, fmt.Errorf("sshPipe [%s] not found", sshPipeName)
}
func (p *plugin) createAuthPipe(pipe pipeConfig, conn ssh.ConnMetadata, challengeContext ssh.AdditionalChallengeContext) (*ssh.AuthPipe, error) {
@ -107,30 +103,22 @@ func (p *plugin) findUpstream(conn ssh.ConnMetadata, challengeContext ssh.Additi
}
// Get config from k8s
config, err := p.getConfig(clientset)
pipeConfig, err := p.getConfig(clientset, user)
if err != nil {
return nil, nil, err
}
// Retreive corresponding configuration
for _, pipe := range config {
matched := pipe.Username == user
if matched {
c, err := upstream.DialForSSH(pipe.UpstreamHost)
if err != nil {
return nil, nil, err
}
a, err := p.createAuthPipe(pipe, conn, challengeContext)
if err != nil {
return nil, nil, err
}
p.logger.Printf("Forwarding connection to [%v] for user [%v]", pipe.UpstreamHost, pipe.Username)
return c, a, nil
}
c, err := upstream.DialForSSH(pipeConfig.UpstreamHost)
if err != nil {
return nil, nil, err
}
return nil, nil, fmt.Errorf("username not [%v] found", user)
a, err := p.createAuthPipe(pipeConfig, conn, challengeContext)
if err != nil {
return nil, nil, err
}
p.logger.Printf("SSH Pipe [%s] forwarding connection to [%s] with user [%s]", user, pipeConfig.UpstreamHost, pipeConfig.Username)
return c, a, nil
}

View file

@ -1,14 +1,33 @@
package kubernetes
import (
"context"
"fmt"
"github.com/tg123/sshpiper/sshpiperd/upstream"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Return All pipes inside upstream
func (p *plugin) ListPipe() ([]upstream.Pipe, error) {
var pipes []upstream.Pipe
pipes := []upstream.Pipe{}
clientset, err := p.getClientSet()
if err != nil {
return nil, err
}
pipeList, err := clientset.PockostV1beta1().SshPipes("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
for _, p := range pipeList.Items {
targetHost := fmt.Sprintf("%s.%s", p.Spec.Target.Name, p.ObjectMeta.Namespace)
pipes = append(pipes, upstream.Pipe{
Username: p.Name,
UpstreamUsername: p.Spec.Users[0],
Host: targetHost,
Port: 22,
})
}
return pipes, nil
}
@ -19,5 +38,20 @@ func (p *plugin) CreatePipe(opt upstream.CreatePipeOption) error {
// Remove a pipe from upstream
func (p *plugin) RemovePipe(name string) error {
return nil
clientset, err := p.getClientSet()
if err != nil {
return err
}
pipeList, err := clientset.PockostV1beta1().SshPipes("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
for _, p := range pipeList.Items {
if p.Name == name {
return clientset.PockostV1beta1().SshPipes(p.ObjectMeta.Namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}
}
return fmt.Errorf("SSH Pipe [%s] not found", name)
}

View file

@ -375,5 +375,5 @@ func (p *plugin) findUpstream(conn ssh.ConnMetadata, challengeContext ssh.Additi
}
}
return nil, nil, fmt.Errorf("username not [%v] found", user)
return nil, nil, fmt.Errorf("username [%v] not found", user)
}