-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[vnet] feat: support diag checks on windows #55856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // Teleport | ||
| // Copyright (C) 2025 Gravitational, Inc. | ||
| // | ||
| // This program is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU Affero General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // This program is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU Affero General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Affero General Public License | ||
| // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| //go:build !darwin && !windows | ||
|
|
||
| package vnet | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "github.com/gravitational/teleport/lib/vnet/diag" | ||
| ) | ||
|
|
||
| func (s *Service) platformDiagChecks(ctx context.Context) ([]diag.DiagCheck, error) { | ||
| return nil, nil | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // Teleport | ||
| // Copyright (C) 2025 Gravitational, Inc. | ||
| // | ||
| // This program is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU Affero General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // This program is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU Affero General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Affero General Public License | ||
| // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| package vnet | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "github.com/gravitational/trace" | ||
|
|
||
| "github.com/gravitational/teleport/lib/vnet/diag" | ||
| ) | ||
|
|
||
| func (s *Service) platformDiagChecks(ctx context.Context) ([]diag.DiagCheck, error) { | ||
| routeConflictDiag, err := diag.NewRouteConflictDiag(&diag.RouteConflictConfig{ | ||
| VnetIfaceName: s.networkStackInfo.InterfaceName, | ||
| Routing: &diag.WindowsRouting{}, | ||
| Interfaces: &diag.NetInterfaces{}, | ||
| }) | ||
| if err != nil { | ||
| return nil, trace.Wrap(err) | ||
| } | ||
|
|
||
| sshDiag, err := diag.NewSSHDiag(&diag.SSHConfig{ | ||
| ProfilePath: s.cfg.profilePath, | ||
| }) | ||
| if err != nil { | ||
| return nil, trace.Wrap(err) | ||
| } | ||
|
|
||
| return []diag.DiagCheck{ | ||
| routeConflictDiag, | ||
| sshDiag, | ||
| }, nil | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| //go:build !darwin | ||
| //go:build !darwin && !windows | ||
|
|
||
| // Teleport | ||
| // Copyright (C) 2025 Gravitational, Inc. | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried it out with Tailscale. It seems like what we report on Windows could be categorized as a false positive. Unlike on macOS, on Windows there's just a few conflicting Tailscale routes, not a whole range. But I think that's fine, no? Technically maybe it could cause issues with VNet, idk. If the user is bothered with the warning, they can dismiss it in the VNet panel and it won't show up again until they manually run diagnostics. ReportVNet Diagnostic Report Created at: 2025-06-18 11:19:13 (Wed, 18 Jun 2025 09:19:13 GMT)
The user's default SSH configuration file does not include VNet's
Ran into an error when executing cat C:\Users\rav.ssh\config:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's maybe fine until VNet tries to assign an IP to an app that tailscale is already routing for, probably still best to know about the potential conflict and use a different IP range |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| // Teleport | ||
| // Copyright (C) 2025 Gravitational, Inc. | ||
| // | ||
| // This program is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU Affero General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // This program is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU Affero General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Affero General Public License | ||
| // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| package diag | ||
|
|
||
| import ( | ||
| "context" | ||
| "net/netip" | ||
| "os/exec" | ||
|
|
||
| "github.com/gravitational/trace" | ||
| "golang.org/x/sys/windows" | ||
| "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" | ||
| ) | ||
|
|
||
| var ipv4Broadcast = netip.AddrFrom4([4]byte{255, 255, 255, 255}) | ||
|
|
||
| // WindowsRouting provides Windows-specific [Routing] implementation used by [RouteConflictDiag]. | ||
| type WindowsRouting struct{} | ||
|
|
||
| // GetRouteDestinations gets routes from the OS and then extracts the only | ||
| // information needed from them: the route destination and the index of the | ||
| // network interface. It operates solely on IPv4 routes. | ||
| func (wr *WindowsRouting) GetRouteDestinations() ([]RouteDest, error) { | ||
| rows, err := winipcfg.GetIPForwardTable2(windows.AF_INET) | ||
| if err != nil { | ||
| return nil, trace.Wrap(err) | ||
| } | ||
| rds := make([]RouteDest, 0, len(rows)) | ||
| for _, row := range rows { | ||
| prefix := row.DestinationPrefix.Prefix() | ||
| addr := prefix.Addr() | ||
| if addr.IsLinkLocalMulticast() || addr == ipv4Broadcast { | ||
| // All interfaces seem to get a link local multicast and broadcast | ||
| // route assigned which would always appear as a conflict, so skip | ||
| // them. | ||
| continue | ||
| } | ||
| if prefix.IsSingleIP() { | ||
| rds = append(rds, &RouteDestIP{ | ||
| Addr: addr, | ||
| ifaceIndex: int(row.InterfaceIndex), | ||
| }) | ||
| } else { | ||
| rds = append(rds, &RouteDestPrefix{ | ||
| Prefix: prefix, | ||
| ifaceIndex: int(row.InterfaceIndex), | ||
| }) | ||
| } | ||
| } | ||
| return rds, nil | ||
| } | ||
|
|
||
| func (n *NetInterfaces) interfaceApp(ctx context.Context, ifaceName string) (string, error) { | ||
| // Interfaces usually have descriptive names on Windows (the TUN interfaces | ||
| // used by VNet and Tailscale do, at least). | ||
| return ifaceName, nil | ||
| } | ||
|
|
||
| func (c *RouteConflictDiag) commands(ctx context.Context) []*exec.Cmd { | ||
| return []*exec.Cmd{ | ||
| exec.CommandContext(ctx, "netstat.exe", "-rn"), | ||
| exec.CommandContext(ctx, "ipconfig.exe", "/all"), | ||
| exec.CommandContext(ctx, "netsh.exe", "namespace", "show", "effectivepolicy"), | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's easy enough for me to understand the changes in this file since I have the required context. But I think for other reviewers it'd have helped if the changes in lib/teleterm/vnet supporting diag checks on Windows were in a separate commit from the routeconflict Windows implementation.