Packet Logs
This service receives packets over NFLog netlink messages.
The packet info is sent to the sprbus where clients subscribing to the nft-prefix gets notified. It's easier to talk to sprbus for packet inspection but also available by packet_logs.
Example: The db service can enable storage of logs by adding the topic to configs/db/config.json
under the SaveEvents key.
See also: sprbus
The Groups
Group 0
chain INPUT { ...
$(if [ "$WANIF" ]; then echo "iifname $WANIF log prefix \"wan:in \" group 0"; fi)
$(if [ "$WANIF" ]; then echo "iifname ne $WANIF log prefix \"lan:in \" group 0"; else echo "log prefix \"lan:in \" group 0"; fi)
}
chain FORWARD { ...
$(if [ "$WANIF" ]; then echo "oifname $WANIF log prefix \"wan:out \" group 0"; fi)
$(if [ "$WANIF" ]; then echo "oifname ne $WANIF log prefix \"lan:out \" group 0"; else echo "log prefix \"lan:out \" group 0"; fi)
}
wan:in
Input from the upstream interface ($WANIF)
lan:in
Input from all other devices (wireguard, wireless clients, wired devices)
wan:out
Packets forwarded upstream to the internet over the $WANIF interface
lan:out
Packets forwaded to any other non-upstream interface
Group 1 - Dropped packets
log prefix "drop:private " group 1
counter log prefix "drop:forward " group 1
counter log prefix "drop:input " group 1
log prefix "drop:mac " group 1
drop:private
This prefix marks packets that were dropped because they were headed upstream to a private network address, but blocked from doing so because they were not in a permitted group
drop:forward
Packets that were dropped during forward
drop:input
Input packets into SPR that were dropped
drop:mac
Packets that were dropped because of an strict MAC filtering in the INPUT chain in the FORWARD chain.
Inspecting packets
Retrieve JSON packet logs on SPR with:
docker exec -it superpacket_logs /stream-json-logs > log.json
will log packets for 20 seconds, can specify with -timeout
flag.
Packets can be inspected with jq
, see following section for fields. Raw data is available and base64 encoded.
Script to inspect traffic
Example script with gum - a tool for glamorous shell scripts.
Install dependencies:
apt install jq
go install github.com/charmbracelet/gum@latest
#!/bin/sh
# packet_logs json stream build if not running on spr:
# cd packet_logs/stream-json-logs && go build -o stream
# ./stream > log.json
F="$PWD/log.json"
F_CSV="${F}.csv"
BIN_STREAM="docker exec -it superpacket_logs /stream-json-logs"
log_stream() {
gum spin -s moon --title "Logging traffic... 20s" -- sh -c "$BIN_STREAM > $F"
}
table() {
F_UDP='[.Timestamp,"UDP",.Prefix, ([.IP.SrcIP,.UDP.SrcPort|tostring]|join(":")), ([.IP.DstIP,.UDP.DstPort|tostring]|join(":"))]'
F_TCP='[.Timestamp,"TCP",.Prefix, ([.IP.SrcIP,.TCP.SrcPort|tostring]|join(":")), ([.IP.DstIP,.TCP.DstPort|tostring]|join(":"))]'
cat "$F" \
| jq -r -c "if .UDP!=null then $F_UDP elif .TCP!=null then $F_TCP else empty end | @csv" \
| sed 's/"//g' > "$F_CSV"
IS_TABLE=0
if [ $IS_TABLE -eq 1 ]; then
SEL_ROW=$(gum table -c "ts, proto, prefix, src, dst" -w 30,8,10,20,20 --height 20 -f "$F_CSV")
else
SEL_ROW=$(cat "$F_CSV" \
| sed 's/,/ /g' \
| gum filter --no-fuzzy --indicator.foreground="99" --match.foreground="99" --height 20)
fi
SEL_TS=$(echo $SEL_ROW|sed 's/,/\t/g'|awk '{print $1}')
if [ -z "$SEL_TS" ]; then
exit
fi
SEL_JSON=$(cat "$F" | jq "select(.Timestamp == \"$SEL_TS\")")
echo "$SEL_JSON" | gum pager
}
gum style --foreground 99 --border double --border-foreground 99 --padding "0 4" --margin 1 "SPR packet logs cli"
gum input --placeholder="Press ENTER to start"
if [ ! -f "$F" ]; then
log_stream
fi
while true; do table; done
save the script in packetlogs.sh and run it:
./packetlogs.sh