Skip to content

Commit

Permalink
Update conchecker.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
fulco committed May 13, 2024
1 parent 1ad2b2d commit 6cdb6b0
Showing 1 changed file with 66 additions and 102 deletions.
168 changes: 66 additions & 102 deletions conchecker.sh
Original file line number Diff line number Diff line change
@@ -1,71 +1,43 @@
#!/bin/bash

# Redirects all output to a log file while also displaying it on the console.
exec > >(tee -a /var/log/conchecker.log) 2>&1
# Constants
readonly NEW_SSH_PORT=2298
readonly ALLOWED_CONNECTIONS_FILE="allowed_ips.txt"
readonly LOG_FILE="/var/log/conchecker.log"

# Function to log messages with timestamps
log() {
local message=$1
echo "$(date '+%Y-%m-%d %H:%M:%S'): $message"
}

# Checks if the script is run as root, exits if not.
check_run_as_root() {
if [ "$(id -u)" -ne 0 ]; then
log "This script must be run as root"
exit 1
fi
local message="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S'): $message" | tee -a "$LOG_FILE"
}

# Validates that a username is provided as a parameter.
validate_parameters() {
if [ -z "$1" ]; then
log "Usage: $0 <username_to_exclude>"
exit 1
fi
}

# Verify the allowed_ips.txt file
verify_allowed_ips_file() {
if [ ! -f "$ALLOWED_CONNECTIONS_FILE" ]; then
log "The allowed_ips.txt file does not exist."
log "Please create the file and add allowed IP addresses, one per line."
exit 1
fi

if [ ! -s "$ALLOWED_CONNECTIONS_FILE" ]; then
log "The allowed_ips.txt file is empty."
log "Please add allowed IP addresses to the file, one per line."
exit 1
fi
}
# Check if the script is run as root
if [[ $EUID -ne 0 ]]; then
log "Error: This script must be run as root."
exit 1
fi

