Skip to content

[v18] vnet linux support#64736

Open
tangyatsu wants to merge 29 commits intobranch/v18from
tangyatsu/vnet-linux-v18
Open

[v18] vnet linux support#64736
tangyatsu wants to merge 29 commits intobranch/v18from
tangyatsu/vnet-linux-v18

Conversation

@tangyatsu
Copy link
Copy Markdown
Contributor

@tangyatsu tangyatsu commented Mar 17, 2026

Backports #63664 and #64493

changelog: Added Linux support for VNet

Manual Test Plan

Test Environment

it relies on the presence of systemd, D-Bus and polkit, most modern desktop Linux distros include them.

To make it work, you need to install the required polkit and D-Bus configuration files.

Polkit action:

sudo tee /usr/share/polkit-1/actions/org.teleport.vnet1.policy > /dev/null <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
  "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>

  <action id="org.teleport.vnet1.manage-daemon">
    <description>Start Teleport VNet</description>
    <message>Authentication is required to start Teleport VNet</message>
    <defaults>
      <allow_any>no</allow_any>
      <allow_inactive>no</allow_inactive>
      <!-- Default behavior if no rule matches -->
      <allow_active>yes</allow_active>
    </defaults>
  </action>

</policyconfig>
EOF

D‑Bus config
By default, d-bus will not allow any user (including root) to own the org.teleport.vnet1 name:

sudo tee /usr/share/dbus-1/system.d/org.teleport.vnet1.conf > /dev/null <<'EOF'
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <policy user="root">
    <allow own="org.teleport.vnet1"/>
  </policy>

  <policy context="default">
    <allow send_destination="org.teleport.vnet1"/>
  </policy>
</busconfig>
EOF

D‑Bus service file (activates systemd unit)

sudo tee /usr/share/dbus-1/system-services/org.teleport.vnet1.service > /dev/null <<'EOF'
[D-BUS Service]
Name=org.teleport.vnet1
SystemdService=teleport-vnet.service
User=root
Exec=/bin/false
EOF

Systemd unit

sudo tee /usr/lib/systemd/system/teleport-vnet.service > /dev/null <<'EOF'
[Unit]
Description=Teleport VNet D-Bus service
After=dbus.service
Requires=dbus.service

[Service]
Type=dbus
BusName=org.teleport.vnet1
ExecStart=/usr/bin/tsh vnet-daemon --debug
User=root
Group=root
EOF

I tested this on a cluster with:

  • PostgreSQL as a TCP app
  • dummy NGINX server as an HTTP app

I also set google.com as a custom DNS zone for VNet and checked access to workspace.google.com with VNet turned on.

It is actually convenient to inspect DNS behavior with resolvectl.

resolvectl status shows all active links.
resolvectl domain shows domains attached to each link, for example:

Link 37 (TeleportVNet): ~internal.example.com ~google.com ~teleport.tangyatsu.com ~teleport.dev

You can query and verify which link handled DNS:

resolvectl query workspace.google.com --legend=yes

Example output:

workspace.google.com: 165.xxx.xxx.xxx  -- link: TeleportVNet

Test Cases

  • can start VNet with tsh vnet
  • can connect to TCP app over VNet
  • can connect to SSH node over VNet
  • HTTP app access continues to work with VNet on and off
  • public URIs under a custom DNS zone are still reachable (with VNet on and off)
  • can view daemon logs with journalctl -u teleport-vnet.service
  • can start and stop VNet from Connect
  • can start VNet with sudo tsh vnet without presence of config files

@tangyatsu tangyatsu marked this pull request as ready for review March 17, 2026 21:45
@github-actions github-actions bot added backport size/lg tsh tsh - Teleport's command line tool for logging into nodes running Teleport. ui labels Mar 17, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3e1f7fb7af

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +177 to +178
if slices.Contains(services, vnetDBusServiceName) {
return nil
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat activatable D-Bus names as unavailable until usable

This check returns success as soon as org.teleport.vnet1 appears in ListActivatableNames, but execAdminProcess only falls back to the root child-process path when this function returns an error. In partial/misconfigured installs (activatable name present but unit or executable broken), runService then fails at Start and sudo tsh vnet exits instead of using the intended fallback path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's probably a good idea to consider fixing the Codex comments on master and backporting if they indeed point out real issues.

Sometimes it behaves like the worst reviewer ever where it doesn't point out all potential problems all at once, like in this PR #64769.

Comment on lines +54 to +55
if addr.IsUnspecified() || addr.IsLoopback() {
continue
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve loopback upstream DNS servers when loading Linux DNS

Filtering out all loopback DNS entries means systems that intentionally use a local resolver (for example dnsmasq/unbound on 127.0.0.1 or ::1) can end up with no upstream resolvers at all. In that case unmatched lookups hit dns.Server.forward with an empty upstream list and fail, breaking non-Teleport DNS while VNet is enabled.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

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

I built Connect using code from tangyatsu/vnet-linux-v18 and tangyatsu/vnet-linux-systemd-dbus-polkit-files-v18. I did some light testing and it seems to work.

@public-teleport-github-review-bot public-teleport-github-review-bot bot removed the request for review from nklaassen March 19, 2026 22:42
…#64493)

* replace TCP socket with unix socket for VNet user-admin IPC for Linux

* review improvements and fixes
@public-teleport-github-review-bot
Copy link
Copy Markdown

@tangyatsu - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes.

@tangyatsu tangyatsu force-pushed the tangyatsu/vnet-linux-v18 branch from c48c961 to 3113071 Compare April 1, 2026 17:51
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3113071b8f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +97 to +100
case <-ticker.C:
state, err := getSystemdUnitState(ctx, conn, vnetSystemdUnitName)
if err != nil {
return trace.Wrap(err, "querying systemd service %s", vnetSystemdUnitName)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Prioritize shutdown path when context is canceled

When ctx is canceled, this loop can still take the ticker.C branch if a tick is ready at the same time, and then getSystemdUnitState(ctx, ...) returns a canceled-context error. That exits runService before calling stopService, so tsh vnet can terminate while teleport-vnet.service is left running. This is most visible on normal shutdowns that race with the 1s poll tick.

Useful? React with 👍 / 👎.

@tangyatsu
Copy link
Copy Markdown
Contributor Author

Cherry-picked the commit that replaces TCP socket with Unix socket and went through the test cases again

@tangyatsu tangyatsu force-pushed the tangyatsu/vnet-linux-v18 branch from 3113071 to 9074652 Compare April 17, 2026 11:10
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9074652cbf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +73 to +76
conn, err := systemddbus.NewWithContext(ctx)
if err != nil {
return trace.NotFound("systemd D-Bus is unavailable: %v", err)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Stop service when post-start systemd attach fails

runService starts teleport-vnet.service before opening the systemd D-Bus monitoring connection, but if systemddbus.NewWithContext fails here it returns immediately and never calls stopService. In that failure path, tsh vnet exits with an error while the privileged service can continue running in the background, which is especially problematic for transient D-Bus/systemd access issues.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport size/lg tsh tsh - Teleport's command line tool for logging into nodes running Teleport. ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants