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>
This commit is contained in:
parent
af8438ad24
commit
a8eb8b1271
@ -431,7 +431,8 @@
|
||||
"Bash(/tmp/build-zkp-x86.sh:*)",
|
||||
"Bash(__NEW_LINE_a9089175728efc91__ echo \"\")",
|
||||
"WebFetch(domain:pent.gk2.secubox.in)",
|
||||
"Bash(__NEW_LINE_84a971cd6a876509__ echo \"Done deploying to clone\")"
|
||||
"Bash(__NEW_LINE_84a971cd6a876509__ echo \"Done deploying to clone\")",
|
||||
"Bash(# Remove build artifacts from staging git reset HEAD -- package/secubox/zkp-hamiltonian/build-musl/ package/secubox/zkp-hamiltonian/build-static/ package/secubox/zkp-hamiltonian/build-x86/ # Add to gitignore echo \"\"package/secubox/zkp-hamiltonian/build-*/\"\" # Check status git status --short)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +54,9 @@ user_add() {
|
||||
mv "${passfile}.tmp" "$passfile"
|
||||
|
||||
# Sync to Dovecot inside container
|
||||
# Use correct uid:gid for vmail user (102:105) and proper mail path with userdb_mail
|
||||
# Use correct uid:gid for vmail user (5000:5000) and proper mail path with userdb_mail
|
||||
local mail_path="/var/mail/$domain/$user"
|
||||
local dovecot_entry="$email:$hash:102:105::$mail_path::userdb_mail=maildir:$mail_path"
|
||||
local dovecot_entry="$email:$hash:5000:5000::$mail_path::userdb_mail=maildir:$mail_path"
|
||||
|
||||
# Write to temp file first to avoid shell expansion issues with $6$ in hash
|
||||
local tmpfile="/tmp/dovecot_entry_$$"
|
||||
@ -139,14 +139,14 @@ user_passwd() {
|
||||
sed -i "s|^$email:.*|$email:$hash|" "$passfile"
|
||||
|
||||
# Sync to Dovecot inside container
|
||||
# Use correct uid:gid for vmail user (102:105) and proper mail path with userdb_mail
|
||||
# Use correct uid:gid for vmail user (5000:5000) and proper mail path with userdb_mail
|
||||
local user=$(echo "$email" | cut -d@ -f1)
|
||||
local domain=$(echo "$email" | cut -d@ -f2)
|
||||
local mail_path="/var/mail/$domain/$user"
|
||||
|
||||
# Build dovecot entry with proper format:
|
||||
# user:password:uid:gid:gecos:home:shell:userdb_mail=maildir:/path
|
||||
local dovecot_entry="$email:$hash:102:105::$mail_path::userdb_mail=maildir:$mail_path"
|
||||
local dovecot_entry="$email:$hash:5000:5000::$mail_path::userdb_mail=maildir:$mail_path"
|
||||
|
||||
# Write to temp file first to avoid shell expansion issues with $6$ in hash
|
||||
local tmpfile="/tmp/dovecot_entry_$$"
|
||||
|
||||
@ -206,12 +206,51 @@ gossip_receive() {
|
||||
# Process by type
|
||||
case "$type" in
|
||||
ioc)
|
||||
# Threat intelligence update
|
||||
if [ -f /usr/lib/secubox/threat-intel.sh ]; then
|
||||
. /usr/lib/secubox/threat-intel.sh
|
||||
local ioc_data
|
||||
ioc_data=$(echo "$message" | jsonfilter -e '@.data')
|
||||
threat_intel_receive "$ioc_data" "$origin"
|
||||
# Threat intelligence update - bridge to p2p-intel with ZKP trust
|
||||
local ioc_data
|
||||
ioc_data=$(echo "$message" | jsonfilter -e '@.data')
|
||||
|
||||
if [ -f /usr/lib/p2p-intel/validator.sh ]; then
|
||||
. /usr/lib/p2p-intel/validator.sh
|
||||
|
||||
# Validate IOC with ZKP-enhanced trust
|
||||
if _is_source_trusted "$origin"; then
|
||||
# Update reputation for valid IOC
|
||||
if [ -f /usr/lib/mirrornet/reputation.sh ]; then
|
||||
. /usr/lib/mirrornet/reputation.sh
|
||||
reputation_valid_ioc "$origin"
|
||||
fi
|
||||
|
||||
# Queue for application
|
||||
if [ -f /usr/lib/p2p-intel/applier.sh ]; then
|
||||
. /usr/lib/p2p-intel/applier.sh
|
||||
queue_pending "$ioc_data" "$origin"
|
||||
fi
|
||||
|
||||
# Track IOC source for feedback attribution
|
||||
if [ -f /usr/lib/p2p-intel/feedback.sh ]; then
|
||||
. /usr/lib/p2p-intel/feedback.sh
|
||||
local ioc_value ioc_type
|
||||
ioc_value=$(echo "$ioc_data" | jsonfilter -e '@.value' 2>/dev/null)
|
||||
ioc_type=$(echo "$ioc_data" | jsonfilter -e '@.type' 2>/dev/null)
|
||||
[ -n "$ioc_value" ] && feedback_track_ioc "$ioc_value" "$ioc_type" "$origin"
|
||||
fi
|
||||
|
||||
logger -t mirrornet "Gossip: valid IOC from ZKP-trusted $origin"
|
||||
else
|
||||
# Untrusted source
|
||||
if [ -f /usr/lib/mirrornet/reputation.sh ]; then
|
||||
. /usr/lib/mirrornet/reputation.sh
|
||||
reputation_invalid_ioc "$origin"
|
||||
fi
|
||||
logger -t mirrornet "Gossip: rejected IOC from untrusted $origin"
|
||||
fi
|
||||
else
|
||||
# Fallback to legacy threat-intel.sh
|
||||
if [ -f /usr/lib/secubox/threat-intel.sh ]; then
|
||||
. /usr/lib/secubox/threat-intel.sh
|
||||
threat_intel_receive "$ioc_data" "$origin"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
peer_status)
|
||||
|
||||
@ -22,6 +22,10 @@ SCORE_VALID_BLOCK=2
|
||||
SCORE_INVALID_BLOCK=-15
|
||||
SCORE_SPAM=-20
|
||||
|
||||
# IOC effectiveness feedback scores
|
||||
SCORE_IOC_EFFECTIVE=5
|
||||
SCORE_IOC_FALSE_POSITIVE=-8
|
||||
|
||||
# Initialize reputation storage
|
||||
reputation_init() {
|
||||
mkdir -p "$REPUTATION_DIR"
|
||||
|
||||
@ -17,6 +17,10 @@ config validation 'validation'
|
||||
option require_signature '1'
|
||||
option min_source_trust '40'
|
||||
# Minimum trust score to accept IOCs
|
||||
option zkp_trust_bonus '20'
|
||||
# Extra trust for ZKP-verified peers
|
||||
option zkp_require_for_critical '1'
|
||||
# Require ZKP verification for critical severity IOCs
|
||||
option verify_transitive '1'
|
||||
# Verify IOCs from peers-of-peers
|
||||
option max_age_hours '168'
|
||||
@ -38,3 +42,12 @@ config application 'application'
|
||||
# 24 hours default
|
||||
option whitelist_local '1'
|
||||
# Never block local subnets
|
||||
|
||||
config feedback 'feedback'
|
||||
option enabled '1'
|
||||
option track_effectiveness '1'
|
||||
# Track if IOCs actually blocked attacks
|
||||
option reputation_update '1'
|
||||
# Update peer reputation on feedback (+5/-8)
|
||||
option blockchain_record '1'
|
||||
# Record feedback to blockchain audit trail
|
||||
|
||||
@ -0,0 +1,175 @@
|
||||
#!/bin/sh
|
||||
# P2P Intel Blockchain - Permanent IOC recording on mesh blockchain
|
||||
# Records threat_ioc and ioc_feedback blocks for audit trail
|
||||
|
||||
. /usr/lib/secubox/p2p-mesh.sh 2>/dev/null
|
||||
|
||||
CHAIN_FILE="/srv/secubox/mesh/chain.json"
|
||||
INTEL_DIR="/var/lib/p2p-intel"
|
||||
PROCESSED_BLOCKS="$INTEL_DIR/processed-blocks.list"
|
||||
|
||||
# Initialize blockchain integration
|
||||
blockchain_init() {
|
||||
mkdir -p "$INTEL_DIR"
|
||||
[ -f "$PROCESSED_BLOCKS" ] || touch "$PROCESSED_BLOCKS"
|
||||
}
|
||||
|
||||
# Record IOC batch to blockchain
|
||||
# Usage: blockchain_record_iocs '<iocs_json_array>' '<source_did>'
|
||||
blockchain_record_iocs() {
|
||||
local iocs_json="$1"
|
||||
local source_did="$2"
|
||||
|
||||
[ -z "$iocs_json" ] && return 1
|
||||
[ "$iocs_json" = "[]" ] && return 0
|
||||
|
||||
local timestamp=$(date +%s)
|
||||
local node_id=$(cat /srv/secubox/mesh/node.id 2>/dev/null || echo "unknown")
|
||||
local ioc_count=$(echo "$iocs_json" | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
|
||||
[ "$ioc_count" -eq 0 ] && return 0
|
||||
|
||||
# Build block data
|
||||
local block_data="{\"version\":1,\"source\":\"$source_did\",\"count\":$ioc_count,\"iocs\":$iocs_json}"
|
||||
local block_hash=$(echo "${block_data}${timestamp}${node_id}" | sha256sum | cut -d' ' -f1)
|
||||
|
||||
# Add to blockchain
|
||||
if type chain_add_block >/dev/null 2>&1; then
|
||||
chain_add_block "threat_ioc" "$block_data" "$block_hash"
|
||||
logger -t p2p-intel "Recorded $ioc_count IOCs to blockchain (hash: ${block_hash:0:16})"
|
||||
echo "$block_hash"
|
||||
return 0
|
||||
else
|
||||
logger -t p2p-intel "Warning: chain_add_block not available"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Scan chain for unprocessed threat_ioc blocks from other nodes
|
||||
# Returns: IOCs as JSON lines (one per line)
|
||||
blockchain_scan_iocs() {
|
||||
[ -f "$CHAIN_FILE" ] || return 0
|
||||
[ -f "$PROCESSED_BLOCKS" ] || touch "$PROCESSED_BLOCKS"
|
||||
|
||||
local my_node=$(cat /srv/secubox/mesh/node.id 2>/dev/null)
|
||||
|
||||
jsonfilter -i "$CHAIN_FILE" -e '@.blocks[*]' 2>/dev/null | while read -r block; do
|
||||
local btype=$(echo "$block" | jsonfilter -e '@.type' 2>/dev/null)
|
||||
[ "$btype" = "threat_ioc" ] || continue
|
||||
|
||||
local bhash=$(echo "$block" | jsonfilter -e '@.hash' 2>/dev/null)
|
||||
local bnode=$(echo "$block" | jsonfilter -e '@.node' 2>/dev/null)
|
||||
|
||||
# Skip own blocks
|
||||
[ "$bnode" = "$my_node" ] && continue
|
||||
|
||||
# Skip already processed
|
||||
grep -q "$bhash" "$PROCESSED_BLOCKS" 2>/dev/null && continue
|
||||
|
||||
# Extract source for trust checking
|
||||
local source=$(echo "$block" | jsonfilter -e '@.data.source' 2>/dev/null)
|
||||
|
||||
# Output each IOC with source attribution
|
||||
echo "$block" | jsonfilter -e '@.data.iocs[*]' 2>/dev/null | while read -r ioc; do
|
||||
# Add source_node to IOC for trust tracking
|
||||
echo "$ioc" | sed "s/}$/,\"source_node\":\"$source\"}/g"
|
||||
done
|
||||
|
||||
# Mark as processed
|
||||
echo "$bhash" >> "$PROCESSED_BLOCKS"
|
||||
done
|
||||
}
|
||||
|
||||
# Count unprocessed threat_ioc blocks
|
||||
blockchain_pending_count() {
|
||||
[ -f "$CHAIN_FILE" ] || { echo "0"; return; }
|
||||
[ -f "$PROCESSED_BLOCKS" ] || touch "$PROCESSED_BLOCKS"
|
||||
|
||||
local my_node=$(cat /srv/secubox/mesh/node.id 2>/dev/null)
|
||||
local count=0
|
||||
|
||||
jsonfilter -i "$CHAIN_FILE" -e '@.blocks[*]' 2>/dev/null | while read -r block; do
|
||||
local btype=$(echo "$block" | jsonfilter -e '@.type' 2>/dev/null)
|
||||
[ "$btype" = "threat_ioc" ] || continue
|
||||
|
||||
local bhash=$(echo "$block" | jsonfilter -e '@.hash' 2>/dev/null)
|
||||
local bnode=$(echo "$block" | jsonfilter -e '@.node' 2>/dev/null)
|
||||
|
||||
[ "$bnode" = "$my_node" ] && continue
|
||||
grep -q "$bhash" "$PROCESSED_BLOCKS" 2>/dev/null && continue
|
||||
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
echo "$count"
|
||||
}
|
||||
|
||||
# Record IOC feedback to chain (effectiveness tracking)
|
||||
# Usage: blockchain_record_feedback '<ioc_hash>' '<feedback_type>' '<details>'
|
||||
# feedback_type: "effective" or "false_positive"
|
||||
blockchain_record_feedback() {
|
||||
local ioc_hash="$1"
|
||||
local feedback_type="$2"
|
||||
local details="${3:-}"
|
||||
|
||||
[ -z "$ioc_hash" ] || [ -z "$feedback_type" ] && return 1
|
||||
|
||||
local timestamp=$(date +%s)
|
||||
local node_id=$(cat /srv/secubox/mesh/node.id 2>/dev/null || echo "unknown")
|
||||
|
||||
local block_data="{\"ioc_hash\":\"$ioc_hash\",\"feedback\":\"$feedback_type\",\"reporter\":\"$node_id\",\"details\":\"$details\",\"ts\":$timestamp}"
|
||||
local block_hash=$(echo "${block_data}${timestamp}" | sha256sum | cut -d' ' -f1)
|
||||
|
||||
if type chain_add_block >/dev/null 2>&1; then
|
||||
chain_add_block "ioc_feedback" "$block_data" "$block_hash"
|
||||
logger -t p2p-intel "Recorded IOC feedback: $ioc_hash -> $feedback_type"
|
||||
echo "$block_hash"
|
||||
return 0
|
||||
else
|
||||
logger -t p2p-intel "Warning: chain_add_block not available"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get feedback statistics from blockchain
|
||||
blockchain_feedback_stats() {
|
||||
[ -f "$CHAIN_FILE" ] || { echo '{"effective":0,"false_positive":0}'; return; }
|
||||
|
||||
local effective=0
|
||||
local false_positive=0
|
||||
|
||||
jsonfilter -i "$CHAIN_FILE" -e '@.blocks[*]' 2>/dev/null | while read -r block; do
|
||||
local btype=$(echo "$block" | jsonfilter -e '@.type' 2>/dev/null)
|
||||
[ "$btype" = "ioc_feedback" ] || continue
|
||||
|
||||
local feedback=$(echo "$block" | jsonfilter -e '@.data.feedback' 2>/dev/null)
|
||||
case "$feedback" in
|
||||
effective) effective=$((effective + 1)) ;;
|
||||
false_positive) false_positive=$((false_positive + 1)) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "{\"effective\":$effective,\"false_positive\":$false_positive}"
|
||||
}
|
||||
|
||||
# Get threat_ioc block count
|
||||
blockchain_ioc_block_count() {
|
||||
[ -f "$CHAIN_FILE" ] || { echo "0"; return; }
|
||||
|
||||
jsonfilter -i "$CHAIN_FILE" -e '@.blocks[*].type' 2>/dev/null | grep -c "threat_ioc" || echo "0"
|
||||
}
|
||||
|
||||
# Clean old processed blocks list (keep last 1000)
|
||||
blockchain_cleanup() {
|
||||
[ -f "$PROCESSED_BLOCKS" ] || return 0
|
||||
|
||||
local lines=$(wc -l < "$PROCESSED_BLOCKS")
|
||||
if [ "$lines" -gt 1000 ]; then
|
||||
tail -n 1000 "$PROCESSED_BLOCKS" > "$PROCESSED_BLOCKS.tmp"
|
||||
mv "$PROCESSED_BLOCKS.tmp" "$PROCESSED_BLOCKS"
|
||||
logger -t p2p-intel "Cleaned processed blocks list (kept last 1000)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Initialize on source
|
||||
blockchain_init
|
||||
@ -0,0 +1,282 @@
|
||||
#!/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
|
||||
@ -27,21 +27,56 @@ _is_too_old() {
|
||||
[ "$age" -gt "$max_age_seconds" ]
|
||||
}
|
||||
|
||||
# Check if source is trusted
|
||||
# Check if peer has ZKP verification on blockchain
|
||||
_check_zkp_verified() {
|
||||
local peer_id="$1"
|
||||
local chain_file="/srv/secubox/mesh/chain.json"
|
||||
|
||||
[ -f "$chain_file" ] || { echo "0"; return 1; }
|
||||
|
||||
# Search for peer_zkp_verified block with matching peer_fp
|
||||
local found=0
|
||||
jsonfilter -i "$chain_file" -e '@.blocks[*]' 2>/dev/null | while read -r block; do
|
||||
local btype=$(echo "$block" | jsonfilter -e '@.type' 2>/dev/null)
|
||||
[ "$btype" = "peer_zkp_verified" ] || continue
|
||||
|
||||
local peer_fp=$(echo "$block" | jsonfilter -e '@.data.peer_fp' 2>/dev/null)
|
||||
local result=$(echo "$block" | jsonfilter -e '@.data.result' 2>/dev/null)
|
||||
|
||||
# Match peer_id (could be ZKP fingerprint or node ID)
|
||||
if [ "$peer_fp" = "$peer_id" ] && [ "$result" = "ACCEPT" ]; then
|
||||
echo "1"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "0"
|
||||
}
|
||||
|
||||
# Check if source is trusted (with ZKP bonus)
|
||||
_is_source_trusted() {
|
||||
local source_did="$1"
|
||||
local min_trust
|
||||
min_trust=$(uci -q get p2p-intel.validation.min_source_trust || echo "40")
|
||||
local zkp_bonus
|
||||
zkp_bonus=$(uci -q get p2p-intel.validation.zkp_trust_bonus || echo "20")
|
||||
|
||||
local base_score=50 # Default for new/unknown peers
|
||||
|
||||
# Get score from identity trust system if available
|
||||
if [ -f /usr/lib/secubox-identity/trust.sh ]; then
|
||||
. /usr/lib/secubox-identity/trust.sh
|
||||
local score
|
||||
score=$(trust_get_score "$source_did")
|
||||
[ "$score" -ge "$min_trust" ]
|
||||
else
|
||||
# No trust system, accept all
|
||||
return 0
|
||||
base_score=$(trust_get_score "$source_did" 2>/dev/null || echo "50")
|
||||
fi
|
||||
|
||||
# Add ZKP bonus if peer is ZKP-verified on blockchain
|
||||
local zkp_verified=$(_check_zkp_verified "$source_did")
|
||||
if [ "$zkp_verified" = "1" ]; then
|
||||
base_score=$((base_score + zkp_bonus))
|
||||
logger -t p2p-intel "ZKP trust bonus applied for $source_did (score: $base_score)"
|
||||
fi
|
||||
|
||||
[ "$base_score" -ge "$min_trust" ]
|
||||
}
|
||||
|
||||
# Check if IP is in local subnet (whitelist)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user