Skip to content

[vnet] feat: write OpenSSH-compatible config file for VNet SSH#55239

Merged
nklaassen merged 1 commit intomasterfrom
nklaassen/vnet-ssh-config
Jun 1, 2025
Merged

[vnet] feat: write OpenSSH-compatible config file for VNet SSH#55239
nklaassen merged 1 commit intomasterfrom
nklaassen/vnet-ssh-config

Conversation

@nklaassen
Copy link
Copy Markdown
Contributor

@nklaassen nklaassen commented May 29, 2025

This PR is the next step in the implementation of VNet SSH (RFD).

VNet SSH now generates an OpenSSH-compatible config file and writes it out to ${TELEPORT_HOME}/vnet_ssh_config. Because the config block must only match subdomains of a Teleport cluster VNet SSH is handling, we must keep the config file up to date in case the user logs into or out of any clusters.

With this PR in place, VNet SSH works! I have tested it with tsh vnet and Connect, connecting with the OpenSSH client directly and in VSCode with the Remote-SSH extension. All the user still has to do manually is tell their SSH client to use the generated file. You can do with with ssh -F ${TELEPORT_HOME}/vnet_ssh_config or just once by adding an include to ~/.ssh/config. A subsequent PR will give the user the option to automatically add the include directive to their default SSH config file.

The demo is pretty simple, this just works with pnpm start-term and VNet running, to SSH to my server node-iot in my cluster called one.private. I even have per-session MFA turned on.

$ ssh -F '/Users/nic/Library/Application Support/Electron/tsh/vnet_ssh_config' node-iot.one.private
Nics-MacBook-Pro:~ nic$ echo "hello from vnet ssh"
hello from vnet ssh
Nics-MacBook-Pro:~ nic$ exit
logout
Connection to node-iot.one.private closed.

Parent PR: #55228

@nklaassen nklaassen added no-changelog Indicates that a PR does not require a changelog entry backport/branch/v17 labels May 29, 2025
@github-actions github-actions Bot requested review from gzdunek and timothyb89 May 29, 2025 00:58
Comment thread lib/vnet/opensshconfig.go Outdated
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-keys branch from 2281ea6 to 173b1e6 Compare May 29, 2025 18:10
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-config branch 2 times, most recently from b5883d6 to 70b22e2 Compare May 29, 2025 23:38
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-keys branch from 39584d4 to 72c85d2 Compare May 30, 2025 17:58
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-config branch from 70b22e2 to 2632b78 Compare May 30, 2025 17:58
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-keys branch from 72c85d2 to dd08608 Compare May 30, 2025 18:47
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-config branch 2 times, most recently from de3361e to 327fe29 Compare May 30, 2025 20:34
Comment on lines +85 to +87
// vnetSSHConfig is the file name of the generated OpenSSH-compatible config
// file to be used by third-party SSH clients connecting to VNet SSH.
vnetSSHConfig = "vnet_ssh_config"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: move this within VNetSSHConfigPath?

Comment thread lib/vnet/opensshconfig.go Outdated
@public-teleport-github-review-bot public-teleport-github-review-bot Bot removed the request for review from timothyb89 May 30, 2025 21:52
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-keys branch from 14b7aa3 to 5e753a8 Compare May 31, 2025 04:16
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-config branch from 327fe29 to 09dec39 Compare May 31, 2025 04:16
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-keys branch from 5e753a8 to 5fb42ce Compare June 1, 2025 05:29
Base automatically changed from nklaassen/vnet-ssh-keys to master June 1, 2025 06:11
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-config branch from 09dec39 to 9eb0d93 Compare June 1, 2025 06:45
@nklaassen nklaassen force-pushed the nklaassen/vnet-ssh-config branch from 9eb0d93 to db1020c Compare June 1, 2025 06:47
@nklaassen nklaassen enabled auto-merge June 1, 2025 06:47
@nklaassen nklaassen added this pull request to the merge queue Jun 1, 2025
Merged via the queue into master with commit 2bedd3f Jun 1, 2025
40 checks passed
@nklaassen nklaassen deleted the nklaassen/vnet-ssh-config branch June 1, 2025 07:28
nklaassen added a commit that referenced this pull request Jun 2, 2025
nklaassen added a commit that referenced this pull request Jun 2, 2025
github-merge-queue Bot pushed a commit that referenced this pull request Jul 22, 2025
* [v17][vnet] feat: TCP dial to SSH targets

Backport #55087 to branch/v17

* [v17][vnet] feat: accept incoming SSH connections

Backport #55155 to branch/v17

* [v17][vnet] feat: forward SSH connections to target

Backport #55156 to branch/v17

* [v17][vnet] feat: write VNet SSH keys to TELEPORT_HOME

Backport #55228 to branch/v17

* [v17][vnet] feat: write OpenSSH-compatible config file for VNet SSH

Backport #55239 to branch/v17

* [v17][vnet] fix: support <hostname>.<leaf-cluster> for VNet SSH

Backport #55688 to branch/v17

* fix BlockUntil API for backport

* [v17][vnet] feat: add "Connect with VNet" button to SSH servers

Backport #55623 to branch/v17

