diff --git a/docs/pages/connect-your-client/putty-winscp.mdx b/docs/pages/connect-your-client/putty-winscp.mdx index db4d9fad7aca1..c6f304452cfc2 100644 --- a/docs/pages/connect-your-client/putty-winscp.mdx +++ b/docs/pages/connect-your-client/putty-winscp.mdx @@ -54,6 +54,7 @@ Node Name Address Labels ----------------------------------- -------------- ---------------------------- ip-172-31-30-140 127.0.0.1:3022 company=acmecorp,env=aws,... ip-172-31-34-128.us-east-2.compu... ⟵ Tunnel access=open,enhanced_reco... +ip-172-31-8-63 172.31.8.63:22 type=openssh ``` 3. Add a saved session for a specific login on a specific node to the Windows registry. @@ -68,6 +69,17 @@ Added PuTTY session for ubuntu@ip-172-31-30-140 [proxy:teleport.example.com] If you don't provide a login to this command, your local Windows username is used instead. +If you are adding a session for a registered OpenSSH node within your cluster (added with +[`teleport join openssh`](../server-access/guides/openssh/openssh.mdx)), you must specify the `sshd` port +(usually 22) when adding a session with `tsh puttyconfig`: + +```bash +C:\Users\gus>tsh puttyconfig --port 22 ubuntu@ip-172-31-8-63 +Added PuTTY session for ubuntu@ip-172-31-8-63 [proxy:teleport.example.com] +``` + +You can also use `tsh puttyconfig user@host:22` if you prefer. + @@ -241,8 +253,8 @@ After a session has been added, you can make changes to it in the PuTTY UI by cl ### If I re-run `tsh puttyconfig` for a given host, will it overwrite any custom changes I've made to the saved session? -Teleport only modifies the configuration parameters that it relies on, like the proxy name, proxy command, hostname, username, and so on. -Any changes to font size, window size, and other parameters are left untouched. +Teleport only modifies the configuration parameters that it relies on, like the proxy name, proxy command, hostname, username, +port, and so on. Any changes to font size, window size, and other parameters are left untouched. ### Can I use other graphical clients like MobaXterm or SecureCRT? @@ -285,6 +297,9 @@ The Teleport proxy is unable to connect to the given host/port provided in the s offline. Check that the node is visible in `tsh ls` and that you can connect to it with `tsh ssh login@hostname`. If this is successful, check the Teleport proxy logs for more detailed errors. +If the node is running OpenSSH rather than Teleport, you must make sure to specify the `sshd` port when adding the session, +for example using `tsh puttyconfig --port 22 user@host` or `tsh puttyconfig user@host:22`. + ### `Unable to use certificate file "C:\Users\\.tsh\keys\\-ssh\-cert.pub" (unable to open file)` You are not logged into Teleport correctly. Run `tsh login --proxy=` to get valid certificates before diff --git a/docs/pages/reference/cli/tsh.mdx b/docs/pages/reference/cli/tsh.mdx index 09e90cb605933..ad0df3b7a4974 100644 --- a/docs/pages/reference/cli/tsh.mdx +++ b/docs/pages/reference/cli/tsh.mdx @@ -180,6 +180,9 @@ $ tsh puttyconfig [--leaf ] [login@]hostname # Add a saved PuTTY session on 'node' for the user 'ec2-user' $ tsh puttyconfig ec2-user@node +# Add a saved PuTTY session for the Teleport-registered OpenSSH node 'openssh' for the user 'ubuntu' +$ tsh puttyconfig --port 22 ubuntu@openssh + # Add a saved PuTTY session on leaf-node for the user 'ec2-user' on the leaf cluster 'example.teleport.sh' $ tsh puttyconfig --leaf example.teleport.sh ec2-user@leaf-node ``` diff --git a/lib/puttyhosts/puttyhosts.go b/lib/puttyhosts/puttyhosts.go index 8d4f198641db5..ce3a25a7a85ed 100644 --- a/lib/puttyhosts/puttyhosts.go +++ b/lib/puttyhosts/puttyhosts.go @@ -142,7 +142,7 @@ func AddHostToHostList(hostList []string, hostname string) []string { return outputHostList } -var hostnameRegexp = regexp.MustCompile("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$") +var hostnameRegexp = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*$`) // NaivelyValidateHostname checks the provided hostname against a naive regex to ensure it doesn't contain obviously // illegal characters. It's not guaranteed to be perfect, just a simple sanity check. It returns true when the hostname validates. diff --git a/lib/puttyhosts/puttyhosts_test.go b/lib/puttyhosts/puttyhosts_test.go index eaee3360403a4..fd517f45ba25c 100644 --- a/lib/puttyhosts/puttyhosts_test.go +++ b/lib/puttyhosts/puttyhosts_test.go @@ -300,6 +300,14 @@ func TestNaivelyValidateHostname(t *testing.T) { hostname: "consecutive..dots", shouldPass: false, }, + { + hostname: "host:22", + shouldPass: false, + }, + { + hostname: "host with spaces", + shouldPass: false, + }, } for _, tt := range tests { diff --git a/tool/tsh/common/putty_config_windows.go b/tool/tsh/common/putty_config_windows.go index 183846b200cd0..c445d6599a11e 100644 --- a/tool/tsh/common/putty_config_windows.go +++ b/tool/tsh/common/putty_config_windows.go @@ -19,6 +19,7 @@ package common import ( "fmt" "net" + "strconv" "strings" "syscall" @@ -257,15 +258,25 @@ func onPuttyConfig(cf *CLIConf) error { return trace.Wrap(err) } - // remove any spaces from provided hostname and validate it against a naive regex to make sure it doesn't contain - // obviously illegal characters due to typos or similar. setting an "invalid" key in the registry makes it impossible - // to delete via the PuTTY UI and requires registry edits, so it's much better to error out early here. - hostname := strings.ReplaceAll(tc.Config.Host, " ", "") + // remove any spaces from the provided hostname. if the hostname contains a colon, it will be a + // hostname:port combination so we split it. this is useful as shorthand when adding OpenSSH hosts + // with `tsh puttyconfig user@host:22`, rather than using the longer `tsh puttyconfig --port 22 user@host` + hostname := strings.TrimSpace(tc.Config.Host) + port := tc.Config.HostPort + if splitHost, splitPort, err := net.SplitHostPort(hostname); err == nil { + hostname = splitHost + port, err = strconv.Atoi(splitPort) + if err != nil { + return trace.Wrap(err) + } + } + // validate the hostname against a naive regex to make sure it doesn't contain obviously illegal characters + // due to typos or similar. setting an "invalid" key in the registry makes it impossible to delete via the + // PuTTY UI and requires registry edits, so it's much better to error out early here. if !puttyhosts.NaivelyValidateHostname(hostname) { return trace.BadParameter("provided hostname %v does not look like a valid hostname. Make sure it doesn't contain illegal characters.", hostname) } - port := tc.Config.HostPort userHostString := hostname login := "" if tc.Config.HostLogin != "" {