- SOUL.md: full agent identity, operating principles, voice - IDENTITY.md: runtime identity, hosts, boundaries - USER.md: operator context imported from hermes-soul - AGENTS.md: actual operating rules, infrastructure, quick reference - memories/curated/: 5 topics (tailscale, forgejo, agents, projects, vaultwarden) - skills/: 9 cross-harness skills imported from hermes-soul after review - docs/PLAN-CONFIGURE-PRIVATE-REPO.md: configuration plan - Validate: passes clean
86 lines
3.3 KiB
Bash
86 lines
3.3 KiB
Bash
#!/usr/bin/env bash
|
|
# Generic before/after interference test for Wi-Fi/SSH/tmux lag.
|
|
# Run once before introducing the suspected interferer, then again after.
|
|
# Usage: WIFI_IFACE=wlp1s0 ROUTER_IP=192.168.1.1 REMOTE_IP=1.2.3.4 ./network-interference-capture.sh [duration-seconds] [output-dir]
|
|
set -euo pipefail
|
|
|
|
DURATION="${1:-90}"
|
|
STAMP="$(date +%Y%m%d-%H%M%S)"
|
|
BASE="${2:-./network-interference-$STAMP}"
|
|
IFACE="${WIFI_IFACE:-}"
|
|
ROUTER="${ROUTER_IP:-}"
|
|
PUBLIC="${PUBLIC_IP:-1.1.1.1}"
|
|
REMOTE="${REMOTE_IP:-}"
|
|
mkdir -p "$BASE"
|
|
|
|
if [[ -z "$IFACE" ]]; then
|
|
IFACE=$(iw dev 2>/dev/null | awk '/Interface/ {print $2; exit}' || true)
|
|
fi
|
|
if [[ -z "$ROUTER" ]]; then
|
|
ROUTER=$(ip route show default 2>/dev/null | awk '{print $3; exit}' || true)
|
|
fi
|
|
|
|
log(){ printf '\n## %s\n' "$*" | tee -a "$BASE/summary.txt"; }
|
|
run(){ printf '\n$ %s\n' "$*" | tee -a "$BASE/summary.txt"; bash -lc "$*" 2>&1 | tee -a "$BASE/summary.txt"; }
|
|
|
|
log "Network interference test $STAMP duration=${DURATION}s iface=${IFACE:-unknown}"
|
|
run "date; uname -a; uptime"
|
|
if [[ -n "$IFACE" ]]; then
|
|
run "nmcli -f GENERAL,WIFI-PROPERTIES,IP4 device show '$IFACE' 2>/dev/null | sed -n '1,140p' || true"
|
|
run "nmcli -f ACTIVE,SSID,BSSID,CHAN,RATE,SIGNAL,BARS,SECURITY dev wifi list --rescan yes 2>/dev/null | sed -n '1,100p' || true"
|
|
run "iw dev '$IFACE' link 2>/dev/null || true"
|
|
run "ip -s link show '$IFACE'"
|
|
fi
|
|
run "ss -nti '( sport = :22 or dport = :22 )' || true"
|
|
run "tailscale status 2>/dev/null | sed -n '1,100p' || true"
|
|
run "tailscale netcheck 2>/dev/null || true"
|
|
|
|
log "Starting ping streams"
|
|
for target in "$ROUTER" "$PUBLIC" "$REMOTE"; do
|
|
[[ -n "$target" ]] || continue
|
|
safe="${target//[^A-Za-z0-9_.-]/_}"
|
|
ping -D -i 0.2 "$target" > "$BASE/ping-$safe.log" 2>&1 &
|
|
echo $! >> "$BASE/pids"
|
|
done
|
|
|
|
FILTER_PARTS=()
|
|
for target in "$ROUTER" "$PUBLIC" "$REMOTE"; do
|
|
[[ -n "$target" ]] && FILTER_PARTS+=("host $target")
|
|
done
|
|
FILTER="port 22"
|
|
if [[ ${#FILTER_PARTS[@]} -gt 0 ]]; then
|
|
FILTER="$(IFS=' or '; echo "${FILTER_PARTS[*]}") or port 22"
|
|
fi
|
|
|
|
if [[ -n "$IFACE" ]] && command -v tshark >/dev/null 2>&1; then
|
|
log "Starting tshark capture"
|
|
sudo tshark -i "$IFACE" -a "duration:$DURATION" -w "$BASE/capture.pcapng" -f "$FILTER" > "$BASE/tshark.log" 2>&1 &
|
|
echo $! >> "$BASE/pids"
|
|
elif [[ -n "$IFACE" ]] && command -v tcpdump >/dev/null 2>&1; then
|
|
log "Starting tcpdump capture"
|
|
sudo timeout "$DURATION" tcpdump -i "$IFACE" -s 0 -w "$BASE/capture.pcap" "$FILTER" > "$BASE/tcpdump.log" 2>&1 &
|
|
echo $! >> "$BASE/pids"
|
|
else
|
|
log "No tshark/tcpdump capture available; install one if packet evidence is needed"
|
|
fi
|
|
|
|
sleep "$DURATION"
|
|
if [[ -f "$BASE/pids" ]]; then
|
|
while read -r pid; do kill "$pid" 2>/dev/null || true; done < "$BASE/pids"
|
|
fi
|
|
sleep 1
|
|
|
|
log "Post-test state"
|
|
run "date; uptime"
|
|
[[ -n "$IFACE" ]] && run "ip -s link show '$IFACE'"
|
|
run "ss -nti '( sport = :22 or dport = :22 )' || true"
|
|
run "journalctl --since '$(date -d "${DURATION} seconds ago" '+%Y-%m-%d %H:%M:%S')' --no-pager 2>/dev/null | egrep -i 'wlan|wlp|iwlwifi|tailscale|dns|disconnect|deauth|timeout|error|warn|UFW BLOCK' | tail -220 || true"
|
|
|
|
log "Ping summaries"
|
|
for f in "$BASE"/ping-*.log; do
|
|
[[ -e "$f" ]] || continue
|
|
echo "--- $f" | tee -a "$BASE/summary.txt"
|
|
tail -20 "$f" | tee -a "$BASE/summary.txt"
|
|
done
|
|
|
|
printf '\nSaved network interference test directory: %s\nMain summary: %s\n' "$BASE" "$BASE/summary.txt"
|