Posted on 11-17-2014 12:13 PM
So my goal here is to create a simple extension attribute that will tell me whether a device is on or off the network. Given the wide swath of 10.x.x.x IPs that we use here (some are internal on the network, others are guest off the network), and the logic to that is hard to boil down easily, I have decided to go at this with an extension attribute.
Basically the extension attribute would go something like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE extensionAttribute PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<extensionAttribute>
<displayName>On the network or not</displayName>
<displayInCategory/>
<dataType>string</dataType>
<description>This Extension Attribute will let me know whether it is possible to ping a specific only on the network site. If the device cannot ping this site, then it is off the network.</description>
<scriptContentsMac>#!/bin/sh
# my goal here is to send 2 pings to a given internal server. I know a status of 0 on exit means I can successfully ping the server. I just don't know how to write this syntax
if [ /sbin/ping -c 2 'myinternalserver.local' HELP NEEDED HERE TO WRITE SYNTAX, IF THIS PING EXITS WITH A 0 STATUS ] ; then
/bin/echo "on the network"
else
/bin/echo "off the network"
fi
exit</scriptContentsMac>
</extensionAttribute>
Posted on 11-17-2014 12:30 PM
Here is what I use to test connection to my JSS, you can tweak this for other ports or servers:
connTest() {
ncTest=`nc -z -w 5 $JSS 8443 > /dev/null; echo $?`
if [ "$ncTest" -eq 0 ]; then
log "JSS Reachable"
else
log "JSS Not Reachable, exiting"
exit 0
fi
}
Posted on 11-17-2014 12:36 PM
No need to check exit status for a ping.
Something like this should work:
if [[ $(ping -c 2 -o 'myinternalserver.local') ]]; then
echo "on the network"
else
echo "off the network"
fi
BTW, the -o flag tells it to exit the pings as soon as it receives a successful response, so it should "lighten" the Extension Attribute script a little (not that pings are anything to be concerned with)
Posted on 11-17-2014 12:36 PM
Here's mine as well. I haven't used nc.
#!/bin/bash
SERVER="www.google.com"
function pingServer()
{
pingResult=$(ping -c 2 "$SERVER")
if [ -z "$pingResult" ]; then
result="off the network."
elif [ ! -z $(echo $pingResult | grep "Request timeout") ]; then
result="off the network."
else
result="on the network."
fi
}
pingServer
echo "<result>$result</result>"
exit 0
Posted on 11-17-2014 01:01 PM
So, I would need to know more about the specifics you are trying to do, but I don't know if I think network state as an extension attribute is the best solution. Since extension attributes are only updated on recon, if you don't have your JSS available externally, the attribute will always show as being on network. But even if your JSS is reachable externally, network state can change multiple times between scheduled recons, especially in a VPN setting, so the extension attribute is likely to always be out of date.
Instead, I might suggest that you scope the policy to machines regardless of network state, and then build code into the script to determine action based on network state. Here is the code I use in several scripts:
VerifyConnection(){ curl -L -s -o /dev/null --silent --head --write-out '%{http_code}' "$FilerURL/" --location-trusted -X GET; }
If the website "$FilerURL/" (for bonus points, you could set the variable to $4-$11 and define those in the JSS interface) is online, then the above function will return "200". If it's not available, then you'll get the usual 403, 404, 500, etc.
One of the additional benefits of this method as you are testing not only for the client to have a viable route to the service, but also that the service is running on the server. My function works for HTTP services, if I needed to test SMB, FTP to other protocols (or any connection other than the usual web ports), I would agree with those recommending NetCat above. I would avoid Ping as it simply doesn't tell you enough about the state of the service.
Posted on 11-17-2014 02:40 PM
Thank everyone for the help.
To give context, JSS is both external and internal. Distribution point is not. Up until recently, we didn't really care, but now I need policies to run both places except for ones that install packages. On those I wish to exclude off the network macs so the policy doesn't show as failed to run. Ideas welcome. Distribution point is traditional AFP share right now. I figured the extension attribute method would work since the alternative would be scoping around network segments (which is a bag of hurt on our network)
Posted on 11-17-2014 03:01 PM
The solution I would use requires nested policy.
First, create a policy to deploy the package, scoped to all computers, ongoing, with a custom trigger.
Second, create a policy, scoped to all machines missing the software in question, schedule unimportant, on a recurring checkin. The second policy runs a script that checks for network connectivity to the distribution point, and if it can connect, it then fires off the custom trigger for the first policy.
Use the FIRST policy, not the second, for your metrics/logs.