mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-29 23:33:45 +00:00
cmd/tailscale: allow SSH to IPs or DNS names without MagicDNS (#16591)
fixes #16381 Signed-off-by: Danni Popova <danni@tailscale.com>
This commit is contained in:
parent
2a5d9c7269
commit
c572442548
@ -70,12 +70,28 @@ func runSSH(ctx context.Context, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prefs, err := localClient.GetPrefs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// hostForSSH is the hostname we'll tell OpenSSH we're
|
// hostForSSH is the hostname we'll tell OpenSSH we're
|
||||||
// connecting to, so we have to maintain fewer entries in the
|
// connecting to, so we have to maintain fewer entries in the
|
||||||
// known_hosts files.
|
// known_hosts files.
|
||||||
hostForSSH := host
|
hostForSSH := host
|
||||||
if v, ok := nodeDNSNameFromArg(st, host); ok {
|
ps, ok := peerStatusFromArg(st, host)
|
||||||
hostForSSH = v
|
if ok {
|
||||||
|
hostForSSH = ps.DNSName
|
||||||
|
|
||||||
|
// If MagicDNS isn't enabled on the client,
|
||||||
|
// we will use the first IPv4 we know about
|
||||||
|
// or fallback to the first IPv6 address
|
||||||
|
if !prefs.CorpDNS {
|
||||||
|
ipHost, found := ipFromPeerStatus(ps)
|
||||||
|
if found {
|
||||||
|
hostForSSH = ipHost
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh, err := findSSH()
|
ssh, err := findSSH()
|
||||||
@ -169,11 +185,40 @@ func genKnownHosts(st *ipnstate.Status) []byte {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&buf, "%s %s\n", ps.DNSName, hostKey)
|
fmt.Fprintf(&buf, "%s %s\n", ps.DNSName, hostKey)
|
||||||
|
for _, ip := range ps.TailscaleIPs {
|
||||||
|
fmt.Fprintf(&buf, "%s %s\n", ip.String(), hostKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// peerStatusFromArg returns the PeerStatus that matches
|
||||||
|
// the input arg which can be a base name, full DNS name, or an IP.
|
||||||
|
func peerStatusFromArg(st *ipnstate.Status, arg string) (*ipnstate.PeerStatus, bool) {
|
||||||
|
if arg == "" {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
argIP, _ := netip.ParseAddr(arg)
|
||||||
|
for _, ps := range st.Peer {
|
||||||
|
if argIP.IsValid() {
|
||||||
|
for _, ip := range ps.TailscaleIPs {
|
||||||
|
if ip == argIP {
|
||||||
|
return ps, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.EqualFold(strings.TrimSuffix(arg, "."), strings.TrimSuffix(ps.DNSName, ".")) {
|
||||||
|
return ps, true
|
||||||
|
}
|
||||||
|
if base, _, ok := strings.Cut(ps.DNSName, "."); ok && strings.EqualFold(base, arg) {
|
||||||
|
return ps, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
// nodeDNSNameFromArg returns the PeerStatus.DNSName value from a peer
|
// nodeDNSNameFromArg returns the PeerStatus.DNSName value from a peer
|
||||||
// in st that matches the input arg which can be a base name, full
|
// in st that matches the input arg which can be a base name, full
|
||||||
// DNS name, or an IP.
|
// DNS name, or an IP.
|
||||||
@ -202,6 +247,20 @@ func nodeDNSNameFromArg(st *ipnstate.Status, arg string) (dnsName string, ok boo
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ipFromPeerStatus(ps *ipnstate.PeerStatus) (string, bool) {
|
||||||
|
if len(ps.TailscaleIPs) < 1 {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a IPv4 address or default to the first IP of the list
|
||||||
|
for _, ip := range ps.TailscaleIPs {
|
||||||
|
if ip.Is4() {
|
||||||
|
return ip.String(), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ps.TailscaleIPs[0].String(), true
|
||||||
|
}
|
||||||
|
|
||||||
// getSSHClientEnvVar returns the "SSH_CLIENT" environment variable
|
// getSSHClientEnvVar returns the "SSH_CLIENT" environment variable
|
||||||
// for the current process group, if any.
|
// for the current process group, if any.
|
||||||
var getSSHClientEnvVar = func() string {
|
var getSSHClientEnvVar = func() string {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user