secubox-openwrt/package/secubox/secubox-p2p-intel/files/usr/lib/p2p-intel/feedback.sh
CyberMind-FR a8eb8b1271 feat(p2p-intel): ZKP trust integration and IOC blockchain recording
P2P Mesh Intelligence implementation:
- Add ZKP trust bonus (+20) for verified peers in IOC validation
- Create blockchain.sh for permanent threat_ioc and ioc_feedback blocks
- Create feedback.sh for IOC effectiveness tracking and reputation updates
- Enhance gossip.sh IOC handler with ZKP-validated trust checks
- Add SCORE_IOC_EFFECTIVE (+5) and SCORE_IOC_FALSE_POSITIVE (-8) to reputation
- Add zkp_trust_bonus and feedback config options

fix(mailserver): Correct vmail UID from 102 to 5000

Dovecot was using wrong UID (102/redis instead of 5000/vmail) causing
permission denied errors when accessing mailboxes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-24 17:20:33 +01:00

283 lines
8.8 KiB
Bash

#!/bin/sh
# P2P Intel Feedback - Track IOC effectiveness and update peer reputation
# Records effectiveness tracking for audit trail and reputation updates
. /usr/lib/p2p-intel/blockchain.sh 2>/dev/null
FEEDBACK_DIR="/var/lib/p2p-intel/feedback"
EFFECTIVENESS_LOG="$FEEDBACK_DIR/effectiveness.json"
IOC_TRACKING_FILE="$FEEDBACK_DIR/ioc-tracking.json"
# Reputation score adjustments for IOC feedback
SCORE_IOC_EFFECTIVE=5
SCORE_IOC_FALSE_POSITIVE=-8
# Initialize feedback storage
feedback_init() {
mkdir -p "$FEEDBACK_DIR"
[ -f "$EFFECTIVENESS_LOG" ] || echo '[]' > "$EFFECTIVENESS_LOG"
[ -f "$IOC_TRACKING_FILE" ] || echo '{}' > "$IOC_TRACKING_FILE"
}
# Generate IOC hash for tracking
_ioc_hash() {
local ioc_value="$1"
echo "$ioc_value" | sha256sum | cut -c1-16
}
# Track IOC source for later feedback attribution
feedback_track_ioc() {
local ioc_value="$1"
local ioc_type="$2"
local source_node="$3"
local timestamp
timestamp=$(date +%s)
local ioc_hash
ioc_hash=$(_ioc_hash "$ioc_value")
local entry="{\"hash\":\"$ioc_hash\",\"value\":\"$ioc_value\",\"type\":\"$ioc_type\",\"source\":\"$source_node\",\"received_at\":$timestamp}"
local tmp_file="/tmp/ioc_tracking_$$.json"
if [ -s "$IOC_TRACKING_FILE" ] && [ "$(cat "$IOC_TRACKING_FILE")" != "{}" ]; then
# Add or update entry
if grep -q "\"$ioc_hash\"" "$IOC_TRACKING_FILE"; then
# Already tracked
return 0
fi
# Add new entry
sed "s/^{/{\"$ioc_hash\":$entry,/" "$IOC_TRACKING_FILE" > "$tmp_file"
else
echo "{\"$ioc_hash\":$entry}" > "$tmp_file"
fi
mv "$tmp_file" "$IOC_TRACKING_FILE"
}
# Get source node for an IOC
_get_ioc_source() {
local ioc_value="$1"
local ioc_hash
ioc_hash=$(_ioc_hash "$ioc_value")
jsonfilter -i "$IOC_TRACKING_FILE" -e "@[\"$ioc_hash\"].source" 2>/dev/null
}
# Record effective IOC (blocked an attack)
# Usage: feedback_ioc_effective '<ip_or_ioc>' [source_node]
feedback_ioc_effective() {
local ioc_value="$1"
local source_node="${2:-}"
local timestamp
timestamp=$(date +%s)
# Get source from tracking if not provided
if [ -z "$source_node" ]; then
source_node=$(_get_ioc_source "$ioc_value")
fi
[ -z "$source_node" ] && {
logger -t p2p-intel "Warning: Cannot attribute effectiveness - no source for $ioc_value"
return 1
}
local ioc_hash
ioc_hash=$(_ioc_hash "$ioc_value")
# Record to blockchain for permanent audit trail
if type blockchain_record_feedback >/dev/null 2>&1; then
blockchain_record_feedback "$ioc_hash" "effective" "blocked_attack"
fi
# Log locally
local entry="{\"type\":\"effective\",\"ioc_hash\":\"$ioc_hash\",\"ioc_value\":\"$ioc_value\",\"source\":\"$source_node\",\"timestamp\":$timestamp}"
_append_effectiveness "$entry"
# Update peer reputation (+5)
if [ -f /usr/lib/mirrornet/reputation.sh ]; then
. /usr/lib/mirrornet/reputation.sh
reputation_adjust "$source_node" "$SCORE_IOC_EFFECTIVE" "ioc_effective"
fi
logger -t p2p-intel "IOC effective: $ioc_value from $source_node (+$SCORE_IOC_EFFECTIVE rep)"
}
# Mark IOC as false positive
# Usage: feedback_false_positive '<ip_or_ioc>' [source_node] [reason]
feedback_false_positive() {
local ioc_value="$1"
local source_node="${2:-}"
local reason="${3:-manual_override}"
local timestamp
timestamp=$(date +%s)
# Get source from tracking if not provided
if [ -z "$source_node" ]; then
source_node=$(_get_ioc_source "$ioc_value")
fi
[ -z "$source_node" ] && {
logger -t p2p-intel "Warning: Cannot attribute false positive - no source for $ioc_value"
return 1
}
local ioc_hash
ioc_hash=$(_ioc_hash "$ioc_value")
# Record to blockchain for permanent audit trail
if type blockchain_record_feedback >/dev/null 2>&1; then
blockchain_record_feedback "$ioc_hash" "false_positive" "$reason"
fi
# Log locally
local entry="{\"type\":\"false_positive\",\"ioc_hash\":\"$ioc_hash\",\"ioc_value\":\"$ioc_value\",\"source\":\"$source_node\",\"reason\":\"$reason\",\"timestamp\":$timestamp}"
_append_effectiveness "$entry"
# Update peer reputation (-8)
if [ -f /usr/lib/mirrornet/reputation.sh ]; then
. /usr/lib/mirrornet/reputation.sh
reputation_adjust "$source_node" "$SCORE_IOC_FALSE_POSITIVE" "ioc_false_positive"
fi
logger -t p2p-intel "IOC false positive: $ioc_value from $source_node ($SCORE_IOC_FALSE_POSITIVE rep) - $reason"
}
# Append to effectiveness log
_append_effectiveness() {
local entry="$1"
local tmp_file="/tmp/effectiveness_$$.json"
if [ -s "$EFFECTIVENESS_LOG" ] && [ "$(cat "$EFFECTIVENESS_LOG")" != "[]" ]; then
sed 's/]$//' "$EFFECTIVENESS_LOG" > "$tmp_file"
echo ",$entry]" >> "$tmp_file"
else
echo "[$entry]" > "$tmp_file"
fi
mv "$tmp_file" "$EFFECTIVENESS_LOG"
}
# Get effectiveness stats for a peer
feedback_peer_stats() {
local peer_id="$1"
[ -f "$EFFECTIVENESS_LOG" ] || { echo '{"effective":0,"false_positive":0,"ratio":0}'; return; }
local effective=0
local false_positive=0
# Count from effectiveness log
effective=$(grep -c "\"source\":\"$peer_id\".*\"type\":\"effective\"" "$EFFECTIVENESS_LOG" 2>/dev/null || echo 0)
false_positive=$(grep -c "\"source\":\"$peer_id\".*\"type\":\"false_positive\"" "$EFFECTIVENESS_LOG" 2>/dev/null || echo 0)
# Calculate ratio (effectiveness percentage)
local total=$((effective + false_positive))
local ratio=0
if [ "$total" -gt 0 ]; then
ratio=$((effective * 100 / total))
fi
echo "{\"effective\":$effective,\"false_positive\":$false_positive,\"total\":$total,\"ratio\":$ratio}"
}
# Get global effectiveness stats
feedback_global_stats() {
[ -f "$EFFECTIVENESS_LOG" ] || { echo '{"effective":0,"false_positive":0,"total":0}'; return; }
local effective=0
local false_positive=0
effective=$(grep -c '"type":"effective"' "$EFFECTIVENESS_LOG" 2>/dev/null || echo 0)
false_positive=$(grep -c '"type":"false_positive"' "$EFFECTIVENESS_LOG" 2>/dev/null || echo 0)
local total=$((effective + false_positive))
echo "{\"effective\":$effective,\"false_positive\":$false_positive,\"total\":$total}"
}
# Get recent feedback events
feedback_recent() {
local count="${1:-20}"
[ -f "$EFFECTIVENESS_LOG" ] || { echo '[]'; return; }
# Get last N entries (simple tail approximation)
local total
total=$(grep -c '"type":' "$EFFECTIVENESS_LOG" 2>/dev/null || echo 0)
if [ "$total" -le "$count" ]; then
cat "$EFFECTIVENESS_LOG"
else
# Return last N entries using jsonfilter
jsonfilter -i "$EFFECTIVENESS_LOG" -e "@[-$count:]" 2>/dev/null || cat "$EFFECTIVENESS_LOG"
fi
}
# Check if peer has poor effectiveness (for trust decisions)
feedback_peer_reliability() {
local peer_id="$1"
local min_samples="${2:-5}"
local min_ratio="${3:-60}"
local stats
stats=$(feedback_peer_stats "$peer_id")
local total ratio
total=$(echo "$stats" | jsonfilter -e '@.total' 2>/dev/null || echo 0)
ratio=$(echo "$stats" | jsonfilter -e '@.ratio' 2>/dev/null || echo 100)
# Not enough samples = assume good
if [ "$total" -lt "$min_samples" ]; then
echo "unknown"
return 0
fi
if [ "$ratio" -ge "$min_ratio" ]; then
echo "reliable"
return 0
else
echo "unreliable"
return 1
fi
}
# Cleanup old tracking data
feedback_cleanup() {
local max_entries="${1:-10000}"
local max_age_days="${2:-30}"
# Clean effectiveness log if too large
if [ -f "$EFFECTIVENESS_LOG" ]; then
local count
count=$(grep -c '"type":' "$EFFECTIVENESS_LOG" 2>/dev/null || echo 0)
if [ "$count" -gt "$max_entries" ]; then
local keep=$((max_entries / 2))
local tmp_file="/tmp/effectiveness_$$.json"
jsonfilter -i "$EFFECTIVENESS_LOG" -e "@[-$keep:]" > "$tmp_file" 2>/dev/null || echo "[]" > "$tmp_file"
mv "$tmp_file" "$EFFECTIVENESS_LOG"
logger -t p2p-intel "Cleaned effectiveness log (kept last $keep entries)"
fi
fi
# Clean IOC tracking (remove entries older than max_age_days)
if [ -f "$IOC_TRACKING_FILE" ]; then
local current_time cutoff_time
current_time=$(date +%s)
cutoff_time=$((current_time - max_age_days * 86400))
# Simple size-based cleanup for now
local file_size
file_size=$(stat -f%z "$IOC_TRACKING_FILE" 2>/dev/null || stat -c%s "$IOC_TRACKING_FILE" 2>/dev/null || echo 0)
if [ "$file_size" -gt 1048576 ]; then # 1MB
echo '{}' > "$IOC_TRACKING_FILE"
logger -t p2p-intel "Reset IOC tracking file (size limit)"
fi
fi
}
# Initialize on source
feedback_init