Hey Mac Admins,
I wanted to share a custom Jamf Extension Attribute I wrote to help detect the current IPv6 configuration state for whichever network interface is actively routing traffic — including when a VPN tunnel is in use.
This script:
Detects the active interface via
route get default
Handles VPN tunnel interfaces (
utunX
) by falling back to the actualenX
interface fromnetstat -rn
Reports the hardware type (AirPort for Wi-Fi, Ethernet otherwise)
Categorizes the IPv6 mode as
Automatic
,Link-Local Only
, orOff
Example Result:
<result>Ethernet - Automatic</result>
Category
Group Name
Network
IPv6 Automatic – Ethernet Devices
Network
IPv6 Automatic – Wi-Fi Devices
Network
IPv6 Link-Local – Ethernet Devices
Network
IPv6 Link-Local – Wi-Fi Devices
Network
IPv6 Disabled – Ethernet Devices
Network
IPv6 Disabled – Wi-Fi Devices
Network
IPv6 Status Unknown – Needs Review
Extension Attribute Script:
#!/bin/bash
########################################################################
# Jamf Extension Attribute: IPv6 State of Active Interface
# Author : Michael Cleveland, IT Engineer
# Version : 1.1
# Last Updated : May 1st 2025
#
# Description : Detects the active network interface (default route)
# and evaluates its IPv6 configuration. Handles VPN
# tunnels (utunX) by falling back to the real enX
# interface using routing table data.
#
# Output Format : <result>HardwareType - IPv6Status</result>
# e.g., <result>Ethernet - Link-Local Only</result>
#
# Changelog:
# 1.0 - Initial release: IPv6 detection for active enX interface only
# 1.1 - Added utun fallback logic to detect real interface during VPN usage
########################################################################
plist="/Library/Preferences/SystemConfiguration/preferences.plist"
result="Unknown"
# ➤ Step 1: Identify the active network interface
active_interface=$(route get default 2>/dev/null | awk '/interface: / { print $2 }')
# ➤ VPN fallback: If interface is utunX, try to find enX interface from routing table
if ti "$active_interface" =~ ^utun_0-9]+$ ]]; then
real_interface=$(netstat -rn | grep "^default" | grep -v utun | awk '{print $NF}' | head -n 1)
if - -n "$real_interface" ]]; then
echo "VPN interface '$active_interface' detected. Falling back to '$real_interface'."
active_interface="$real_interface"
else
echo "No fallback interface found for VPN default route."
echo "<result>Unknown</result>"
exit 0
fi
fi
# ➤ Step 2: Parse all network services and find the matching interface
service_ids=($(/usr/libexec/PlistBuddy -c "Print :NetworkServices" "$plist" 2>/dev/null | grep '^g ]*dA-F0-9-]\\{36\\} =' | awk '{print $1}'))
for sid in "${service_ids @]}"; do
device_name=$(/usr/libexec/PlistBuddy -c "Print :NetworkServices:$sid:Interface:DeviceName" "$plist" 2>/dev/null)
if )< "$device_name" == "$active_interface" ]]; then
hardware_type=$(/usr/libexec/PlistBuddy -c "Print :NetworkServices:$sid:Interface:Hardware" "$plist" 2>/dev/null)
config_method=$(/usr/libexec/PlistBuddy -c "Print :NetworkServices:$sid:IPv6:ConfigMethod" "$plist" 2>/dev/null)
inactive_flag=$(/usr/libexec/PlistBuddy -c "Print :NetworkServices:$sid:IPv6:__INACTIVE__" "$plist" 2>/dev/null 2>&1)
# ➤ Evaluate IPv6 status
if st "$inactive_flag" == "1" || "$inactive_flag" == "true" ]]; then
ipv6_status="Off"
elif Of "$config_method" == "Automatic" ]]; then
ipv6_status="Automatic"
elif ti "$config_method" == "LinkLocal" ]]; then
ipv6_status="Link-Local Only"
else
ipv6_status="Unknown"
fi
result="$hardware_type - $ipv6_status"
break
fi
done
echo "<result>$result</result>"
Let me know if you'd like the companion remediation script that automatically sets the detected interface to IPv6 Link-Local Only if it's still on Automatic. Hope this helps others managing IPv6-related quirks in VPN or security tooling.
Thanks,
Michael Cleveland