Load Testing Script Explanation

This page provides a detailed explanation of a Bash script designed for load testing. The script sends requests to a target URL and IP address, using both random IPv4 and IPv6 addresses, and logs real-time details of each request including headers, IP addresses, User-Agent strings, and response times.

Script Overview

The script aims to perform a load distribution test by sending a high volume of HTTP GET requests to a specified URL and IP address. It uses random IPv4 and IPv6 addresses to simulate real-world traffic and logs key details about each request for monitoring and analysis.

Script Code


#!/bin/bash

# Define the target URL and IP address
url="https://www.miralishahidi.ir"  # Target domain
ip_address="185.55.227.184"  # Target public IP address

# Define requests per second (RPS) and test duration
pps=1000  # Number of requests per second
duration=300  # Test duration in seconds
total_requests=2500000  # Total number of requests

# Function to generate random IPv4 address
function generate_random_ipv4() {
  echo "$(shuf -i 1-255 -n 1).$(shuf -i 0-255 -n 1).$(shuf -i 0-255 -n 1).$(shuf -i 1-254 -n 1)"
}

# Function to generate random IPv6 address
function generate_random_ipv6() {
  # Generate a random 128-bit IPv6 address
  printf "%x:%x:%x:%x:%x:%x:%x:%x\n" \
    $((RANDOM % 0xFFFF)) $((RANDOM % 0xFFFF)) \
    $((RANDOM % 0xFFFF)) $((RANDOM % 0xFFFF)) \
    $((RANDOM % 0xFFFF)) $((RANDOM % 0xFFFF)) \
    $((RANDOM % 0xFFFF)) $((RANDOM % 0xFFFF))
}

# Function to generate random User-Agent
function generate_random_user_agent() {
  local user_agents=(
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0"
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"
    "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1"
    "Mozilla/5.0 (Linux; Android 10; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Mobile Safari/537.36"
    "Mozilla/5.0 (Linux; Android 11; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Mobile Safari/537.36"
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"
  )
  echo "${user_agents[$RANDOM % ${#user_agents[@]}]}"
}

# Function to generate random Referer
function generate_random_referer() {
  local referers=(
    "https://www.google.com/"
    "https://www.bing.com/"
    "https://www.yahoo.com/"
    "https://www.duckduckgo.com/"
    "https://www.ask.com/"
    "https://search.yahoo.com/"
    "https://www.aol.com/"
    "https://www.baidu.com/"
    "https://www.yandex.com/"
  )
  echo "${referers[$RANDOM % ${#referers[@]}]}"
}

# Function to send an HTTP GET request and log details
function send_request() {
  local ip_version="$1"
  local ip_address="$2"
  local user_agent=$(generate_random_user_agent)
  local referer=$(generate_random_referer)

  local headers=(
    "-H" "User-Agent: $user_agent"
    "-H" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
    "-H" "Accept-Language: en-US,en;q=0.5"
    "-H" "Connection: keep-alive"
    "-H" "Upgrade-Insecure-Requests: 1"
    "-H" "Referer: $referer"
    "-H" "X-Forwarded-For: $ip_address"
  )

  # Capture the start time
  local start_time=$(date +%s%3N)

  # Send the request and capture the response status and duration
  local response=$(curl -s -o /dev/null -w "%{http_code}" "${headers[@]}" "$url")
  local end_time=$(date +%s%3N)
  local duration=$((end_time - start_time))

  # Log the request details
  echo "Request: IP: $ip_address, User-Agent: $user_agent, Status Code: $response, Duration: ${duration}ms"
}

# Start the load test
echo "[!] Starting load distribution test for $url and IP $ip_address with 2.5 million requests..."

# Initialize request count
request_count=0

# Loop to send requests in parallel
for i in $(seq 1 $total_requests); do
  if [ $((i % 2)) -eq 0 ]; then
    ip=$(generate_random_ipv4)
    send_request "ipv4" "$ip" &
  else
    ip=$(generate_random_ipv6)
    send_request "ipv6" "$ip" &
  fi

  # Increment the request count
  ((request_count++))

  # Log the total number of requests sent
  echo "Total Requests Sent: $request_count"

  # Control the rate of requests per second
  if [ $((request_count % pps)) -eq 0 ]; then
    sleep 1
  fi
done

# Wait for all background processes to complete
wait

# Finish the load test
echo "[!] Load distribution test completed."

# Terminate all background processes
pkill -P $$
            

Explanation and Key Points

This section explains the main components of the script: