add net grpc
This commit is contained in:
parent
dbef31dd3d
commit
4bb9470d7d
4 changed files with 175 additions and 54 deletions
102
cmd/sshpiperd/grpc.go
Normal file
102
cmd/sshpiperd/grpc.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/tg123/sshpiper/cmd/sshpiperd/internal/plugin"
|
||||
"github.com/urfave/cli/v2"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func createNetGrpcPlugin(args []string) (grpcPlugin *plugin.GrpcPlugin, err error) {
|
||||
app := &cli.App{
|
||||
Name: "grpc",
|
||||
Usage: "sshpiperd grpc plugin",
|
||||
HideHelpCommand: true,
|
||||
HideHelp: true,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "endpoint",
|
||||
Usage: "grpc endpoint address",
|
||||
EnvVars: []string{"SSHPIPERD_GRPC_ENDPOINT"},
|
||||
Required: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "insecure",
|
||||
Usage: "disable tls",
|
||||
EnvVars: []string{"SSHPIPERD_GRPC_INSECURE"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "key",
|
||||
Usage: "grpc client key path",
|
||||
EnvVars: []string{"SSHPIPERD_GRPC_KEY"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "cert",
|
||||
Usage: "grpc client cert path",
|
||||
EnvVars: []string{"SSHPIPERD_GRPC_CERT"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "cacert",
|
||||
Usage: "grpc ca cert path",
|
||||
EnvVars: []string{"SSHPIPERD_GRPC_CACERT"},
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
|
||||
var secopt grpc.DialOption
|
||||
if c.Bool("insecure") {
|
||||
secopt = grpc.WithTransportCredentials(insecure.NewCredentials())
|
||||
} else {
|
||||
|
||||
clientCert, err := tls.LoadX509KeyPair(c.String("cert"), c.String("key"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := &tls.Config{
|
||||
Certificates: []tls.Certificate{clientCert},
|
||||
}
|
||||
|
||||
cacert := c.String("cacert")
|
||||
if cacert != "" {
|
||||
ca, err := ioutil.ReadFile(cacert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
certPool := x509.NewCertPool()
|
||||
if !certPool.AppendCertsFromPEM(ca) {
|
||||
return fmt.Errorf("failed to append ca")
|
||||
}
|
||||
|
||||
config.RootCAs = certPool
|
||||
}
|
||||
|
||||
secopt = grpc.WithTransportCredentials(credentials.NewTLS(config))
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(c.String("endpoint"), secopt, grpc.WithBlock())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
grpcPlugin, err = plugin.DialGrpc(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
if err := app.Run(args); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return grpcPlugin, nil
|
||||
}
|
||||
|
|
@ -48,6 +48,29 @@ func splitByDash(args []string) ([]string, []string) {
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func createPlugin(args []string) (*plugin.GrpcPlugin, error) {
|
||||
exe := args[0]
|
||||
|
||||
switch exe {
|
||||
case "grpc":
|
||||
log.Info("starting net grpc plugin: ")
|
||||
return createNetGrpcPlugin(args)
|
||||
|
||||
default:
|
||||
cmd := exec.Command(exe)
|
||||
cmd.Args = args
|
||||
|
||||
log.Info("starting child process plugin: ", cmd.Args)
|
||||
|
||||
p, err := plugin.DialCmd(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &p.GrpcPlugin, nil
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
app := &cli.App{
|
||||
|
|
@ -91,18 +114,6 @@ func main() {
|
|||
EnvVars: []string{"SSHPIPERD_LOG_LEVEL"},
|
||||
},
|
||||
},
|
||||
// Commands: []*cli.Command{
|
||||
// &cli.Command{
|
||||
// Name: "plug",
|
||||
|
||||
// },
|
||||
// // &cli.Command{
|
||||
// // Name: "grpc",
|
||||
// // Action: func(ctx *cli.Context) error {
|
||||
// // return fmt.Errorf("not implemented")
|
||||
// // },
|
||||
// // },
|
||||
// },
|
||||
Action: func(ctx *cli.Context) error {
|
||||
level, err := log.ParseLevel(ctx.String("log-level"))
|
||||
if err != nil {
|
||||
|
|
@ -134,19 +145,13 @@ func main() {
|
|||
continue
|
||||
}
|
||||
|
||||
exe := args[0]
|
||||
cmd := exec.Command(exe)
|
||||
cmd.Args = args
|
||||
|
||||
log.Info("starting plugin: ", cmd.Args)
|
||||
|
||||
p, err := plugin.DialCmd(cmd)
|
||||
p, err := createPlugin(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go p.RecvLogs(log.StandardLogger().Out)
|
||||
|
||||
plugins = append(plugins, &p.GrpcPlugin)
|
||||
go p.RecvLogs(log.StandardLogger().Out)
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
|
||||
if err := d.install(plugins...); err != nil {
|
||||
|
|
|
|||
9
go.sum
9
go.sum
|
|
@ -69,7 +69,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
|||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
|
|
@ -93,7 +92,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
|
|||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
|
|
@ -206,8 +204,6 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
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/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
|
||||
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
|
|
@ -451,7 +447,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
@ -599,8 +594,6 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
|||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
|
||||
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
|
@ -638,8 +631,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
|||
|
|
@ -1,44 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tg123/sshpiper/libplugin"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
log.Fatal("no target address provided")
|
||||
}
|
||||
|
||||
target := os.Args[1]
|
||||
app := &cli.App{
|
||||
Name: "fixed",
|
||||
Usage: "sshpiperd fixed plugin, only password auth is supported",
|
||||
HideHelpCommand: true,
|
||||
HideHelp: true,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "target",
|
||||
Usage: "target ssh endpoint address",
|
||||
EnvVars: []string{"SSHPIPERD_FIXED_TARGET"},
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
Writer: os.Stderr,
|
||||
ErrWriter: os.Stderr,
|
||||
Action: func(c *cli.Context) error {
|
||||
target := c.String("target")
|
||||
|
||||
host, port, err := libplugin.SplitHostPortForSSH(target)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
host, port, err := libplugin.SplitHostPortForSSH(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := libplugin.SshPiperPluginConfig{
|
||||
PasswordCallback: func(conn libplugin.ConnMetadata, password []byte) (*libplugin.Upstream, error) {
|
||||
log.Info("routing to ", target)
|
||||
return &libplugin.Upstream{
|
||||
Host: host,
|
||||
Port: int32(port),
|
||||
IgnoreHostKey: true,
|
||||
Auth: libplugin.CreatePasswordAuth(password),
|
||||
}, nil
|
||||
config := libplugin.SshPiperPluginConfig{
|
||||
PasswordCallback: func(conn libplugin.ConnMetadata, password []byte) (*libplugin.Upstream, error) {
|
||||
log.Info("routing to ", target)
|
||||
return &libplugin.Upstream{
|
||||
Host: host,
|
||||
Port: int32(port),
|
||||
IgnoreHostKey: true,
|
||||
Auth: libplugin.CreatePasswordAuth(password),
|
||||
}, nil
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
p, err := libplugin.NewFromStdio(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
libplugin.ConfigStdioLogrus(p, nil)
|
||||
|
||||
log.Printf("starting fix routing to ssh endpoint %v (password only)", target)
|
||||
return p.Serve()
|
||||
},
|
||||
}
|
||||
|
||||
p, err := libplugin.NewFromStdio(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "cannot start plugin: %v\n", err)
|
||||
}
|
||||
|
||||
libplugin.ConfigStdioLogrus(p, nil)
|
||||
|
||||
log.Printf("starting fix routing to ssh %v (password only)", target)
|
||||
panic(p.Serve())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue