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 [[ "$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
-