#!/usr/bin/env bash # ────────────────────────────────────────────────────────────── # simulate_accesses.sh # # Writes synthetic HTTP-scan log lines to a file that matches # the bangui-access fail2ban filter. Use this to populate the # Access List tab in BanGUI without a real web server. # # Usage: # bash Docker/simulate_accesses.sh [COUNT] [SOURCE_IP] [LOG_FILE] # # Defaults: # COUNT : 5 # SOURCE_IP: 203.0.113.7 # LOG_FILE : Docker/logs/access.log (relative to repo root) # # Log line format (must match bangui-access failregex exactly): # YYYY-MM-DD HH:MM:SS bangui-access: http scan from " HTTP/1.1" # # fail2ban bans the IP after maxretry (default 3) matching lines. # ────────────────────────────────────────────────────────────── set -euo pipefail # ── Defaults ────────────────────────────────────────────────── readonly DEFAULT_COUNT=5 readonly DEFAULT_IP="203.0.113.7" # Resolve script location so defaults work regardless of cwd. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly DEFAULT_LOG_FILE="${SCRIPT_DIR}/logs/access.log" # ── Arguments ───────────────────────────────────────────────── COUNT="${1:-${DEFAULT_COUNT}}" SOURCE_IP="${2:-${DEFAULT_IP}}" LOG_FILE="${3:-${DEFAULT_LOG_FILE}}" # ── Validate COUNT is a positive integer ────────────────────── if ! [[ "${COUNT}" =~ ^[1-9][0-9]*$ ]]; then echo "ERROR: COUNT must be a positive integer, got: '${COUNT}'" >&2 exit 1 fi # ── Common bot-scan paths ───────────────────────────────────── PATHS=( "GET /.env HTTP/1.1" "GET /wp-login.php HTTP/1.1" "GET /admin HTTP/1.1" "POST /wp-login.php HTTP/1.1" "GET /.git/config HTTP/1.1" "GET /phpinfo.php HTTP/1.1" "GET /wp-config.php HTTP/1.1" "GET /phpmyadmin HTTP/1.1" ) readonly PATHS NUM_PATHS="${#PATHS[@]}" # ── Ensure log directory exists ─────────────────────────────── LOG_DIR="$(dirname "${LOG_FILE}")" mkdir -p "${LOG_DIR}" # ── Write scan lines ────────────────────────────────────────── echo "Writing ${COUNT} HTTP-scan line(s) for ${SOURCE_IP} to ${LOG_FILE} ..." for ((i = 1; i <= COUNT; i++)); do TIMESTAMP="$(date '+%Y-%m-%d %H:%M:%S')" # Cycle through the scan paths so each run looks varied. PATH_ENTRY="${PATHS[$(( (i - 1) % NUM_PATHS ))]}" printf '%s bangui-access: http scan from %s "%s" 404\n' \ "${TIMESTAMP}" "${SOURCE_IP}" "${PATH_ENTRY}" >> "${LOG_FILE}" sleep 0.5 done # ── Summary ─────────────────────────────────────────────────── echo "Done." echo " Lines written : ${COUNT}" echo " Source IP : ${SOURCE_IP}" echo " Log file : ${LOG_FILE}" echo "" echo " fail2ban bans after maxretry=3 matching lines." echo " Check ban status with: bash Docker/check_ban_status.sh"