This setup ensures that each macOS user gets their assigned NextDNS config β even with fast user switching and standard (non-admin) accounts β without requiring manual scripts, prompts, or login hooks.
Automatically install the correct NextDNS profile within 30 seconds of user login or fast user switch, but only if the current profile is incorrect.
We deploy a root-owned LaunchDaemon that runs a script every 30 seconds. The script:
- Detects the active console user.
- Maps the user to their designated NextDNS config ID.
- Fetches the currently active NextDNS config ID.
- Compares the two IDs and only runs the
install
command if they differ.
Create the file /usr/local/bin/nextdns-poll.sh
with the updated logic.
#!/bin/bash
LOG=/var/log/nextdns-poll.log
export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin"
# Detect active console user
user=$(stat -f "%Su" /dev/console)
# Map macOS username to its NextDNS Config ID
case "<span class="math-inline">user" in
mac\-username\-1\) cfg\=nextdns\-config\-profile\-1 ;;
mac\-username\-2\) cfg\=nextdns\-config\-profile\-2 ;;
mac\-username\-3\) cfg\=nextdns\-config\-profile\-3 ;;
mac\-username\-4\) cfg\=nextdns\-config\-profile\-4 ;;
\*\)
\# Exit if the user is not in our list \(e\.g\., '\_mbsetupuser' during startup\)
exit 0
;;
esac
\# Get the currently installed NextDNS Config ID
current\=</span>(/opt/homebrew/bin/nextdns status 2>/dev/null | awk '/Config ID/ {print $3}')
# --- Conditional Check ---
# Only run the 'install' command if the current config ID does not match the
# expected config ID for the logged-in user. This prevents unnecessary work.
if [ "$current" != "<span class="math-inline">cfg" \]; then
echo "\[</span>(date)] User '$user' requires config '$cfg', but '$current' is active. Switching..." >> $LOG
# Run the install command with the correct user's config
sudo /opt/homebrew/bin/nextdns install \
-config "$cfg" \
-report-client-info \
-auto-activate >> $LOG 2>&1
fi
Make it executable:
sudo chmod +x /usr/local/bin/nextdns-poll.sh
Edit sudoers
using sudo visudo
and add one specific NOPASSWD
line for each user's exact installation command.
# Allow each user to run only the specific NextDNS install command for their own profile
mac-username-1 ALL=(root) NOPASSWD: /opt/homebrew/bin/nextdns install -config nextdns-config-profile-1 -report-client-info -auto-activate
mac-username-2 ALL=(root) NOPASSWD: /opt/homebrew/bin/nextdns install -config nextdns-config-profile-2 -report-client-info -auto-activate
mac-username-3 ALL=(root) NOPASSWD: /opt/homebrew/bin/nextdns install -config nextdns-config-profile-3 -report-client-info -auto-activate
mac-username-4 ALL=(root) NOPASSWD: /opt/homebrew/bin/nextdns install -config nextdns-config-profile-4 -report-client-info -auto-activate
Security Note: This remains a secure approach because it doesn't grant broad permissions. It only allows the execution of a single, non-interactive command.
Create /Library/LaunchDaemons/com.nextdns.poll.plist
:
<?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](http://www.apple.com/DTDs/PropertyList-1.0.dtd)">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nextdns.poll</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nextdns-poll.sh</string>
</array>
<key>StartInterval</key>
<integer>30</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/nextdns-poll.log</string>
<key>StandardErrorPath</key>
<string>/var/log/nextdns-poll.err</string>
</dict>
</plist>
Then, install and load it:
sudo chown root:wheel /Library/LaunchDaemons/com.nextdns.poll.plist
sudo chmod 644 /Library/LaunchDaemons/com.nextdns.poll.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.nextdns.poll.plist
Here is the revised helper script incorporating the more clearly commented polling script. Customize the case
statement with your usernames and config IDs before running.
#!/usr/bin/env bash
set -e
echo "π§ Installing NextDNS polling setup with conditional check..."
# Create the polling script
sudo tee /usr/local/bin/nextdns-poll.sh > /dev/null << 'EOF'
#!/bin/bash
LOG=/var/log/nextdns-poll.log
export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin"
# Detect active console user
user=$(stat -f "%Su" /dev/console)
# Map macOS username to its NextDNS Config ID
case "<span class="math-inline">user" in
mac\-username\-1\) cfg\=nextdns\-config\-profile\-1 ;;
mac\-username\-2\) cfg\=nextdns\-config\-profile\-2 ;;
mac\-username\-3\) cfg\=nextdns\-config\-profile\-3 ;;
mac\-username\-4\) cfg\=nextdns\-config\-profile\-4 ;;
\*\)
\# Exit if the user is not in our list
exit 0
;;
esac
\# Get the currently installed NextDNS Config ID
current\=</span>(/opt/homebrew/bin/nextdns status 2>/dev/null | awk '/Config ID/ {print $3}')
# Only run install if the active config doesn't match the expected one
if [ "$current" != "<span class="math-inline">cfg" \]; then
echo "\[</span>(date)] User '$user' requires config '$cfg', but '$current' is active. Switching..." >> $LOG
sudo /opt/homebrew/bin/nextdns install \
-config "$cfg" \
-report-client-info \
-auto-activate >> $LOG 2>&1
fi
EOF
sudo chmod +x /usr/local/bin/nextdns-poll.sh
# Create the LaunchDaemon plist
sudo tee /Library/LaunchDaemons/com.nextdns.poll.plist > /dev/null << 'EOF'
<?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](http://www.apple.com/DTDs/PropertyList-1.0.dtd)">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nextdns.poll</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nextdns-poll.sh</string>
</array>
<key>StartInterval</key>
<integer>30</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/nextdns-poll.log</string>
<key>StandardErrorPath</key>
<string>/var/log/nextdns-poll.err</string>
</dict>
</plist>
EOF
# Set correct ownership and permissions, then load the service
sudo chown root:wheel /Library/LaunchDaemons/com.nextdns.poll.plist
sudo chmod 644 /Library/LaunchDaemons/com.nextdns.poll.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.nextdns.poll.plist
echo "β
Done. Auto-switching NextDNS is active."
echo "β‘οΈ Next step: Edit sudoers with 'sudo visudo' to grant NOPASSWD access."
- Switch between users or log out and back in.
- Run
nextdns status
in the Terminal to confirm the correct Config ID is active. - Check the log file for switch events:
tail -f /var/log/nextdns-poll.log