Skip to content

Commit

Permalink
Support WSL2 distros accessing private (apiserver, ssh, cockpit) serv…
Browse files Browse the repository at this point in the history
…ices

Bind Windows host-side vSock ports to the Window's machines IP on the WSL2 network
allowing both Windows host and WSL2 to connect to VM services that aren't shared publically.
  • Loading branch information
GingerGeek authored and anjannath committed Aug 21, 2023
1 parent 5d48458 commit a1a76cf
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 5 deletions.
6 changes: 5 additions & 1 deletion cmd/crc/cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/crc-org/crc/pkg/crc/constants"
"github.com/crc-org/crc/pkg/crc/daemonclient"
"github.com/crc-org/crc/pkg/crc/logging"
"github.com/crc-org/crc/pkg/crc/machine"
"github.com/docker/go-units"
"github.com/gorilla/handlers"
"github.com/pkg/errors"
Expand Down Expand Up @@ -238,7 +239,10 @@ func gatewayAPIMux() *http.ServeMux {
mux := http.NewServeMux()
mux.HandleFunc("/hosts/add", func(w http.ResponseWriter, r *http.Request) {
acceptJSONStringArray(w, r, func(hostnames []string) error {
return adminhelper.AddToHostsFile("127.0.0.1", hostnames...)
// Most of the time we will add a hosts entry to resolve this to 127.0.0.1
// On a Windows machine running WSL this is the "IP" of the machine within the WSL2 network,
// so it is accessible from both WSL2 and Windows
return adminhelper.AddToHostsFile(machine.VsockPrivateAddress(), hostnames...)
})
})
mux.HandleFunc("/hosts/remove", func(w http.ResponseWriter, r *http.Request) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/crc/machine/virtualmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (vm *virtualMachine) State() (state.State, error) {

func (vm *virtualMachine) IP() (string, error) {
if vm.vsock {
return "127.0.0.1", nil
return VsockPrivateAddress(), nil
}
return vm.Driver.GetIP()
}
Expand Down
11 changes: 8 additions & 3 deletions pkg/crc/machine/vsock.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,15 @@ func vsockPorts(preset crcPreset.Preset, ingressHTTPPort, ingressHTTPSPort uint)
socketProtocol = types.NPIPE
socketLocal = constants.DefaultPodmanNamedPipe
}

// API, Cockpit and Internal SSH are all bound to a private address, usually 127.0.0.1
// On Windows, where WSL2 is active, it's bound to the Windows machine's address within the private WSL2 network
privateIP := VsockPrivateAddress()

exposeRequest := []types.ExposeRequest{
{
Protocol: "tcp",
Local: net.JoinHostPort(localIP, strconv.Itoa(constants.VsockSSHPort)),
Local: net.JoinHostPort(privateIP, strconv.Itoa(constants.VsockSSHPort)),
Remote: net.JoinHostPort(virtualMachineIP, internalSSHPort),
},
{
Expand All @@ -110,7 +115,7 @@ func vsockPorts(preset crcPreset.Preset, ingressHTTPPort, ingressHTTPSPort uint)
exposeRequest = append(exposeRequest,
types.ExposeRequest{
Protocol: "tcp",
Local: net.JoinHostPort(localIP, apiPort),
Local: net.JoinHostPort(privateIP, apiPort),
Remote: net.JoinHostPort(virtualMachineIP, apiPort),
},
types.ExposeRequest{
Expand All @@ -127,7 +132,7 @@ func vsockPorts(preset crcPreset.Preset, ingressHTTPPort, ingressHTTPSPort uint)
exposeRequest = append(exposeRequest,
types.ExposeRequest{
Protocol: "tcp",
Local: net.JoinHostPort(localIP, cockpitPort),
Local: net.JoinHostPort(privateIP, cockpitPort),
Remote: net.JoinHostPort(virtualMachineIP, cockpitPort),
})
default:
Expand Down
8 changes: 8 additions & 0 deletions pkg/crc/machine/vsockprivateaddress_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build !windows
// +build !windows

package machine

func VsockPrivateAddress() (addrStr string) {
return "127.0.0.1"
}
29 changes: 29 additions & 0 deletions pkg/crc/machine/vsockprivateaddress_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package machine

import (
"fmt"
"strings"

"github.com/crc-org/crc/pkg/crc/logging"
"github.com/crc-org/crc/pkg/os/windows/powershell"
)

const (
fallbackPrivateAddress = "127.0.0.1"
adapterName = "vEthernet (WSL)"
)

// On Windows it would be useful if WSL2 can access VSock resources as well
// This address should work on both the windows side and the WSL2 side
func VsockPrivateAddress() (addrStr string) {
cmd := fmt.Sprintf(`(Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias "%s").IPAddress`, adapterName)
stdout, stderr, err := powershell.Execute(cmd)
if err != nil {
logging.Debugf("Unable to find IP address for WSL vswitch: %v: %s", err, stderr)
return fallbackPrivateAddress
}
if strings.TrimSpace(stdout) == "" {
return fallbackPrivateAddress
}
return strings.TrimSpace(stdout)
}

0 comments on commit a1a76cf

Please sign in to comment.