Create a Post
cancel
Showing results for 
Search instead for 
Did you mean: 
Bob_Zimmerman
Authority
Authority

Run a command on each firewall via CPRID

I recently needed to collect some information from every firewall in my environment. I have an MDS and a couple of SmartCenters managing a bunch of firewalls, so decided to try using CPRID to collect this. I put together a script which others may find useful:

 

unset cmaList
cmaList=$(mgmt_cli -r true -f json show domains limit 500 details-level full \
| jq -c '.objects[]|{name:.name,server:.servers[]|{host:."multi-domain-server",ipAddress:."ipv4-address"}}' \
| grep $(hostname) \
| jq -c '[.name,.server.ipAddress]')
if [ ${#cmaList} -eq 0 ];then cmaList=("[\"$(hostname)\",\"\"]");fi
for cmaRow in $cmaList; do
cmaName=$(echo "${cmaRow}" | jq '.[0]' | sed 's#"##g')
cmaAddress=$(echo "${cmaRow}" | jq '.[1]' | sed 's#"##g')
mdsenv "${cmaAddress}" 2>/dev/null
firewallList=$(mgmt_cli -f json -d "${cmaAddress}" -r true show gateways-and-servers limit 500 details-level full \
| jq -c '.objects[]|{type:.type,address:."ipv4-address"}' \
| grep -v CpmiGatewayCluster \
| grep -v CpmiVsClusterNetobj \
| grep -v CpmiVsxClusterNetobj \
| grep -v "checkpoint-host" \
| jq -c '.address' \
| sed 's#"##g')
for firewall in $firewallList; do
printf "%15s %15s: " "${cmaName}" "${firewall}"
cprid_util -verbose -server "${firewall}" rexec -rcmd sh -c '
########################################################################
### Commands go here
########################################################################
'
done
done

 

An earlier version of this post had two scripts, one for an MDS and one for a SmartCenter. This script should work on either.

It works with up to 500 CMAs, and up to 500 Check Point objects (a cluster consumes an object for the cluster and an object for each member). It finds all the firewalls and runs the commands you specify on them. Replace the comment block with the command you want to run everywhere. Here are a few I've found interesting:

 

### Name, version, and uptime:
printf "%-25s %-6s %3s  " \
$(hostname) \
$(fw ver | awk "{print $7}") \
$(cpinfo -y fw1 2>/dev/null | grep Take | awk "{print $NF}")
echo -n $(uptime | cut -d, -f1)



### Name and GAIA API status.
printf "%-25s " $(hostname)
echo -n $(gaia_api status 2>/dev/null | grep Overall)



### Look for firewalls which have fwkern.conf
printf "%-25s " $(hostname)
echo -n $(ls $FWDIR/boot/modules/fwkern* 2>/dev/null)

 

If the management can't talk to the firewall via CPRID for whatever reason (for example, if the firewall is in FIPS mode, which disables CPRID), it will print "(NULL BUF)" for that firewall.

 

I've taken to running the first one when I start work in the morning to catch up on any upgrades other people on the team have done.

9 Replies
Danny
Champion Champion
Champion

Thanks. Your code looks longer than it might be required. My version:

echo;for i in `grep 'sic_name\|ipaddr' $FWDIR/conf/objects.C|grep -A1 sic_name|grep 'ipaddr '|tr -d ':ipadr ()\t'`;do cprid_util -server $i -verbose rexec -rcmd /bin/bash -c "hostname;cat /etc/cp-release";done

 

0 Kudos
Bob_Zimmerman
Authority
Authority

That script depends on objects.C existing, which isn't guaranteed in future versions. It doesn't work over all the CMAs on a box, doesn't provide feedback on which devices failed (just that a device failed), and tries to run commands on OPSEC servers. It also doesn't play especially well with commands you want to run remotely which require quotes or dollar signs (for example, using awk to print the contents of a particular column of remote output).

Mine could definitely do with some more smarts to auto-size the CMA column, for example. Overall, though, I think it's pretty good.

0 Kudos
Danny
Champion Champion
Champion

Nothing is guaranteed in the future. My code works well for all environments I've tested it in. I've rarely seen someone using OPSEC servers. Also your concern regarding quotes or dollar signs is invalid as this can be simply avoided by base64 encoding the remote commands. I use this feature in many of my SmartConsole Extensions and in ccc. I also don't see why CMAs wouldn't work. Btw, they are called MDSs for many years now. Maybe just the objects.c location would need to be adjusted after mdsenv into the specific MDS environment.

0 Kudos
Bob_Zimmerman
Authority
Authority

I'm aware the top level is called an MDS. That's why I called it an MDS. When run on an MDS, that smaller script only runs in the current environment. It doesn't run over the CMAs which are on that MDS. Nice if you want to get data only for that CMA, but needs an additional loop if you want to iterate over all the CMAs on the box.

It doesn't provide feedback on what it's trying to do, which provides important context for failures. For example, here's slightly redacted output from one of my CMAs:

vsxMember2
Check Point Gaia R80.20

vsxMember1
Check Point Gaia R80.20

(NULL BUF)
(NULL BUF)
(NULL BUF)
(NULL BUF)
(NULL BUF)
(NULL BUF)

Which devices did it fail to talk to? By changing 'do cprid_util' to 'do echo "$i:";cprid_util', I found that it tries to connect to a bunch of VSs and switch contexts, but those fail silently because their IP address is 0.0.0.0. It tries to connect to the standby CMA, but that CMA's representation in objects.C has the IP address before the SIC name, so the 'grep -A 1 sic_name' instead gets the IP address of some random other object which happens to be next in the file. Same thing happens with my CLMs and my SmartEvent server. My firewall in FIPS mode at least gets an address from its topology table, but it's nowhere close to the right one. These connections fail, which wouldn't ordinarily be a problem, but now my logs show my management server trying to connect out to things it isn't managing. That makes people in my SOC ask if the MDS has been compromised.

Here's the output from mine trimmed down to the same CMA:

     myFirstCMA     10.20.30.41: vsxMember1                R80.20 211  11:12:13 up 61 days
     myFirstCMA     10.20.30.42: vsxMember2                R80.20 211  11:12:14 up 61 days
     myFirstCMA     10.20.30.44: (NULL BUF)
     myFirstCMA     10.20.30.45: (NULL BUF)

Shorter, with context for the failures. It also got the right IP address for the members of my firewall in FIPS mode. If I wanted to run commands via CPRID on a standby SmartCenter, a log server, or a SmartEvent server, the shorter script would just fail, since it's getting IPs for completely incorrect objects. My script could be easily modified to do so by removing the '| grep -v "checkpoint-host" \' line.

0 Kudos
hGhim9148
Explorer

Hello Bob, 

I am quite newbie to checkpoint and learning it.  May I ask what the differences  between CpmiVsClusterNetobj vs CpmiVsxClusterNetobj ?

 

0 Kudos
Bob_Zimmerman
Authority
Authority

CpmiVsxClusterNetobj is the VSX cluster itself. It's the SmartConsole object to represent VS 0.

CpmiVsClusterNetobj is the object you see in SmartConsole for all non-0 VSs. It's technically a cluster object with a member for each member of the VSX cluster, but the members of the VS cluster object don't show up via the API.

In this particular context, I'm trying to run a command on each physical device to check the version, for example. Cluster objects aren't physical devices, so I want to remove them from the list of candidates I feed to the later step.

0 Kudos
Sven_Glock
Advisor

Nice one! I will combine it with my old objects.c oriented script.

Instead of fetching the cmas via API I am using "$MDSVERUTIL AllCMAs". It is much faster, but I am not sure if this command will survive upcoming version. I guess your API way is the more future oriented one 😉

Moreover I have dialog which gives me the option to choose between getting the data from the database our using a cache which is filled once your run the script the first time or every time you are using the option "database".
The cache file has all data to run without database. As we do not add new gateways so often using the cache is the fastest way for me to execute commands.

0 Kudos
Bob_Zimmerman
Authority
Authority

The API commands are fast enough and I need few enough of them that I didn't find adding a cache to be worth taking on the invalidation problem. Computer time is cheap, and development time is not.

I really should spend the time to figure out a good way to handle more than 500 objects. It's not common to have more than 100 clusters in a CMA, but it's definitely possible. The gateways-and-servers count blows up rapidly with VSX.

0 Kudos
Bob_Zimmerman
Authority
Authority

I have a new version which solves several issues.

  • Added support for the API running on non-default ports.
  • Added support for over 500 CMAs and for over 500 firewall objects within a CMA.
  • Improved how the script to run on each system is defined. It's now a heredoc at the top of the script block, and it's literal, so you no longer need to play around with any weird quoting. Run commands on one firewall, then you can copy them exactly into this script to run on every firewall.
  • Improved reporting of connectivity errors. Now, instead of "(NULL BUF)", a connectivity failure will result in "[Couldn't connect via CPRID]".
scriptFile=$(mktemp)
cat << 'EOF' > "${scriptFile}"
########################################################################
printf "%-25s %5s %-6s %3s %-20s" \
$(hostname) \
$(clish -c "show asset system" | egrep -q "^Model";if [ $? -eq 0 ];then clish -c "show asset system" | egrep "^Model" | awk '{print $NF}';else clish -c "show asset system" | egrep "^Platform" | cut -d" " -f2 | cut -c 1-5;fi) \
$(fw ver | awk '{print $7}') \
$(jumbo=$(cpinfo -y fw1 2>/dev/null | grep JUMBO | grep Take | awk '{print $NF}');echo "${jumbo:-0}") \
"$(uptime | cut -d, -f1 | xargs)"
########################################################################
EOF

unset cmaList cmaAddress
. /etc/profile.d/CP.sh
portNumber=$(api status | grep "APACHE Gaia Port" | awk '{print $NF}')
showAll() {
IFS=$(printf "\377")
sharedArguments=( --port ${portNumber} -f json ${cmaAddress:+-d} ${cmaAddress:+${cmaAddress}} -r true show "$1" details-level full limit 500 )
firstResult=$(mgmt_cli ${sharedArguments[@]})
if [ $? -ne 0 ];then return 1;fi
toReturn="$(echo "${firstResult}" | jq -c '.objects[]|.')
";objectCount=$(echo "${firstResult}" | jq -c '.total')
if [ "$objectCount" -lt 501 ];then echo "${toReturn}" | head -n -1;return 0;fi
for offsetVal in $(seq 500 500 "${objectCount}" 2>/dev/null | tr "\n" "$IFS");do
toReturn+="$(mgmt_cli ${sharedArguments[@]} offset "${offsetVal}" \
| jq -c '.objects[]|.')
";done;echo "${toReturn}" | head -n -1;}
cmaList=$(showAll domains \
| jq -c '{name:.name,server:.servers[]|{host:."multi-domain-server",ipAddress:."ipv4-address"}}' \
| grep $(hostname) \
| jq -c '[.name,.server.ipAddress]')
if [ ${#cmaList} -eq 0 ];then cmaList=("[\"$(hostname)\",\"\"]");fi

for cmaRow in $cmaList; do
cmaName=$(echo "${cmaRow}" | jq '.[0]' | sed 's#"##g')
cmaAddress=$(echo "${cmaRow}" | jq '.[1]' | sed 's#"##g')
mdsenv "${cmaAddress}" 2>/dev/null
firewallList=$(showAll gateways-and-servers \
| jq -c '{type:.type,address:."ipv4-address"}' \
| grep -v CpmiGatewayCluster \
| grep -v CpmiVsClusterNetobj \
| grep -v CpmiVsxClusterNetobj \
| grep -v "checkpoint-host" \
| jq -c '.address' \
| sed 's#"##g')
for firewall in $firewallList; do
printf "%15s %15s: " "${cmaName}" "${firewall}"
cprid_util -server "${firewall}" putfile -local_file "${scriptFile}" -remote_file "${scriptFile}" -perms 500
if [ "$?" == "0" ];then
cprid_util -verbose -server "${firewall}" rexec -rcmd sh -c "${scriptFile};rm ${scriptFile} >/dev/null 2>/dev/null"
else echo "[Couldn't connect via CPRID]";fi
done;done;rm "${scriptFile}"

I've split it into three parts. The top is where you define the script you want to run on every system. This is the only part you should need to change to use the script.

The second gets the management API port number, defines a function to get all instances of a given type of object (this is what got rid of the 500 object limitation), gets all of the CMAs, and makes a fake CMA if it's running on a SmartCenter. If you're running the script a bunch of times, you should only need to run this part once each time you log in.

The third part connects to each CMA and gets a list of all of the firewalls in that CMA. It then goes through the list one by one and tries to copy the script to run to that system. If the copy works, it then tries to run it, then delete it. If the copy doesn't work, it prints the error message to tell you it couldn't connect, then moves on.

(1)

Leaderboard

Epsum factorial non deposit quid pro quo hic escorol.

Upcoming Events

    CheckMates Events