Wi-Fi = OFF

Leaving Wi-Fi on while traveling can expose you to security risks. While macOS tries to restore your last Wi-Fi state, it is unreliable: Wi-Fi may turn back on if you forget to turn it off at shutdown or if a system service interferes. This is why we created a tool to keep Wi-Fi off at startup.

Wi-Fi = OFF



We recommend keeping Wi-Fi turned off unless you need it, especially while traveling, because leaving it on can pose serious privacy and security risks:


1) Your device broadcasts probes for known networks:
This means anyone with a Wi-Fi sniffer (like Wireshark) can see which networks your laptop is searching for. These SSIDs may reveal where you’ve been - home, work, cafés, airports - and can be exploited to create rogue access points (Evil Twin attacks). Your device may automatically connect to these fake networks, exposing your traffic to interception, monitoring, or even malware injection (Man-in-the-Middle attacks).

2) Your location can be tracked:
These probe requests, combined with your device’s MAC address, make it easy to trace your movements. While macOS randomizes your MAC address during scanning, it uses your real MAC when connecting to a network. This can be used to build a detailed profile of your behavior. That’s why we strongly recommend spoofing your MAC address.


You can disable auto-join for known networks in System Settings, but your Mac will still continuously scan for nearby Wi-Fi networks. While macOS is supposed to remember your last Wi-Fi state after a reboot, this isn’t reliable: Wi-Fi may turn back on automatically when you reboot your computer, either due to system processes or simply because you forgot to turn it off before shutdown. Since there’s no built-in setting to prevent this, we created a tool that keeps Wi-Fi disabled at startup. When you need it, just re-enable Wi-Fi manually with one click.

This tutorial will show you how to improve your privacy on macOS by disabling Wi-Fi at startup.

Wi-Fi Tracking Countermeasure

Wi-Fi = OFF

To enhance privacy and security on macOS we have written a simple tool that:

  • Prevents any Wi-Fi traffic or scanning during boot and login.
  • Blocks auto-reconnection to known networks.
  • Makes Wi-Fi available only in a user-controlled state after login.
  • Helps minimize MAC address tracking and probe leaks, especially in sensitive environments.

Wi-Fi | OFF consists of 2 scripts and 2 LaunchDaemons. Our script also makes use of SpoofMac to randomize your Wi-Fi MAC address.

About a year ago, we have written a separate tutorial that helps you to install SpoofMAC, a tool that can reliably randomize your Mac's MAC address:

SpoofMAC
A MAC address uniquely identifies your device to each new network it connects to. MAC addresses can therefore be used to track your location as you move between WiFi networks and Bluetooth receivers. We show you how to randomize your devices MAC addresses every time you reboot your computer!

CONCEPT:


Preventing Automatic Wi-Fi Connections on macOS

The goal of this setup is to block any Wi-Fi connection unless you explicitly allow it. To achieve this, we need to prevent macOS from connecting to any known networks as early as possible during the boot process, before the system or any user-related services have a chance to enable networking.

Phase 1: Early Boot Protection (Pre-Login)

The first part of the setup uses a LaunchDaemon that runs very early during system startup, before any user session is active. This daemon is configured with a high priority (nice value set to -20), ensuring it runs ahead of other system processes.

This daemon performs several important tasks. First, it checks if the SpoofMAC tool is installed and, if available, it spoofs your device’s Wi-Fi MAC address to help prevent tracking. Next, it disables the Wi-Fi network service entirely, which stops macOS from automatically connecting to any previously known networks during the boot process. Finally, it disables power-related settings such as Wake-on-Wi-Fi using pmset, ensuring that Wi-Fi cannot be used to wake the machine remotely.

After completing these actions, this first script uses launchctl to trigger a second LaunchDaemon.

Phase 2: Post-Login Cleanup

The second LaunchDaemon runs a separate script, but it waits until a user has successfully logged into the system. This delay is important because certain macOS graphical user interface components and background services may re-enable Wi-Fi as part of the login process, even if it was disabled earlier.

