feat: add container packet capture helper
This commit is contained in:
1 parent
1881eac588
commit
ce835b5a09
1 file changed
+86
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly NETSHOOT_IMAGE="${NETSHOOT_IMAGE:-nicolaka/netshoot}"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") CONTAINER [PORT | FILTER]
|
||||
|
||||
Capture traffic from a running container's network namespace.
|
||||
|
||||
Arguments:
|
||||
CONTAINER Container name or ID
|
||||
PORT Capture inbound TCP traffic to this port
|
||||
FILTER Custom tcpdump filter expression (quote it as one argument)
|
||||
|
||||
Examples:
|
||||
$(basename "$0") gitea 3000
|
||||
$(basename "$0") immich-server 2283
|
||||
$(basename "$0") nginx 'tcp port 443'
|
||||
$(basename "$0") adguardhome 'udp port 53'
|
||||
|
||||
Environment:
|
||||
NETSHOOT_IMAGE Packet-capture image (default: nicolaka/netshoot)
|
||||
EOF
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "ERROR: $*" >&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"
|
||||
Reference in new issue
Block a user