Skip to content

mavogel/go-ssh-forward

Repository files navigation

MIT license PkgGoDev Build Status Coverage Status Go Report Card

go-ssh-forward: A library for setting up a Forward via SSH in go

Table of Contents

Motivation

I wanted it to be possible to establish a tunnel like the following in go

$ ssh -f -L 2376:localhost:2376 \ 
  -o ExitOnForwardFailure=yes \ 
	-o ProxyCommand="ssh -l jumpuser1 -i /Users/abc/.ssh/id_rsa_jump_host1 10.0.0.1 -W %h:%p" \ 
	-o UserKnownHostsFile=/dev/null \ 
	-o StrictHostKeyChecking=no \ 
	-i /Users/abc/.ssh/id_rsa_end_host \ 
	[email protected] \
	sleep 10

In this scenario the end host is only accessible via the jump host

    localhost:2376 --(j)--> 10.0.0.1:22 --(e)--> 20.0.0.1:2376 -> 127.0.0.1:2376
       `host A`              `jump host`          `end host          `end host`          

Usage

package main

import (
	"log"
	"time"

    fw "github.com/mavogel/go-ssh-forward"
)
func main() {
  forwardConfig := &fw.Config{
		JumpHostConfigs: []*fw.SSHConfig{
			&fw.SSHConfig{
				Address:        "10.0.0.1:22",
				User:           "jumpuser1",
				PrivateKeyFile: "/Users/abc/.ssh/id_rsa_jump_host1",
			},
		},
		EndHostConfig: &fw.SSHConfig{
			Address:        "20.0.0.1:22",
			User:           "endhostuser",
			PrivateKeyFile: "/Users/abc/.ssh/id_rsa_end_host",
		},
		LocalAddress:  "localhost:2376",
		RemoteAddress: "localhost:2376",
  }
 
  forward, forwardErrors, bootstrapErr := fw.NewForward(forwardConfig)
  handleForwardErrors(forward)
  defer forward.Stop()
  if bootstrapErr != nil {
		log.Printf("bootstrapErr: %s", bootstrapErr)
		return
  }
  
  // run commands against 127.0.0.1:2376
  // ...

}

func handleForwardErrors(forwardErrors chan error) {
	go func() {
		for {
			select {
			case forwardError := <-forwardErrors:
				log.Printf("forward err: %s", forwardError)
			case <-time.After(3 * time.Second):
				log.Printf("NO forward err...")
			}
		}
	}()
}

Inspiration

Release

$ VERSION=vX.Y.Z make release
# EXAMPLE:
$ VERSION=v0.11.3 make release

License

Copyright (c) 2018-2021 Manuel Vogel
Source code is open source and released under the MIT license.