Fixlet - Ping Remote Server

Hi Guys,

I am working on deploying an application that once installed, it needs to register the computer with a remote server. If the endpoint is in a remote network, home or hotel, and cannot reach the server, it will be useless.

therefore, I would like to create an if statement before starting to install the application. For example,

if {ping remote server successful on port 12345}
msiexec /i setup.exe /qn
endif

Can someone provide me with a good method for doing this fixlet?

@lions1855, because the relevance language is read-only, you cannot execute a command like “ping” within substitution relevance (like your example above) or inline content relevance.

There are a couple options with a use case like this. For example:

  1. An infinitely reoccuring policy fixlet that populates a property in a custom analysis on some interval with the ping. Your MSI installer would then leverage that ping property contains the desired value to proceed.
  2. Expand the scope of your MSI installer fixlet to include execution of the prerequisite ping commands to determine if on-network or VPN to proceed with software installation. Said fixlet would then repeat on some interval until software has been installed. If not on network, the fixlet simply exists without installing.
  3. Create a new fixlet that tests the ping condition. Add ping fixlet and MSI installer fixlet to new baseline. Make sure to uncheck the “Run all member actions of action group regardless of error” so that the ping failure stops the MSI execution.

Assuming that you proceed with option #2 or #3, make sure that the “Reply this action” on the “Execution” tab for the new action is set correctly.

I hope the above is helpful.

One choice might be to look at things like “DNS Servers”, “DHCP Servers”, etc to try and determine if the client is “Inside” your network or not. I find that DHCP and DNS Servers tend to not have too many instances inside even large networks.

DNS Servers (Windows)
Q: (addresses of dns servers of network)

DHCP Server (Windows)
Q: if (exists adapter whose (address of it != "0.0.0.0" AND dhcp enabled of it) of network) then (dhcp servers of adapters whose (address of it != "0.0.0.0") of network as string) else "n/a (Static IP)"

