Forum Discussion
Automate ASM "Ready to Be Enforced" Attack Signatures
Hi All,
Problem scenario is this: Multiple F5 ASM deplyoments which use BigIQ to push out updated attack signatures ( works well ) and a 14 day Enforcement Readiness Period. This all works well up to this point, where someone manually has to go and click the "Enforce Ready Entities" button.
That sounds like a minor thing to do, but in an Enterprise it includes change control/PVT etc to do...
...but automating this out as a fortnightly thing should reduce risk and I can do other things.
So I am comfortable with the API, but looking at v13/v14 API I dont see a functionality that can do this for me. Has anyone done this last step to fully utomate attack signature updates ?
In case anyone is still looking for a way to do this, I created a Big-IQ script that can be pushed to your ASM devices. Here's what it does:
- It checks the HA status, and exits the script if the HA status is Standby
- It uses iControl REST to create a file that lists the policy hashes for each of your ASM policies
- It uses a bash for loop to loop through each of your ASM policy hashes, and Enforces Ready Signatures for each policy, and apply each policy
This is a plug-n-play script, so you shouldn't need to modify it at all. I've used it on v15.1.5 and v15.1.8.
------------------------------------------------------------------------------------------------------------------------
# Determines HA Status, creates variable, then loops through it on Active devices
bash
cd /var/tmp/# Static Variables
CREDS=admin# Writes HA Status to a file
tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
chmod 755 /var/tmp/ha-status.txt# Exits script if the HA Status file contains the string STANDBY
if grep -q STANDBY /var/tmp/ha-status.txt; then
exit
fi# Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[]
printf "$FILENAME\n" > /var/tmp/policy-hashes.txtFILENAME="policy-hashes.txt"
LINES=$(cat $FILENAME)# ASM - Enforces Ready Entities and Applies Policies - All Policies
for LINE in $LINES
do
curl -kvu $CREDS -X PATCH "https://localhost/mgmt/tm/asm/policies/$LINE/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -u $CREDS -k -v -H "Content-Type: application/json" -d '{"performStaging":false}' | jq .
LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
sleep 10s
done------------------------------------------------------------------------------------------------------------------------
If you want to exclude specific policies, such as a Parent or Template policy, you can change the line where the FILENAME variable is created to exclude those policies like this:
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | select(.name!="asm_parent") | select(.name!="asm_template") | .id')
- 2BsNimbostratus
Thanks guys, I have managed to run it succesfuly using this script however it seems as it sends the Apply Policy command to all the policies and not only the ones who changed, is it possible to make it apply only at the policies that were changed?
#!/bin/bash
# Determines HA Status, creates variable, then loops through it on Active devices
cd /var/tmp
# Static Variables
CREDS=admin:password
# Writes HA Status to a file
tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
chmod 755 /var/tmp/ha-status.txt
# Exits script if the HA Status file contains the string STANDBY
if grep -q STANDBY /var/tmp/ha-status.txt; then
exit
fi
# Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | .id')
printf "$FILENAME\n" > /var/tmp/policy-hashes.txt
FILENAME="policy-hashes.txt"
LINES=$(cat $FILENAME)
# ASM - Enforces Ready Entities and Applies Policies - All Policies
for LINE in $LINES
do
curl -kvu $CREDS -X PATCH "https://localhost/mgmt/tm/asm/policies/$LINE/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -u $CREDS -k -v -H "Content-Type: application/json" -d '{"performStaging":false}' | jq .
LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
sleep 10s
done
- 2BsNimbostratus
Hello guys,
Thanks for your hard work!
Did you get it to work on v16?
I've been trying to use the scripts but unfortunately none of the works.
- Holy64Nimbostratus
Hi, I run my script in an ssh session on a 16.1.4.1 Big-IP. I have an admin profile.
- DanSkowCirrus
Good morning,
I was able to run the Big-IQ script just now against my lab running v16.1.4.3 without any issues.
Are you running the script from the Big-IQ, or trying to run it locally on the Big-IP? If you're trying to run it locally on the Big-IP, you'll need to update the "CREDS=admin" line to include your admin password. For example, "CREDS=admin:password"
If your password has certain special characters, you'll have to escape them with a backslash. For example, "CREDS=admin:password\!"
If you're pushing it from the Big-IQ, you might be able to figure out the issue by looking at the Big-IQ script log. One common issue is not having Advanced Shell access for the admin user.
Let me know if you're able to find any logs related to the failure or any additional information on how you're running the script.
Thank you,
Dan
- 2BsNimbostratus
Hi Dan!
Thanks for your response.
When I try to run the script it does not show any output.
I run it directly from the BIGIP itself and do have special characters in the password so I added the backslash before each special character but I got the same result.
I am running BIGIP v16.1.4.1
- Holy64Nimbostratus
I would to share my script. We use partitions on our infrastructure. I don't use the standby check status yet but that's good to add that function to my script.
I use has input parameter, all or the the list of partition where you would to enforce signatures ready to be enforced separate by a space. That's because in our case, partitions could be active on node 1 or on node 2.
I put a sleep 20 after requesting the signature enforcement and I checked during maximum 60 seconds for the ASM policy applying success status. The script give detailled information in console.
Tested on BigIP versions 15.1.8 and 14.1.5.
---------------------------------------------------------------------------------------------------# YHO 20220207 ASM staging signature enforcement
# ASM-SignEnforcement.ksh
# v01 yho 20220207
export runUser=${USER}
export logfolder=${HOME}/
export policyList=${logfolder}/PolList.txtif [ "$1" == "" ];
then
echo ------------------------------------------------
echo Partitions list :
tmsh list auth partition one-line | awk '{print $3}' | sed ':a;N;$!ba;s/\n/ /g'
echo ------------------------------------------------
echo Give the option as first parameter
echo Options are :
echo " all : all partition in the above list"
echo " or the partitions list between quotes \"partion list\""
exit 1
else
if [ "$1" == "all" ]
then
export Partis=`tmsh list auth partition one-line | awk '{print $3}' | sed ':a;N;$!ba;s/\n/ /g'`
else
export Partis=$1
fi
fi
echo ------------------------------------------------
echo Signature enforcement for partitions
echo ------------------------------------------------
echo $Partis
echo ------------------------------------------------
echo "sleep 10 seconds - CTRL C to stop"
sleep 10# List policies/policies ID
mysql -uasm -p`perl -MF5::Cfg -e 'print F5::Cfg::get_mysql_password()'` -e "select name, rest_uuid from PLC.PL_POLICIES" > $policyList
sed -i 's/\x09/,/' $policyList
for parti in ${Partis}
do
for pol in `cat $policyList | grep "^\/"`
do
name=`echo $pol | awk -F ',' '{print $1}'`
id=`echo $pol | awk -F ',' '{print $2}'`
echo ${name} | grep "/${parti}/"
if [ $? -eq 0 ]
then
echo ------------------------------------------------
echo Check manual learning $name $id
#restcurl -s -u ${runUser}: /tm/asm/policies/$id/policy-builder?$select=learningMode
restcurl -s -u ${runUser}: /tm/asm/policies/$id/policy-builder?$select=learningMode | grep manual
if [ $? -eq 0 ]
then
# enforce ready to enforce signatures
echo Chek ready to enforce signatures number $name
#restcurl -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true&\$top=1"
restcurl -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true&\$top=1" | grep totalItems
restcurl -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true&\$top=1" | grep 'totalItems.: [1-9]'
if [ $? -eq 0 ]
then
echo Enforce ready to enforce signatures $name
restcurl -X PATCH -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -d '{"performStaging":false}' | grep 'totalItems.: [1-9]'
echo sleep 20 - signature update ongoing
sleep 20
# Apply policy
echo Apply policy $name
TaskId=`restcurl -s -u ${runUser}: -X POST /tm/asm/tasks/apply-policy -d "{\"policyReference\": {\"link\": \"https://localhost/mgmt/tm/asm/policies/$id\"}}" | grep -e "id.:" | sed 's/.*\"id\": \"//' | sed 's/\",.*//'`
echo Apply policy TaskId : $TaskId - $name
# Check policy applied
app=60
echo Check policy applied for max $app seconds for $name
#exit 0
while [ $app -ge 2 ]
do
app=$(($app-1))
restcurl -s -u ${runUser}: "/tm/asm/tasks/apply-policy/$TaskId" | grep COMPLETED
if [ $? -eq 0 ] ; then app=0; fi
sleep 1
done
echo Policy applied COMPLETE if $app = 0 - $name
else
echo No signature to enforce for $name
fi
else
echo Policy not in manual mode $name
fi
echo ==============================================
fi
done
done
# End---------------------------------------------------------------------------------------------------
- DanSkowCirrus
In case anyone is still looking for a way to do this, I created a Big-IQ script that can be pushed to your ASM devices. Here's what it does:
- It checks the HA status, and exits the script if the HA status is Standby
- It uses iControl REST to create a file that lists the policy hashes for each of your ASM policies
- It uses a bash for loop to loop through each of your ASM policy hashes, and Enforces Ready Signatures for each policy, and apply each policy
This is a plug-n-play script, so you shouldn't need to modify it at all. I've used it on v15.1.5 and v15.1.8.
------------------------------------------------------------------------------------------------------------------------
# Determines HA Status, creates variable, then loops through it on Active devices
bash
cd /var/tmp/# Static Variables
CREDS=admin# Writes HA Status to a file
tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
chmod 755 /var/tmp/ha-status.txt# Exits script if the HA Status file contains the string STANDBY
if grep -q STANDBY /var/tmp/ha-status.txt; then
exit
fi# Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[]
printf "$FILENAME\n" > /var/tmp/policy-hashes.txtFILENAME="policy-hashes.txt"
LINES=$(cat $FILENAME)# ASM - Enforces Ready Entities and Applies Policies - All Policies
for LINE in $LINES
do
curl -kvu $CREDS -X PATCH "https://localhost/mgmt/tm/asm/policies/$LINE/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -u $CREDS -k -v -H "Content-Type: application/json" -d '{"performStaging":false}' | jq .
LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
sleep 10s
done------------------------------------------------------------------------------------------------------------------------
If you want to exclude specific policies, such as a Parent or Template policy, you can change the line where the FILENAME variable is created to exclude those policies like this:
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | select(.name!="asm_parent") | select(.name!="asm_template") | .id')
- Jan_LoukotaNimbostratus
Hello,
its awesome :). Could it be please extended a little bit? Because you need to also know which signatures were not ready for enforcement and review those. Those are possible attacks and you do not consider such situation.
Thank you
Best regards
- DanSkowCirrus
I'm glad the script works for you 🙂
When a new batch of signatures is released, they should be reviewed to determine if there's a reason to enforce them before they complete their staging period. For example, when the Log4j and most other critical signatures are released, I've followed a different process.
First of all, my environment has a separate Signature Set named "Immediate Enforcement Signatures (Critical Sigs)". This Signature Set is attached to all policies.
Then when I want to enforce a new signature that hasn't completed it's staging period, I manually add that signature to the Signature Set using the GUI, then run this script from the Big-IQ:
---------------------------------------------------------------------------------------------------
# This script skips Standby devices, then creates a list of all ASM policy hashes, then finds the ID of the Immediate Enforcement Signatures (Critical Sigs) signature set, and enforces the signatures in that signature set for all ASM policies that have the signature set attached.
# In ASM GUI, add new signature(s) to the Immediate Enforcement Signatures (Critical Sigs) signature set, then run this script to enforce the set on all policiesbash
cd /var/tmpCREDS=admin
# Writes HA Status to a file
tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
chmod 755 /var/tmp/ha-status.txt# Exits script if the HA Status file contains the string STANDBY
if grep -q STANDBY /var/tmp/ha-status.txt; then
exit
fi# Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | .id')
printf "$FILENAME\n" > /var/tmp/policy-hashes.txtFILENAME="policy-hashes.txt"
LINES=$(cat $FILENAME)# ASM - Enable and Enforce Signatures in Signature Set on all policies, and Applies Policies - All Policies
for LINE in $LINES
do
SETID=$(curl -kvu $CREDS -X GET "https://localhost/mgmt/tm/asm/policies/$LINE/signature-sets" -u $CREDS -k -v -H "Content-Type: application/json" | jq -r '.items[] | select(.signatureSetReference.name=="Immediate Enforcement Signatures (Critical Sigs)") | .id')
DATA='{"commands":[{"method":"PATCH","uri":"/mgmt/tm/asm/policies/'$LINE'/signatures?$filter=signatureSets/id+eq+'\'$SETID\''","body":{"performStaging":false,"enabled":true}}]}'
curl -kvu $CREDS -X POST "https://localhost/mgmt/tm/asm/tasks/bulk" -u $CREDS -k -v -H "Content-Type: application/json" -d $DATA | jq .
LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
sleep 10s
done---------------------------------------------------------------------------------------------------
This script does the equivilent of going to Security > Application Security > Policy Building > Learning and Blocking Settings, then under the Attack Signatures section, clicking "Enforce and Enable all Attack Signatures in the Signature Set" for Signature Set "Immediate Enforcement Signatures (Critical Sigs)", then it applies the policy.
The script automatically loops through all of your policies to enforce the Signature Set and apply the policy on all of them one-at-a-time. If you already have a Signature Set for this purpose, you can change the name in the script to match your Signature Set.
If you want to exclude specific policies, such as a Parent or Template policy, you can change the line where the FILENAME variable is created to exclude those policies like this:
FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | select(.name!="asm_parent") | select(.name!="asm_template") | .id')
- Leslie_HubertusRet. Employee
Thanks for this, DanSkow! I'm sure it'll come in handy for future users. Apologies to danielpenna for not having spotted that his question was hanging for so long! The team is working to correct that going forward.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com