Changes: - Added 80+ scripts with organized structure - payloads/ for third-party pentesting tools - pentesting/ for custom security scripts - Daily drivers remain flat for fast access - Converted wes() function to proper script - Removed .sh extensions from pentesting scripts - Cleaned up aliases (removed 31 redundant lines) - Added kanata/, build artifacts to gitignore - Removed old fre.sh scripts and empty a.out - Updated configs: helix, tmux, zsh, ulauncher, redshift Security: All sensitive data excluded via gitignore
348 lines
8.4 KiB
Bash
Executable file
348 lines
8.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Script Name: tunnel
|
|
# Description: SSH tunnel manager with saved configurations
|
|
# Usage: tunnel list # List saved tunnels
|
|
# tunnel add name user@host:port ... # Add new tunnel config
|
|
# tunnel start name # Start a saved tunnel
|
|
# tunnel stop name # Stop a running tunnel
|
|
# tunnel status # Show active tunnels
|
|
|
|
VERSION="1.0.0"
|
|
TUNNEL_DIR="$HOME/.tunnels"
|
|
TUNNEL_CONF="$TUNNEL_DIR/tunnels.conf"
|
|
PID_DIR="$TUNNEL_DIR/pids"
|
|
|
|
# Colors
|
|
readonly RED='\033[0;31m'
|
|
readonly GREEN='\033[0;32m'
|
|
readonly YELLOW='\033[1;33m'
|
|
readonly BLUE='\033[0;34m'
|
|
readonly CYAN='\033[0;36m'
|
|
readonly MAGENTA='\033[0;35m'
|
|
readonly BOLD='\033[1m'
|
|
readonly NC='\033[0m'
|
|
|
|
# Initialize tunnel directory
|
|
init_tunnel() {
|
|
if [[ ! -d "$TUNNEL_DIR" ]]; then
|
|
mkdir -p "$TUNNEL_DIR" "$PID_DIR"
|
|
touch "$TUNNEL_CONF"
|
|
fi
|
|
}
|
|
|
|
show_help() {
|
|
echo -e "${BOLD}tunnel${NC} - SSH Tunnel Manager v${VERSION}"
|
|
echo
|
|
echo -e "${BOLD}USAGE:${NC}"
|
|
echo " tunnel <COMMAND> [OPTIONS]"
|
|
echo
|
|
echo -e "${BOLD}COMMANDS:${NC}"
|
|
echo -e " ${CYAN}list${NC} List all saved tunnels"
|
|
echo -e " ${CYAN}add NAME SPEC${NC} Add new tunnel configuration"
|
|
echo -e " ${CYAN}start NAME${NC} Start a saved tunnel"
|
|
echo -e " ${CYAN}stop NAME${NC} Stop a running tunnel"
|
|
echo -e " ${CYAN}restart NAME${NC} Restart a tunnel"
|
|
echo -e " ${CYAN}status${NC} Show active tunnels"
|
|
echo -e " ${CYAN}delete NAME${NC} Delete saved tunnel"
|
|
echo -e " ${CYAN}edit NAME${NC} Edit tunnel configuration"
|
|
echo
|
|
echo -e "${BOLD}TUNNEL TYPES:${NC}"
|
|
echo -e " ${YELLOW}Local forward:${NC} -L local_port:remote_host:remote_port"
|
|
echo -e " ${YELLOW}Remote forward:${NC} -R remote_port:local_host:local_port"
|
|
echo -e " ${YELLOW}Dynamic (SOCKS):${NC} -D local_port"
|
|
echo
|
|
echo -e "${BOLD}EXAMPLES:${NC}"
|
|
echo " # Forward local port 3000 to remote port 80"
|
|
echo " tunnel add web user@server.com -L 3000:localhost:80"
|
|
echo
|
|
echo " # Expose local port 8080 on remote port 9000"
|
|
echo " tunnel add reverse user@server.com -R 9000:localhost:8080"
|
|
echo
|
|
echo " # SOCKS proxy on local port 1080"
|
|
echo " tunnel add socks user@server.com -D 1080"
|
|
echo
|
|
echo " # Multiple forwards"
|
|
echo " tunnel add multi user@server.com -L 3000:localhost:80 -L 5432:localhost:5432"
|
|
echo
|
|
echo " # Start/stop tunnels"
|
|
echo " tunnel start web"
|
|
echo " tunnel stop web"
|
|
echo " tunnel status"
|
|
}
|
|
|
|
# Add tunnel configuration
|
|
add_tunnel() {
|
|
local name="$1"
|
|
shift
|
|
local ssh_target="$1"
|
|
shift
|
|
local ssh_args="$*"
|
|
|
|
if grep -q "^$name|" "$TUNNEL_CONF" 2>/dev/null; then
|
|
echo -e "${RED}Error:${NC} Tunnel '$name' already exists"
|
|
echo "Use: tunnel delete $name (then re-add)"
|
|
return 1
|
|
fi
|
|
|
|
echo "$name|$ssh_target|$ssh_args" >> "$TUNNEL_CONF"
|
|
echo -e "${GREEN}✓${NC} Added tunnel: ${BOLD}$name${NC}"
|
|
echo -e " Target: $ssh_target"
|
|
echo -e " Args: $ssh_args"
|
|
}
|
|
|
|
# List tunnels
|
|
list_tunnels() {
|
|
if [[ ! -f "$TUNNEL_CONF" ]] || [[ ! -s "$TUNNEL_CONF" ]]; then
|
|
echo -e "${YELLOW}No tunnels configured${NC}"
|
|
echo "Add one with: tunnel add <name> <user@host> <args>"
|
|
return 0
|
|
fi
|
|
|
|
echo -e "${BOLD}${CYAN}Saved Tunnels:${NC}"
|
|
echo
|
|
|
|
while IFS='|' read -r name target args; do
|
|
# Check if running
|
|
pid_file="$PID_DIR/$name.pid"
|
|
if [[ -f "$pid_file" ]]; then
|
|
pid=$(cat "$pid_file")
|
|
if ps -p "$pid" &>/dev/null; then
|
|
status="${GREEN}●${NC} running"
|
|
else
|
|
status="${RED}●${NC} dead"
|
|
rm -f "$pid_file"
|
|
fi
|
|
else
|
|
status="${YELLOW}○${NC} stopped"
|
|
fi
|
|
|
|
echo -e " [$status] ${BOLD}$name${NC}"
|
|
echo -e " Target: $target"
|
|
echo -e " Args: $args"
|
|
echo
|
|
done < "$TUNNEL_CONF"
|
|
}
|
|
|
|
# Get tunnel config
|
|
get_tunnel() {
|
|
local name="$1"
|
|
|
|
if [[ ! -f "$TUNNEL_CONF" ]]; then
|
|
echo -e "${RED}Error:${NC} No tunnels configured" >&2
|
|
return 1
|
|
fi
|
|
|
|
local line=$(grep "^$name|" "$TUNNEL_CONF")
|
|
if [[ -z "$line" ]]; then
|
|
echo -e "${RED}Error:${NC} Tunnel '$name' not found" >&2
|
|
return 1
|
|
fi
|
|
|
|
echo "$line"
|
|
}
|
|
|
|
# Start tunnel
|
|
start_tunnel() {
|
|
local name="$1"
|
|
|
|
local config=$(get_tunnel "$name")
|
|
IFS='|' read -r _ target args <<< "$config"
|
|
|
|
pid_file="$PID_DIR/$name.pid"
|
|
|
|
# Check if already running
|
|
if [[ -f "$pid_file" ]]; then
|
|
pid=$(cat "$pid_file")
|
|
if ps -p "$pid" &>/dev/null; then
|
|
echo -e "${YELLOW}⚠${NC} Tunnel '$name' is already running (PID: $pid)"
|
|
return 0
|
|
else
|
|
rm -f "$pid_file"
|
|
fi
|
|
fi
|
|
|
|
echo -e "${CYAN}[*]${NC} Starting tunnel: ${BOLD}$name${NC}"
|
|
echo -e " Target: $target"
|
|
echo -e " Args: $args"
|
|
|
|
# Start SSH tunnel in background
|
|
ssh -f -N $args "$target" &
|
|
local pid=$!
|
|
|
|
echo "$pid" > "$pid_file"
|
|
echo -e "${GREEN}✓${NC} Tunnel started (PID: $pid)"
|
|
}
|
|
|
|
# Stop tunnel
|
|
stop_tunnel() {
|
|
local name="$1"
|
|
|
|
pid_file="$PID_DIR/$name.pid"
|
|
|
|
if [[ ! -f "$pid_file" ]]; then
|
|
echo -e "${YELLOW}⚠${NC} Tunnel '$name' is not running"
|
|
return 0
|
|
fi
|
|
|
|
pid=$(cat "$pid_file")
|
|
|
|
if ! ps -p "$pid" &>/dev/null; then
|
|
echo -e "${YELLOW}⚠${NC} Tunnel process not found (stale PID file)"
|
|
rm -f "$pid_file"
|
|
return 0
|
|
fi
|
|
|
|
echo -e "${CYAN}[*]${NC} Stopping tunnel: ${BOLD}$name${NC} (PID: $pid)"
|
|
kill "$pid" 2>/dev/null || true
|
|
|
|
# Wait a moment and verify
|
|
sleep 1
|
|
if ps -p "$pid" &>/dev/null; then
|
|
echo -e "${YELLOW}⚠${NC} Process didn't stop gracefully, using SIGKILL"
|
|
kill -9 "$pid" 2>/dev/null || true
|
|
fi
|
|
|
|
rm -f "$pid_file"
|
|
echo -e "${GREEN}✓${NC} Tunnel stopped"
|
|
}
|
|
|
|
# Restart tunnel
|
|
restart_tunnel() {
|
|
local name="$1"
|
|
|
|
echo -e "${CYAN}[*]${NC} Restarting tunnel: ${BOLD}$name${NC}"
|
|
stop_tunnel "$name"
|
|
sleep 1
|
|
start_tunnel "$name"
|
|
}
|
|
|
|
# Show status of all tunnels
|
|
show_status() {
|
|
echo -e "${BOLD}${CYAN}Active SSH Tunnels:${NC}"
|
|
echo
|
|
|
|
local found_any=false
|
|
|
|
if [[ -f "$TUNNEL_CONF" ]]; then
|
|
while IFS='|' read -r name target args; do
|
|
pid_file="$PID_DIR/$name.pid"
|
|
if [[ -f "$pid_file" ]]; then
|
|
pid=$(cat "$pid_file")
|
|
if ps -p "$pid" &>/dev/null; then
|
|
found_any=true
|
|
echo -e " ${GREEN}●${NC} ${BOLD}$name${NC} (PID: $pid)"
|
|
echo -e " $target $args"
|
|
echo
|
|
fi
|
|
fi
|
|
done < "$TUNNEL_CONF"
|
|
fi
|
|
|
|
if [[ "$found_any" == "false" ]]; then
|
|
echo -e " ${YELLOW}No active tunnels${NC}"
|
|
fi
|
|
}
|
|
|
|
# Delete tunnel
|
|
delete_tunnel() {
|
|
local name="$1"
|
|
|
|
if ! grep -q "^$name|" "$TUNNEL_CONF" 2>/dev/null; then
|
|
echo -e "${RED}Error:${NC} Tunnel '$name' not found"
|
|
return 1
|
|
fi
|
|
|
|
# Stop if running
|
|
pid_file="$PID_DIR/$name.pid"
|
|
if [[ -f "$pid_file" ]]; then
|
|
echo -e "${YELLOW}⚠${NC} Stopping running tunnel first..."
|
|
stop_tunnel "$name"
|
|
fi
|
|
|
|
# Remove from config
|
|
sed -i "/^$name|/d" "$TUNNEL_CONF"
|
|
echo -e "${GREEN}✓${NC} Deleted tunnel: ${BOLD}$name${NC}"
|
|
}
|
|
|
|
# Edit tunnel
|
|
edit_tunnel() {
|
|
local name="$1"
|
|
|
|
if ! grep -q "^$name|" "$TUNNEL_CONF" 2>/dev/null; then
|
|
echo -e "${RED}Error:${NC} Tunnel '$name' not found"
|
|
return 1
|
|
fi
|
|
|
|
"${EDITOR:-vim}" "$TUNNEL_CONF"
|
|
echo -e "${GREEN}✓${NC} Configuration updated"
|
|
}
|
|
|
|
# Initialize
|
|
init_tunnel
|
|
|
|
# Parse command
|
|
if [[ $# -eq 0 ]] || [[ "$1" =~ ^(-h|--help|help)$ ]]; then
|
|
show_help
|
|
exit 0
|
|
fi
|
|
|
|
command="$1"
|
|
shift
|
|
|
|
case "$command" in
|
|
list|ls)
|
|
list_tunnels
|
|
;;
|
|
add|new)
|
|
if [[ $# -lt 2 ]]; then
|
|
echo -e "${RED}Error:${NC} Usage: tunnel add <name> <user@host> <args>"
|
|
exit 1
|
|
fi
|
|
add_tunnel "$@"
|
|
;;
|
|
start|up)
|
|
if [[ $# -lt 1 ]]; then
|
|
echo -e "${RED}Error:${NC} Usage: tunnel start <name>"
|
|
exit 1
|
|
fi
|
|
start_tunnel "$1"
|
|
;;
|
|
stop|down)
|
|
if [[ $# -lt 1 ]]; then
|
|
echo -e "${RED}Error:${NC} Usage: tunnel stop <name>"
|
|
exit 1
|
|
fi
|
|
stop_tunnel "$1"
|
|
;;
|
|
restart)
|
|
if [[ $# -lt 1 ]]; then
|
|
echo -e "${RED}Error:${NC} Usage: tunnel restart <name>"
|
|
exit 1
|
|
fi
|
|
restart_tunnel "$1"
|
|
;;
|
|
status|ps)
|
|
show_status
|
|
;;
|
|
delete|del|rm)
|
|
if [[ $# -lt 1 ]]; then
|
|
echo -e "${RED}Error:${NC} Usage: tunnel delete <name>"
|
|
exit 1
|
|
fi
|
|
delete_tunnel "$1"
|
|
;;
|
|
edit)
|
|
if [[ $# -lt 1 ]]; then
|
|
echo -e "${RED}Error:${NC} Usage: tunnel edit <name>"
|
|
exit 1
|
|
fi
|
|
edit_tunnel "$1"
|
|
;;
|
|
*)
|
|
echo -e "${RED}Error:${NC} Unknown command: $command"
|
|
echo "Run 'tunnel --help' for usage"
|
|
exit 1
|
|
;;
|
|
esac
|