This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
forked from cloudfoundry/bosh-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssh_args.go
119 lines (93 loc) · 2.73 KB
/
ssh_args.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
112
113
114
115
116
117
118
119
package ssh
import (
"fmt"
"strings"
boshsys "github.com/cloudfoundry/bosh-utils/system"
boshdir "github.com/cloudfoundry/bosh-cli/director"
)
type SSHArgs struct {
ConnOpts ConnectionOpts
Result boshdir.SSHResult
ForceTTY bool
PrivKeyFile boshsys.File
KnownHostsFile boshsys.File
}
func (a SSHArgs) LoginForHost(host boshdir.Host) []string {
return []string{host.Host, "-l", host.Username}
}
func (a SSHArgs) OptsForHost(host boshdir.Host) []string {
// Options are used for both ssh and scp
cmdOpts := []string{}
if a.ForceTTY {
cmdOpts = append(cmdOpts, "-tt")
}
cmdOpts = append(cmdOpts, []string{
"-o", "ServerAliveInterval=30",
"-o", "ForwardAgent=no",
"-o", "PasswordAuthentication=no",
"-o", "IdentitiesOnly=yes",
"-o", "IdentityFile=" + a.PrivKeyFile.Name(),
"-o", "StrictHostKeyChecking=yes",
"-o", "UserKnownHostsFile=" + a.KnownHostsFile.Name(),
}...)
gwUsername, gwHost, gwPrivKeyPath := a.gwOpts()
if len(a.ConnOpts.SOCKS5Proxy) > 0 {
proxyOpt := fmt.Sprintf(
"ProxyCommand=nc -x %s %%h %%p",
strings.TrimPrefix(a.ConnOpts.SOCKS5Proxy, "socks5://"),
)
cmdOpts = append(cmdOpts, "-o", proxyOpt)
} else if len(gwHost) > 0 {
gwCmdOpts := []string{
"-o", "ServerAliveInterval=30",
"-o", "ForwardAgent=no",
"-o", "ClearAllForwardings=yes",
// Strict host key checking for a gateway is not necessary
// since ProxyCommand is only used for forwarding TCP and
// agent forwarding is disabled
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
}
if len(gwPrivKeyPath) > 0 {
gwCmdOpts = append(
gwCmdOpts,
"-o", "PasswordAuthentication=no",
"-o", "IdentitiesOnly=yes",
"-o", "IdentityFile="+gwPrivKeyPath,
)
}
// It appears that when using ssh -W, IPv6 address needs to be put in brackets
// fixes: `Bad stdio forwarding specification 'fd7a:eeed:e696:...'`
proxyHostPortTmpl := "%h:%p"
if strings.Contains(host.Host, ":") {
proxyHostPortTmpl = "[%h]:%p"
}
proxyOpt := fmt.Sprintf(
// Always force TTY for gateway ssh
"ProxyCommand=ssh -tt -W %s -l %s %s %s",
proxyHostPortTmpl,
gwUsername,
gwHost,
strings.Join(gwCmdOpts, " "),
)
cmdOpts = append(cmdOpts, "-o", proxyOpt)
}
cmdOpts = append(cmdOpts, a.ConnOpts.RawOpts...)
return cmdOpts
}
func (a SSHArgs) gwOpts() (string, string, string) {
if a.ConnOpts.GatewayDisable {
return "", "", ""
}
// Take server provided gateway options
username := a.Result.GatewayUsername
host := a.Result.GatewayHost
if len(a.ConnOpts.GatewayUsername) > 0 {
username = a.ConnOpts.GatewayUsername
}
if len(a.ConnOpts.GatewayHost) > 0 {
host = a.ConnOpts.GatewayHost
}
privKeyPath := a.ConnOpts.GatewayPrivateKeyPath
return username, host, privKeyPath
}