Skip to content

Instantly share code, notes, and snippets.

@jeffdyke
Last active June 12, 2024 00:48
Show Gist options
  • Save jeffdyke/00bd3e327d501d4de53a6f1a7dd65f8d to your computer and use it in GitHub Desktop.
Save jeffdyke/00bd3e327d501d4de53a6f1a7dd65f8d to your computer and use it in GitHub Desktop.
Go - SSH Through Bastion Host
// I created this to attach to https://stackoverflow.com/questions/60046598/ssh-through-bastion-host
package main
import (
"flag"
"fmt"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"log"
"net"
"os"
"os/user"
)
const TCP = "tcp"
const PORT = "22"
const SOCKET = "SSH_AUTH_SOCK"
const UNIX = "unix"
func sshAgentConnect() agent.ExtendedAgent {
socket := os.Getenv(SOCKET)
conn, err := net.Dial(UNIX, socket)
if err != nil {
log.Fatalf("Failed to connect to %v", SOCKET)
}
agentClient := agent.NewClient(conn)
return agentClient
}
func clientAuth(usr string, auth ssh.AuthMethod) *ssh.ClientConfig {
config := &ssh.ClientConfig{
User: usr,
Auth: []ssh.AuthMethod{
auth,
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
return config
}
func formatHost(host string) string {
return fmt.Sprintf("%s:%s", host, PORT)
}
func main() {
var usr, _ = user.Current()
userF := flag.String("user", usr.Username, "user to connect as")
bastionF := flag.String("bastion", "" , "Bation host to connect to")
lanHostF := flag.String("host", "", "Lan Host to connect to")
flag.Parse()
var sshAgent = sshAgentConnect()
var config = clientAuth(*userF, ssh.PublicKeysCallback(sshAgent.Signers))
sshc, err := ssh.Dial(TCP, formatHost(*bastionF), config)
if err != nil {
log.Fatalf("Failed to connect to %s\n%v\n", *bastionF, err)
}
defer sshc.Close()
lanConn, err := sshc.Dial(TCP, formatHost(*lanHostF))
if err != nil {
fmt.Printf("got error trying to dial %v\n -- %v\n", *lanHostF, err)
log.Fatal(err)
}
defer lanConn.Close()
ncc, chans, reqs, err := ssh.NewClientConn(lanConn, formatHost(*lanHostF), config)
if err != nil {
fmt.Printf("got error trying to get new client connection %v\n -- %v\n", formatHost(*lanHostF), err)
log.Fatal(err)
}
sClient := ssh.NewClient(ncc, chans, reqs)
defer sClient.Close()
fmt.Printf("Connection to %v created at %v", *lanHostF, sClient.Conn.LocalAddr())
}
/*
You can run this with
./agentssh -bastion jump.example.com -host lanweb01
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment