#!/bin/sh set -eu cd "$(dirname "$0")/.." CONFIG_FILE="${DEPLOY_CONFIG:-deploy-routeros.env}" if [ -f "$CONFIG_FILE" ]; then # shellcheck disable=SC1090 case "$CONFIG_FILE" in /*) . "$CONFIG_FILE" ;; *) . "./$CONFIG_FILE" ;; esac fi : "${ROUTER_HOST:=192.168.88.1}" : "${ROUTER_USER:=admin}" : "${ROUTER_PORT:=22}" : "${ROUTER_IDENTITY_FILE:=}" : "${ROUTER_SCP_DIR:=/}" : "${CONTAINER_IP:=172.31.255.2/30}" : "${TZSP_PORT:=37008}" : "${CONFIGURE_IPV4_MANGLE:=true}" : "${CONFIGURE_L2_SNIFFER:=true}" : "${START_L2_SNIFFER:=true}" : "${TZSP_L2_INTERFACE:=}" : "${TZSP_L2_MAC_PROTOCOL:=!ip}" TZSP_L2_FILTER_INTERFACE="${TZSP_L2_INTERFACE:-all}" : "${KEEP_REMOTE_RSC:=false}" : "${DRY_RUN:=false}" case "$ROUTER_PORT" in *[!0-9]*|'') echo "ROUTER_PORT must be numeric" >&2; exit 2 ;; esac case "$TZSP_PORT" in *[!0-9]*|'') echo "TZSP_PORT must be numeric" >&2; exit 2 ;; esac for bool_pair in \ "CONFIGURE_IPV4_MANGLE=$CONFIGURE_IPV4_MANGLE" \ "CONFIGURE_L2_SNIFFER=$CONFIGURE_L2_SNIFFER" \ "START_L2_SNIFFER=$START_L2_SNIFFER" \ "DRY_RUN=$DRY_RUN" do case "${bool_pair#*=}" in true|false) ;; *) echo "${bool_pair%%=*} must be true or false" >&2; exit 2 ;; esac done check_ros_value() { label="$1" value="$2" case "$value" in *'"'*|*'\\'*|*'$'*|*';'*|*'`'*) echo "$label contains a character not supported by this helper: $value" >&2 exit 3 ;; esac } check_ros_value CONTAINER_IP "$CONTAINER_IP" check_ros_value TZSP_L2_INTERFACE "$TZSP_L2_INTERFACE" check_ros_value TZSP_L2_MAC_PROTOCOL "$TZSP_L2_MAC_PROTOCOL" TARGET="${ROUTER_USER}@${ROUTER_HOST}" ssh_run() { if [ -n "$ROUTER_IDENTITY_FILE" ]; then ssh -i "$ROUTER_IDENTITY_FILE" -p "$ROUTER_PORT" "$TARGET" "$1" else ssh -p "$ROUTER_PORT" "$TARGET" "$1" fi } scp_put() { src="$1" dst="$2" if [ -n "$ROUTER_IDENTITY_FILE" ]; then scp -i "$ROUTER_IDENTITY_FILE" -P "$ROUTER_PORT" "$src" "${TARGET}:$dst" else scp -P "$ROUTER_PORT" "$src" "${TARGET}:$dst" fi } CONTAINER_IP_ONLY="${CONTAINER_IP%/*}" ID="$(date -u +%Y%m%d%H%M%S)" mkdir -p build LOCAL_RSC="build/configure-tzsp-hybrid-${ID}.rsc" REMOTE_NAME="configure-tzsp-hybrid-${ID}.rsc" REMOTE_PATH="${ROUTER_SCP_DIR%/}/${REMOTE_NAME}" [ "$ROUTER_SCP_DIR" = "/" ] && REMOTE_PATH="/${REMOTE_NAME}" cat > "$LOCAL_RSC" <> "$LOCAL_RSC" < 0) do={ /ip/firewall/mangle/add chain=forward action=sniff-tzsp sniff-target="${CONTAINER_IP_ONLY}" sniff-target-port=${TZSP_PORT} comment="MikroSuricata TZSP IPv4" place-before=0 } else={ /ip/firewall/mangle/add chain=forward action=sniff-tzsp sniff-target="${CONTAINER_IP_ONLY}" sniff-target-port=${TZSP_PORT} comment="MikroSuricata TZSP IPv4" } RSC fi if [ "$CONFIGURE_L2_SNIFFER" = "true" ]; then cat >> "$LOCAL_RSC" <> "$LOCAL_RSC" <<'RSC' /tool/sniffer/start RSC fi fi cat >> "$LOCAL_RSC" <<'RSC' /ip/firewall/mangle/print stats where comment="MikroSuricata TZSP IPv4" /tool/sniffer/print RSC if [ "$DRY_RUN" = "true" ]; then cat "$LOCAL_RSC" echo "[capture] dry run only; RouterOS was not modified" exit 0 fi command -v ssh >/dev/null 2>&1 || { echo "ssh is required" >&2; exit 2; } command -v scp >/dev/null 2>&1 || { echo "scp is required" >&2; exit 2; } echo "[capture] preflight ${TARGET}" ssh_run '/ip/firewall/mangle/print' >/dev/null if [ "$CONFIGURE_L2_SNIFFER" = "true" ]; then ssh_run '/tool/sniffer/print' >/dev/null fi echo "[capture] uploading $REMOTE_PATH" scp_put "$LOCAL_RSC" "$REMOTE_PATH" echo "[capture] applying hybrid capture" ssh_run "/import file-name=\"${REMOTE_NAME}\"" if [ "$KEEP_REMOTE_RSC" != "true" ]; then ssh_run "/file/remove [find where name=\"${REMOTE_NAME}\"]" || true fi echo "[capture] done" echo "[capture] IPv4: mangle sniff-tzsp -> ${CONTAINER_IP_ONLY}:${TZSP_PORT}" if [ "$CONFIGURE_L2_SNIFFER" = "true" ]; then if [ -n "$TZSP_L2_INTERFACE" ]; then echo "[capture] non-IPv4: Packet Sniffer on ${TZSP_L2_INTERFACE} -> ${CONTAINER_IP_ONLY}:${TZSP_PORT}" else echo "[capture] non-IPv4: Packet Sniffer on all interfaces -> ${CONTAINER_IP_ONLY}:${TZSP_PORT}" fi fi