add net grpc

This commit is contained in:
Boshi Lian 2022-07-04 13:11:57 +00:00
parent dbef31dd3d
commit 4bb9470d7d
4 changed files with 175 additions and 54 deletions

102
cmd/sshpiperd/grpc.go Normal file
View 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
}

View file

@ -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
View file

@ -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=

View file

@ -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())
}