bash
20 TopicsUse F5 LTM as HTTP Proxy
Problem this snippet solves: LTM product can be used as a HTTP Proxy for servers and PC. This code explains minimum requirements to configure proxy feature without SWG module (configurations from Explicit Forward Proxy documentation without documentation ) and without explicit proxy iApp. How to use this snippet: All these commands must be run in bash shell. Create HTTP PROXY VIRTUAL SERVER Configure variables used in next commands Variable HTTPBaseName is used to create : Resolver object : RESOLVER_${HTTPBaseName} HTTP profile : http_${HTTPBaseName} virtual server : VS_${HTTPBaseName} HTTPBaseName="HTTP_FORWARD_PROXY" VS_IP="192.168.2.80" VS_PORT="8080" create DNS resolver with your DNS server (1.1.1.1 is for demo using cloudflare) tmsh create net dns-resolver RESOLVER_${HTTPBaseName} { forward-zones replace-all-with { . { nameservers replace-all-with { 1.1.1.1:domain { } } } } route-domain 0 } create HTTP profile type explicit, using DNS resolver. The parameter default-connect-handling allow enables HTTPS connections without SSL inspection tmsh create ltm profile http http_${HTTPBaseName} { defaults-from http-explicit explicit-proxy { default-connect-handling allow dns-resolver RESOLVER_${HTTPBaseName} } proxy-type explicit } create HTTP proxy Virtual server tmsh create ltm virtual VS_${HTTPBaseName} { destination ${VS_IP}:${VS_PORT} ip-protocol tcp mask 255.255.255.255 profiles replace-all-with { http_${HTTPBaseName} { } tcp } source 0.0.0.0/0 source-address-translation { type automap } translate-address enabled translate-port enabled} ENABLE SSL FORWARD PROXY This section is not required to forward HTTPS requests but only to enable SSL inspection on HTTPS requests. Note : Following configuration requires SSL, Forward Proxy License. Configure variables used in next commands Variable SSLBaseName is used to create : certificate / key pair : ${SSLBaseName} Client SSL profile : clientssl_${SSLBaseName} Server SSL profile : serverssl_${SSLBaseName} virtual server : VS_${SSLBaseName} SSLBaseName="SSL_FORWARD_PROXY" dirname="/var/tmp" CASubject="/C=FR/O=DEMO\ COMPANY/CN=SSL\ FORWARD\ PROXY\ CA" Create self-signed certificate for CA purpose (not available in WebUI) Self-signed certificates created in WebUI doesn't have CA capability required for SSL FORWARD PROXY. openssl genrsa -out ${dirname}/${SSLBaseName}.key 4094 openssl req -sha512 -new -x509 -days 3650 -key ${dirname}/${SSLBaseName}.key -out ${dirname}/${SSLBaseName}.crt -subj "${CASubject}" Import certificates in TMOS tmsh install sys crypto key ${SSLBaseName}.key from-local-file ${dirname}/${SSLBaseName}.key; tmsh install sys crypto cert ${SSLBaseName}.crt from-local-file ${dirname}/${SSLBaseName}.crt; After CA Certificate is imported, browse in WebUI, retrieve it and import it in client browsers trusted CA Create SSL profiles for SSL FORWARD PROXY tmsh create ltm profile client-ssl clientssl_${SSLBaseName} { cert-lookup-by-ipaddr-port disabled defaults-from clientssl mode enabled proxy-ca-cert ${SSLBaseName}.crt proxy-ca-key ${SSLBaseName}.key ssl-forward-proxy enabled } tmsh create ltm profile server-ssl serverssl_${SSLBaseName} { defaults-from serverssl ssl-forward-proxy enabled } create SSL FORWARD PROXY Virtual server tmsh create ltm virtual VS_${SSLBaseName} { destination 0.0.0.0:https ip-protocol tcp profiles replace-all-with { clientssl_${SSLBaseName} { context clientside } serverssl_${SSLBaseName} { context serverside } http { } tcp { } } source 0.0.0.0/0 translate-address disabled translate-port disabled vlans replace-all-with { http-tunnel } vlans-enabled } Change HTTP EXPLICIT PROXY Default Connect Handling to Deny tmsh modify ltm profile http http_${HTTPBaseName} explicit-proxy { default-connect-handling deny } Note : These commands were tested in both 12.1 and 13.1 versions. Code : No Code11KViews1like24CommentsTemplate For External Monitors
Problem this snippet solves: This external monitor template shows how to use a shell command to perform a custom health check of a pool How to use this snippet: Create a new file containing the code below on the LTM filesystem. Required location is /usr/bin/monitors/. Permissions on the file must be 700 or better, giving root rwx access to the file. For GTM monitors, set permissions to 755 to allow the big3d process execute access to the file1. Example: chmod 755 /usr/bin/monitors/custom_monitor.bash Create a monitor profile of type "External" with the following values: External Program: . . the name of the script file created in step 1 Arguments: . . . . .None needed Variables: . . . . . .DEBUG=0 or DEBUG=1 to log debug messages to /var/log/ltm If you add a DEBUG variable in the monitor definition and set it to 1, the script will write out debug to /var/log/ltm. 3.Customize the shell command run and the debug logging for the command or result under the following two comments: #### Customize the shell command to run here. ### #### Customize the log statement here if you want to log the command run or the output #### Example monitor definition # b monitor custom_external_monitor list monitor custom_external_monitor { defaults from external DEBUG "0" run "custom_monitor.bash" } Adjust the interval and timeout as appropriate for your application Code : #!/bin/bash # Save as /usr/bin/monitors/custom_monitor.bash # Make executable using chmod 700 custom_monitor.bash # Use a custom shell command to perform a health check of the pool member IP address and port # Log debug to local0.debug (/var/log/ltm)? # Check if a variable named DEBUG exists from the monitor definition # This can be set using a monitor variable DEBUG=0 or 1 if [ -n "$DEBUG" ] then if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: \$DEBUG: $DEBUG" | logger -p local0.debug; fi else # If the monitor config didn't specify debug, enable/disable it here DEBUG=0 #echo "EAV `basename $0`: \$DEBUG: $DEBUG" | logger -p local0.debug fi # Remove IPv6/IPv4 compatibility prefix (LTM passes addresses in IPv6 format) IP=`echo $1 | sed 's/::ffff://'` # Save the port for use in the shell command PORT=$2 # Check if there is a prior instance of the monitor running pidfile="/var/run/`basename $0`.$IP.$PORT.pid" if [ -f $pidfile ] then kill -9 `cat $pidfile` > /dev/null 2>&1 echo "EAV `basename $0`: exceeded monitor interval, needed to kill ${IP}:${PORT} with PID `cat $pidfile`" | logger -p local0.error fi # Add the current PID to the pidfile echo "$$" > $pidfile # Debug if [ $DEBUG -eq 1 ] then #### Customize the log statement here if you want to log the command run or the output #### echo "EAV `basename $0`: Running for ${IP}:${PORT} using custom command" | logger -p local0.debug fi #### Customize the shell command to run here. ### # Use $IP and $PORT to specify which host/port to perform the check against # Modify this portion of the line: # nc $IP $PORT | grep "my receive string" # And leave this portion as is: # '2>&1 > /dev/null' # The above code redirects stderr and stdout to nothing to ensure we don't errantly mark the pool member up # Send the request request and check the response nc $IP $PORT | grep "my receive string" 2>&1 > /dev/null # Check if the command ran successfully # Note that any standard output will result in the script execution being stopped # So do any cleanup before echoing to STDOUT if [ $? -eq 0 ] then rm -f $pidfile if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: Succeeded for ${IP}:${PORT}" | logger -p local0.debug; fi echo "UP" else rm -f $pidfile if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: Failed for ${IP}:${PORT}" | logger -p local0.debug; fi fi3.2KViews0likes0CommentsF5 Automation - TCL & Bash
Problem this snippet solves: This is a really simple way to automate CLI command execution on multiple F5 devices using Bash & TCL scripting. How to use this snippet: On a linux machine that is utilized to connect to the F5 device: Create a directory mkdir F5_Check Within the "F5_Check" directory, create the following 3 files: F5_Host.txt (This file contains F5's IP address) F5_Bash_v1 (This is the bash script used to collect username/password for F5) F5_Out_v1.exp (This is the TCL script executes the relevant commands on F5) Explanation of the 3 files: File Content: F5_Out_v1.exp is provided as code share. This is the main TCL script that is utiliezd to execute CLI commands on multiple F5 devices. File Content: F5_Bash_v1 #!/bin/bash # Collect the username and password for F5 access echo -n "Enter the username " read -s -e user echo -ne '\n' echo -n "Enter the password " read -s -e password echo -ne '\n' # Feed the expect script a device list & the collected username & passwords for device in `cat ~/F5_Check/F5_Host.txt`; do ./F5_Out_v1.exp $device $password $user ; done File Contents: F5_Host.txt This contains the management IP of the F5 devices. Example: cat F5_Host.txt 10.12.12.200 10.12.12.201 10.12.12.202 10.12.12.203 Code : #!/usr/bin/expect -f # Set variables set hostname [lindex $argv 0] set password [lindex $argv 1] set username [lindex $argv 2] # Log results log_file -a ~/F5_Check/F5LOG.log # Announce which device we are working on and the time send_user "\n" send_user ">>>>> Working on $hostname @ [exec date] <<<<<\n" send_user "\n" # SSH access to device spawn ssh $username@$hostname expect { "no)? " { send "yes\n" expect "*assword: " sleep 1 send "$password\r" } "*assword: " { sleep 1 send "$password\r" } } expect "(tmos)#" send "sys\n" expect "(tmos.sys)#" send "show software\n" expect "#" send "exit\n" expect "#" send "quit\n" expect ":~\$" exit Tested this on version: 11.51.8KViews0likes2CommentsQuick and dirty shell script to find unused certificates
Problem this snippet solves: This has been edited quite a bit since I first posted so it's probably not as quick and dirty as it was before. This in response to a question regarding removing unused certificateshttps://devcentral.f5.com/questions/how-to-find-the-unused-ssl-certificates-63166 The following bash script will output any installed certificate names to a file, then iterate over each line. If the certificate is not referenced in bigip.conf in either the /config/ or within a partition folder, then it can be reasonably assumed it is not in use and can be safely deleted. The script will give you the option to delete any certs that are not in use and save a UCS archive (just in case) If there are any keys associated with the certificate, this will be deleted too. As the moment, the script will not look for keys without an equivalent cert, e.g. my-cert.key and my-cert.crt. So you many still end up with rouge keys. I'll look to get this updated eventually. There is an array called ignoreCerts ignoreCerts=("f5-irule.crt" "ca-bundle.crt") Here you can add certificates you may want to ignore. For example, f5-irule.crt is used to sign F5 provided iRules and bigip.conf does not reference it. Add any additional certs to this array to ensure they are not deleted Script can be downloaded directly from GitLab using the link below https://gitlab.com/stratalabs/f5-devcental/snippets/1863498/raw?inline=false How to use this snippet: paste into vi chmod +x myScript.sh ./myScript.sh Code : #!/bin/sh function buildInstalledCertsArray { tmsh save sys config partitions all tmsh list sys file ssl-cert | awk '/crt/ {print $4}' | sed '/^[[:space:]]*$/d' > /var/tmp/installedCerts.tmp # iterate over tmp file to create array of used certificates while read line; do for i in "${!ignoreCerts[@]}"; do if [[ $line = ${ignoreCerts[$i]} ]]; then ignore="true" else if [[ $ignore != "true" ]];then ignore="" else # do not add cert to array if already added if [[ ! " ${instCertsArr[@]} " =~ " ${line} " ]]; then instCertsArr+=("$line") fi fi fi done done /dev/null 2>&1) if ! [ -z "$hasKey" ];then deleteKeys+=("${cert%.*}.key") fi done } function deleteUnusedCerts { if [ ${#deleteCerts[@]} -eq 0 ]; then echo "-------------------------------------------------------------------------" echo "There are no unused certificates to delete, existing" echo "-------------------------------------------------------------------------" exit 0 else echo "-------------------------------------------------------------------------" echo "The following keys are not in use can can be deleted:" for cert in "${deleteCerts[@]}"; do echo " ${cert}" done echo "-------------------------------------------------------------------------" read -p "would you like to delete these unused certificates? (y/n)?" answer case ${answer:0:1} in y|Y ) createUcsArchive echo "-------------------------------------------------------------------------" echo "deleting certs..." for cert in "${deleteCerts[@]}"; do delete sys file ssl-key $cert echo " $cert" done if [ ${#deleteKeys[@]} -eq 0 ]; then echo "-------------------------------------------------------------------------" echo "no associated keys to delete, exiting" exit 0 else echo "-------------------------------------------------------------------------" echo "deleting keys..." for key in "${deleteKeys[@]}"; do delete sys file ssl-key $cert echo "$key" exit 0 done fi ;; * ) exit 0 ;; esac fi } function createUcsArchive { echo today=`date +%Y-%m-%d.%H.%M.%S` echo "Creating UCS archive auto.${today}.ucs" tmsh save sys ucs ${today}.ucs } # initialise vars instCertsArr=() deleteCerts=() # ignore certs defined here - f5-irile.crt is used to sign F5 iRules ignoreCerts=("f5-irule.crt" "ca-bundle.crt") # build installed certificates array - excluding certs to ignore buildInstalledCertsArray # check if installed certs are used in bigip.conf (including partitions) - ltm sys files are exluded from results buildDeleteCertsArray # build list of associated keys (not all certs will have keys) buildDeleteKeysArray # optionally delete unused certs deleteUnusedCerts Tested this on version: No Version Found1.8KViews3likes7CommentsDownload a BIG-IP UCS archive with "curl".
Problem this snippet solves: Download a BIG-IP UCS archive using the program "curl" and verifies the output file's signature. Tested on 13.1.1. How to use this snippet: Edit the code to input the hostname of your F5 UI, admin credentials, source UCS file name (defaults to config.ucs), and the output file name. Code : #!/bin/bash # # Download a UCS archive (across a stable network) with curl. # #------------------------------------------------------------------------- F5_HOST='myhost.example.com' CREDENTIALS='admin:admin' FINAL_FILE='/tmp/config.ucs' ARCHIVE_NAME_ON_SERVER='config.ucs' DEBUG='' #------------------------------------------------------------------------- # # Get the md5 checksum for the archive. # #------------------------------------------------------------------------- ARCHIVE_CHECKSUM=$(curl -sku $CREDENTIALS -X POST -H "Content-type: application/json" \ -d "{\"command\":\"run\", \"utilCmdArgs\": \"-c '/usr/bin/md5sum /var/local/ucs/$ARCHIVE_NAME_ON_SERVER'\"}" \ https://$F5_HOST/mgmt/tm/util/bash | awk -F':' '{print $NF}' | awk -F'"' '{ print $2 }' | awk '{print $1}') [ -z "$ARCHIVE_CHECKSUM" ] && echo "Failed to get archive signature. Aborting." && exit 1 [ ! -z "$DEBUG" ] && echo "Archive checksum: $ARCHIVE_CHECKSUM" #------------------------------------------------------------------------- # # Find out the size of the archive and the size of the data packet. # #------------------------------------------------------------------------- Content_Range=$(curl -I -kv -u $CREDENTIALS -H 'Content-Type: application/json' -X GET "https://$F5_HOST/mgmt/shared/file-transfer/ucs-downloads/$ARCHIVE_NAME_ON_SERVER" 2>/dev/null | grep "Content-Range: " | cut -d ' ' -f 2) FIRST_CONTENT_RANGE=$(echo -n $Content_Range | cut -d '/' -f 1 | tr -d '\r') [ ! -z "$DEBUG" ] && echo -n "FIRST_CONTENT_RANGE: " [ ! -z "$DEBUG" ] && echo $FIRST_CONTENT_RANGE NUMBER_OF_LAST_BYTE=$(echo -n $FIRST_CONTENT_RANGE | cut -d '-' -f 2) [ ! -z "$DEBUG" ] && echo -n "NUMBER_OF_LAST_BYTE: " [ ! -z "$DEBUG" ] && echo $NUMBER_OF_LAST_BYTE INITIAL_CONTENT_LENGTH=$NUMBER_OF_LAST_BYTE CONTENT_LENGTH=$(($NUMBER_OF_LAST_BYTE+1)) [ ! -z "$DEBUG" ] && echo -n "CONTENT_LENGTH: " [ ! -z "$DEBUG" ] && echo $CONTENT_LENGTH DFILE_SIZE=$(echo -n $Content_Range | cut -d '/' -f 2 | tr -d '\r' ) [ ! -z "$DEBUG" ] && echo -n "DFILE_SIZE: " [ ! -z "$DEBUG" ] && echo $DFILE_SIZE LAST_END_BYTE=$((DFILE_SIZE-1)) CUMULATIVE_NO=0 [ ! -z "$DEBUG" ] && echo "CUMULATIVE_NO: $CUMULATIVE_NO" SEQ=0 LAST=0 #------------------------------------------------------------------------- # # Clean up: Remove the previous output file. # #------------------------------------------------------------------------- /bin/rm $FINAL_FILE 2>/dev/null #------------------------------------------------------------------------- # # Get the archive file. # #------------------------------------------------------------------------- while true do if [ $LAST -gt 0 ]; then [ ! -z "$DEBUG" ] && echo 'End of run reached.' break fi if [ $SEQ -eq 0 ]; then NEXT_RANGE=$FIRST_CONTENT_RANGE CUMULATIVE_NO=$NUMBER_OF_LAST_BYTE CONTENT_LENGTH=$INITIAL_CONTENT_LENGTH else START_BYTE=$(($CUMULATIVE_NO+1)) END_BYTE=$(($START_BYTE + $CONTENT_LENGTH)) if [ $END_BYTE -gt $LAST_END_BYTE ]; then [ ! -z "$DEBUG" ] && echo "END_BYTE greater than LAST_END_BYTE: $END_BYTE:$LAST_END_BYTE" LAST=1 let END_BYTE=$LAST_END_BYTE [ ! -z "$DEBUG" ] && echo "Getting the last data packet." fi NEXT_RANGE="${START_BYTE}-${END_BYTE}" CUMULATIVE_NO=$END_BYTE fi [ ! -z "$DEBUG" ] && echo "NEXT_RANGE: $NEXT_RANGE" let SEQ+=1 [ ! -z "$DEBUG" ] && echo "SEQ: $SEQ" OUTPUT_FILE_NAME="/tmp/$$_downloaded_ucs_archive_file_part_$SEQ"; curl -H "Content-Range: ${NEXT_RANGE}/${DFILE_SIZE}" -s -k -u $CREDENTIALS -H 'Content-Type: application/json' -X GET "https://$F5_HOST/mgmt/shared/file-transfer/ucs-downloads/$ARCHIVE_NAME_ON_SERVER" -o $OUTPUT_FILE_NAME cat $OUTPUT_FILE_NAME >> $FINAL_FILE /bin/rm $OUTPUT_FILE_NAME [ ! -z "$DEBUG" ] && echo "End of loop $SEQ" done #------------------------------------------------------------------------- # # Verify downloaded file. # #------------------------------------------------------------------------- FINAL_FILE_CHECKSUM=$(/usr/bin/md5sum $FINAL_FILE | awk '{print $1}') if [ "$FINAL_FILE_CHECKSUM" == "$ARCHIVE_CHECKSUM" ]; then echo "Download completed and verified." else echo "Downloaded file has incorrect checksum." exit 1 fi # END -------------------------------------------------------------------- Tested this on version: 13.01.4KViews2likes5CommentsBIG-IP backup script with SCP transfer
Problem this snippet solves: BIP-IP backup script with SCP transfer option. First version works with 10.2 (bigpipe) command. Second version works with 11.2 (tmsh). 11.2 version also contains some logic fixes. This script creates tar.bz2 archives which include a .ucs file and a .scf of the F5's configuration. It optionally stores them locally and/or transfers them to a remote system using SCP. Code : #!/bin/bash # f5backup.sh # Copyright (C) 2010 Colin Stubbs # Changes to 11.2.x (tmsh syntax) and additional logic by Tim Davies # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <> # # Additional files you'll need to create, example content: # # # /etc/cron.d/f5backup # SHELL=/bin/bash # PATH=/sbin:/bin:/usr/sbin:/usr/bin # MAILTO=user@somewhere # HOME=/var/tmp # 0 0 * * * root /bin/bash /var/local/bin/f5backup.sh 1>/var/tmp/f5backup.log 2>&1 # # EOF # # # /root/.ssh/f5archive_config # # Host * # User f5archive # PasswordAuthentication no # StrictHostKeyChecking yes # IdentityFile /root/.ssh/f5archive_dsa # Port 22 # Protocol 2 # Ciphers aes128-cbc,aes192-cbc,aes256-cbc # UserKnownHostsFile /root/.ssh/f5archive_host # # # EOF # # REQUIRES: # F5 BIG-IP 11.2.x # Debug ? Set to non-blank if so. DEBUG='' # Current date/time stamp DATETIME="`date +%Y%m%d%H%M%S`" # Base f5backup.sh working directory OUT_DIR='/var/tmp' # Unique temporary output location TEMP_DIR="`mktemp -d ${OUT_DIR}/f5backup.XXXXXXXXXX`" # Backup options # Export a UCS archive DO_UCS='x' # Export a single config file DO_SCF='x' # Export SCF with oneline bigpipe statements DO_SCF_ONELINE='x' # Use SCP with pubkey to export to remote system DO_SCP_EXPORT=1 # SCP options must be set if you want to use this SCP_OPTIONS="" # Destination list, can be a list of username:IPorHostname if you want to # transfer to multiple destinations. Same public key used for auth to all. # ** MAKE SURE YOU INCLUDE :<%DIRECTORY%> HERE SCP_DESTINATION="f5archive@10.50.108.12:" # All SCP options should be encapsulated in a special config file SCP_CONFIG="/root/.ssh/f5archive_config" # UCS output location UCS_FILE="${TEMP_DIR}/ucs.${DATETIME}.backup" # Encrypt UCS archive with passphrase # ** If blank this will not be used UCS_PASSPHRASE='' # SCF output location SCF_FILE="${TEMP_DIR}/scf.${DATETIME}.backup" # tar output location TAR_FILE="${TEMP_DIR}/scf.${DATETIME}.backup.tar" # Local archive location # ** If this variable is blank, or the destination is not writable then # this script will not copy the backup to the local archive. LOCAL_ARCHIVE="/var/local/backups" # Remove all older local backups than this many days LOCAL_CLEANUP_DAYS=7 # Name of compressed backup archive to produce OUTPUT_FILE="f5backup-${HOSTNAME}-${DATETIME}.tar.bz2" if [ "${DEBUG}x" != "x" ] ; then for i in HOSTNAME DATETIME OUT_DIR TEMP_DIR DO_UCS DO_SCF DO_SCF_ONELINE DO_SCP_EXPORT SCP_DESTINATION SCP_OPTIONS SCP_CONFIG ASM_POLICY_LIST UCS_FILE UCS_PASSPHRASE SCF_FILE LOCAL_ARCHIVE OUTPUT_FILE ; do eval var=\$$i echo "${i} = $var" done fi function usage { echo "Usage: f5backup.sh" exit 0 } function export_scf() { if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi if [ "${DO_SCF}x" != "x" ] ; then if [ "${DO_SCF_ONELINE}x}" != "x" ] ; then tmsh save sys config one-line file "${SCF_FILE}" else tmsh save sys config one-line file "${SCF_FILE}" fi fi } function export_ucs() { if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi if [ "${DO_UCS}x" != "x" ] ; then if [ "${UCS_PASSPHRASE}x" != "x" ] ; then tmsh save sys ucs "${UCS_FILE}" passphrase "${UCS_PASSPHRASE}" else tmsh save sys ucs "${UCS_FILE}" fi fi } function create_backup() { if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi tar -v -j -c -f "${OUT_DIR}/${OUTPUT_FILE}" -C "${TEMP_DIR}" . } # Transfer backup archive to offsite location/s function backup_remote() { if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi if [ -f "${OUT_DIR}/${OUTPUT_FILE}" ] ; then if [ "${DO_SCP_EXPORT}x" != "x" ] ; then echo "Copying to remote archive ${SCP_DESTINATION}${OUTPUT_FILE}" if [ "${DEBUG}x" != "x" ] ; then echo "Exec: /usr/bin/scp ${SCP_OPTIONS} -F ${SCP_CONFIG} ${OUT_DIR}/${OUTPUT_FILE} ${SCP_DESTINATION}" ; fi /usr/bin/scp ${SCP_OPTIONS} -F "${SCP_CONFIG}" "${OUT_DIR}/${OUTPUT_FILE}" "${SCP_DESTINATION}" || echo "Error: SCP ${OUT_DIR}/${OUTPUT_FILE} ${SCP_DESTINATION} failed!" fi else echo "Error: ${OUT_DIR}/${OUTPUT_FILE} doesn't exist, something has gone wrong!" fi } function backup_local() { if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi if [ "${LOCAL_ARCHIVE}x" != "x" ] ; then echo "Copying to local archive ${LOCAL_ARCHIVE}/${OUTPUT_FILE}" if [ ! -d "${LOCAL_ARCHIVE}" ] ; then mkdir "${LOCAL_ARCHIVE}" if [ ${?} -ne 0 ] ; then echo "Error: ${LOCAL_ARCHIVE} doesn't exist and I can't create it." fi fi mv -f "${OUT_DIR}/${OUTPUT_FILE}" "${LOCAL_ARCHIVE}"/ find "${LOCAL_ARCHIVE}" -type f -mtime +${LOCAL_CLEANUP_DAYS} -exec rm -v -f {} \; fi } # Cleanup what this script has done function cleanup() { if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi rm -rf ${TEMP_DIR} if [ -f "${OUT_DIR}/${OUTPUT_FILE}" ] ; then rm -f "${OUT_DIR}/${OUTPUT_FILE}" fi } # Sanity checking # 1. Must be run as root if [ "`id -u`x" != "0x" ] ; then echo "Error: You need to run this script as root." exit 1 fi # 2. Command line args # not applicable yet # 3. Temp dir must exist if [ ! -d "${TEMP_DIR}" ] ; then echo "Error: ${TEMP_DIR} was not created for some reason. Fix this issue and try again." exit 1 fi echo "${0} start `date +%Y%m%d%H%M%S`" export_ucs export_scf create_backup backup_remote backup_local cleanup echo "${0} finish `date +%Y%m%d%H%M%S`" # EOF Tested this on version: 11.2999Views0likes2CommentsWindows File Share Monitor SMB CIFS
Problem this snippet solves: This external monitor performs a health check of a Windows file share using CIFS/Samba. There is an inbuilt SMB monitor for LTM. However, GTM does not (yet?) have this. See the comments in the script for details on how to implement it. Please post any questions about this monitor in the Advanced Design/Config forum Code : #!/bin/bash # Samba (CIFS) external monitor script # # Use smbget to perform a health check of an SMB/CIFS pool member IP address and port for LTM or GTM # # v0.3 - 2011-04-20 - Aaron Hooley - F5 Networks - hooleylists at gmail dot com - Initial version tested on 10.2.1 LTM and GTM # # Save this script as /usr/bin/monitors/smb_monitor.bash # Make executable using chmod 755 /usr/bin/monitors/smb_monitor.bash # # Example LTM monitor which references this script: # #monitor smb_external_monitor { # defaults from external # DEBUG "1" # FILE "/share/test.txt" # PASSWORD "Test123!" # run "smb_monitor.bash" # SEARCH_STRING "got it" # USERNAME "aaron" #} # # Example GTM monitor which references this script: #monitor "smb_external_monitor" { # defaults from "external" # interval 10 # timeout 40 # probe_interval 1 # probe_timeout 5 # probe_num_probes 1 # probe_num_successes 1 # dest *:* # "SEARCH_STRING" "got it" # "DEBUG" "1" # run "smb_monitor.bash" # "USERNAME" "aaron" # "FILE" "/share/test.txt" # args "" # "PASSWORD" "Test123!" # partition "Common" #} # Log debug to local0.debug (/var/log/ltm)? # Check if a variable named DEBUG exists from the monitor definition # This can be set using a monitor variable DEBUG=0 or 1 if [ -n "$DEBUG" ] then if [ $DEBUG -eq 1 ] then logger -p local0.debug "EAV `basename $0` (PID $$): Start of PID $$" logger -p local0.debug "EAV `basename $0` (PID $$): \$DEBUG: $DEBUG" fi else # If the monitor config didn't specify debug, enable/disable it here DEBUG=0 #logger -p local0.debug "EAV `basename $0` (PID $$): \$DEBUG: $DEBUG" fi # If user and pass are both not set, then use anonymous/guest access for the server if [ "x$USERNAME" = "x" ] && [ "x$PASSWORD" = "x" ] then GUEST_FLAG="--guest" if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): No username and no password specified, using guest access"; fi else GUEST_FLAG="" fi # Check if a variable named USERNAME exists from the monitor definition # This can be set using a monitor variable USERNAME=my_username if [ -n "$USERNAME" ] then if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Username: $USERNAME"; fi USERNAME="-u $USERNAME" else if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): No username specified"; fi USERNAME='' fi # Check if a variable named PASSWORD exists from the monitor definition # This can be set using a monitor variable PASSWORD=my_password if [ -n "$PASSWORD" ] then if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Password: $PASSWORD"; fi # Set the password flag PASSWORD="-p $PASSWORD" else if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): No password specified"; fi PASSWORD='' fi # Check if a variable named FILE exists from the monitor definition # This can be set using a monitor variable FILE=/path/to/file.txt if [ -n "$FILE" ] then # Replace \ with / for *nix paths FILE=${FILE//\\/\//replacement} if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Checking \$FILE: $FILE"; fi else FILE="/" logger -p local0.notice "EAV `basename $0` (PID $$): \$FILE is not defined, checking smb://$IP/" fi # Remove IPv6/IPv4 compatibility prefix (LTM passes addresses in IPv6 format) IP=`echo $1 | sed 's/::ffff://'` # Save the port for use in the shell command. smbget doesn't seem to support a port other than 445. PORT=$2 if [ "$PORT" != 445 ] then logger -p local0.debug "EAV `basename $0` (PID $$): Port $PORT will be ignored. This monitor only supports port 445 due to smbget limitation." fi # Check if there is a prior instance of the monitor running pidfile="/var/run/`basename $0`.$IP.$PORT.pid" if [ -f $pidfile ] then kill -9 `cat $pidfile` > /dev/null 2>&1 logger -p local0.debug "EAV `basename $0` (PID $$): Exceeded monitor interval, needed to kill past check for ${IP}:${PORT} with PID `cat $pidfile`" fi # Add the current PID to the pidfile echo "$$" > $pidfile if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Running for ${IP}:${PORT}"; fi # Send the request and check the response. If we have a string to search for, use grep to look for it. # Check if a variable named SEARCH_STRING exists from the monitor definition # This can be set using a monitor variable SEARCH_STRING=my_string if [ -n "$SEARCH_STRING" ] then SUCCESS_STATUS=0 if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Checking ${IP}${FILE} for "$SEARCH_STRING" with status of $SUCCESS_STATUS using\ smbget $USERNAME $PASSWORD $GUEST_FLAG --nonprompt --quiet --stdout smb://${IP}${FILE} | grep \"$SEARCH_STRING\" 1>/dev/null 2>/dev/null"; fi smbget $USERNAME $PASSWORD $GUEST_FLAG --nonprompt --quiet --stdout smb://${IP}${FILE} | grep $SEARCH_STRING 2>&1 > /dev/null else SUCCESS_STATUS=1 if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Checking ${IP}${FILE} with status of $SUCCESS_STATUS using\ smbget $USERNAME $PASSWORD $GUEST_FLAG --nonprompt --quiet --stdout smb://${IP}${FILE} 1>/dev/null 2>/dev/null"; fi smbget $USERNAME $PASSWORD $GUEST_FLAG --nonprompt --quiet --stdout smb://${IP}${FILE} 1>/dev/null 2>/dev/null fi # Check if the command ran successfully # # For some reason, smbget returns a status of 1 for success which is the opposite of typical commands. See this page (or its cache) for details: # http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6828364 # http://webcache.googleusercontent.com/search?q=cache:Ef3KgrvGnygJ:bugs.opensolaris.org/bugdatabase/view_bug.do%3Fbug_id%3D6828364+&cd=2&hl=en&ct=clnk&gl=us # # Note that any standard output will result in the script execution being stopped # So do any cleanup before echoing to STDOUT if [ $? -eq $SUCCESS_STATUS ] then rm -f $pidfile if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Succeeded for ${IP}:${PORT}"; fi echo "UP" else rm -f $pidfile if [ $DEBUG -eq 1 ]; then logger -p local0.debug "EAV `basename $0` (PID $$): Failed for ${IP}:${PORT}"; fi fi949Views0likes2CommentsBIGIP LTM Automated Pool Monitor Flap Troubleshooting Script in Bash
Problem this snippet solves: A bash script is mainly for collecting data when F5 BIG-IP LTM pool member monitor flaps in a period of time and help determine the Root Cause of BIGIP monitor health check failure; Script will monitor the LTM logs, if new pool member down message event occurs, script will perform following functions: 1. Turn on LTM bigd debug ; 2. Start to tcpdump capture to capture relevant traffics; 3. Turn off bigd debug and terminate tcpdump process when timer elapse (timer is configurable) 4. Generate qkview (optinal) 5. Tar ball full logs files under /var/log/ directory (optinal) Script has been tested on v11.x Code : #!/usr/bin/bash ##########identify the log file that script is monitoring filename="/var/log/ltm" ##########identify the period of time that debug and tcpdump are running, please change it according to the needs; timer=60 ##########IP address of pool member flaps poolMemberIP="10.10.10.229" ##########self IP address of LTM is usd to send LTM Health Monitor traffics ltmSelfip="10.10.10.248" ##########pool member service port number poolMemberPort="443" ##########TMOS command to turn on bigd debug turnonBigdDebug="tmsh modify sys db bigd.debug value enable" ##########TMOS command to turn off bigd debug turnoffBigdDebug="tmsh modify sys db bigd.debug value disable" ##########BASH command to tar BIGIP log files tarLogs="tar -czpf /var/tmp/logfiles.tar.gz /var/log/*" ####### function file check: following code will check if /var/log/ltm exist on the system, ####### if it exists, script will be running and perform subsequent functions if [ -f $filename ] then echo "/var/log/ltm exists and program is running to collect data when BG-IP pool member flaps" else ####### if it does not exist, programe will be terminated and log following message echo "no /var/log/ltm file found and program is terminated" exit 0 fi ####### function file check ends ###### write timestap to /var/log/ltm for tracking purpose echo "$(date) monitoring the log" >> $filename ###### start to monitor the /var/log/ltm for new events tail -f -n 0 $filename | while read -r line do ###### counter for pool down message appears hit=$(echo "$line" | grep -c "$poolMemberIP:$poolMemberPort monitor status down") #echo $hit ###### if [ "$hit" == "1" ]; then ###### diplay the pool down log event in file /var/log/ltm echo $line ###### show timestamp of debug is on echo "$(date) Turning on system bigddebug" ###### turn on bigd debug echo $($turnonBigdDebug) ###### turn on tcpdump capture echo $(tcpdump -ni 0.0:nnn -s0 -w /var/tmp/Monitor.pcap port $poolMemberPort and \(host $poolMemberIP and host $ltmSelfip\)) & ###### running timer sleep $timer ###### show timestamp of debug is off echo "$(date) Truning off system bigddebug" ###### turn off bigd debug echo $($turnoffBigdDebug) ###### terminate tcpdump process echo $(killall tcpdump) ###### generate qkview, it's an optional function, enable it by remove "#" sign #echo $(qkview) ###### tar log files, it's an optional function, enable it by remove "#" sign #echo $($tarLogs) break #else #echo "Monitor in progress" fi done ###### show message that programe is end echo "$(date) exiting from programe" ###### exit from the program exit 0 Tested this on version: 11.6927Views0likes6CommentsBASH Script to make UCS and FTP off to remote Server
Problem this snippet solves: Automate UCS Backup and copy via FTP to remote FTP Server. How to use this snippet: Run as a script to save and ship off a UCS file, via FTP, from the BIGIP Device to a Remote Server. Code : #!/bin/bash # set the date variable TODAY=$(date +'%Y%m%d') # Set FTP Remote Hostname or IP FTPHOST="Your IP" # FTP User name and password USER='Your User' PASSWORD='your password' # ID Hostname for Backup File host="$HOSTNAME" # Used to identify the first 3 letters of the hostname which can be # to separted backups on the remote FTP Server by Site ID or Device ID folder=$(echo $HOSTNAME -s|cut -c 1-3) #run the F5 bigpipe config builder cd /var/local/ucs tmsh save sys ucs /var/local/ucs/$host.ucs #Rename the config.ucs and append the date to the end NUM=0 until [ "$NUM" -eq 5 ] do if [ -f /var/local/ucs/$host.ucs ] then mv $host.ucs $host-$TODAY.ucs ; break else sleep 5 fi NUM=`expr "$NUM" + 1` done [[ ! -f /var/local/ucs/$host-$TODAY.ucs ]] && exit 1 #Open the FTP connection and move the file ftp -inv $FTPHOST < Tested this on version: 12.0756Views0likes2CommentsBIG-IP Backup Script In Bash
Problem this snippet solves: A script that can backup F5 configurations, runs daily, and FTP's the backup to a defined remote server. You will need to change the ftphost, user and password variables to reflect the FTP server you are connecting to as well as change the directory where the script has "cd /F5/JAX1" to reflect the clients directory structure. Cron job setup To ensure a daily backup, save the script source below in /etc/cron.daily: Code : #!/bin/bash # set the date variable today=$(date +'%Y%m%d') ftphost="ADD FTP IP HERE" user="ADD FTP USERNAME HERE" password="ADD FTP PASSWORD HERE" #run the F5 bigpipe config builder cd / bigpipe config save /config.ucs #Rename the config.ucs and append the date to the end NUM=0 until [ "$NUM" -eq 5 ] do if [ -f /config.ucs ] then mv config.ucs config-$today.ucs ; break else sleep 5 fi NUM=`expr "$NUM" + 1` done [[ ! -f /config-$today.ucs ]] && exit 1 #Open the FTP connection and move the file ftp -in <699Views0likes3Comments