Tim,
This is really good stuff. Now, I am concern about the machine being outside of the organization network, like connecting from a home wireless or hotel. I would like to include in the fixlet statement like an if (exist or in other words, the end-user’s computer can reach the public ip of our organization’s server. Then, if it is true, to continue with running the fixlet script.

if {ping remote server successful on port 12345}

I wanted to chime in here on a sidebar as a former network guy.
“Ping,” you should expect me to say, “doesn’t use ports.”
And then you should expect another former network dude to bring up UDP ping, followed by a flamewar.
So, while all that is true (besides the flamewar), nobody else cares. We want a ping that uses ports, and usually that means TCP.

Most UNIX/LINUX versions have a “tcping” package in their repo, if not in their install. For Windows, a fellow named “Eli Fulkerson” wrote a TCPing that works great. But if you can’t use third-party software on Windows, the next-best thing is Powershell’s “Test-NetConnection” which has an alias of “tnc”.

TCPing gives you output very, very similar to just Ping. Test-NetConnection/tnc is much less useful, especially across spotty connections (which, these days, very few people have), but on the upside tries both a TCP SYN handshake and an ICMP Ping. Especially on a LAN, this can help you determine when the host is up but the service on it is not (TCP fails, so service is down, but ICMP succeeds).

I’m no BigFix pro, but I can imagine a couple ways you could retrieve the results of these tools to tell functionally have BigFix ping a server on a port for you.

2 Likes

Oryx, This is exactly what i was looking for. Thanks I know enough about network and commands. But, I am still learning how the fixlet works inside bigfix, and the syntax.

All great points! I was going to chime in with similar, and I was actually building content to use Test-NetConnection to solve a customer problem…only to find that we have bigger problems too.

Testing the TCP SYN alone is not enough in some cases. Layer-4 firewalls, that do protocol inspection will allow TCP SYN to connect (so Test-NetConnection is successful), but then send resets and block connections when they don’t like the protocol (so BigFix fails).

Test-NetConnection may work fine in some/most deployments, but in other cases we may need to actually download a file from the relay to be sure everything is allowed at layer-4. More info on that to come.

1 Like

Back to the original use case, what happens if you try to install and can’t reach the server? Does msiexec roll back with an error code? Might be easiest to just try the install, let it fail, and track {exit code of action} for status and retry/reapply options on the action to retry later.

1 Like

Additional options for testing ports would include Wget or curl if it is a web-based port. Microsoft’s PortQry tool is also very useful on Windows systems.

Example syntax:
PortQry.exe -n TARGET -p udp -e 135 -sl -l c:\temp\logfile.log
PortQry.exe -n TARGET -p tcp -e 445 -sl -l c:\temp\logfile.log
continue if {exists file “c:\temp\logfile.log” whose (content of it contains “LISTENING”)}

We have a policy that runs all the time and repeats every 24 hours.

The issue was, we have internal and external Relays. The masthead has our base url, 'bigfix.mycompany.com'

That url resolves to two different relays, one of the internel and one of the external for remote systems. So when a system says it is connected to 'bigfix.mycompany.com' as it's relay, we don't know what is is connected to.

So the policy above has a batch script to ping 'bigfix.mycompany.com' and log the results in the registry. Our task looks like this, and is only relevant to windows systems

createfile until _endIPget_
@ECHO OFF
setlocal enabledelayedexpansion enableextensions
CLS
FOR /F "usebackq tokens=1,2,3* delims=[]" %%i IN (`ping -n 1 bigfix.mycompany.com^|Find "Pinging"`) DO (
REG ADD "HKLM\Software\My-Co" /v bigfix.mycompany.com /d "%%j" /t REG_SZ /reg:64 /f >NUL
)
GOTO :EOF
_endIPget_

folder delete "c:\Installers\My-Coinstallers\GetBFIP"
folder create "c:\Installers\My-Coinstallers\GetBFIP"

copy __createfile "C:\Installers\My-Coinstallers\GetBFIP\getpatchIP.bat"
waithidden "C:\Installers\My-Coinstallers\GetBFIP\getpatchIP.bat"
delete __createfile
folder delete "c:\Installers\My-Coinstallers\GetBFIP"

Then build a property to retreive the reg entry, HKLM\Software\My-Co value of 'bigfix.mycompany.com'

How will this work for you? Modify the script to ping whichever server or servers you want to check. Multiple servers are good and each will have it's own reg key. Then pull those into a property in Bigfix. We run ours once a day.

1 Like

Very nice!

In a related vein, I have an Analysis that creates some properties using the RelayChain text files that are generated on the client. While the client's 'Relay' property reflects the relay name as it appears on the client, the results in the RelayChain file reflect both the Relay's computername (as it reports itself), and the relay's Computer ID. In my experience, the RelayChain reports are correct regardless of DNS games, NAT translations, fake-root / last-fallback-relay, etc.

I think in most cases one would only care to keep one or two of these properties, but once I get started sometimes it's hard to stop.

Most Recent Registration Information

/* filename/date, time, Success/Failure, Server, Relay Path, Client */ (tuple string item 0 of it, following text of first " " of tuple string item 1 of it, tuple string item 2 of it, tuple string item 3 of it | "none", unique value of concatenation of tuple string items whose (it starts with "r:") of it | "none", tuple string item (number of tuple string items of it - 1) of it ) of (tuple string of (name of it; substrings separated by " - " of lines (maximum of line numbers of lines of it) of it)) of items 0 of (files of it, maximum of modification times of files of it) whose (modification time of item 0 of it = item 1 of it) of folders "RelayChain" of folders "__Global" of data folders of clients

Most Recent Registration Attempt

following text of last "|" of preceding text of last "|" of ("|" & it & "|") of concatenation "|" of (item 0 of it & "::" & item 1 of it) of ( name of it, lines of it) of files of folders "RelayChain" of folders "__Global" of data folders of clients

Most Recent Registration Success

(following text of last "|" of preceding text of last " - S - " of it | "NoSuccess", preceding text of first "|" of following text of last " - S - " of it|"NoSuccesses") of ("|" & it & "|") of concatenation "|" of (item 0 of it & "::" & item 1 of it) of ( name of it, lines of it) of files of folders "RelayChain" of folders "__Global" of data folders of clients

Most Recent Registration Failure

(following text of last "|" of preceding text of last " - F - " of it | "NoFail", preceding text of first "|" of following text of last " - F - " of it|"NoFailures" ) of ("|" & it & "|") of concatenation "|" of (item 0 of it & "::" & item 1 of it) of ( name of it, lines of it) of files of folders "RelayChain" of folders "__Global" of data folders of clients

Most Recent Relay Chain

tuple string of tuple string items whose (it starts with "r:" or it starts with "s:") of tuple string of substrings separated by " - " of following text of last "|||" of ("|||" & it ) of concatenation "|||" of lines containing " - S - " of files of folders "RelayChain" of folders "__Global" of data folders of clients

Relay Chain: Direct Parent Relay

tuple string items (number of tuple string items of it - 1) of tuple string of tuple string items whose (it starts with "r:" or it starts with "s:") of tuple string of substrings separated by " - " of following text of last "|||" of ("|||" & it ) of concatenation "|||" of lines containing " - S - " of files of folders "RelayChain" of folders "__Global" of data folders of clients

Relay Chain: Ancestor Relays

tuple string items (integers in (0, number of tuple string items of it - 2)) of tuple string of tuple string items whose (it starts with "r:" or it starts with "s:") of tuple string of substrings separated by " - " of following text of last "|||" of ("|||" & it ) of concatenation "|||" of lines containing " - S - " of files of folders "RelayChain" of folders "__Global" of data folders of clients

edit: these concatenate together all the lines of all the RelayChain files, to cover an edge case that occurs after midnight rollover, where the current registration is in yesterday's file because a new selection has not yet occurred today. The relevance to join these lines is quite performant so it wasn't really worth it to me to limit to just the yesterday and today's files.

2 Likes

Would using _BESCLIENT_Relay_NameOverride affect this?

I only ask because all of our relays are using name override because we are multi-tenant

I even have a task that will set the nameoverride on new relays when they are installed.

I'm actually not sure on that point, I'll need to check that out.