From ce835b5a09d54a1601958e8aae35d74a8b85df49 Mon Sep 17 00:00:00 2001 From: lingkai5wu Date: Tue, 22 Sep 2026 15:31:45 +0800 Subject: [PATCH] feat: add container packet capture helper --- capture.sh | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100755 capture.sh diff --git a/capture.sh b/capture.sh new file mode 100755 index 0000000..018d393 --- /dev/null +++ b/capture.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -euo pipefail + +readonly NETSHOOT_IMAGE="${NETSHOOT_IMAGE:-nicolaka/netshoot}" + +usage() { + cat <&2 + exit 1 +} + +if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then + usage + exit 0 +fi + +[[ $# -ge 1 ]] || { + usage >&2 + exit 2 +} +[[ $# -le 2 ]] || die "FILTER must be quoted as one argument" + +readonly CONTAINER="$1" +readonly CAPTURE_TARGET="${2:-tcp}" + +command -v docker >/dev/null 2>&1 || die "docker is not installed or not in PATH" + +running="$(docker container inspect --format '{{.State.Running}}' "$CONTAINER" 2>/dev/null)" || + die "container not found: $CONTAINER" +[[ "$running" == "true" ]] || die "container is not running: $CONTAINER" + +network_mode="$(docker container inspect --format '{{.HostConfig.NetworkMode}}' "$CONTAINER")" +if [[ "$network_mode" == "host" ]]; then + echo "WARNING: $CONTAINER uses host networking; the capture may include host traffic." >&2 +fi + +if [[ "$CAPTURE_TARGET" =~ ^[0-9]+$ ]]; then + ((CAPTURE_TARGET >= 1 && CAPTURE_TARGET <= 65535)) || + die "invalid TCP port: $CAPTURE_TARGET" + filter="tcp dst port $CAPTURE_TARGET" +else + filter="$CAPTURE_TARGET" +fi + +docker_args=( + run + --rm + --network "container:$CONTAINER" + --cap-add NET_RAW + --cap-add NET_ADMIN +) + +if [[ -t 0 && -t 1 ]]; then + docker_args+=(-it) +else + docker_args+=(-i) +fi + +echo "Container: $CONTAINER" +echo "Filter: $filter" +echo "Press Ctrl-C to stop. Packet contents may include credentials or other secrets." >&2 + +exec docker "${docker_args[@]}" "$NETSHOOT_IMAGE" \ + tcpdump -ni any -A -s 0 "$filter"