Once a user is logged in, the second script disables the Wi-Fi radio itself using networksetup -setairportpower en0 off, which powers down the interface at the hardware level. It then waits a few seconds to ensure the disconnect is fully processed. After that, it re-enables the Wi-Fi network service so that the Wi-Fi interface becomes visible again in the macOS user interface. However, since the radio remains off, the system does not automatically reconnect to any networks. This allows the user to manually enable Wi-Fi when needed, without triggering unintended connections.

Why Not Use One Script?

It may seem simpler to combine these steps into a single script triggered by a single LaunchDaemon, but doing so introduces problems due to how macOS manages system startup and daemon execution. LaunchDaemons are expected to run quickly and exit. If a daemon script runs too long, such as when it waits for a user to log in, macOS may consider it unresponsive and force-terminate it before it finishes. Additionally, some of the system’s network-related services and graphical components are only fully initialized after login. If a combined script disables Wi-Fi too early, those services may re-enable it, which defeats the goal of maintaining a fully disconnected state until manual intervention.

By separating the tasks into two dedicated daemons, one for early boot and one for post-login, we maintain complete control over the Wi-Fi state across the entire system lifecycle. This ensures that the system remains disconnected from any network unless you deliberately choose to connect.

Wi-Fi = OFF / Manual Setup

Reliably switch off Wi-Fi at boot

Follow this step-by-step guide to learn how to configure the scripts and LaunchDaemons that ensure Wi-Fi is turned off every time your Mac starts. If SpoofMAC is installed, the script will also randomize your MAC address at boot. Prefer a faster, automated setup? Use our ready-to-go solution: Wifi-Off: Interactive Script

CREATE SCRIPTS -> Wi-Fi = OFF:


We use the Shared folder on macOS as the central location to store our scripts and the log file that will be generated later. Start by running the following command to create the required folder structure:

# Prepare work environment:mkdir -p /Users/Shared/Enhancements/disable_wifi

Then set the appropriate permissions for the folder:

# Set permissions:chmod 755 /Users/Shared/Enhancements/disable_wifi

Next, we’ll create two scripts: one that runs at boot time, and another that runs after a user logs in.

Start by creating the boot-time script:

# Disable Wi-Fi:nano /Users/Shared/Enhancements/disable_wifi/01_disable_wifi.sh

Insert the following content:

#!/bin/bash

LOGFILE="/Users/Shared/Enhancements/disable_wifi/disable_wifi.log"
mkdir -p "$(dirname "$LOGFILE")"
touch "$LOGFILE"
chmod 666 "$LOGFILE"

log() {
  echo "$(date): $1" >> "$LOGFILE"
}

run_and_log() {
  CMD="$1"
  log "Running: $CMD"
  OUTPUT=$(eval "$CMD" 2>&1)
  EXITCODE=$?
  log "Exit code: $EXITCODE"
  if [ -n "$OUTPUT" ]; then
    log "Output: $OUTPUT"
  fi
  return $EXITCODE
}

echo "$(date): Boot stage: $(/bin/launchctl print system | grep -m 1 state | awk '{print $NF}')" > "$LOGFILE"
log "System uptime: $(uptime)"

log "===== Daemon Script 1) started ====="

# Spoof Wi-Fi MAC Address if SpoofMAC exists
if [ -x /opt/local/bin/spoof ]; then
    log "SPOOF MAC-ADDRESS:"
    run_and_log "/opt/local/bin/node /opt/local/bin/spoof randomize en0"

    log "CURRENT SPOOF STATUS:"
    SPOOF_OUTPUT=$(/opt/local/bin/node /opt/local/bin/spoof list --wifi 2>&1)
    log "$SPOOF_OUTPUT"
else
    log "SpoofMAC not found at /opt/local/bin/spoof – skipping MAC spoofing and status check."
fi

# Immediately disable Wi-Fi network service to prevent early connections
log "DISABLE WI-FI:"
run_and_log "/usr/sbin/networksetup -setnetworkserviceenabled Wi-Fi off"

# Apply system power settings
log "PREVENT WAKE-ON-LAN WI-FI ACTIVATIONS:" >> "$LOGFILE"
run_and_log "/usr/bin/pmset -a womp 0"
log "PREVENT WAKE-FROM-SLEEP WI-FI ACTIVATIONS:" >> "$LOGFILE"
run_and_log "/usr/bin/pmset -a networkoversleep 0"

