Posted on 08-11-2017 04:51 PM
Long story short, a few months ago we changed CA's and found ourselves stuck with updating the existing wifi configuration profile. We ended up having to change the entire company's wifi SSID to get around this. (more info here - https://www.jamf.com/jamf-nation/discussions/23826/config-profile-question)
We ultimately decided to deploy the wifi config profile through a script using the "profiles -I -F" command instead of configuration profile for fear of getting stuck in the same situation. While the cutover to the new CA server went relatively seamless, we don't have a seamless way of updating the wireless certificates. (it only works if the user goes through Self Service)
What I'm looking for:
I'm looking for a way to have seamless wifi certificate renewals.
Here's the problem:
Running the script as the logged on user through Self Service works 100%. It'll remove the old wifi cert, download a new wifi cert, then It'll create the com.apple.network.eap.user.identity.wlan.ssid.SSIDHERE in the user's keychain properly.
When pushing the same exact script from Casper, it'll remove the old wifi cert, download a new wifi ciert, but the com.apple.network.eap.system.identity.wlan.ssid.SSIDHERE keychain entry is created in the system keychain. The user is unable to connect to wifi with this setting.
I've tried multiple variations of things for days and can't get it to work. How are people managing 802.1x wifi profiles and how are you renewing them?
#!/bin/sh
# Wifi Self Service.sh
# Script to connect to SSID
# Brandon Wong 4/24/2017
function connectWifi (){
/usr/bin/profiles -I -F /Library/LC/LC-#.mobileconfig
Cert="$compname.DOMAIN.com"
#security set-identity-preference -n -s "com.apple.network.eap.user.identity.wlan.ssid.SSID" /Library/Keychains/System.keychain
security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID" /Library/Keychains/System.keychain
#sudo security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID" /Library/Keychains/System.keychain
wservice=`/usr/sbin/networksetup -listallnetworkservices | grep -Ei '(Wi-Fi|AirPort)'`
whwport=`networksetup -listallhardwareports | awk "/$wservice/,/Ethernet Address/" | awk 'NR==2' | cut -d " " -f 2`
hwports=`networksetup -listallhardwareports | awk '/Hardware Port: Wi-Fi/,/Ethernet/' | awk 'NR==2' | cut -d " " -f 2`
wirelessnw=`networksetup -getairportnetwork $hwports | cut -d " " -f 4`
sleep 10
if [[ $wirelessnw == "SSID" ]]; then
echo "Connected to SSID"
else
echo "Machine is not connected to SSID. Checking identity preference"
security get-identity-preference -s "com.apple.network.eap.user.identity.wlan.ssid.SSID" /Library/Keychains/System.keychain
fi
}
function bindToDomain (){
# Unbind machine from domain
dsconfigad -remove -force -username macimaging -password $Pass
sleep 10
echo "Unbinding"
killall opendirectoryd
sleep 5
## Testing has shown that unbinding twice may be necessary.
dsconfigad -remove -force -username username -password $Pass &> /dev/null
sleep 10
echo "Unbinding twice just incase"
## Begin rebinding process
#Basic variables
computerid=`scutil --get LocalHostName`
domain=SSID.us
udn=
OU="CN=Computers,DC=Corp,DC=#,DC=com"
#Advanced variables
alldomains="disable"
localhome="enable"
protocol="smb"
mobile="enable"
mobileconfirm="disable"
user_shell="/bin/bash"
admingroups="Corp"
namespace="domain"
packetsign="allow"
packetencrypt="allow"
useuncpath="disable"
passinterval="90"
# Bind to AD
dsconfigad -add $domain -alldomains $alldomains -username $udn -password $Pass -computer $computerid -ou "$OU" -force -packetencrypt $packetencrypt
sleep 1
echo "Rebinding to AD and setting advanced options"
#set advanced options
dsconfigad -localhome $localhome
sleep 1
dsconfigad -groups "$admingroups"
sleep 1
dsconfigad -mobile $mobile
sleep 1
dsconfigad -mobileconfirm $mobileconfirm
sleep 1
dsconfigad -alldomains $alldomains
sleep 1
dsconfigad -useuncpath "$useuncpath"
sleep 1
dsconfigad -protocol $protocol
sleep 1
dsconfigad -shell $user_shell
sleep 1
dsconfigad -passinterval $passinterval
sleep 1
#dsconfigad adds "All Domains"
# Set the search paths to "custom"
dscl /Search -create / SearchPolicy CSPSearchPath
dscl /Search/Contacts -create / SearchPolicy CSPSearchPath
sleep 1
# Add the "XXXX.XXXXX.us" search paths
dscl /Search -append / CSPSearchPath "/Active Directory/CORP/DOMAIN.com"
dscl /Search/Contacts -append / CSPSearchPath "/Active Directory/CORP/DOMAIN.com"
sleep 1
# Delete the "All Domains" search paths
dscl /Search -delete / CSPSearchPath "/Active Directory/CORP/All Domains"
dscl /Search/Contacts -delete / CSPSearchPath "/Active Directory/CORP/All Domains"
dscl /Search -delete / CSPSearchPath "/Active Directory/CORP/#.us"
dscl /Search/Contacts -delete / CSPSearchPath "/Active Directory/CORP/#.us"
dscl /Search -delete / CSPSearchPath "/Active Directory/CORP/#.us"
dscl /Search/Contacts -delete / CSPSearchPath "/Active Directory/CORP/#.us"
sleep 1
# Restart opendirectoryd
killall opendirectoryd
sleep 3
dependenciesCheck
}
function dependenciesCheck(){
# Check for an AD computer object
ad_computer_name=`dsconfigad -show | grep "Computer Account" | awk '{print $4}'`
compObj=`dscl /Active Directory/CORP/All Domains read /Computers/$ad_computer_name RecordName | awk '{print $2}'`
if [ $ad_computer_name = $compObj ]; then
echo Matching AD object exists. Continue script...
# Make sure mobileconfig exists
file=/Library/LC/NAMEOFCONFIG.mobileconfig
if [ -f "$file" ]; then
connectWifi
else
echo Profile missing. Downloading profile
jamf policy -trigger *TRIGGER*
if [ -f "$file" ]; then
connectWifi
else
echo Cannot connect to *SSID*. Mobileconfig is missing.
exit 1
fi
fi
else
echo "Missing Domain Binding"
bindToDomain
fi
}
# HARDCODED VALUES ARE SET HERE
Pass=""
# CHECK TO SEE IF VALUES WERE PASSED FOR $4, AND IF SO, ASSIGN THEM
if [ "$4" != "" ] && [ "$Pass" == "" ]; then
Pass=$4
fi
# Check to make sure Pass variable was passed down from Casper
if [ "$Pass" == "" ]; then
echo "Error: The parameter 'Pass' is blank. Please specify a value."
exit 1
fi
# Variables
currUser=`stat -f "%Su" /dev/console`
echo "Current user is $currUser"
# Cleanup duplicate machine certificates
compname=`dsconfigad -show | grep "Computer Account" | awk '{print $4}' | sed 's/.$//'`
Certs="$compname.#.com"
hashes=$(security find-certificate -c "$Certs" -a -Z|grep SHA-1|awk '{ print $NF }')
for hash in $hashes; do
echo deleting duplicate certs $hash
sudo security delete-certificate -Z $hash
done
# Check dependencies
dependenciesCheck
exit 0
Solved! Go to Solution.
Posted on 08-14-2017 06:49 AM
@bbot In your script, you keep specifying the System keychain as the target for the security command. /Library/Keychains/System.keychain
Is there a reason why? Maybe I'm misunderstanding, but are you attempting to add the wi-fi identity preference into the System keychain, but have user accounts use that identity preference? If so, I don't think that's going to work. As far as I know, identity preferences need to go into the user's keychains. I'm wondering if that is part of the issue here.
As for us, we don't do the cert renewals with a script. We had a custom agent built for us that communicates with our CMS servers. The agent is local (pushed from Jamf Pro) to all Macs and is run by a LaunchAgent every 30 minutes. It checks to see if the Wi-Fi 802.1x certs for the user are valid. If they are it just exits silently. If they are not, the user is prompted with a GUI window to enter their account password, which gets sent back to CMS and will issue a new set of certs to the device.
However, the one thing this agent will not do is create the Wi-Fi identity preference. We do that with a LaunchAgent that keeps checking periodically to make sure if the certs for the user are present, that there is an accompanying identity preference that pairs up the cert to our Wi-Fi SSID.
But it's not a requirement to use a LaunchAgent for that. You can do this with a script called by root, but need to make sure you are running the command to create the identity preference as the logged in user, otherwise it will add the pref to the System keychain, and as you already found out, clients can't use identity prefs in the system keychain.
Try this variation and see if it helps
#!/bin/bash
loggedInUser=$(stat -f%Su /dev/console)
loggedInUID=$(id -u "$loggedInUser")
/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/usr/bin/security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID""
Posted on 08-12-2017 02:37 PM
When a policy pushes a script using the recurring check in trigger, it's running entirely as root, since it's called by a LaunchDaemon. So it makes sense it is adding the wi-fi setting in the System.keychain.
What you have to do is run any commands in the script that must be run as the logged in user, as the logged in user. This question and situation comes up a lot, probably every week here on average, no exaggeration. If you do searches on how to run commands within a script as the logged in user, you should find 100 threads if you find 1. One of them will have a solution for you.
And just to let you know, it's going to be the security set-identity-preference
lines that will need to get run as the user, as I'm sure you guessed already.
Posted on 08-13-2017 10:02 PM
@mm2270 I was under the impression that running Self Service policies are also executed as root, which left me a bit confused.
I've tried variations of /usr/bin/profiles with the -U and sudo -u /usr/bin/profiles command to specify user to no avail. Been trying to figure this out on and off for the past few months and feel like I'm hitting a dead end.
I've tried making sure to wipe the keychain entry -- security set-identity-preference -n -s "com.apple.network.eap.user.identity.wlan.ssid.SSID " /Library/Keychains/System.keychain
Tried setting it with commands similar to --
security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.LC-Authorized" /Library/Keychains/System.keychain
sudo security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.LC-Authorized" /Library/Keychains/System.keychain
sudo -u "$currentUser" -i /usr/bin/security set-identity-preference -s com.apple.network.eap.user.identity.wlan.ssid /Library/Keychains/System.keychain
How are you renewing wifi certificates without user interaction with using /usr/bin/profiles?
Posted on 08-13-2017 11:38 PM
To add --
Having the configuration profile set to Computer level generates a computer certificate, just doesn't assign the identity properly.
Having the configuration profile set to User level doesn't generate a cert at all.
Posted on 08-14-2017 06:49 AM
@bbot In your script, you keep specifying the System keychain as the target for the security command. /Library/Keychains/System.keychain
Is there a reason why? Maybe I'm misunderstanding, but are you attempting to add the wi-fi identity preference into the System keychain, but have user accounts use that identity preference? If so, I don't think that's going to work. As far as I know, identity preferences need to go into the user's keychains. I'm wondering if that is part of the issue here.
As for us, we don't do the cert renewals with a script. We had a custom agent built for us that communicates with our CMS servers. The agent is local (pushed from Jamf Pro) to all Macs and is run by a LaunchAgent every 30 minutes. It checks to see if the Wi-Fi 802.1x certs for the user are valid. If they are it just exits silently. If they are not, the user is prompted with a GUI window to enter their account password, which gets sent back to CMS and will issue a new set of certs to the device.
However, the one thing this agent will not do is create the Wi-Fi identity preference. We do that with a LaunchAgent that keeps checking periodically to make sure if the certs for the user are present, that there is an accompanying identity preference that pairs up the cert to our Wi-Fi SSID.
But it's not a requirement to use a LaunchAgent for that. You can do this with a script called by root, but need to make sure you are running the command to create the identity preference as the logged in user, otherwise it will add the pref to the System keychain, and as you already found out, clients can't use identity prefs in the system keychain.
Try this variation and see if it helps
#!/bin/bash
loggedInUser=$(stat -f%Su /dev/console)
loggedInUID=$(id -u "$loggedInUser")
/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/usr/bin/security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID""
Posted on 08-14-2017 09:28 AM
@mm2270 I have to double check, but I believe why I had to specify /Library/Keychains/System.keychain was because the machine certificate that is requested is placed in the System keychain.
I am trying to have the identity preference in the login keychain, not the system.
Generating the certificate isn't the issue for us, the mobileconfig does that perfectly. It sounds like what you're suggesting to create the identity pref in the user keychain will work...
I've tried /usr/bin/security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID as my current logged in user and confirmed this creates the identity preference in the login keychain; however... when I try "sudo -iu "$loggedInUser" "/usr/bin/security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID""" -- nothing happens.
I'm wondering if there's some security in-place that prevents the creation of keychain items in other user's keychain.
Thanks for your time on this. I really appreciate it.
Posted on 08-14-2017 09:56 AM
Wait, I'm on to something. I wasn't using the UID for "launchctl asuser" Looks like I was able to create the identity in the login keychain when specifying the UID. (i overlooked it and put the user account) Going to test and will post back here.
Posted on 08-14-2017 01:31 PM
@mm2270 It works! The trick was to use launchctl to run it as the user. I owe you big time.
Now I just need to create an EA that can help me determine whether a certificate needs renewing or not, then I can use the profiles command to generate a new certificate from my config profile...then use launchctl and /usr/binsecurity to create the identity preference.
Thanks so much!
On a side note, using the same format you provided didn't work for some reason. /bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/usr/bin/security set-identity-preference -c "$Cert" -s "com.apple.network.eap.user.identity.wlan.ssid.SSID""
I took out the " and the and it works. (it was giving me an error about the file or directory doesn't exist)
Posted on 06-07-2019 09:03 AM
This also helped me as well.
One thing I did notice is that WiFi doesn't work at the login screen. When you logged back in it auto connects just fine.
Anyone got a solution to keep the WiFi connection at the login screen?
Posted on 04-15-2021 11:03 PM
This looks like something I need too so I tried the script @mm2270 wrote above but like @bbot I got the error "the file or directory doesn't exist". I couldn't see a fixed version so started playing with the script and got it to this state where it works (probably more by luck)
#!/bin/bash
loggedInUser=$(stat -f%Su /dev/console)
loggedInUID=$(id -u "$loggedInUser")
Cert=$(hostname)
/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" /usr/bin/security set-identity-preference -c "$Cert" -s com.apple.network.eap.user.identity.wlan.ssid.Unifi /Library/Keychains/System.keychain
For us the Certificate is a machine certificate with the name being the hostname and "Unifi" is the SSID of our Wifi
It does set the preference up but then I had a few other problems that I'm hoping someone might have some suggestions for.
The first thing I found was that the wireless "Unifi" is not set up as the default but am hoping there is some way to to fix
But I can at worst manually choose the correct one
Then the user is asked to allow eapolclient to access the logon keychain
This is the one I'm most worried about because it's asking for access to the system keychain. For the life of me I can't see a way to do that in the command line and I'm not sure what is wanting that access.
The last issue is that when all this is set up I get this and I have to disconnect and then reconnect via the button before it actually
Posted on 05-18-2021 08:24 AM
@dlondon Any update on this? We're now testing the same thing and the admin password for access to the System keychain is my biggest obstacle at this point.
Posted on 05-18-2021 11:33 PM
Sorry @mwilkerson no success with the admin prompt for System keychain
Posted on 05-19-2021 06:38 AM
@dlondon I discovered yesterday that if I dismiss the admin credentials prompt (hit esc or click Deny), it joins the wifi network anyway... So, even though it comes up, it doesn't seem like it's even necessary. Now if I can just get it to not prompt at all....