pupirka

Форк
0
/
parent.go 
117 строк · 3.1 Кб
1
package main
2

3
import (
4
	"errors"
5
	"fmt"
6
	"golang.org/x/crypto/ssh"
7
	"io"
8
	"math/rand"
9
	"net"
10
	"time"
11
)
12

13
var MDeviceList = make(map[string]Device)
14
var MLocalPort = make(map[uint16]string)
15

16
func SshForwardNewDevice(parent Device, child Device) Device {
17
	child.LogDebug("SshForwardNewDevice: Get new address", child.Name)
18
	lport := SshLocalGeneratePort()
19
	go SshClientRunForward(&parent, child, lport)
20
	child.Address = "localhost"
21
	child.PortSSH = lport
22
	child.LogDebug(fmt.Sprintf("SshForwardNewDevice: new address (%s), new port (%d)", child.Address, child.PortSSH))
23
	return child
24

25
}
26

27
func SshClientRunForward(parent *Device, child Device, lport uint16) {
28
	auth, _ := SshClientDeviceAuth(parent)
29

30
	config := &ssh.ClientConfig{
31
		Config: ssh.Config{
32
			KeyExchanges: sshkkeysAlgo,
33
			Ciphers:      sshChippers,
34
		},
35
		User:            parent.Username,
36
		Auth:            auth,
37
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
38
		Timeout:         time.Duration(parent.Timeout) * time.Second,
39
	}
40

41
	localAddrString := fmt.Sprintf("localhost:%d", lport)
42
	localListener, err := net.Listen("tcp", localAddrString)
43
	if err != nil {
44
		child.LogError(fmt.Sprintf("SshClientRunForward net.Listen failed: %s", err.Error()))
45
		return
46
	}
47

48
	for {
49
		// Setup localConn (type net.Conn)
50
		localConn, err := localListener.Accept()
51
		if err != nil {
52
			child.LogError(fmt.Sprintf("SshClientRunForward listen.Accept failed: %s", err.Error()))
53
			return
54
		}
55
		go forward(localConn, config, SshAddressFormat(parent), SshAddressFormat(&child))
56
	}
57
}
58

59
func forward(localConn net.Conn, config *ssh.ClientConfig, parentaddress string, childaddress string) {
60
	// Setup sshClientConn (type *ssh.ClientConn)
61
	sshClientConn, err := ssh.Dial("tcp", parentaddress, config)
62
	if err != nil {
63
		LogConsole.Info(fmt.Sprintf("ssh.Dial failed %s ... Child %s, Parent %s", err.Error(), childaddress, parentaddress))
64
		_ = sshClientConn.Close()
65
		return
66
	}
67
	// Setup sshConn (type net.Conn)
68
	sshConn, err := sshClientConn.Dial("tcp", childaddress)
69

70
	// Copy localConn.Reader to sshConn.Writer
71
	go func() {
72
		_, err = io.Copy(sshConn, localConn)
73
		if err != nil {
74
			LogConsole.Info(fmt.Sprintf("io.Copy failed %s ... Child %s, Parent %s", err.Error(), childaddress, parentaddress))
75
			_ = sshConn.Close()
76
			_ = sshClientConn.Close()
77
			return
78
		}
79
	}()
80

81
	// Copy sshConn.Reader to localConn.Writer
82
	go func() {
83
		_, err = io.Copy(localConn, sshConn)
84
		if err != nil {
85
			LogConsole.Info(fmt.Sprintf("io.Copy failed %s ... Child %s, Parent %s", err.Error(), childaddress, parentaddress))
86
			_ = sshConn.Close()
87
			_ = sshClientConn.Close()
88
			return
89
		}
90
	}()
91

92
}
93

94
func SshLocalGeneratePort() uint16 {
95
	min := 40000
96
	max := 50000
97

98
	for {
99
		rand.Seed(time.Now().UnixNano())
100
		r := rand.Intn(max-min+1) + min
101
		if _, ok := MLocalPort[uint16(r)]; ok {
102
			continue
103
		}
104
		MLocalPort[uint16(r)] = ""
105
		return uint16(r)
106
	}
107
}
108

109
func SshNeedForward(device *Device) (Device, Device, error) {
110

111
	if _, ok := MDeviceList[device.Parent]; !ok {
112
		return Device{}, Device{}, errors.New("SshNeedForward: no isset parent device")
113
	}
114
	parent := MDeviceList[device.Parent]
115
	dev := *device
116
	return parent, dev, nil
117
}
118

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.