Manually configure static IP and DNS for macOS recovery without DHCP

Tl; dr: you must manually edit /Library/Preferences/SystemConfiguration/preferences.plist. This is especially useful for macOS in PVE.

When using macOS Recovery in a network without DHCP, you may encounter the error “The recovery server could not be contacted”. The networking error will persist even after the user manually configured network in the Terminal:

ifconfig en0 inet 192.168.0.102  # Configure IPv4 address
route add default 192.168.0.1    # Configure default route
ping 8.8.8.8 -c1                 # Test connectivity, it works!
curl apple.com                   # Fail to resolve.

The error persists due to a lack of DNS configuration. Debugging the issue leads to a detour into a huge rabbit hole, and now I end up knowing much more about the internal workings of macOS DNS.

Using echo "nameserver 8.8.8.8" > /etc/resolv.conf is not the correct way to configure DNS: macOS apps (including the system installer) does not honor resolv.conf, but rather use a system-level DNS hierarchy visible via scutil --dns. (dig may work since it’s using the linux-style resolution based on resolv.conf; here dns-sd is the right debugging command that uses the Unix resolution stack and have the same behavior as GUI applications.)

Unfortunately, there seems to be no way to correctly configure DNS using the “macOS way” under macOS Recovery. There’s no Network Manager GUI interface, and the CLI equivalent (networksetup -setdnsservers Wi-Fi 8.8.8.8) is also unusable — the networksetup command is unavailable in macOS Recovery. To add insult to injury, even changing the DNS state in configuration daemon using scutil doesn’t work:

scutil
> list ".*DNS"
        # Will show all currently-configured DNS across different services
> open
> d.init
> d.add ServerAddresses * 8.8.8.8 9.9.9.9
> set State:/Network/Service/PRIMARY_SERVICE_ID/DNS
> set State:/Network/Service/Global/DNS
> close
> quit

Normally, typing these commands would change DNS configuration in a running macOS, equivalent to changing from within System Configuration GUI. However, in macOS recovery, there’s another gotcha: unlike normal macOS, the recovery OS will not automatically mark the newly-added DNS as “reachable”; scutil --dns will now show a configured but unreachable DNS server, and applications still suffers from resolution failure.

It turns out there’s no easy way to force a reachability check for the configured DNS server. If you ask an AI assistant, it may suggest the obvious solution: kill and restart configd, or restart macOS entirely — both will wipe out the manual change you just made using scutil. At this point, there’s only one way out: edit the config file shipped with macOS recovery itself.

You must manually edit /Library/Preferences/SystemConfiguration/preferences.plist. Locate the section related to en0 and change it from

<key>UUID-PRIMARY_SERVICE_ID-FULL-UUID</key>
<dict>
  <key>DNS</key>
  <dict/>
  <key>IPv4</key>
  <dict>
    <key>ConfigMethod</key>
    <string>DHCP</string>
  </dict>
...

Into the following (remember to keep the original UUID and replace with your own IPv4 configuration):

<key>UUID-PRIMARY_SERVICE_ID-FULL-UUID</key>
<dict>
  <key>DNS</key>
  <dict>
    <key>ServerAddresses</key>
    <array>
      <string>8.8.8.8</string>
    </array>
  </dict>
  <key>IPv4</key>
  <dict>
    <key>ConfigMethod</key>
    <string>Manual</string>
    <key>Addresses</key>
    <array>
      <string>192.168.0.102</string>
    </array>
    <key>SubnetMasks</key>
    <array>
     <string>255.255.255.0</string>
    </array>
    <key>Router</key>
    <string>192.168.0.1</string>
  </dict>
  <key>IPv6</key>
  <dict>
    <key>ConfigMethod</key>
    <string>Automatic</string>
  </dict>
  <key>Interface</key>
  <dict>
    <key>DeviceName</key>
    <string>en0</string>
  </dict>
</dict>

When you’re done editing, make sure to check syntax with

plutil -lint /Library/Preferences/SystemConfiguration/preferences.plist

Then, you can reload the new config by running

killall configd

scutil --dns should now show an active resolver and curl apple.com should now resolve successfully. Now, you have the proper IPv4 and DNS setup in macOS recovery, and you may head back to the macOS installer app to continue network install.


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Powered by WordPress. Design: Supermodne.