Keep tcpdump privileged for private nonprod evidence
This commit is contained in:
@@ -80,6 +80,8 @@ esac
|
||||
# "any" includes both provider SIP and the local Asterisk ExternalMedia RTP.
|
||||
# Reducing it to the default-route NIC silently omits loopback media.
|
||||
if [[ -z "$evidence_dir" ]]; then
|
||||
# Debian's tcpdump AppArmor profile denies writes under hidden home dirs.
|
||||
# Use this root-only system path unless another capture-approved path is known.
|
||||
evidence_dir="/var/lib/sip-go-agent/evidence/$call_id"
|
||||
fi
|
||||
install -d -m 0700 "$evidence_dir"
|
||||
@@ -104,7 +106,7 @@ command -v python3 >/dev/null || { echo 'python3 unavailable for SIP evidence su
|
||||
# A successful one-packet probe or a timeout after opening the capture proves
|
||||
# that the binary can open a raw capture socket; permission errors fail closed.
|
||||
probe_status=0
|
||||
timeout 2s "$tcpdump_bin" -i "$interface" -nn -c 1 -w /dev/null >/dev/null 2>"$evidence_dir/tcpdump-preflight.log" || probe_status=$?
|
||||
timeout 2s "$tcpdump_bin" -Z root -i "$interface" -nn -c 1 -w /dev/null >/dev/null 2>"$evidence_dir/tcpdump-preflight.log" || probe_status=$?
|
||||
if [[ "$probe_status" != 0 && "$probe_status" != 124 ]]; then
|
||||
echo "tcpdump CAP_NET_RAW preflight failed: status=$probe_status" >&2
|
||||
exit 1
|
||||
@@ -331,7 +333,7 @@ trap cleanup EXIT
|
||||
asterisk_cli "pjsip set logger on" >"$evidence_dir/pjsip-logger-on.txt" 2>&1 || { echo 'cannot enable PJSIP logger; fail-closed' >&2; exit 1; }
|
||||
logger_enabled=1
|
||||
|
||||
"$tcpdump_bin" -i "$interface" -nn -s0 -U -w "$evidence_dir/capture.pcap" \
|
||||
"$tcpdump_bin" -Z root -i "$interface" -nn -s0 -U -w "$evidence_dir/capture.pcap" \
|
||||
"udp port $sip_port or (udp portrange $rtp_start-$rtp_end)" >"$evidence_dir/tcpdump.log" 2>&1 &
|
||||
capture_pid=$!
|
||||
sleep 1
|
||||
|
||||
@@ -11,6 +11,19 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNonprodCaptureKeepsWriteAccessToPrivateEvidence(t *testing.T) {
|
||||
script, err := os.ReadFile("../../deploys/test/nonprod-call-evidence.sh")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Debian tcpdump drops to its unprivileged account by default. Both
|
||||
// capture invocations must retain root to write inside the root-only
|
||||
// evidence directory; otherwise the preflight succeeds but capture fails.
|
||||
if count := strings.Count(string(script), `"$tcpdump_bin" -Z root -i "$interface"`); count != 2 {
|
||||
t.Fatalf("preflight and live capture must both retain write access: found %d root-owned invocations", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNonprodCallEvidenceFailsBeforeDialWithoutRequiredGates(t *testing.T) {
|
||||
cases := []struct {
|
||||
name, hour, environment, enabled, active, ari, endpoint, want string
|
||||
|
||||
Reference in New Issue
Block a user