181 lines
5.1 KiB
Bash
Executable File
181 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# /usr/local/bin/opsec-traffic-blend.sh — Decoy Traffic Blending Daemon
|
|
# Generates background browsing noise through Tor/VPN to blend tool traffic
|
|
# with normal-looking web activity. Ghost mode only.
|
|
# Usage: opsec-traffic-blend.sh start|stop|status
|
|
|
|
set -euo pipefail
|
|
|
|
PID_FILE="/var/run/opsec-traffic-blend.pid"
|
|
LOG_FILE="/var/log/opsec-traffic-blend.log"
|
|
|
|
# Source config
|
|
OPSEC_CONF="/etc/opsec/opsec.conf"
|
|
[ -f "$OPSEC_CONF" ] && . "$OPSEC_CONF"
|
|
|
|
SOCKS_PORT="${TOR_SOCKS_PORT:-9050}"
|
|
# Mean interval in seconds (Poisson distribution approximation)
|
|
BLEND_INTERVAL="${TRAFFIC_BLEND_INTERVAL:-30}"
|
|
|
|
# Color helpers
|
|
_green() { echo -e "\033[38;5;49m[+] $*\033[0m"; }
|
|
_red() { echo -e "\033[38;5;196m[-] $*\033[0m"; }
|
|
_yellow() { echo -e "\033[38;5;214m[*] $*\033[0m"; }
|
|
|
|
# Benign URLs to simulate normal browsing (mix of news, tech, social)
|
|
DECOY_URLS=(
|
|
"https://en.wikipedia.org/wiki/Special:Random"
|
|
"https://www.bbc.com/news"
|
|
"https://news.ycombinator.com"
|
|
"https://www.reuters.com"
|
|
"https://stackoverflow.com/questions"
|
|
"https://github.com/trending"
|
|
"https://www.reddit.com/r/technology/.json"
|
|
"https://www.weather.gov"
|
|
"https://httpbin.org/get"
|
|
"https://www.kernel.org"
|
|
"https://www.python.org"
|
|
"https://www.debian.org"
|
|
"https://archive.org"
|
|
"https://www.mozilla.org"
|
|
"https://duckduckgo.com/?q=weather"
|
|
"https://lite.cnn.com"
|
|
"https://text.npr.org"
|
|
)
|
|
|
|
# Random delay using Poisson-like distribution (exponential inter-arrival)
|
|
poisson_delay() {
|
|
# Approximate exponential distribution using bash
|
|
# -ln(U) * mean where U is uniform(0,1)
|
|
local mean="$1"
|
|
local rand
|
|
rand=$((RANDOM % 1000 + 1))
|
|
# Approximate: -ln(rand/1000) * mean
|
|
# Using awk for floating point
|
|
awk -v r="$rand" -v m="$mean" 'BEGIN {
|
|
u = r / 1000.0;
|
|
if (u < 0.001) u = 0.001;
|
|
delay = -log(u) * m;
|
|
if (delay < 5) delay = 5;
|
|
if (delay > 120) delay = 120;
|
|
printf "%d\n", delay;
|
|
}'
|
|
}
|
|
|
|
is_running() {
|
|
[ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE" 2>/dev/null)" 2>/dev/null
|
|
}
|
|
|
|
blend_loop() {
|
|
local url_count=${#DECOY_URLS[@]}
|
|
|
|
echo "[$(date -Is)] Traffic blend daemon started (mean interval: ${BLEND_INTERVAL}s)" >> "$LOG_FILE"
|
|
|
|
while true; do
|
|
# Pick a random URL
|
|
local idx=$((RANDOM % url_count))
|
|
local url="${DECOY_URLS[$idx]}"
|
|
|
|
# Determine proxy method
|
|
local curl_opts=("--silent" "--output" "/dev/null" "--max-time" "15")
|
|
|
|
# Use Tor SOCKS if available
|
|
if ss -tln 2>/dev/null | grep -q ":${SOCKS_PORT} "; then
|
|
curl_opts+=("--socks5-hostname" "127.0.0.1:${SOCKS_PORT}")
|
|
fi
|
|
|
|
# Add realistic headers
|
|
curl_opts+=("-H" "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0")
|
|
curl_opts+=("-H" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
|
|
curl_opts+=("-H" "Accept-Language: en-US,en;q=0.5")
|
|
|
|
# Make the request
|
|
curl "${curl_opts[@]}" "$url" 2>/dev/null || true
|
|
|
|
# Calculate next delay (Poisson-distributed)
|
|
local delay
|
|
delay=$(poisson_delay "$BLEND_INTERVAL")
|
|
|
|
sleep "$delay"
|
|
done
|
|
}
|
|
|
|
blend_start() {
|
|
if ! [ -f /var/run/opsec-advanced.enabled ]; then
|
|
_yellow "Traffic blending requires ghost mode to be active"
|
|
return 1
|
|
fi
|
|
|
|
if is_running; then
|
|
_yellow "Traffic blend already running (PID $(cat "$PID_FILE"))"
|
|
return 0
|
|
fi
|
|
|
|
# Start the blend loop as a background process
|
|
blend_loop &
|
|
local pid=$!
|
|
echo "$pid" > "$PID_FILE"
|
|
disown "$pid"
|
|
|
|
sleep 1
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
_green "Traffic blend started (PID ${pid}, mean interval ${BLEND_INTERVAL}s)"
|
|
else
|
|
rm -f "$PID_FILE"
|
|
_red "Traffic blend failed to start"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
blend_stop() {
|
|
if ! is_running; then
|
|
_yellow "Traffic blend not running"
|
|
rm -f "$PID_FILE"
|
|
return 0
|
|
fi
|
|
|
|
local pid
|
|
pid=$(cat "$PID_FILE" 2>/dev/null)
|
|
kill "$pid" 2>/dev/null || true
|
|
|
|
# Wait for process to stop
|
|
local i=0
|
|
while kill -0 "$pid" 2>/dev/null && [ $i -lt 5 ]; do
|
|
sleep 1
|
|
i=$((i + 1))
|
|
done
|
|
|
|
kill -9 "$pid" 2>/dev/null || true
|
|
rm -f "$PID_FILE"
|
|
|
|
echo "[$(date -Is)] Traffic blend daemon stopped" >> "$LOG_FILE"
|
|
_green "Traffic blend stopped"
|
|
}
|
|
|
|
blend_status() {
|
|
if is_running; then
|
|
local pid
|
|
pid=$(cat "$PID_FILE" 2>/dev/null)
|
|
_green "Traffic blend ACTIVE (PID ${pid})"
|
|
_yellow "Mean interval: ${BLEND_INTERVAL}s"
|
|
else
|
|
_yellow "Traffic blend NOT running"
|
|
rm -f "$PID_FILE"
|
|
fi
|
|
}
|
|
|
|
case "${1:-}" in
|
|
start) blend_start ;;
|
|
stop) blend_stop ;;
|
|
restart)
|
|
blend_stop
|
|
sleep 1
|
|
blend_start
|
|
;;
|
|
status) blend_status ;;
|
|
*)
|
|
echo "Usage: opsec-traffic-blend.sh start|stop|status|restart"
|
|
exit 1
|
|
;;
|
|
esac
|