littleshop/TeleBot/Scripts/tor-health-monitor.sh
SysAdmin d31c0b4aeb CI/CD: Add GitLab CI/CD pipeline for Hostinger deployment
- Updated .gitlab-ci.yml with complete build, test, and deploy stages
- Added authentication redirect fix in Program.cs (302 redirect for admin routes)
- Fixed Cookie vs Bearer authentication conflict for admin panel
- Configure pipeline to build from .NET 9.0 source
- Deploy to Hostinger VPS with proper environment variables
- Include rollback capability for production deployments

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-01 13:10:48 +01:00

347 lines
9.6 KiB
Bash

#!/bin/bash
################################################################################
# TOR Health Monitoring Script
#
# Purpose: Continuous monitoring of TOR connectivity and TeleBot TOR usage
# Usage: ./tor-health-monitor.sh [--daemon] [--interval=60]
# Output: Health reports and alerts
#
# Features:
# - Real-time TOR connectivity monitoring
# - Circuit health tracking
# - IP leak detection
# - Automated alerting
# - Historical logging
#
# Author: Mr Tickles, Security Consultant
# Date: 2025-10-01
################################################################################
set -euo pipefail
# Configuration
INTERVAL=60 # Check interval in seconds
DAEMON_MODE=false
LOG_DIR="/var/log/telebot"
HEALTH_LOG="$LOG_DIR/tor-health.log"
ALERT_LOG="$LOG_DIR/tor-alerts.log"
STATE_DIR="/var/lib/telebot"
TOR_SOCKS_PORT=9050
EMAIL_ALERTS=false
ALERT_EMAIL="admin@example.com"
# Parse arguments
for arg in "$@"; do
case $arg in
--daemon)
DAEMON_MODE=true
shift
;;
--interval=*)
INTERVAL="${arg#*=}"
shift
;;
--email=*)
ALERT_EMAIL="${arg#*=}"
EMAIL_ALERTS=true
shift
;;
*)
;;
esac
done
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Create directories
mkdir -p "$LOG_DIR" "$STATE_DIR"
################################################################################
# Logging Functions
################################################################################
log() {
local level=$1
shift
local message="$@"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" >> "$HEALTH_LOG"
if [ "$DAEMON_MODE" = false ]; then
case $level in
INFO)
echo -e "${BLUE}[INFO]${NC} $message"
;;
SUCCESS)
echo -e "${GREEN}[✓]${NC} $message"
;;
WARNING)
echo -e "${YELLOW}[⚠]${NC} $message"
;;
ERROR)
echo -e "${RED}[✗]${NC} $message"
;;
ALERT)
echo -e "${RED}[ALERT]${NC} $message"
echo "[$timestamp] [ALERT] $message" >> "$ALERT_LOG"
;;
esac
fi
}
send_alert() {
local subject="$1"
local message="$2"
log ALERT "$subject: $message"
if [ "$EMAIL_ALERTS" = true ]; then
echo "$message" | mail -s "TeleBot TOR Alert: $subject" "$ALERT_EMAIL" 2>/dev/null || true
fi
}
################################################################################
# Health Check Functions
################################################################################
check_tor_service() {
if systemctl is-active --quiet tor 2>/dev/null; then
log SUCCESS "TOR service is running"
return 0
else
log ERROR "TOR service is not running"
send_alert "TOR Service Down" "TOR service is not running. TeleBot location is EXPOSED!"
return 1
fi
}
check_tor_socks() {
if netstat -tln 2>/dev/null | grep -q ":${TOR_SOCKS_PORT} "; then
log SUCCESS "TOR SOCKS5 proxy is listening on port ${TOR_SOCKS_PORT}"
return 0
else
log ERROR "TOR SOCKS5 proxy is not listening"
send_alert "TOR SOCKS5 Down" "TOR SOCKS5 proxy not available. Traffic cannot be routed through TOR!"
return 1
fi
}
check_tor_circuits() {
local bootstrap_status=$(journalctl -u tor -n 100 --no-pager 2>/dev/null | \
grep -i "Bootstrapped" | tail -1)
if echo "$bootstrap_status" | grep -q "100%"; then
log SUCCESS "TOR circuits are established (100%)"
return 0
else
log WARNING "TOR circuits may not be fully established"
return 1
fi
}
check_tor_ip() {
local tor_ip=""
local direct_ip=""
# Get IP through TOR
tor_ip=$(timeout 15 curl --socks5 127.0.0.1:${TOR_SOCKS_PORT} -s https://api.ipify.org 2>/dev/null || echo "")
if [ -z "$tor_ip" ]; then
log ERROR "Failed to get IP through TOR"
return 1
fi
# Get direct IP
direct_ip=$(timeout 10 curl -s https://api.ipify.org 2>/dev/null || echo "")
if [ -z "$direct_ip" ]; then
log WARNING "Failed to get direct IP (network issue?)"
return 0
fi
# Compare IPs
if [ "$tor_ip" != "$direct_ip" ]; then
log SUCCESS "TOR IP ($tor_ip) is different from direct IP ($direct_ip)"
# Save IPs for tracking
echo "$tor_ip" > "$STATE_DIR/current_tor_ip"
echo "$direct_ip" > "$STATE_DIR/real_ip"
return 0
else
log ERROR "TOR IP matches direct IP - TOR may not be working!"
send_alert "TOR IP Mismatch" "TOR IP ($tor_ip) matches direct IP! TOR may be bypassed!"
return 1
fi
}
check_telebot_process() {
if pgrep -f "TeleBot" > /dev/null; then
local pid=$(pgrep -f "TeleBot" | head -1)
log SUCCESS "TeleBot is running (PID: $pid)"
# Check TOR connections
local tor_conns=$(lsof -p "$pid" -i TCP 2>/dev/null | grep -c ":${TOR_SOCKS_PORT}" || echo 0)
if [ "$tor_conns" -gt 0 ]; then
log SUCCESS "TeleBot has $tor_conns active TOR connections"
else
log WARNING "TeleBot has no active TOR connections"
fi
return 0
else
log WARNING "TeleBot is not running"
return 1
fi
}
check_ip_leaks() {
if ! pgrep -f "TeleBot" > /dev/null; then
return 0 # Can't check if not running
fi
local pid=$(pgrep -f "TeleBot" | head -1)
# Check for direct external connections
local external_conns=$(ss -tnp 2>/dev/null | grep "$pid" | \
grep -v "127.0.0.1" | \
grep -v "::1" | \
grep -v ":${TOR_SOCKS_PORT}" | \
wc -l)
if [ "$external_conns" -eq 0 ]; then
log SUCCESS "No IP leaks detected (all connections through TOR)"
return 0
else
log ERROR "Detected $external_conns direct external connections - IP LEAK!"
send_alert "IP Leak Detected" "TeleBot has $external_conns direct external connections not through TOR!"
# Log the suspicious connections
ss -tnp 2>/dev/null | grep "$pid" | \
grep -v "127.0.0.1" | \
grep -v "::1" | \
grep -v ":${TOR_SOCKS_PORT}" >> "$ALERT_LOG"
return 1
fi
}
check_dns_leaks() {
# Monitor for DNS queries not through TOR
local dns_count=$(timeout 5 tcpdump -i any -c 10 'port 53' 2>/dev/null | wc -l || echo 0)
if [ "$dns_count" -eq 0 ]; then
log SUCCESS "No DNS leaks detected"
return 0
else
log WARNING "Detected DNS queries - potential DNS leak"
return 1
fi
}
################################################################################
# Performance Metrics
################################################################################
measure_tor_latency() {
local start_time=$(date +%s%N)
local test_result=$(timeout 10 curl --socks5 127.0.0.1:${TOR_SOCKS_PORT} -s -o /dev/null -w "%{http_code}" https://check.torproject.org 2>/dev/null || echo "0")
local end_time=$(date +%s%N)
if [ "$test_result" = "200" ]; then
local latency=$(( (end_time - start_time) / 1000000 )) # Convert to milliseconds
log INFO "TOR latency: ${latency}ms"
echo "$latency" > "$STATE_DIR/tor_latency"
if [ "$latency" -gt 5000 ]; then
log WARNING "TOR latency is high (${latency}ms)"
fi
return 0
else
log ERROR "Failed to measure TOR latency"
return 1
fi
}
################################################################################
# Main Health Check
################################################################################
run_health_check() {
local check_id=$(date +%Y%m%d_%H%M%S)
log INFO "==================== Health Check $check_id ===================="
local total_checks=0
local passed_checks=0
# Run all checks
for check in check_tor_service check_tor_socks check_tor_circuits \
check_tor_ip check_telebot_process check_ip_leaks \
check_dns_leaks measure_tor_latency; do
total_checks=$((total_checks + 1))
if $check; then
passed_checks=$((passed_checks + 1))
fi
done
# Calculate health score
local health_score=$((passed_checks * 100 / total_checks))
log INFO "Health Score: $health_score% ($passed_checks/$total_checks checks passed)"
# Save health score
echo "$health_score" > "$STATE_DIR/health_score"
# Alert if health is poor
if [ "$health_score" -lt 80 ]; then
send_alert "Poor Health Score" "TOR health score is $health_score%. Review logs: $HEALTH_LOG"
fi
log INFO "================================================================"
echo ""
}
################################################################################
# Daemon Mode
################################################################################
run_daemon() {
log INFO "Starting TOR health monitor daemon (interval: ${INTERVAL}s)"
# Create PID file
echo $$ > "$STATE_DIR/monitor.pid"
# Trap signals
trap 'log INFO "Stopping TOR health monitor daemon"; rm -f "$STATE_DIR/monitor.pid"; exit 0' SIGTERM SIGINT
while true; do
run_health_check
sleep "$INTERVAL"
done
}
################################################################################
# Main
################################################################################
main() {
if [ "$DAEMON_MODE" = true ]; then
run_daemon
else
run_health_check
fi
}
# Execute
main "$@"