forked from HeroesAwaken/GoBot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
remotecon.go
111 lines (92 loc) · 2.23 KB
/
remotecon.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"io"
"io/ioutil"
"net"
"os"
"github.com/HeroesAwaken/GoAwaken/Log"
"golang.org/x/crypto/ssh"
)
// Get default location of a private key
func privateKeyPath() string {
return os.Getenv("HOME") + "/.ssh/id_rsa"
}
// Get private key for ssh authentication
func parsePrivateKey(keyPath string) (ssh.Signer, error) {
buff, _ := ioutil.ReadFile(keyPath)
return ssh.ParsePrivateKey(buff)
}
// Get ssh client config for our connection
// SSH config will use 2 authentication strategies: by key and by password
func makeSshConfig(user string) (*ssh.ClientConfig, error) {
key, err := parsePrivateKey(privateKeyPath())
if err != nil {
return nil, err
}
config := ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(key),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
return &config, nil
}
// Handle local client connections and tunnel data to the remote serverq
// Will use io.Copy - http://golang.org/pkg/io/#Copy
func handleClient(client net.Conn, sshClient *ssh.Client, remoteAddr string) {
defer client.Close()
chDone := make(chan bool)
// Establish connection with remote server
remote, err := sshClient.Dial("tcp", remoteAddr)
if err != nil {
log.Fatalln(err)
}
defer remote.Close()
// Start remote -> local data transfer
go func() {
_, err := io.Copy(client, remote)
if err != nil {
log.Errorln("error while copy remote->local:", err)
}
chDone <- true
}()
// Start local -> remote data transfer
go func() {
_, err := io.Copy(remote, client)
if err != nil {
log.Errorln(err)
}
chDone <- true
}()
<-chDone
}
func startRemoveCon(sshAddr, localAddr, remoteAddr string) {
// Build SSH client configuration
cfg, err := makeSshConfig("forge")
if err != nil {
log.Fatalln(err)
}
// Establish connection with SSH server
conn, err := ssh.Dial("tcp", sshAddr, cfg)
if err != nil {
log.Fatalln(err)
}
// Start local server to forward traffic to remote connection
local, err := net.Listen("tcp", localAddr)
if err != nil {
log.Fatalln(err)
}
// Handle incoming connections
go func() {
for {
client, err := local.Accept()
if err != nil {
log.Fatalln(err)
}
handleClient(client, conn, remoteAddr)
}
local.Close()
conn.Close()
}()
}