Articles,Deployment,Management,OS X March 7, 2013 at 7:00 am

Another Way to Enable Wi-Fi At Login Window (with Profiles!)

The Premise:

Nick McSpadden and I were both working on a similar goal this week: getting Macs to connect to Wi-Fi at the loginwindow. By default, adding preferred wireless networks will only connect once a user is logged in, either via the networksetup command or Profiles. By using a modified .mobileconfig from the iPhone Configuration Utility, we can achieve this goal without having to use Profile Manager.

We shared a common goal in this, to be able to bootstrap new MacBook Airs over Wi-Fi using Munki. I had an additional goal, to be able to authenticate to Active Directory over Wi-Fi. Without a Wi-Fi connection at the loginwindow, Directory Services must rely on cached credentials, which interferes with some authentication  methods as well as Kerberos, and also prevents new users from signing in.

Nick created a script which is run by a LaunchAgent that makes this work on Snow Leopard and later, but if you are using Lion or Mountain Lion, this can all be accomplished with the built-in functionality of Profiles.

The iPhone Configuration Utility can make .mobileconfig profiles, but these are ‘User’ profiles, in that wireless networks and credentials are installed in the current user’s Keychain. In order to achieve our goal, we need a ‘System’ profile, so this information is stored in the System Keychain and therefore usable by any user. We also must instruct the computer to connect at the loginwindow, and not just after users log in.

By using this setup, you will no longer need an Ethernet connection to setup new machines and users, and it will make it much easier to keep your fleet of portables updated. Be careful when bootstrapping over Wi-Fi, as a few machines downloading tens of gigabytes can easily overwhelm poorly-configured or cheap access points.

The Setup:

Download and install the iPhone Configuration Utility, and create a .mobileconfig profile for your Wi-Fi network(s). If you use 802.1x, be sure to include any certificates. Export the profile, and open it in your favorite text editior.

Your initial .mobileconfig should look like the following example. This example contains two Wi-Fi networks, a WPA2-PSK network and a WPA2-Enterprise, 802.1x authenticated network. We must make some manual modifications to this file.

<?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">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>AutoJoin</key>
<true/>
<key>EAPClientConfiguration</key>
<dict>
<key>AcceptEAPTypes</key>
<array>
<integer>25</integer>
</array>
<key>EAPFASTProvisionPAC</key>
<false/>
<key>EAPFASTProvisionPACAnonymously</key>
<false/>
<key>EAPFASTUsePAC</key>
<false/>
<key>PayloadCertificateAnchorUUID</key>
<array>
<string>9B733672-E764-4B5F-9B86-B3D6D5C8E6FE</string>
</array>
<key>UserName</key>
<string>SampleUser</string>
<key>UserPassword</key>
<string>SamplePass</string>
</dict>
<key>EncryptionType</key>
<string>WPA</string>
<key>HIDDEN_NETWORK</key>
<false/>
<key>PayloadDescription</key>
<string>Configures wireless connectivity settings.</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi (SampleNET-WPA2E)</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example.wifi</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>FB096D71-25B9-418B-82CB-FB9BD0707B23</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProxyType</key>
<string>None</string>
<key>SSID_STR</key>
<string>SampleNET-WPA2E</string>
</dict>
<dict>
<key>AutoJoin</key>
<true/>
<key>EncryptionType</key>
<string>WPA</string>
<key>HIDDEN_NETWORK</key>
<false/>
<key>Password</key>
<string>SamplePass!</string>
<key>PayloadDescription</key>
<string>Configures wireless connectivity settings.</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi (SampleNET-WPA2PSK)</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example.wifi1</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>484F40AD-DE85-4851-A565-608E069350C6</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProxyType</key>
<string>None</string>
<key>SSID_STR</key>
<string>SampleNET-WPA2PSK</string>
</dict>
<dict>
<key>PayloadCertificateFileName</key>
<string>AAA Certificate Services.cer</string>
<key>PayloadContent</key>
<data>
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYD
VQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAw
DgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGlt
aXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2Vz
MB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezELMAkG
A1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQ
MA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExp
bWl0ZWQxITAfBgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNl
czCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL5AnfRu
4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLN
SS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMi
WPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5
YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsU
K6+3qszWY19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58O
Ad7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cmez6KJcfA3Z3m
NWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8G
A1UdEwEB/wQFMAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDov
L2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFD
ZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUFAAOC
AQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3s
Ag9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz
9vHCv8S5dIa2LX1rzNLzRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYur
DC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z8VlIMCFl
A2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF50
1KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3t
Pxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
</data>
<key>PayloadDescription</key>
<string>Provides device authentication (certificate or identity).</string>
<key>PayloadDisplayName</key>
<string>AAA Certificate Services</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example.credential</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.security.root</string>
<key>PayloadUUID</key>
<string>9B733672-E764-4B5F-9B86-B3D6D5C8E6FE</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Sets up Wi-Fi for all users that will connect at loginwindow.</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi Example</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>228420C8-9D51-4171-BD98-A37A7E8906C1</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

1. To have the Wi-Fi networks installed into System.keychain, add this key to each Wi-Fi network’s dict, underneath the SSID_STR key.

<key>SetupModes</key>
<array>
<string>System</string>
</array>

view raw
gistfile1.xml
hosted with ❤ by GitHub

2. To tell the computer to connect to these Wi-Fi networks at the loginwindow in addition to when users log in, add this key to the main dict, underneath the PayloadRemovalDisallowed key.

<key>PayloadScope</key>
<string>Loginwindow</string>

view raw
gistfile1.xml
hosted with ❤ by GitHub

The resulting .mobileconfig should look like this:

<?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">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>AutoJoin</key>
<true/>
<key>EAPClientConfiguration</key>
<dict>
<key>AcceptEAPTypes</key>
<array>
<integer>25</integer>
</array>
<key>EAPFASTProvisionPAC</key>
<false/>
<key>EAPFASTProvisionPACAnonymously</key>
<false/>
<key>EAPFASTUsePAC</key>
<false/>
<key>PayloadCertificateAnchorUUID</key>
<array>
<string>9B733672-E764-4B5F-9B86-B3D6D5C8E6FE</string>
</array>
<key>UserName</key>
<string>SampleUser</string>
<key>UserPassword</key>
<string>SamplePass</string>
</dict>
<key>EncryptionType</key>
<string>WPA</string>
<key>HIDDEN_NETWORK</key>
<false/>
<key>PayloadDescription</key>
<string>Configures wireless connectivity settings.</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi (SampleNET-WPA2E)</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example.wifi</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>FB096D71-25B9-418B-82CB-FB9BD0707B23</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProxyType</key>
<string>None</string>
<key>SSID_STR</key>
<string>SampleNET-WPA2E</string>
<key>SetupModes</key>
<array>
<string>System</string>
</array>
</dict>
<dict>
<key>AutoJoin</key>
<true/>
<key>EncryptionType</key>
<string>WPA</string>
<key>HIDDEN_NETWORK</key>
<false/>
<key>Password</key>
<string>SamplePass!</string>
<key>PayloadDescription</key>
<string>Configures wireless connectivity settings.</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi (SampleNET-WPA2PSK)</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example.wifi1</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>484F40AD-DE85-4851-A565-608E069350C6</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProxyType</key>
<string>None</string>
<key>SSID_STR</key>
<string>SampleNET-WPA2PSK</string>
<key>SetupModes</key>
<array>
<string>System</string>
</array>
</dict>
<dict>
<key>PayloadCertificateFileName</key>
<string>AAA Certificate Services.cer</string>
<key>PayloadContent</key>
<data>
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYD
VQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAw
DgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGlt
aXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2Vz
MB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezELMAkG
A1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQ
MA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExp
bWl0ZWQxITAfBgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNl
czCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL5AnfRu
4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLN
SS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMi
WPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5
YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsU
K6+3qszWY19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58O
Ad7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cmez6KJcfA3Z3m
NWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8G
A1UdEwEB/wQFMAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDov
L2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFD
ZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUFAAOC
AQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3s
Ag9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz
9vHCv8S5dIa2LX1rzNLzRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYur
DC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z8VlIMCFl
A2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF50
1KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3t
Pxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
</data>
<key>PayloadDescription</key>
<string>Provides device authentication (certificate or identity).</string>
<key>PayloadDisplayName</key>
<string>AAA Certificate Services</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example.credential</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.security.root</string>
<key>PayloadUUID</key>
<string>9B733672-E764-4B5F-9B86-B3D6D5C8E6FE</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Sets up Wi-Fi for all users that will connect at loginwindow.</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi Example</string>
<key>PayloadIdentifier</key>
<string>com.keeleysam.wifi.example</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadScope</key>
<string>Loginwindow</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>228420C8-9D51-4171-BD98-A37A7E8906C1</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

As DeployStudio and Munki cannot currently install profiles themselves, a payload-free package should be created with it, using this command to install as a device profile:

/usr/bin/profiles -I -F WiFi.mobileconfig

view raw
gistfile1.sh
hosted with ❤ by GitHub

Here is an example of a postflight script to use to install this profile:

#!/bin/sh
#############################################################################
#
# wifi profile install script
# Version 1.0.1, 2013-03-05
# Samuel Keeley, [email protected]
#
#############################################################################
# Getting package root path.
# Root path is given as $1 argument with bundle's path.
root_path="$1"
echo "Package root path: ${root_path}"
echo Currently installed profiles
sudo /usr/bin/profiles -L
echo installing wifi profile
sudo /usr/bin/profiles -I -F "${root_path}/Contents/Resources/WiFi.mobileconfig"
echo Currently installed profiles
sudo /usr/bin/profiles -L
exit 0

view raw
gistfile1.sh
hosted with ❤ by GitHub

If installing with DeployStudio, be sure to mark it as a postponed installation, as the profiles command can only install on the currently booted disk. Adding this resulting package to your current DeployStudio or other thin/no-imaging workflow will make the machine connect to your Wi-Fi network and bootstrap with Munki, no Ethernet required.

Samuel Keeley

Samuel Keeley can frequently be found in ##osx-server on Freenode, or on Twitter @keeleysam.

More Posts - Website

Follow Me:
Twitter

Tags:

5 Comments

  • What if I still need or want to provide user credentials, instead of a predefined password for a specific network, eduroam for instance?
    Can this somehow be tweaked so that a prompt for username and password is provided “above” the loginwindow or somesuch?

    Thanks in advance!

  • Thank you for your post, will test!

  • Dear Samuel
    Thank you for your great article. It is great to adapt the xml but I have one question. I would love to sign or even encrypt the profiles after changing them so that I can be sure the profile is the right version. Of course IPCU does not import manipulated profile neither does profile manager. Do you know some “terminal/bash”-magic or any other way to at least sign profiles?
    Thank you so much for your help in advance!
    Mike

    • You can use the PayloadVersion key to ensure that it is the correct version. Signing is possible, but encryption is unfortunately not supported for these profiles.

  • Hello Samuel,

    I believe I followed your instructions but it does not work. I do not have the login window and the the profile disappear for each new user. it does not stay in the profile preference !
    Any advices, ideas ?

    thanks

Leave a reply

You must be logged in to post a comment.