Skip to content

Commit

Permalink
Add support for SSH via Bastion Host (Juniper#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
vpatel95 committed Apr 29, 2024
1 parent dfbc77f commit 3c61e43
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module github.com/Juniper/go-netconf
module github.com/vpatel95/go-netconf

go 1.12

require (
github.com/Juniper/go-netconf v0.3.0
github.com/google/go-cmp v0.5.1
golang.org/x/crypto v0.1.0
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
github.com/Juniper/go-netconf v0.3.0 h1:STAqk495sGA0MqQ3Q8mUmk/CmTfWuIfbXRqpDYXgWNA=
github.com/Juniper/go-netconf v0.3.0/go.mod h1:QhfUOux77kzKAdY1+DOpQswtzp7LeeooYTn2MT7iXkY=
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
57 changes: 57 additions & 0 deletions netconf/transport_ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
)

const (
// bastionDefaultPort is the default port used when SSH via Bastion
bastionDefaultPort = 22
// sshDefaultPort is the default SSH port used when communicating with
// NETCONF
sshDefaultPort = 830
Expand Down Expand Up @@ -60,6 +62,49 @@ func (t *TransportSSH) Close() error {
return fmt.Errorf("No connection to close")
}

// DialWithBasstion connects and establishes SSH sessions over bastion host
//
// bastion can be an IP address (e.g) 172.16.2.1 which uses default port 22.
// Bastion can also specify port with format <host>:<port> (e.g 172.16.2.1:5001)
// target can be an IP address (e.g.) 172.16.1.1 which utlizes the default
// NETCONF over SSH port of 830. Target can also specify a port with the
// following format <host>:<port (e.g 172.16.1.1:22)
//
// config takes a ssh.ClientConfig connection. See documentation for
// go.crypto/ssh for documenation. There is a helper function SSHConfigPassword
// thar returns a ssh.ClientConfig for simple username/password authentication
func (t *TransportSSH) DialWithBasstion(bastion, target string, bastionConf, config *ssh.ClientConfig) error {
var err error

if !strings.Contains(bastion, ":") {
bastion = fmt.Sprintf("%s:%d", bastion, bastionDefaultPort)
}

bastionClient, err := ssh.Dial("tcp", bastion, bastionConf)
if err != nil {
return err
}

if !strings.Contains(target, ":") {
target = fmt.Sprintf("%s:%d", target, sshDefaultPort)
}

targetConn, err := bastionClient.Dial("tcp", target)
if err != nil {
return err
}

ncc, chans, reqs, err := ssh.NewClientConn(targetConn, target, config)
if err != nil {
return err
}

t.sshClient = ssh.NewClient(ncc, chans, reqs)

err = t.setupSession()
return err
}

// Dial connects and establishes SSH sessions
//
// target can be an IP address (e.g.) 172.16.1.1 which utlizes the default
Expand Down Expand Up @@ -117,6 +162,18 @@ func NewSSHSession(conn net.Conn, config *ssh.ClientConfig) (*Session, error) {
return NewSession(t), nil
}

// DialSSHWithBastion creates a new NETCONF session using a SSH Transport.
// See TransportSSH.Dial for arguments.
func DialSSHWithBastion(bastion, target string, bastionConf, config *ssh.ClientConfig) (*Session, error) {
var t TransportSSH
err := t.DialWithBasstion(bastion, target, bastionConf, config)
if err != nil {
t.Close()
return nil, err
}
return NewSession(&t), nil
}

// DialSSH creates a new NETCONF session using a SSH Transport.
// See TransportSSH.Dial for arguments.
func DialSSH(target string, config *ssh.ClientConfig) (*Session, error) {
Expand Down

0 comments on commit 3c61e43

Please sign in to comment.