# Validates that exactly one argument is provided.
if [ $# -ne 1 ]; then
log "Incorrect usage. Please provide exactly one username as an argument."
# Validate the provided username parameter
if [[ $# -ne 1 ]]; then
log "Error: Please provide exactly one username as an argument."
log "Usage: $0 <username_to_exclude>"
exit 1
fi

# Constants
NEW_SSH_PORT=2298 # Define your SSH port here
ALLOWED_CONNECTIONS_FILE="allowed_ips.txt"
CURRENT_USER=$1

# Check if the script is run as root
check_run_as_root

# Validate the provided username parameter
validate_parameters "$CURRENT_USER"
readonly CURRENT_USER="$1"

# Verify the allowed_ips.txt file
verify_allowed_ips_file
if [[ ! -f "$ALLOWED_CONNECTIONS_FILE" || ! -s "$ALLOWED_CONNECTIONS_FILE" ]]; then
log "Error: The allowed_ips.txt file does not exist or is empty."
log "Please create the file and add allowed IP addresses, one per line."
exit 1
fi

# Function to check for the availability of firewall tools
check_firewall_tool() {
if command -v ufw > /dev/null; then
get_firewall_tool() {
if command -v ufw &> /dev/null; then
echo "ufw"
elif command -v iptables > /dev/null; then
elif command -v iptables &> /dev/null; then
echo "iptables"
else
echo "none"
Expand All @@ -74,9 +46,9 @@ check_firewall_tool() {

# Function to add firewall rules
add_firewall_rule() {
local local_ip=$1
local remote_ip=$2
local tool=$3
local local_ip="$1"
local remote_ip="$2"
local tool="$3"

case "$tool" in
"ufw")
Expand All @@ -95,8 +67,8 @@ add_firewall_rule() {

# Function to kill a process by PID
kill_process() {
local pid=$1
local signal=$2
local pid="$1"
local signal="$2"
kill "-$signal" "$pid"
log "Process with PID $pid killed with signal $signal"
}
Expand All @@ -107,62 +79,54 @@ check_connections() {
current_ssh_connection=$(who | awk -v user="$CURRENT_USER" '$1 == user {print $NF}' | sed 's/[()]//g')

local firewall_tool
firewall_tool=$(check_firewall_tool)
firewall_tool=$(get_firewall_tool)

log "Starting connection checks..."

netstat -antp | grep 'tcp' | while read -r line; do
local local_ip
local_ip=$(echo "$line" | awk '{print $4}')

local remote_ip
remote_ip=$(echo "$line" | awk '{print $5}')
while read -r line; do
local local_ip remote_ip pid_program program_name local_port

local pid_program
pid_program=$(echo "$line" | awk '{print $7}' | awk -F'/' '{print $1}')
if [[ "$line" =~ ^tcp.*ESTABLISHED$ ]]; then
local_ip=$(echo "$line" | awk '{print $4}')
remote_ip=$(echo "$line" | awk '{print $5}')
pid_program=$(echo "$line" | awk '{print $7}' | awk -F'/' '{print $1}')
program_name=$(echo "$line" | awk '{print $7}' | awk -F'/' '{print $2}')
local_port=$(echo "$local_ip" | awk -F':' '{print $NF}')

local program_name
program_name=$(echo "$line" | awk '{print $7}' | awk -F'/' '{print $2}')

# Skip the connection if it belongs to the current user's SSH connection
if [[ "$program_name" == "sshd" ]] && [[ "$remote_ip" == *"$current_ssh_connection"* ]]; then
continue
fi
# Skip the connection if it belongs to the current user's SSH connection
if [[ "$program_name" == "sshd" && "$remote_ip" == *"$current_ssh_connection"* ]]; then
continue
fi

# Extract the local port from the local_ip
local local_port
local_port=$(echo "$local_ip" | awk -F':' '{print $NF}')

# Check if the connection is allowed based on the allowed_ips.txt file or if the local port matches NEW_SSH_PORT
if ! grep -q "$local_ip $remote_ip" "$ALLOWED_CONNECTIONS_FILE" && [ "$local_port" -ne "$NEW_SSH_PORT" ]; then
log "Unauthorized connection: $local_ip <-> $remote_ip (Process: $program_name, PID: $pid_program)"

# Prompt the user to kill the unauthorized process
local answer_kill
read -r -p "Would you like to kill this process? (yes/no) " answer_kill
if [[ "$answer_kill" == "yes" ]]; then
log "User chose to kill the process with PID $pid_program"
kill_process "$pid_program" "15"
sleep 5
if ps -p "$pid_program" > /dev/null; then
log "Process with PID $pid_program is still running after SIGTERM, sending SIGKILL"
kill_process "$pid_program" "9"
# Check if the connection is allowed based on the allowed_ips.txt file or if the local port matches NEW_SSH_PORT
if ! grep -qE "^$remote_ip\s+$local_port$" "$ALLOWED_CONNECTIONS_FILE" && [[ $local_port -ne $NEW_SSH_PORT ]]; then
log "Unauthorized connection: $local_ip <-> $remote_ip (Process: $program_name, PID: $pid_program)"

# Prompt the user to kill the unauthorized process
read -r -p "Do you want to kill this process? (yes/no) " answer_kill
if [[ "$answer_kill" =~ ^(yes|y)$ ]]; then
log "User chose to kill the process with PID $pid_program"
kill_process "$pid_program" "15"
sleep 5
if ps -p "$pid_program" > /dev/null; then
log "Process with PID $pid_program is still running after SIGTERM, sending SIGKILL"
kill_process "$pid_program" "9"
fi
else
log "User chose not to kill the process with PID $pid_program"
fi
else
log "User chose not to kill the process with PID $pid_program"
fi

# Prompt the user to add a firewall rule to block the unauthorized connection
local answer_firewall
read -r -p "Would you like to block this connection using firewall? (yes/no) " answer_firewall
if [[ "$answer_firewall" == "yes" ]]; then
log "User chose to block the connection from $remote_ip to $local_ip using $firewall_tool"
add_firewall_rule "$local_ip" "$remote_ip" "$firewall_tool"
else
log "User chose not to block the connection from $remote_ip to $local_ip"
# Prompt the user to add a firewall rule to block the unauthorized connection
read -r -p "Do you want to block this connection using firewall? (yes/no) " answer_firewall
if [[ "$answer_firewall" =~ ^(yes|y)$ ]]; then
log "User chose to block the connection from $remote_ip to $local_ip using $firewall_tool"
add_firewall_rule "$local_ip" "$remote_ip" "$firewall_tool"
else
log "User chose not to block the connection from $remote_ip to $local_ip"
fi
fi
fi
done
done < <(netstat -antp 2>/dev/null)

log "Connection checks completed."
}
Expand Down

0 comments on commit 6cdb6b0

Please sign in to comment.