* [v17][vnet] feat: support VNet SSH when cluster name does not match proxy public addr

Backport #55655 to branch/v17

* [v17][vnet] feat: add SSH configuration diagnostic

Backport #55594 to branch/v17

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>

* [v17][vnet] feat: show SSH status in VNet slider

Backport #55755 to branch/v17

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>

* [v17][vnet] feat: support proxy recording mode with VNet SSH

Backport #55788 to branch/v17

* [v17][vnet] feat: support diag checks on windows

Backport #55856 to branch/v17

* [v17] fix: data race in vnet.TestSSH

Backport #55980 to branch/v17

* [v17][vnet] feat: mention SSH on VNet info page

Backport #55973 to branch/v17

* [v17][vnet] feat: serve DNS on IPv4

Backport #55539 to branch/v17

* [v17][vnet] fix: close proxied channel only after data and requests are complete

Backport #56020 to branch/v17

* [v17][vnet] feat: automatic SSH client configuration

Backport #55923 to branch/v17

* VNet docs: Provide clear instructions for getting debug logs (#56068)

* VNet diag notification: Do not show button to open report if there's no workspace selected (#56067)

* VNet diag report: Don't show button in notification if there's no workspace

* Replace deprecated MutableRefObject with RefObject

* Make openReport not depend on value of rootClusterUri

Otherwise the effect that uses setInterval re-runs whenever the user
switches to another workspace.

* [v17][vnet] feat: automatic SSH client configuration in Connect

Backport #55924 to branch/v17

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
Co-authored-by: Grzegorz Zdunek <grzegorz.zdunek@goteleport.com>

* [v17][vnet] fix: avoid empty host matchers in generated SSH config

Backport #56103 to branch/v17

* avoid t.Context() pre go1.24

* fix cspell lint

* [v17][docs] VNet SSH

Backport #56147 to branch/v17

* [v17][vnet] feat: SSH usage reporting

Backport #56537 to branch/v17

* [v17][vnet] fix: mask default IP route on windows

Backport #56957 to branch/v17

---------

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
Co-authored-by: Grzegorz Zdunek <grzegorz.zdunek@goteleport.com>
github-merge-queue Bot pushed a commit that referenced this pull request Jul 22, 2025
* [v18][vnet] feat: TCP dial to SSH targets

Backport #55087 to branch/v18

* [v18][vnet] feat: accept incoming SSH connections

Backport #55155 to branch/v18

* [v18][vnet] feat: forward SSH connections to target

Backport #55156 to branch/v18

* [v18][vnet] feat: write VNet SSH keys to TELEPORT_HOME

Backport #55228 to branch/v18

* [v18][vnet] feat: write OpenSSH-compatible config file for VNet SSH

Backport #55239 to branch/v18

* [v18][vnet] fix: support <hostname>.<leaf-cluster> for VNet SSH

Backport #55688 to branch/v18

* [v18][vnet] feat: add "Connect with VNet" button to SSH servers

Backport #55623 to branch/v18

* fix test in backport

* [v18][vnet] feat: support VNet SSH when cluster name does not match proxy public addr

Backport #55655 to branch/v18

* [v18][vnet] feat: add SSH configuration diagnostic

Backport #55594 to branch/v18

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>

* [v18][vnet] feat: show SSH status in VNet slider

Backport #55755 to branch/v18

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>

* [v18][vnet] feat: support proxy recording mode with VNet SSH

Backport #55788 to branch/v18

* [v18][vnet] feat: support diag checks on windows

Backport #55856 to branch/v18

* [v18] fix: data race in vnet.TestSSH

Backport #55980 to branch/v18

* [v18][vnet] feat: mention SSH on VNet info page

Backport #55973 to branch/v18

* [v18][vnet] feat: serve DNS on IPv4

Backport #55539 to branch/v18

* [v18][vnet] fix: close proxied channel only after data and requests are complete

Backport #56020 to branch/v18

* [v18][vnet] feat: automatic SSH client configuration

Backport #55923 to branch/v18

* VNet diag notification: Do not show button to open report if there's no workspace selected (#56067)

* VNet diag report: Don't show button in notification if there's no workspace

* Replace deprecated MutableRefObject with RefObject

* Make openReport not depend on value of rootClusterUri

Otherwise the effect that uses setInterval re-runs whenever the user
switches to another workspace.

* [v18][vnet] feat: automatic SSH client configuration in Connect

Backport #55924 to branch/v18

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
Co-authored-by: Grzegorz Zdunek <grzegorz.zdunek@goteleport.com>

* [v18][vnet] fix: avoid empty host matchers in generated SSH config

Backport #56103 to branch/v18

* [v18][docs] VNet SSH

Backport #56147 to branch/v18

* [v18][docs] add VNet warnings

Backport #56601 to branch/v18

* [v18][vnet] feat: SSH usage reporting

Backport #56537 to branch/v18

* [v18][vnet] fix: mask default IP route on windows

Backport #56957 to branch/v18

---------

Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
Co-authored-by: Grzegorz Zdunek <grzegorz.zdunek@goteleport.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a PR does not require a changelog entry size/md

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants