Block specific wireless network.

easyedc
Valued Contributor II

Is anyone out there successfully blocking your Macs from joining specific wireless networks? We have a public guest network and a hidden production network and would like to block workstations from connecting to our guest network and force them to our prod network.

12 REPLIES 12

rhoward
Contributor

We are using a configuration profile to force the computers to default to one network. You could restrict the PreferencePane for Network and hide the icon using something like:

/usr/libexec/PlistBuddy -c 'Delete :menuExtras:1' ~/Library/Preferences/com.apple.systemuiserver.plist
killall SystemUIServer

easyedc
Valued Contributor II

@rhoward That doesn't work for us. We only want them to not join our guest wireless when at the office. These are mostly laptops, and thus travel, and we would want to allow access to network controls to be able to join wifi when off-premises/travel/etc.

mm2270
Legendary Contributor III

Most effective way to do something like this would be with a NAC based solution, but that's a large-ish project to implement. We've been working with a NAC vendor here for similar functionality, and compliance checking for our corporate Wi-Fi, for close to a year now, and we're only now getting to the full deployment stage, so, lots of testing to do with any NAC solution.

Another possible way would be to have a LaunchDaemon monitor network changes, have the script check to see if the current Wi-Fi connection is on your Guest network and if so, drop the connection and force a connection back to the regular Wi-Fi AP name. And if necessary, delete any saved network setting (preferred wireless networks) from the Mac.

jrwilcox
Contributor

We have an extension attribute that records SSID's and then policy to delete networks we do not want users to use.

bpavlov
Honored Contributor

@jrwilcox Would you be willing to share the extension attribute and the script (I imagine you use a script) to remove the unwanted networks via policy?

TomH
New Contributor III

You could run a policy / launchD to check the current SSID against a banned SSID, and if they match disassociate the user and remove the SSID from Preferred Networks.

It won't stop users manually re joining the network, but if you run it on a fairly regular basis I'm sure they will soon get bored / won't notice its switched back to the corporate network.

Here's an example that produces a CLI Tool that you can run, would need some checking for production but should work as a PoC. It will disassociate them, remove the SSID from Preferred Networks at which point the Mac will simply revert to the next best network in its preferred networks list / profile.

TJH:bin tom$ sudo /Users/tom/Library/Developer/Xcode/DerivedData/bannedWifi-faxfdmfmywrgllbkuccsxyxygkts/Build/Products/Debug/bannedWifi "Premier Inn Ultimate Wi-Fi" Current SSID is Premier Inn Ultimate Wi-Fi Banned SSID is Premier Inn Ultimate Wi-Fi Disconnecting from Banned SSID Removing from Preferred Networks 0 TJH:bin tom$
//
//  main.swift
//  bannedWifi
//
//  Created by Thomas Holbrook on 05/10/2015.
//  Copyright © 2015 Thomas Holbrook. All rights reserved.
//

// Banned WiFi CLI App
// Bored in a hotel with SSID "Premier Inn Ultimate Wi-Fi"

import Cocoa
import CoreWLAN
import Foundation

let iface = CWWiFiClient.sharedWiFiClient().interface()?.interfaceName


func getCurrentSsid() -> String?


{
    //We should check wifi if up here!
    return CWWiFiClient.sharedWiFiClient().interface()!.ssid()
}

func getBannedSsid() -> String?

{
    //We should check that this argument exists, and if not return a help?
    return Process.arguments[1]
}

//Whats our current SSID?
let currentSSID = (getCurrentSsid())
print("Current SSID is " + (currentSSID)!)

//What Banned SSID have we been passed?
let bannedSSID = (getBannedSsid())
print("Banned SSID is " + (bannedSSID)!)

//Check if our current SSID is banned?
if currentSSID == bannedSSID {

    //If its a banned SSID diconnect the client
    print("Disconnecting from Banned SSID")
    CWWiFiClient.sharedWiFiClient().interface()!.disassociate()

    //Use networksetup to remove the prefered network entry

    let taskCheck = NSTask()
    taskCheck.launchPath = "/usr/sbin/networksetup"
    taskCheck.arguments = ["-removepreferredwirelessnetwork",iface!,bannedSSID!]

    let pipe = NSPipe()
    taskCheck.standardOutput = pipe

    taskCheck.launch()
    taskCheck.waitUntilExit()

    print(taskCheck.terminationStatus)

}

else

{
    print("Allowed SSID Doing Nothing")
}

Maybe a launchd to watch /etc/resolve so it runs on network changes for a more responsive block?

tony_schaps
Contributor

I've had success in the past with actually defining the guest network in the Configuration Profile with "auto join" unchecked but adding manual proxy settings for an imaginary proxy server. So, yes, someone could connect manually, but they would get no Internet, and very, very few folks would know to look in the proxy settings to troubleshoot, they'd just give up. At one point at a school, the reverse proxy pointed to an old Xserve and would bring up a page explaining that the use of the guest network with student iPads was forbidden, and then iOS at that time would switch back to the working network automatically within a few seconds of finding no Internet connectivity. It was pretty cool. Not sure if that all would work with the modern Mac OS X, but at least the first part is worth a try, very simple to set up.

Aaron
Contributor II

I made a similar solution here: https://jamfnation.jamfsoftware.com/discussion.html?id=13347

But basically, as outlined above, the only real solution is to detect and disconnect. There doesn't seem to be any active way to block the ability to connect to it in the first place.

jrwilcox
Contributor

Here is our Extension Attribute:

#!/bin/bash

#  WiFi_Info.sh
#  
#
#  Created by James Wilcox on 5/4/15.
#

#
#  obtain en number for airport device
#

en=$(networksetup -listallhardwareports | egrep -A 2 "(AirPort|Wi-Fi)" | grep Device | awk '{print $2}')

#
#  return list of SSID's in use
#

SSID=$(networksetup -listpreferredwirelessnetworks $en)
echo "<result>$(echo -e "${SSID[@]}" | sed -e 's/^ *//' -e $'s/	/ /' )</result>"

We then have a script that is generalized because we actually have 3 SSID'd that should not be used by District owned devices.

#!/bin/bash

#  WiFi_Info.sh
#  
#
#  Created by James Wilcox on 5/4/15.
#

#
#  obtain en number for airport device
#

en=$(networksetup -listallhardwareports | egrep -A 2 "(AirPort|Wi-Fi)" | grep Device | awk '{print $2}')

#
#  remove SSID passed in 4
#

networksetup -removepreferredwirelessnetwork "$en" "$4"

easyedc
Valued Contributor II

So I should have probably prefaced that I am already searching for workstations that trust our guest network, and remediating as needed. And that we're only concerned about laptops since our iMacs obviously have build in ethernet ports, which we take advantage of. Given 99.9% of our laptops are newer, I made a generalization about en0 being the default wifi port.

#!/bin/sh
wifi=`networksetup -listpreferredwirelessnetworks en0 | grep 'GuestWireless' || echo "No"`
echo "<result>$wifi</result>"

And then cleaning up with

#!/bin/sh
networksetup -removepreferredwirelessnetwork en0 GuestWireless
exit 0

But i think it gets to the point that it's H.A.R.D. to block an SSID without doing some major dancing, or trying to cheat the system with a false positive. A second additional bit of info going is that our workstations get bound to our guest by our local tech support (we're 60K winboxes and only a few hundred macs - so our frontline guys skew windows and "struggle" supporting macs). Tricking the system wouldn't work since they come by when there's a support ticket about wireless issues and join the only network they see, which is our guest network. The answer to that is training, I know.

Last point, I need to get better at searching the JAMF pages. Looks like lots of people have worked at this same issue, but in my haste, I didn't come across some of the things that others have already worked on. Some of you guys have great looking solutions that I would have loved to borrow leverage in my work.

jkuo
Contributor

@easyedc I think you might be able accomplish this with a Configuration profile. Essentially, what you'd do is configure a profile for the SSID you want, but fill in the required security settings with incorrect information.

