From 46d5a2f7b927bbc01e13364c8bb64cc5277ae14b Mon Sep 17 00:00:00 2001 From: Carlos Nihelton Date: Tue, 28 May 2024 15:29:21 -0300 Subject: [PATCH 1/4] Removes dependency on /etc/resolv.conf MS recently updated their docs about finding the host IP address. Two are the documented ways: 1. 127.0.0.1 if net mode is mirrored or 2. default gateway if NAT. As of WSL 2.2.1, /etc/resolv.conf contains an IP of type 10.0.0.0/8 if net mode is NAT but DNS tunneling is ON (which is the new default). That breaks our host IP detection mechanism, because we relied on finding an address of type 127.0.0.0/8 in /etc/resolv.conf nameserver entry to decide whether we should try to talk to that address or the default gateway. --- wsl-pro-service/internal/system/networking.go | 63 ------------------- .../internal/system/system_test.go | 22 ++----- .../etc-resolv.conf.bad | 3 - .../etc-resolv.conf.bad-ip | 3 - .../etc-resolv.conf.good | 3 - .../etc-resolv.conf.loopback | 3 - 6 files changed, 5 insertions(+), 92 deletions(-) delete mode 100644 wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.bad delete mode 100644 wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.bad-ip delete mode 100644 wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.good delete mode 100644 wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.loopback diff --git a/wsl-pro-service/internal/system/networking.go b/wsl-pro-service/internal/system/networking.go index e26378ee8..d0c09ab11 100644 --- a/wsl-pro-service/internal/system/networking.go +++ b/wsl-pro-service/internal/system/networking.go @@ -4,7 +4,6 @@ import ( "bufio" "context" "encoding/binary" - "errors" "fmt" "net" "os" @@ -27,15 +26,6 @@ func (s *System) WindowsHostAddress(ctx context.Context) (ip net.IP, err error) return net.IPv4(127, 0, 0, 1), nil } - nameserver, err := s.nameServer() - if err != nil { - return nil, fmt.Errorf("could not find nameserver: %v", err) - } - - if !nameserver.IsLoopback() { - return nameserver, nil - } - return s.defaultGateway() } @@ -50,59 +40,6 @@ func (s *System) networkingMode(ctx context.Context) (string, error) { return strings.TrimSpace(string(out)), nil } -// nameServer parses /etc/resolv.conf to get the IP address of the nameserver. -func (s *System) nameServer() (ip net.IP, err error) { - /* - We parse the IP address of the nameserver from /etc/resolv.conf. Here is an example - of what this file may look like: - - # This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf: - # [network] - # generateResolvConf = false - nameserver 172.22.16.1 - */ - const fileName = "/etc/resolv.conf" - - r, err := os.Open(s.Path(fileName)) - if err != nil { - // Error mesage already says could not open - return nil, err - } - defer r.Close() - - var address string - var line int - - sc := bufio.NewScanner(r) - for sc.Scan() { - line++ - - suffix, found := strings.CutPrefix(sc.Text(), "nameserver") - if !found { - continue - } - address = strings.TrimSpace(suffix) - break - } - - defer decorate.OnError(&err, "could not parse %s", fileName) - - if err := sc.Err(); err != nil { - return nil, fmt.Errorf("line %d: %v", line, err) - } - - if address == "" { - return nil, errors.New("no line matches 'nameserver '") - } - - ip = net.ParseIP(address) - if ip == nil { - return nil, fmt.Errorf("line %d: could not parse address %q", line, address) - } - - return ip, nil -} - // defaultGateway returns the default gateway of the machine. func (s *System) defaultGateway() (ip net.IP, err error) { /* diff --git a/wsl-pro-service/internal/system/system_test.go b/wsl-pro-service/internal/system/system_test.go index 5cd75b07a..9c4539670 100644 --- a/wsl-pro-service/internal/system/system_test.go +++ b/wsl-pro-service/internal/system/system_test.go @@ -468,7 +468,6 @@ func TestWindowsHostAddress(t *testing.T) { fileNotExist fileBroken fileIPbroken - fileIPisLoopback ) // copyFile is a helper that copies the appropriate version of a fixture to the desired destination. @@ -487,8 +486,6 @@ func TestWindowsHostAddress(t *testing.T) { suffix = ".bad" case fileIPbroken: suffix = ".bad-ip" - case fileIPisLoopback: - suffix = ".loopback" } from = from + suffix @@ -501,7 +498,6 @@ func TestWindowsHostAddress(t *testing.T) { // These are the addresses hard-coded on the fixtures labelled as "good" const ( localhost = "127.0.0.1" - nameserver = "172.22.16.1" degaultGway = "172.25.32.1" ) @@ -509,28 +505,21 @@ func TestWindowsHostAddress(t *testing.T) { networkNotNAT bool breakWslInfo bool - etcResolv fileState procNetRoute fileState want string wantErr bool }{ - "Success without NAT": {networkNotNAT: true, want: localhost}, - "Success with NAT, nameserver is not loopback": {want: nameserver}, - "Success with NAT, nameserver is loopback": {etcResolv: fileIPisLoopback, want: degaultGway}, + "Without NAT": {networkNotNAT: true, want: localhost}, + "With NAT": {want: degaultGway}, // WSL info errors "Error when wslinfo returns an error": {breakWslInfo: true, wantErr: true}, - // NAT errors with broken /etc/resolv.conf - "Error with NAT when /etc/resolv.conf does not exist": {etcResolv: fileNotExist, wantErr: true}, - "Error with NAT when /etc/resolv.conf is ill-formed": {etcResolv: fileBroken, wantErr: true}, - "Error with NAT when /etc/resolv.conf has an ill-formed IP": {etcResolv: fileIPbroken, wantErr: true}, - // NAT errors with loopback nameserver and broken /proc/net/route - "Error with NAT when /proc/net/route does not exist": {etcResolv: fileIPisLoopback, procNetRoute: fileNotExist, wantErr: true}, - "Error with NAT when /proc/net/route is ill-formed": {etcResolv: fileIPisLoopback, procNetRoute: fileBroken, wantErr: true}, - "Error with NAT when /proc/net/route has an ill-formed IP": {etcResolv: fileIPisLoopback, procNetRoute: fileIPbroken, wantErr: true}, + "Error with NAT when /proc/net/route does not exist": {procNetRoute: fileNotExist, wantErr: true}, + "Error with NAT when /proc/net/route is ill-formed": {procNetRoute: fileBroken, wantErr: true}, + "Error with NAT when /proc/net/route has an ill-formed IP": {procNetRoute: fileIPbroken, wantErr: true}, } for name, tc := range testCases { @@ -547,7 +536,6 @@ func TestWindowsHostAddress(t *testing.T) { mock.SetControlArg(testutils.WslInfoIsNAT) } - copyFile(t, tc.etcResolv, filepath.Join(commontestutils.TestFamilyPath(t), "etc-resolv.conf"), mock.Path("/etc/resolv.conf")) copyFile(t, tc.procNetRoute, filepath.Join(commontestutils.TestFamilyPath(t), "proc-net-route"), mock.Path("/proc/net/route")) got, err := sys.WindowsHostAddress(ctx) diff --git a/wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.bad b/wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.bad deleted file mode 100644 index b666d061b..000000000 --- a/wsl-pro-service/internal/system/testdata/TestWindowsHostAddress/etc-resolv.conf.bad +++ /dev/null @@ -1,3 +0,0 @@ -# This is a comment -# nameserver 1.2.3.4 - Date: Tue, 28 May 2024 15:33:44 -0300 Subject: [PATCH 2/4] Fix typo de**g**aultGway --- wsl-pro-service/internal/system/system_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wsl-pro-service/internal/system/system_test.go b/wsl-pro-service/internal/system/system_test.go index 9c4539670..e8877d465 100644 --- a/wsl-pro-service/internal/system/system_test.go +++ b/wsl-pro-service/internal/system/system_test.go @@ -498,7 +498,7 @@ func TestWindowsHostAddress(t *testing.T) { // These are the addresses hard-coded on the fixtures labelled as "good" const ( localhost = "127.0.0.1" - degaultGway = "172.25.32.1" + defaultGway = "172.25.32.1" ) testCases := map[string]struct { @@ -511,7 +511,7 @@ func TestWindowsHostAddress(t *testing.T) { wantErr bool }{ "Without NAT": {networkNotNAT: true, want: localhost}, - "With NAT": {want: degaultGway}, + "With NAT": {want: defaultGway}, // WSL info errors "Error when wslinfo returns an error": {breakWslInfo: true, wantErr: true}, From 79e496ef14ad08223122b60eccd2b9efcaf6a5d7 Mon Sep 17 00:00:00 2001 From: Carlos Nihelton Date: Tue, 28 May 2024 17:35:28 -0300 Subject: [PATCH 3/4] Remove ref to resolv.conf in docs --- docs/howto/set-up-up4w.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/howto/set-up-up4w.md b/docs/howto/set-up-up4w.md index 3702db84a..f518a881d 100644 --- a/docs/howto/set-up-up4w.md +++ b/docs/howto/set-up-up4w.md @@ -49,10 +49,8 @@ Sure: wslinfo --networking-mode ``` - If it says `mirrored`, the relevant IP is `127.0.0.1`. Take note of this address. - - Otherwise, open file `/etc/resolv.conf` in the WSL instance named _Ubuntu-22.04_. Find the line starting with `nameserver` followed by an IP address. - - If the IP address does not start with `127`, take note of this address. - - Otherwise, run the command `ip route | grep ^default` and take note of the IP address that is printed. - 3. Set up a Landscape Beta server: + - Otherwise, run the command `ip route | grep ^default` and take note of the IP address that is printed. + 3. Set up a Landscape Beta server: 1. Start a shell in your _Ubuntu-22.04_ distro. 2. Install the Landscape (beta) following the steps in the Landscape Quickstart deployment with the following considerations: - Make sure you install the beta version. @@ -185,9 +183,7 @@ On your Windows host, in the Microsoft Store, search for the `Ubuntu-Preview` or - - - + From ac9a54b6533bb6566f49074a2fba021a86b12c9f Mon Sep 17 00:00:00 2001 From: Carlos Nihelton Date: Tue, 28 May 2024 17:39:07 -0300 Subject: [PATCH 4/4] Remove references to resolv.conf in mock_executables.go --- wsl-pro-service/internal/testutils/mock_executables.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/wsl-pro-service/internal/testutils/mock_executables.go b/wsl-pro-service/internal/testutils/mock_executables.go index bb10f27bb..430c7ec5a 100644 --- a/wsl-pro-service/internal/testutils/mock_executables.go +++ b/wsl-pro-service/internal/testutils/mock_executables.go @@ -58,9 +58,6 @@ var ( //go:embed filesystem_defaults/os-release defaultOsReleaseContents []byte - //go:embed filesystem_defaults/resolv.conf - defaultResolvConfContents []byte - //go:embed filesystem_defaults/proc.mounts defaultProcMountsContents []byte @@ -655,9 +652,6 @@ func mockFilesystemRoot(t *testing.T) (rootDir string) { err := os.MkdirAll(filepath.Join(rootDir, "etc"), 0750) require.NoError(t, err, "Setup: could not create mock /etc/") - err = os.WriteFile(filepath.Join(rootDir, "etc/resolv.conf"), defaultResolvConfContents, 0600) - require.NoError(t, err, "Setup: could not write mock /etc/resolv.conf") - err = os.WriteFile(filepath.Join(rootDir, "etc/os-release"), defaultOsReleaseContents, 0600) require.NoError(t, err, "Setup: could not write mock /etc/os-release")