added Malcolm
This commit is contained in:
		
							
								
								
									
										90
									
								
								Vagrant/resources/malcolm/pcap-capture/scripts/netsniff-roll.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										90
									
								
								Vagrant/resources/malcolm/pcap-capture/scripts/netsniff-roll.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Copyright (c) 2021 Battelle Energy Alliance, LLC.  All rights reserved. | ||||
|  | ||||
| lastmod(){ | ||||
|   expr $(date +%s) - $(stat -c %X "$1") | ||||
| } | ||||
|  | ||||
| shopt -s nullglob | ||||
|  | ||||
| PCAP_ROTATE_MINUTES=${PCAP_ROTATE_MINUTES:-15} | ||||
| PCAP_ROTATE_SECONDS=$(echo "$PCAP_ROTATE_MINUTES*60" | bc) | ||||
|  | ||||
| # we want to HUP any netsniff-ng process that has been writing to the | ||||
| # same file for >= PCAP_ROTATE_SECONDS. netsniff-ng itself takes care | ||||
| # of rolling the file based on filesize, this way we won't interfere | ||||
| # with that because we'll be looking at the actual file time itself | ||||
|  | ||||
| declare -A NETSNIFF_LAST_HUP_TIMES_BY_PID | ||||
|  | ||||
| while true; do | ||||
|   sleep 10 | ||||
|  | ||||
|   NETSNIFF_PIDS=$(pidof netsniff-ng) | ||||
|   for NETSNIFF_PID in $NETSNIFF_PIDS; do | ||||
|  | ||||
|     unset OUTPUT_DIR | ||||
|     unset PCAP_PREFIX | ||||
|  | ||||
|     NOW_DATE_UNIX="$(date +%s)" | ||||
|  | ||||
|     # if this netsniff-ng was previously HUP'ed, read out which PCAP file caused it | ||||
|     if [ ${NETSNIFF_LAST_HUP_TIMES_BY_PID[$NETSNIFF_PID]+_} ]; then | ||||
|       PID_LAST_HUP_TIME=${NETSNIFF_LAST_HUP_TIMES_BY_PID[$NETSNIFF_PID]} | ||||
|       PID_LAST_HUP_SECONDS_AGO=$((NOW_DATE_UNIX-PID_LAST_HUP_TIME)) | ||||
|     else | ||||
|       PID_LAST_HUP_SECONDS_AGO=86400 | ||||
|     fi | ||||
|  | ||||
|     # no reason to even check if this PID has been HUP'ed more recently than the threshold | ||||
|     if (( $PID_LAST_HUP_SECONDS_AGO >= $PCAP_ROTATE_SECONDS )); then | ||||
|  | ||||
|       # when was this netsniff-ng started (we don't want to roll based on leftover pcap files from a previous instance) | ||||
|       PROC_START_DATE_STR="$(ps -q $NETSNIFF_PID -o lstart=)" | ||||
|       PROC_START_DATE_UNIX="$(date +%s -d "$PROC_START_DATE_STR")" | ||||
|       PROC_START_SECONDS_AGO=$((NOW_DATE_UNIX-PROC_START_DATE_UNIX)) | ||||
|  | ||||
|       # see what arguments this netsniff-ng was started with | ||||
|       NETSNIFF_ARGS=($(cat /proc/$NETSNIFF_PID/cmdline | tr '\000' ' ' | python -c 'import shlex; print shlex.split(None)' | tr -d '[],')) | ||||
|       NETSNIFF_ARGS_LEN=${#NETSNIFF_ARGS[@]} | ||||
|  | ||||
|       # extract the --out directory and --prefix prefix for the file(s) being written to by this netsniff-ng | ||||
|       # (we would just use /proc/$NETSNIFF_PID/fd/ but in docker we can't resolve the symlink) | ||||
|       CURR_IDX=0 | ||||
|       for ARG in ${NETSNIFF_ARGS[@]}; do | ||||
|         if (( CURR_IDX > 0 )) && (( CURR_IDX < NETSNIFF_ARGS_LEN - 1 )); then | ||||
|           if [[ "$ARG" = "'-o'" ]] || [[ "$ARG" = "'--out'" ]]; then | ||||
|             OUTPUT_DIR=$(sed -e "s/^'//" -e "s/'$//" <<< "${NETSNIFF_ARGS[(( CURR_IDX + 1 ))]}") | ||||
|           elif [[ "$ARG" = "'-P'" ]] || [[ "$ARG" = "'--prefix'" ]]; then | ||||
|             PCAP_PREFIX=$(sed -e "s/^'//" -e "s/'$//" <<< "${NETSNIFF_ARGS[(( CURR_IDX + 1 ))]}") | ||||
|           fi | ||||
|         fi | ||||
|         CURR_IDX=$((CURR_IDX+1)) | ||||
|       done | ||||
|  | ||||
|       if [[ -n $OUTPUT_DIR ]] && [[ -n $PCAP_PREFIX ]]; then | ||||
|         # for the file(s) being written to by this netsniff-ng, if the creation time (okay, | ||||
|         # access time, but nobody's "accessed" it since it was created) is longer ago than | ||||
|         # PCAP_ROTATE_SECONDS then we're gonna HUP it | ||||
|         NEEDS_HUP=0 | ||||
|         MAX_SEC_SINCE_MOD=0 | ||||
|         for PCAP_FILE in "$OUTPUT_DIR/$PCAP_PREFIX"*; do | ||||
|           SEC_SINCE_MOD=$(lastmod "$PCAP_FILE") | ||||
|           # if this file is younger than the netsniff-ng process AND older than the rotate threshold | ||||
|           if (( $SEC_SINCE_MOD <= $PROC_START_SECONDS_AGO )) && (( $SEC_SINCE_MOD >= $PCAP_ROTATE_SECONDS )); then | ||||
|             NEEDS_HUP=$((NEEDS_HUP+1)) | ||||
|             (( $SEC_SINCE_MOD > $MAX_SEC_SINCE_MOD )) && MAX_SEC_SINCE_MOD=$SEC_SINCE_MOD | ||||
|           fi | ||||
|         done | ||||
|         if (( $NEEDS_HUP > 0 )); then | ||||
|           kill -s HUP $NETSNIFF_PID && echo "Rolling netsniff-ng ($PCAP_PREFIX...) at $MAX_SEC_SINCE_MOD seconds" | ||||
|           NETSNIFF_LAST_HUP_TIMES_BY_PID[$NETSNIFF_PID]=$NOW_DATE_UNIX | ||||
|         fi | ||||
|       fi # $OUTPUT_DIR and $PCAP_PREFIX | ||||
|  | ||||
|     fi # $PID_LAST_HUP_SECONDS_AGO and $PCAP_ROTATE_SECONDS | ||||
|  | ||||
|   done # for NETSNIFF_PID in $NETSNIFF_PIDS | ||||
|  | ||||
| done # while true | ||||
							
								
								
									
										74
									
								
								Vagrant/resources/malcolm/pcap-capture/scripts/supervisor.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								Vagrant/resources/malcolm/pcap-capture/scripts/supervisor.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Copyright (c) 2021 Battelle Energy Alliance, LLC.  All rights reserved. | ||||
|  | ||||
|  | ||||
| set -e | ||||
|  | ||||
| CONFIG_DIR="/etc/supervisor.d" | ||||
| CONFIG_FILE="/etc/supervisord.conf" | ||||
| CAPTURE_GROUPS_FILE="capture-groups.conf" | ||||
|  | ||||
| function join_by { local IFS="$1"; shift; echo "$*"; } | ||||
|  | ||||
| # Create config files for each capture interface for the various capture programs (tcpdump, netsniff) | ||||
| # so that supervisord can manage instances of each of these programs for each interface. | ||||
| # bro is now managed by broctl (via brodeploy.sh) rather than individually by supervisord so that | ||||
| # we can use pf_ring | ||||
| function CreateCaptureConfigs() { | ||||
|  | ||||
|   declare -a CAPTURE_PROGS=("tcpdump" "netsniff") | ||||
|  | ||||
|   if [[ -d "$CONFIG_DIR" ]]; then | ||||
|     rm -f "$CONFIG_DIR"/"$CAPTURE_GROUPS_FILE" | ||||
|  | ||||
|     for PROG in "${CAPTURE_PROGS[@]}"; do | ||||
|       declare -a PROG_GROUP=() | ||||
|  | ||||
|       # remove any old .conf files for this capture program, we'll create them all fresh | ||||
|       rm -f "$CONFIG_DIR"/$PROG*.conf | ||||
|       if [[ -n $PCAP_IFACE ]]; then | ||||
|  | ||||
|         # for each capture interface, expand the capture program's template and substitute for the $IFACE variable | ||||
|         for IFACE in ${PCAP_IFACE//,/ }; do | ||||
|           if [[ -r "$CONFIG_DIR"/$PROG.template ]]; then | ||||
|  | ||||
|             # expand $IFACE into interface name in a new configuration file | ||||
|             export $IFACE | ||||
|             sed -e "s/[$]IFACE/${IFACE}/g" "$CONFIG_DIR"/$PROG.template > "$CONFIG_DIR"/$PROG-"$IFACE".conf | ||||
|  | ||||
|             # get new program name for group inclusion | ||||
|             INSTANCE_NAME="$(grep '^\[program:' "$CONFIG_DIR"/$PROG-"$IFACE".conf | sed "s/^\[program://" | sed "s/\]$//")" | ||||
|             PROG_GROUP+=($INSTANCE_NAME) | ||||
|  | ||||
|           fi # capture program template exists | ||||
|         done # loop over capture interfaces | ||||
|  | ||||
|       fi # capture interface(s) defined | ||||
|  | ||||
|       if (( ${#PROG_GROUP[@]} )); then | ||||
|         GROUP_PROGS="$(join_by , "${PROG_GROUP[@]}")" | ||||
|         # define group config file | ||||
|         echo "[group:$PROG]" >> "$CONFIG_DIR"/"$CAPTURE_GROUPS_FILE" | ||||
|         echo "programs=$GROUP_PROGS" >> "$CONFIG_DIR"/"$CAPTURE_GROUPS_FILE" | ||||
|         echo "" >> "$CONFIG_DIR"/"$CAPTURE_GROUPS_FILE" | ||||
|       fi | ||||
|  | ||||
|     done # loop over capture programs | ||||
|   fi # config dir exists | ||||
| } | ||||
|  | ||||
| function SetCaptureCapabilities() { | ||||
|   setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /sbin/ethtool || true | ||||
|   setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/sbin/tcpdump || true | ||||
|   setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip CAP_IPC_LOCK+eip CAP_SYS_ADMIN+eip' /usr/sbin/netsniff-ng || true | ||||
| } | ||||
|  | ||||
| CreateCaptureConfigs | ||||
| SetCaptureCapabilities | ||||
|  | ||||
| if [[ -z $PCAP_ROTATE_SECONDS ]] && [[ -n $PCAP_ROTATE_MINUTES ]]; then | ||||
|   export PCAP_ROTATE_SECONDS=$(echo "$PCAP_ROTATE_MINUTES * 60" | bc) | ||||
| fi | ||||
|  | ||||
| supervisord -c "$CONFIG_FILE" -n | ||||
							
								
								
									
										33
									
								
								Vagrant/resources/malcolm/pcap-capture/supervisord.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Vagrant/resources/malcolm/pcap-capture/supervisord.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| ; Copyright (c) 2021 Battelle Energy Alliance, LLC.  All rights reserved. | ||||
|  | ||||
| [unix_http_server] | ||||
| file=/tmp/supervisor.sock   ; (the path to the socket file) | ||||
| chmod=0700 | ||||
|  | ||||
| [supervisord] | ||||
| nodaemon=true | ||||
| user=root | ||||
| logfile=/dev/null | ||||
| logfile_maxbytes=0 | ||||
| pidfile=/tmp/supervisord.pid | ||||
|  | ||||
| [rpcinterface:supervisor] | ||||
| supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface | ||||
|  | ||||
| [supervisorctl] | ||||
| serverurl=unix:///tmp/supervisor.sock | ||||
|  | ||||
| [program:netsniff-roll] | ||||
| startsecs=15 | ||||
| command=/usr/local/bin/netsniff-roll.sh | ||||
| user=%(ENV_PUSER)s | ||||
| stopasgroup=true | ||||
| killasgroup=true | ||||
| stdout_logfile=/dev/fd/1 | ||||
| stdout_logfile_maxbytes=0 | ||||
| redirect_stderr=true | ||||
| autostart=%(ENV_PCAP_ENABLE_NETSNIFF)s | ||||
| directory=%(ENV_PCAP_PATH)s | ||||
|  | ||||
| [include] | ||||
| files = /etc/supervisor.d/*.conf | ||||
| @@ -0,0 +1,9 @@ | ||||
| [program:netsniff-$IFACE] | ||||
| command=/usr/sbin/netsniff-ng -i "$IFACE" -T "%(ENV_PCAP_NETSNIFF_MAGIC)s" -o "%(ENV_PCAP_PATH)s" -P "netsniff-$IFACE_" -F "%(ENV_PCAP_ROTATE_MEGABYTES)sMiB" --silent "%(ENV_PCAP_FILTER)s" | ||||
| user=%(ENV_PUSER)s | ||||
| startsecs=5 | ||||
| startretries=3 | ||||
| stopasgroup=true | ||||
| killasgroup=true | ||||
| autostart=%(ENV_PCAP_ENABLE_NETSNIFF)s | ||||
| directory=%(ENV_PCAP_PATH)s | ||||
| @@ -0,0 +1,9 @@ | ||||
| [program:tcpdump-$IFACE] | ||||
| command=/usr/sbin/tcpdump -i "$IFACE" -s %(ENV_PCAP_SNAPLEN)s -w "tcpdump-$IFACE_%(ENV_PCAP_TCPDUMP_FILENAME_PATTERN)s" -G %(ENV_PCAP_ROTATE_SECONDS)s -C %(ENV_PCAP_ROTATE_MEGABYTES)s -K -n "%(ENV_PCAP_FILTER)s" | ||||
| user=%(ENV_PUSER)s | ||||
| startsecs=5 | ||||
| startretries=3 | ||||
| stopasgroup=true | ||||
| killasgroup=true | ||||
| autostart=%(ENV_PCAP_ENABLE_TCPDUMP)s | ||||
| directory=%(ENV_PCAP_PATH)s | ||||
		Reference in New Issue
	
	Block a user