Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

SSH Socks Proxy Menu

I use a jump host to get to my other servers. I use socks proxy because the apache acl blocks /wp-admin access and other sensitive access unless you appear to come from the proper IP address.

Instead of trying to remember the various ssh jump commands and servers, I needed to write a script.

#!/bin/bash

# Jumphost details
JUMP_USER="root"
JUMP_IP="22.33.44.55"
JUMP_PORT1="22"
JUMP_PORT2="5590"
LOCAL_PORT1="7070"
MAX_PORT="6000"  # Define a max port limit to avoid infinite loops

DEBUG1="" # "-vv" if needed
DEBUG2="" # "-vv" if needed

# Color definitions
YELLOW='\033[1;33m'
GREY='\033[1;30m'
BLUE='\033[1;34m'
RED='\033[1;31m'
GREEN='\033[1;32m'
NC='\033[0m' # No Color

# Servers to connect through the jumphost
declare -A servers
servers=(
    [1]="root@10.10.23.116:22 root@ss6.com"
    [2]="root@10.10.46.68:22 root@ss5.com"
    [3]="root@10.10.116.11:22 root@ss4.com"
    [4]="root@10.10.147.69:22 root@somesite3.com"
    [5]="ubuntu@10.10.49.246:44443 ubuntu@somesite2.com"
    [6]="root@10.10.161.133:22 root@somesite.com"
)

# Function to check if port is open on the jumphost
check_port_on_jumphost() {
    local host=$1
    local port=$2
    ssh -q -o ConnectTimeout=2 ${JUMP_USER}@${JUMP_IP} "timeout 2 bash -c '</dev/tcp/${host}/${port}'" &>/dev/null
    return $?
}

# Function to find an available port starting from JUMP_PORT2 on the jumphost
find_available_port() {
    local port=$1
    while [ $port -lt $MAX_PORT ]; do
        if ! check_port_on_jumphost $JUMP_IP $port; then
            echo $port
            return
        fi
        port=$((port + 1))
    done
    echo "No available port found in the range up to $MAX_PORT on $JUMP_IP" >&2
    exit 1
}

# Function to perform the SSH proxy jump
ssh_proxy_jump() {
    local server_info=$1
    if [[ $server_info == "JUMPHOST_ONLY" ]]; then
        local ssh_command="ssh $DEBUG1 -p $JUMP_PORT1 -D $LOCAL_PORT1 ${JUMP_USER}@${JUMP_IP}"
    else
        local remote_user_host_port=$(echo $server_info | cut -d' ' -f1)
        local description=$(echo $server_info | cut -d' ' -f2-)
        local remote_user=$(echo $remote_user_host_port | cut -d@ -f1)
        local remote_host=$(echo $remote_user_host_port | cut -d@ -f2 | cut -d: -f1)
        local remote_port=$(echo $remote_user_host_port | cut -d: -f2)

        echo -e "${GREY}server_info: ${server_info}${NC}"
        echo -e "${GREY}remote_user_host_port: ${remote_user_host_port}${NC}"
        echo -e "${GREY}description: ${description}${NC}"
        echo -e "${GREY}remote_user: ${remote_user}${NC}"
        echo -e "${GREY}remote_host: ${remote_host}${NC}"
        echo -e "${GREY}remote_port: ${remote_port}${NC}"

        # Find an available port starting from JUMP_PORT2 on the jumphost
        echo -e "${GREY}Checking for an available port starting from $JUMP_PORT2 on $JUMP_IP...${NC}"
        available_port=$(find_available_port $JUMP_PORT2)
        echo -e "${GREY}Using available port: $available_port${NC}"

        local ssh_command="ssh $DEBUG1 -p $JUMP_PORT1 -t -L${LOCAL_PORT1}:localhost:${available_port} ${JUMP_USER}@${JUMP_IP} ssh $DEBUG2 -p ${remote_port} -t -D${available_port} ${remote_user}@${remote_host}"
    fi

    # Echo the command for troubleshooting
    echo -e "${BLUE}Executing: $ssh_command${NC}"

    # Execute the command
    eval $ssh_command
}

# Main menu loop
while true; do
    echo -e "${YELLOW}Select a server to connect through the jumphost:${NC}"
    echo "0) Jump only through the jumphost (no remote connection)"
    for i in "${!servers[@]}"; do
        echo "$i) ${servers[$i]}"
    done
    echo "Type 'exit' to quit."
    echo -e "${YELLOW}"
    read -p "Enter the number of the server: " choice
    echo -e "${NC}"

    if [[ $choice == "exit" ]]; then
        echo -e "${GREY}Exiting...${NC}"
        break
    elif [[ $choice == "0" ]]; then
        ssh_proxy_jump "JUMPHOST_ONLY"
    elif [[ -n "${servers[$choice]}" ]]; then
        ssh_proxy_jump "${servers[$choice]}"
    else
        echo -e "${RED}Invalid choice. Please try again.${NC}"
    fi
done

This runs from git bash and allows me to jump through a jump.