log "===== Daemon Script 1) completed ====="

sudo launchctl kickstart -k system/info.term7.on.networksetup.daemon

Press [Control] + X, then Y followed by [Enter] to save the file and close the editor. Next, create the second script, which runs after a user logs in:

# Enable Wi-Fi Interface:nano /Users/Shared/Enhancements/disable_wifi/02_enable_wifi.sh

Insert:

#!/bin/bash

LOGFILE="/Users/Shared/Enhancements/disable_wifi/disable_wifi.log"

log() {
  echo "$(date): $1" >> "$LOGFILE"
}

run_and_log() {
  CMD="$1"
  log "Running: $CMD"
  OUTPUT=$(eval "$CMD" 2>&1)
  EXITCODE=$?
  log "Exit code: $EXITCODE"
  if [ -n "$OUTPUT" ]; then
    log "Output: $OUTPUT"
  fi
  return $EXITCODE
}

log "===== Daemon Script 2) started ====="

log "Boot stage: $(/bin/launchctl print system | grep -m 1 state | awk '{print $NF}')"
log "System uptime: $(uptime)"

log "Waiting for user login..."

WAITED=0

while ! /usr/bin/stat -f%Su /dev/console | grep -vq '^root$'; do
  log "No user logged in yet... waiting ($WAITED seconds elapsed)"
  sleep 1
  WAITED=$((WAITED + 1))
done

log "Detected user login after $WAITED seconds. Proceeding..."

log "Detected user login. Proceeding..."

log "DISCONNECT WIFI:"

# Turn off the Wi-Fi radio interface (en0)
for i in {1..10}; do
  run_and_log "/usr/sbin/networksetup -setairportpower en0 off"
  if [ $? -eq 0 ]; then
    break
  fi
  log "Retrying setairportpower in 2 seconds..."
  sleep 2
done

log "ENABLE OFFLINE WIFI:"

# Pause to let Wi-Fi disconnect cleanly
log "Waiting 3 seconds before re-enabling the Wi-Fi network service..."
sleep 3

# Re-enable the Wi-Fi network service (so it's visible but disconnected)
run_and_log "/usr/sbin/networksetup -setnetworkserviceenabled Wi-Fi on"

log "===== Daemon Script 2) completed ====="

Save and exit, then make both scripts executable:

# Make script 1 executable:chmod 755 /Users/Shared/Enhancements/disable_wifi/01_disable_wifi.sh
# Make script 2 executable:chmod 755 /Users/Shared/Enhancements/disable_wifi/02_enable_wifi.sh

When these scripts run, they generate a log file in the installation folder, useful for debugging if something doesn’t work as expected.

CREATE LAUNCHDAEMONS:


Open a command-line editor like nano to create the first LaunchDaemon. This daemon will run the first script during system boot:

sudo nano /Library/LaunchDaemons/info.term7.off.networksetup.daemon.plist

Insert:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>info.term7.off.networksetup.daemon</string>
	<key>Nice</key>
	<integer>-20</integer>
	<key>ProgramArguments</key>
	<array>
		<string>/Users/Shared/Enhancements/disable_wifi/01_disable_wifi.sh</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

Save and exit the file.

Next, create the second LaunchDaemon. This one is triggered by the first script and runs the second script after a user logs in:

sudo nano /Library/LaunchDaemons/info.term7.on.networksetup.daemon.plist

Insert:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>info.term7.on.networksetup.daemon</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/Shared/Enhancements/disable_wifi/02_enable_wifi.sh</string>
    </array>
</dict>
</plist>

Press [Control] + X, then Y followed by [Enter] to save the file and close the editor.

Next, configure the required ownership and permissions for both LaunchDaemon files:

# Ownershipsudo chown root:wheel /Library/LaunchDaemons/info.term7.off.networksetup.daemon.plist
# Permissionsudo chmod 644 /Library/LaunchDaemons/info.term7.off.networksetup.daemon.plist
# Ownershipsudo chown root:wheel /Library/LaunchDaemons/info.term7.on.networksetup.daemon.plist
# Permissionsudo chmod 644 /Library/LaunchDaemons/info.term7.on.networksetup.daemon.plist

Finally, activate both LaunchDaemons so they will run immediately, no reboot required:

