Remote tcpdump script
-
Hello
I've created this script that allows you to make a remote
tcpdump
via SSH from any machine running Bash. The script saves the.pcap
files in the default directory (/tmp
), so they can be viewed from the WebUI, or viewed with Wireshark or similar software. To run the script you will (of course) need to have set up an SSH key on the pfSense system.The script takes up to 2 arguments: Host or port filter, and number of packets to capture. The other options are defined in a
.conf
file, which also sets the default values when nu arguments are used. Finally, it's possible to define up to 9 predefined host/port and number of packet combinations, which can be triggered when the argument is 1 to 9 (kind of a shortcut).Here's the script file:
#!/bin/bash # Initial configuration variables scriptpath="/path/to/file" # Include configuration file source "${scriptpath}/rtcpdump.conf" # Local function definition exit_error() { echo "Error: $1" exit 1 } # Example command to be run - for reference # ssh admin@10.10.1.1 "/usr/sbin/tcpdump -ni igc0 -c 4000 -s 128 -U -w /tmp/packetcapture-igc0-$(date '+%Y%m%d%H%M%S').pcap \"((host 10.10.2.22)) and ((not vlan))\"" # Check that $1 is a valid IP address or port if [[ "$1" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ || "$1" =~ ^[0-9]{1,5}$ ]] then # Set filter with first parameter (exclude 1-9, that are reserved for predefined array) if [[ ! "$1" =~ ^[0-9]{1}$ ]] then filter_new="$1" # Set # of packets to $2 or default if [[ "$2" =~ ^[0-9]{1,5}$ ]] then nr_p_new="$2" else nr_p_new="${rtcp_p_nr}" fi fi # Check if $1 matches predefined filters for i in "${!rtcp_ar_filters[@]}" do # Matches the first argument against the list in rtcp_ar_filters, or shortcut 1-9 if [[ "$1" == "${rtcp_ar_filters[i]}" || "$1" == $(( i+1 )) ]] then filter_new="${rtcp_ar_filters[i]}" # Set # of packets to $2 or default if [[ "$2" =~ ^[0-9]{1,5}$ ]] then nr_p_new="$2" else nr_p_new="${rtcp_ar_packets[i]}" fi fi done #echo "Filter is valid" fi # If no arguments are given, just set to defaults if [[ -z "$1" ]] then filter_new="${rtcp_filter}" nr_p_new="${rtcp_p_nr}" fi if [[ -n "${filter_new}" ]] then # Set filter type to host or port, depending on the format of $1 if [[ "${filter_new}" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] then rtcp_type="host" elif [[ "${filter_new}" =~ ^[0-9]{2,5}$ ]] then rtcp_type="port" fi echo "$rtcp_type: $filter_new" echo "packets: $nr_p_new" # Set output filename rtcp_filename="/tmp/packetcapture-${rtcp_nic_id}-$(date '+%Y%m%d%H%M%S').pcap" # Run TCP dump command echo "Remote TCP dump initiated - please run diagnostics" # shellcheck disable=SC2029 ssh "${rtcp_user}@${rtcp_server}" "/usr/sbin/tcpdump -ni ${rtcp_nic_id} -c ${nr_p_new} -s ${rtcp_p_size} -U -w ${rtcp_filename} \"((${rtcp_type} ${filter_new})) and ((not vlan))\"" else exit_error "No valid filter given" fi
And here's the config:
# IP of the Firewall performing the capture rtcp_server="10.10.1.1" # Admin user of the Firewall (requires SSH key) rtcp_user="admin" # ID of the network interface to capture rtcp_nic_id="igc0" # Default filter for capture (IP of the client) rtcp_filter="10.10.2.22" # Default number of packets to capture rtcp_p_nr="4000" # Size of packets written to disk rtcp_p_size="128" # Primary Array with predefined filters rtcp_ar_filters=("10.10.2.22" "8080") # Complimentary Array with # of packets rtcp_ar_packets=("4000" "10")
So it can be used in one of the following ways:
- With no arguments:
rtcp_filter
andrtcp_p_nr
from the config is used. - With one argument, that can be one of the following:
- A number 1 to 9, which selects the corresponding
rtcp_ar_filters
andrtcp_ar_packets
from the arrays (up to 9 "shortcuts", which are likely not used as ports). - Any host (IP address) or port. If it matches the host or port in
rtcp_ar_filters
, the corresponding number of packets are used, else the default is used.
- A number 1 to 9, which selects the corresponding
- With two arguments that is any host/port and number of packets. In this case, these values override the default
rtcp_filter
andrtcp_p_nr
from the config.
The arguments for host will match any IPv4 address, and the port will match any port between 2 to 5 digits (and yes I know there are only 65535 possible ports). Number of packets will match any number between 1 and 99999 (actually from 0, but doesn't matter).
The default settings are in the config, and it also filters no vlan by default. Hope it's of use to somebody, and of course change all you like.
- With no arguments: