Skip to content

Instantly share code, notes, and snippets.

@drhema
Last active December 12, 2024 16:53
Show Gist options
  • Save drhema/31652c72c0be1bc43c7d5082bbfe84cd to your computer and use it in GitHub Desktop.
Save drhema/31652c72c0be1bc43c7d5082bbfe84cd to your computer and use it in GitHub Desktop.
#!/bin/bash
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored messages
print_message() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}
# Function to get IPv4 address with strict checking
get_ipv4() {
IPv4=$(curl -4s -m 5 https://api.ipify.org) || \
IPv4=$(curl -4s -m 5 https://ipv4.icanhazip.com) || \
IPv4=$(curl -4s -m 5 http://v4.ident.me) || \
IPv4=$(curl -4s -m 5 http://ipv4.ident.me)
if [[ $IPv4 =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$IPv4"
else
IPv4=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '^127' | head -n1)
if [[ $IPv4 =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$IPv4"
else
echo "Unable to determine IPv4 address"
exit 1
fi
fi
}
# Function to cleanup PID files
cleanup_pid() {
if [ -f /run/squid.pid ]; then
rm -f /run/squid.pid
fi
if [ -f /var/run/squid.pid ]; then
rm -f /var/run/squid.pid
fi
}
# Check if script is run as root
if [ "$EUID" -ne 0 ]; then
print_message "$RED" "Please run as root (use sudo)"
exit 1
fi
# Function to detect OS
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
VERSION=$VERSION_ID
else
OS=$(uname -s)
VERSION=$(uname -r)
fi
}
# Function to install required packages
install_packages() {
print_message "$YELLOW" "Installing required packages..."
case "$OS" in
*"Ubuntu"*|*"Debian"*)
apt update -y
apt install -y squid apache2-utils curl net-tools iproute2
;;
*"CentOS"*|*"Red Hat"*)
yum update -y
yum install -y squid httpd-tools curl net-tools iproute
;;
*)
print_message "$RED" "Unsupported operating system: $OS"
exit 1
;;
esac
}
# Function to get valid port number
get_valid_port() {
while true; do
read -p "Enter proxy port number (1024-65535) or press Enter for default port 2024: " port
if [ -z "$port" ]; then
echo "2024"
return 0
fi
if [[ "$port" =~ ^[0-9]+$ && "$port" -ge 1024 && "$port" -le 65535 ]]; then
if ! (netstat -tuln 2>/dev/null || ss -tuln) | grep ":$port " > /dev/null; then
echo "$port"
return 0
else
print_message "$RED" "Port $port is already in use. Please choose another port."
fi
else
print_message "$RED" "Invalid port number. Please enter a number between 1024 and 65535."
fi
done
}
# Function to get valid username
get_valid_username() {
while true; do
read -p "Enter username for proxy authentication or press Enter for default username 'proxy': " username
if [ -z "$username" ]; then
echo "proxy"
return 0
fi
if [[ "$username" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "$username"
return 0
else
print_message "$RED" "Invalid username. Use only letters, numbers, underscore, and hyphen."
fi
done
}
# Function to get valid password
get_valid_password() {
while true; do
read -s -p "Enter password (3-12 characters) or press Enter for default password '123': " password
echo
if [ -z "$password" ]; then
echo "123"
return 0
fi
if [ ${#password} -ge 3 ] && [ ${#password} -le 12 ]; then
read -s -p "Confirm password: " password2
echo
if [ "$password" = "$password2" ]; then
echo "$password"
return 0
else
print_message "$RED" "Passwords do not match. Please try again."
fi
else
print_message "$RED" "Password must be between 3 and 12 characters."
fi
done
}
# Main setup function
setup_proxy() {
detect_os
install_packages
print_message "$GREEN" "\n=== Squid Proxy Setup ==="
# Get configuration from user
PROXY_PORT=$(get_valid_port)
PROXY_USER=$(get_valid_username)
PROXY_PASS=$(get_valid_password)
# Stop any running instance and cleanup
print_message "$YELLOW" "Stopping any running Squid instance..."
systemctl stop squid
sleep 2
cleanup_pid
# Backup original config
if [ -f /etc/squid/squid.conf ]; then
cp /etc/squid/squid.conf "/etc/squid/squid.conf.backup.$(date +%Y%m%d_%H%M%S)"
fi
# Clean and recreate necessary directories
print_message "$YELLOW" "Preparing cache directories..."
rm -rf /var/spool/squid/*
mkdir -p /var/spool/squid
# Determine correct user/group
SQUID_USER="proxy"
if getent passwd squid >/dev/null; then
SQUID_USER="squid"
fi
# Create new squid.conf
cat > /etc/squid/squid.conf << EOL
# Basic port setup
http_port 0.0.0.0:${PROXY_PORT}
# Authentication programs
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 5
auth_param basic realm Squid Basic Authentication
auth_param basic credentialsttl 2 hours
# ACL definitions
acl authenticated proxy_auth REQUIRED
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 443 # https
acl CONNECT method CONNECT
# Access rules
http_access allow localhost
http_access allow authenticated Safe_ports
http_access allow CONNECT authenticated SSL_ports
http_access deny all
# Basic options
cache_mem 64 MB
dns_nameservers 8.8.8.8 8.8.4.4
# Logging
debug_options ALL,1 33,2 28,9
cache_log /var/log/squid/cache.log
# Privacy Settings
forwarded_for off
request_header_access Allow allow all
request_header_access Authorization allow all
request_header_access WWW-Authenticate allow all
request_header_access Proxy-Authorization allow all
request_header_access Proxy-Authenticate allow all
request_header_access Cache-Control allow all
request_header_access Content-Length allow all
request_header_access Content-Type allow all
request_header_access Date allow all
request_header_access Expires allow all
request_header_access Host allow all
request_header_access If-Modified-Since allow all
request_header_access Last-Modified allow all
request_header_access Location allow all
request_header_access Pragma allow all
request_header_access Accept allow all
request_header_access Accept-Charset allow all
request_header_access Accept-Encoding allow all
request_header_access Accept-Language allow all
request_header_access Connection allow all
request_header_access All deny all
EOL
# Generate password file using htpasswd
rm -f /etc/squid/passwd
touch /etc/squid/passwd
chown ${SQUID_USER}:${SQUID_USER} /etc/squid/passwd
chmod 600 /etc/squid/passwd
# Use htpasswd to generate credentials
if [[ "$OS" == *"Ubuntu"* || "$OS" == *"Debian"* ]]; then
htpasswd -b -c /etc/squid/passwd $PROXY_USER $PROXY_PASS
else
htpasswd -b -c /etc/squid/passwd $PROXY_USER $PROXY_PASS
fi
# Set correct permissions
chown -R ${SQUID_USER}:${SQUID_USER} /etc/squid /var/spool/squid
chmod 644 /etc/squid/squid.conf
chmod 600 /etc/squid/passwd
# Initialize cache directory
print_message "$YELLOW" "Initializing cache..."
squid -z
# Start Squid
print_message "$YELLOW" "\nStarting Squid service..."
sleep 2
systemctl start squid
sleep 5
systemctl enable squid
# Check if service is running
if systemctl is-active --quiet squid; then
SERVER_IP=$(get_ipv4)
print_message "$GREEN" "\n=== Proxy Setup Completed Successfully ==="
echo "Proxy Settings:"
echo "Host: $SERVER_IP"
echo "Port: $PROXY_PORT"
echo "Username: $PROXY_USER"
echo "Password: $PROXY_PASS"
# Display test commands
echo -e "\nTo test your proxy, you can use either of these commands:"
echo "1. Simple URL format:"
echo " curl -v -x http://$PROXY_USER:$PROXY_PASS@$SERVER_IP:$PROXY_PORT http://example.com/"
echo "2. Explicit authentication format:"
echo " curl -v --proxy-basic --proxy-user $PROXY_USER:$PROXY_PASS -x http://$SERVER_IP:$PROXY_PORT http://example.com/"
print_message "$GREEN" "\nProxy is running and ready to use!"
else
print_message "$RED" "\nError: Squid failed to start!"
echo "Please check the logs using: journalctl -xe -u squid"
fi
}
# Run the setup
setup_proxy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment