#!/bin/bash # SSH Tunnel Docker Container Script # Maintains SSH tunnel to Oracle database set -e # Configuration from environment variables SSH_SERVER="${SSH_SERVER:-83.103.197.79}" SSH_PORT="${SSH_PORT:-22122}" SSH_USER="${SSH_USER:-roa2web}" SSH_KEY_PATH="${SSH_KEY_PATH:-/home/tunnel/.ssh/roa_oracle_server}" LOCAL_PORT="${LOCAL_PORT:-1521}" REMOTE_HOST="${REMOTE_HOST:-10.0.20.36}" REMOTE_PORT="${REMOTE_PORT:-1521}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log() { echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1" } log "${BLUE}🚀 Starting SSH tunnel container...${NC}" log "${BLUE}Tunnel: localhost:${LOCAL_PORT} -> ${SSH_SERVER}:${SSH_PORT} -> ${REMOTE_HOST}:${REMOTE_PORT}${NC}" # Check if SSH key exists if [ ! -f "$SSH_KEY_PATH" ]; then log "${RED}❌ SSH private key not found at $SSH_KEY_PATH${NC}" log "${YELLOW}Please mount your SSH key as a volume:${NC}" log "${YELLOW} -v ~/.ssh/roa_oracle_server:/home/tunnel/.ssh/roa_oracle_server:ro${NC}" exit 1 fi # Set proper permissions for SSH key (skip if operation not permitted) chmod 600 "$SSH_KEY_PATH" 2>/dev/null || log "${YELLOW}⚠️ Could not set SSH key permissions (continuing anyway)${NC}" # Create SSH config for better connection handling mkdir -p /home/tunnel/.ssh cat > /home/tunnel/.ssh/config << EOF Host tunnel-server HostName ${SSH_SERVER} Port ${SSH_PORT} User ${SSH_USER} IdentityFile ${SSH_KEY_PATH} StrictHostKeyChecking no UserKnownHostsFile /dev/null ServerAliveInterval 30 ServerAliveCountMax 3 TCPKeepAlive yes ExitOnForwardFailure yes BatchMode yes EOF chmod 600 /home/tunnel/.ssh/config # Function to establish tunnel establish_tunnel() { log "${YELLOW}🔗 Establishing SSH tunnel...${NC}" ssh -N -T \ -o ConnectTimeout=30 \ -o ServerAliveInterval=30 \ -o ServerAliveCountMax=3 \ -o ExitOnForwardFailure=yes \ -o GatewayPorts=yes \ -L "0.0.0.0:${LOCAL_PORT}:${REMOTE_HOST}:${REMOTE_PORT}" \ tunnel-server & SSH_PID=$! echo $SSH_PID > /tmp/ssh_tunnel.pid # Wait a moment for tunnel to establish sleep 5 # Test tunnel if nc -z localhost "$LOCAL_PORT" >/dev/null 2>&1; then log "${GREEN}✅ SSH tunnel established successfully (PID: $SSH_PID)${NC}" return 0 else log "${RED}❌ Failed to establish SSH tunnel${NC}" return 1 fi } # Function to monitor tunnel monitor_tunnel() { while true; do if [ -f /tmp/ssh_tunnel.pid ]; then local pid=$(cat /tmp/ssh_tunnel.pid) # Check if process is still running if ! ps -p "$pid" > /dev/null 2>&1; then log "${YELLOW}⚠️ SSH tunnel process died, restarting...${NC}" establish_tunnel fi # Check if port is still accessible if ! nc -z localhost "$LOCAL_PORT" >/dev/null 2>&1; then log "${YELLOW}⚠️ SSH tunnel port not accessible, restarting...${NC}" if [ -f /tmp/ssh_tunnel.pid ]; then kill $(cat /tmp/ssh_tunnel.pid) 2>/dev/null || true rm -f /tmp/ssh_tunnel.pid fi establish_tunnel fi else log "${YELLOW}⚠️ SSH tunnel not running, starting...${NC}" establish_tunnel fi sleep 30 done } # Function to handle shutdown gracefully cleanup() { log "${YELLOW}📋 Shutting down SSH tunnel...${NC}" if [ -f /tmp/ssh_tunnel.pid ]; then local pid=$(cat /tmp/ssh_tunnel.pid) kill "$pid" 2>/dev/null || true rm -f /tmp/ssh_tunnel.pid fi log "${GREEN}✅ SSH tunnel stopped${NC}" exit 0 } # Set up signal handlers trap cleanup SIGTERM SIGINT # Initial tunnel establishment if establish_tunnel; then log "${GREEN}🎉 SSH tunnel container ready!${NC}" log "${BLUE}Oracle database accessible at localhost:${LOCAL_PORT}${NC}" # Start monitoring monitor_tunnel else log "${RED}💥 Failed to establish initial SSH tunnel${NC}" exit 1 fi