In this example, I set an SSID, pick a security type, and then pick a bad certificate name that will never show up (unless the cert presented by the wireless controller is called "blahblahblah"). Then when the computer tries to connect to it, it will have a wireless configuration profile looking for that cert but it won't be there.

Just a note, I have not tested this, this is just an idea.

c41bcba2a3aa47d282a5e665b0a9f1e9

TomH
New Contributor III

@easyedc I updated the code for the little util to contain some error checking, and combined it with a launchD that triggers it when the WiFi changes, and in testing it works well as soon as i switch WiFi networks or power on /off it triggers and then around 10 seconds later disconnects and moves onto another SSID in my preferred list with the SSID having been removed from Preferred Networks.

Like you i track and remove bad SSID's through extension attributes, but it would be nice to implement something a little 'quicker'.

Download Here

//
//  main.swift
//  bannedWifi
//
//  Created by Thomas Holbrook on 05/10/2015.
//  Copyright © 2015 Thomas Holbrook. All rights reserved.
//

// Banned WiFi CLI App
// Bored in a hotel with SSID "Premier Inn Ultimate Wi-Fi"

import Cocoa
import CoreWLAN
import Foundation

let iface = CWWiFiClient.sharedWiFiClient().interface()?.interfaceName

// Argument parsing Errors.

let arguments = Process.arguments
let currentSSID = CWWiFiClient.sharedWiFiClient().interface()?.ssid()
let executableName = NSString(string: Process.arguments.first!).pathComponents.last!

func usage() {

    print("")
    print("Usage:")
    print("	(executableName) <banned_ssid> <wait_time>")
    print("")
    print("	(executableName) checks the current SSID against banned SSID")
    print("")
    print("wait_time defines the amount of time we wait for WiFi to settle before executing the check")
    print("")
    print("Where a match is found the client is disassociated and the SSID removed from Prefered Networks")
    print("")
    print("Example - bannedSSID "Tom Tom" 30")
    print("")
    print("Thomas Holbrook - The software is provided "as is", without warranty of any kind")
    print("")
}

//Wait for Wireless to settle.

if arguments.count == 3 {

    var delay = UInt32(arguments[2])
    sleep(delay!)

}

if arguments.contains("-help") || arguments.contains("-h") {
    usage()
    exit(0)
}

else if arguments.count == 1 {
    usage()
    exit(0)
}

else if arguments.count == 2 {
    usage()
    exit(0)
}


else if arguments.count > 3 {
    usage()
    exit(0)
}

else if currentSSID == nil {
    print("Wifi Not Connected to SSID")
    exit(0)
}


let bannedSSID = arguments[1]

let delay = arguments[2]

print("Current SSID is " + currentSSID!)

print("Banned SSID is " + bannedSSID)


//Check if our current SSID is banned?
if currentSSID! == bannedSSID {

    //If its a banned SSID diconnect the client

    print("Disconnecting from Banned SSID")
    CWWiFiClient.sharedWiFiClient().interface()!.disassociate()

    //Use networksetup to remove the prefered network entry

    print("Removing from Preferred Networks")
    let taskCheck = NSTask()
    taskCheck.launchPath = "/usr/sbin/networksetup"
    taskCheck.arguments = ["-removepreferredwirelessnetwork",iface!,bannedSSID]

    let pipe = NSPipe()
    taskCheck.standardOutput = pipe

    taskCheck.launch()
    taskCheck.waitUntilExit()

    print(taskCheck.terminationStatus)
}

else

{
    print("Allowed SSID Doing Nothing")
}

//The End

exit(0)

Here is the launchD:

/Library/LaunchDaemons/uk.co.tomholbrook.bannedSSID.plist

<?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>Label</key>
        <string>uk.co.tomholbrook.bannedSSID</string>
        <key>LowPriorityIO</key>
        <true/>
        <key>ProgramArguments</key>
        <array>
                <string>./usr/local/j24/bannedSSID</string>
                <string>Premier Inn Ultimate Wi-Fi</string>
                <string>30</string>
        </array>
        <key>WatchPaths</key>
        <array>
                <string>/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist</string>
        </array>
</dict>
</plist>