# Activate LaunchDaemon 1: sudo launchctl bootstrap system /Library/LaunchDaemons/info.term7.off.networksetup.daemon.plist
# Activate LaunchDaemon 2:sudo launchctl bootstrap system /Library/LaunchDaemons/info.term7.on.networksetup.daemon.plist

That's all you need to keep Wi-Fi turned off after every reboot. You can still connect manually whenever you choose.

AVOID CONFLICTS WITH SPOOFMAC DAEMON:


If you previously followed our  SpoofMac tutorial, you may have created a LaunchDaemon to spoof your Wi-Fi MAC address at startup. This is no longer needed, as our new Wi-Fi script now handles MAC spoofing automatically. In fact, keeping the old SpoofMAC daemon may cause it to fail, since the Wi-Fi interface is already disabled by the time it runs.

To disable and delete the old SpoofMac Daemon, run the following commands:

# Unload SpoofMAC LaunchDemonsudo launchctl unload /Library/LaunchDaemons/info.term7.spoof.mac.plist
# Delete SpoofMAC LaunchDemonsudo rm /Library/LaunchDaemons/info.term7.spoof.mac.plist

Wi-Fi = ON

Uninstall Wi-Fi = OFF

1) Unload the LaunchDemons:

# Unload LaunchDemon 1sudo launchctl bootout system /Library/LaunchDaemons/info.term7.off.networksetup.daemon.plist
# Unload LaunchDemon 2sudo launchctl bootout system /Library/LaunchDaemons/info.term7.on.networksetup.daemon.plist

2) Delete the LaunchDemons:

# Delete LaunchDemon 1sudo rm /Library/LaunchDaemons/info.term7.off.networksetup.daemon.plist
# Delete LaunchDemon 2sudo rm /Library/LaunchDaemons/info.term7.on.networksetup.daemon.plist

3) Delete the folders with your scripts:

# Delete Folderssudo rm -R  /Users/Shared/Enhancements/disable_wifi

WiFi = OFF has been purged from your system. Your computer will start Wi-Fi automatically at boot.

WiFi = OFF: Interactive Script

Setup WiFi = OFF interactively

Both our interactive script and speedy install script install WiFi = OFF and set up a LaunchDaemons that runs automatically every time you boot up your computer. We also provide a simple uninstall script in case you ever want to remove everything cleanly.


BE CAREFUL: YOU SHOULD ALWAYS LOOK THROUGH THE CONTENT OF ANY SHELL SCRIPT YOU DOWNLOAD FROM AN UNKNOWN SOURCE BEFORE YOU EXECUTE IT! MAKE SURE IT IS SAFE TO EXECUTE!

WE HOST OUR SCRIPTS FOR EVERYONE TO SEE ON CODEBERG.

To run our script, you first have to download it. Open the Terminal.app (found with Spotlight: press and [SPACE], then type Terminal, or find it in your Applications -> Utilities Folder). In your Terminal, use this command to navigate to your Downloads Folder:

cd ~/Downloads

Download the interactive script:

# Interactive Scriptcurl -O https://codeberg.org/term7/MacOS-Privacy-and-Security-Enhancements/raw/branch/main/05_WiFi-OFF/script/install_WiFi-OFF.sh

Download the speedy install script:

# Speedy Install Scriptcurl -O https://codeberg.org/term7/MacOS-Privacy-and-Security-Enhancements/raw/branch/main/05_WiFi-OFF/script/SPEEDY-INSTALL_WiFi-OFF.sh

If you ever want to uninstall WiFi = OFF, download our uninstall script:

# Uninstall Scriptcurl -O https://codeberg.org/term7/MacOS-Privacy-and-Security-Enhancements/raw/branch/main/05_WiFi-OFF/script/UNINSTALL_WiFi-OFF.sh

Give the respective file execute permissions:

chmod +x *WiFi-OFF.sh

Execute the respective script:

./install_WiFi-OFF.sh
./SPEEDY-INSTALL_WiFi-OFF.sh
./UNINSTALL_WiFi-OFF.sh

If asked, enter your administrator password and hit [ENTER] and follow the instructions. Your password won't be shown by default.

PREVIEW:


Making sure you’re not a bot!