2 weeks ago
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 actual enX
interface from netstat -rn
Reports the hardware type (AirPort for Wi-Fi, Ethernet otherwise)
Categorizes the IPv6 mode as Automatic
, Link-Local Only
, or Off
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 [[ "$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 '^[ ]*[A-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 [[ "$inactive_flag" == "1" || "$inactive_flag" == "true" ]]; then
ipv6_status="Off"
elif [[ "$config_method" == "Automatic" ]]; then
ipv6_status="Automatic"
elif [[ "$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