Skip to content

Instantly share code, notes, and snippets.

@rusco
Created September 14, 2022 08:03
Show Gist options
  • Save rusco/ef2c50eaeb5b5c940bbefaddaf70cff4 to your computer and use it in GitHub Desktop.
Save rusco/ef2c50eaeb5b5c940bbefaddaf70cff4 to your computer and use it in GitHub Desktop.
SSH Tunnel over HTTPS
package main
// 20220914, jr
import (
"C"
"context"
"fmt"
"net"
"os"
"os/signal"
"syscall"
"github.com/armon/go-socks5"
"golang.org/x/crypto/ssh"
)
const (
privateKeyPath = "/home/someusr/.ssh/id_rsa"
usr = "someusr"
sshAddress = "someserver:443"
socks5Address = "localhost:8888"
)
func parsePrivateKey(keyPath string) (ssh.Signer, error) {
buff, _ := os.ReadFile(keyPath)
return ssh.ParsePrivateKey(buff)
}
func main() {
key, err := parsePrivateKey(privateKeyPath)
if err != nil {
fmt.Println("error reading key: ", err)
return
}
sshConf := &ssh.ClientConfig{
User: usr,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(key),
//ssh.Password("somepass"),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
sshConn, err := ssh.Dial("tcp", sshAddress, sshConf)
if err != nil {
fmt.Println("error tunnel to server: ", err)
return
}
defer sshConn.Close()
fmt.Println("connected to ssh server")
go func() {
conf := &socks5.Config{
Dial: func(ctx context.Context, network, addr string) (net.Conn, error) {
return sshConn.Dial(network, addr)
},
}
serverSocks, err := socks5.New(conf)
if err != nil {
fmt.Println(err)
return
}
if err := serverSocks.ListenAndServe("tcp", socks5Address); err != nil {
fmt.Println("failed to create socks5 server", err)
}
}()
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
<-ch
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment