Jump to content

Auto SSH Script - Auto reconnect to your SSH server whenever it is dropped!


Hector Nguyen
 Share

Hector Poll  

2 members have voted

  1. 1. Do you think this script is useful?

    • Yes.
      2
    • Absolutely!
      0


Recommended Posts

Hello there,

If you are the guy who is living in terminal like me, then I assume that you will love this script :) If you usually SSH-ing to servers, then I believe you used to have headache when you are trying to keep your SSH sessions alive.

Most of them can resolve by adding this to your ~/.ssh/config

Host *
  ServerAliveInterval 60

But if you are working in a company or you are connecting to Interet through VPN/Proxy, then your SSH sessions are really unstable. Like this:

Write failed: broken pipe
packet_write_wait connection to: XXXXX

 

To use this script, you can download the attach file below and move it to /usr/local/bin or /usr/bin or ~/bin or just simple put it anywhere you want.

I assume that you will put it into /usr/local/bin, then you can use autossh command globally.

 

USAGE

It's simple, you can just run autossh alone or with parameters

autossh your_user@your_server_ip

 

Below is the whole script

 

#!/bin/bash
# ------------------------------------------------------------------------------
# FILE: autossh
# DESCRIPTION: This is an SSH-D proxy with auto-reconnect on disconnect
# AUTHOR: Hector Nguyen (hectornguyen at octopius dot com)
# VERSION: 1.0.0
# ------------------------------------------------------------------------------
VERSION="1.0.0"
GITHUB="https://github.com/hectornguyen/autossh"
AUTHOR="Hector Nguyen"
SCRIPT=${0##*/}
IFS=$'\n'
ALIVE=0
HISTFILE="$HOME/.autossh.history"

# Use colors, but only if connected to a terminal, and that terminal supports them.
if which tput >/dev/null 2>&1; then
  ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
  RED="$(tput setaf 1)"
  GREEN="$(tput setaf 2)"
  YELLOW="$(tput setaf 3)"
  BLUE="$(tput setaf 4)"
  BOLD="$(tput bold)"
  NORMAL="$(tput sgr0)"
else
  RED=""
  GREEN=""
  YELLOW=""
  BLUE=""
  BOLD=""
  NORMAL=""
fi

# Progress or something
start_progress()
{
  while true
  do
    echo -ne "#"
    sleep 1
  done
}

quick_progress()
{
  while true
  do
    echo -ne "#"
    sleep .033
  done
}

long_progress()
{
  while true
  do
    echo -ne "#"
    sleep 3
  done
}

dot_progress()
{
  for i in {1..100}; do
    printf "." $i -1 $i
    sleep .033
  done
  echo_c green " 100%{$NORMAL}"
  sleep 1
}

stop_progress()
{
  kill $1
  wait $1 2>/dev/null
  echo -en "\n"
}

# Case-insensitive for regex matching
shopt -s nocasematch

# Prepare history mode
set -i
history -c
history -r

# Input method
get_input()
{
  read -e -p "${BLUE}$1${NORMAL}" "$2"
  history -s "${!2}"
}

# Echo in bold
echo_b()
{
  if [ "$1" = "-e" ]; then
    echo -e "${BOLD}$2${NORMAL}"
  else
    echo "${BOLD}$1${NORMAL}"
  fi
}

# Echo in colour
echo_c()
{
  case "$1" in
    red | r | -red | -r | --red | --r ) echo "${RED}$2${NORMAL}" ;;
    green | g | -green | -g | --green | --g ) echo "${GREEN}$2${NORMAL}" ;;
    blue | b | -blue | -b | --blue | --b ) echo "${BLUE}$2${NORMAL}" ;;
    yellow | y | -yellow | -y | --yellow | --y ) echo "${YELLOW}$2${NORMAL}" ;;
    * ) echo "$(BOLD)$2$(RESET)" ;;
  esac
}

# Get data from parameters
if [[ ! -n "$remote_param" && -n "$1" ]]; then
    remote_param="$1"
    remote_user="${remote_param%%@*}"
    remote_ip="${remote_param##*@}"
fi

# Get input data and save to history
save_input()
{
  if [[ ! -n "$remote_user" && ! -n "$1" ]]; then
    while get_input "SSH Username > " remote_user; do
      case ${remote_user%% *} in
        * )
            if [ -n "$remote_user" ]; then
              break
            else
              continue
            fi
        ;;
      esac
    done
  fi
  if [[ ! -n "$remote_ip" && ! -n "$1" ]]; then
    while get_input "SSH Alias/IP-address > " remote_ip; do
      case ${remote_ip%% *} in
        * )
            if [ -n "$remote_ip" ]; then
              break
            else
              continue
            fi
        ;;
      esac
    done
  fi
}

# Infinitie loop to keep connecting
auto_connect()
{
  while true; do
    exist=`ps aux | grep "$remote_user@$remote_ip" | grep 22`
    if test -n "$exist"
    then
      if test $ALIVE -eq 0
      then
        echo_c yellow "I'm alive since $(date)"
      fi
      ALIVE=1
    else
      ALIVE=0
      echo_c red "I'm dead... God is bringing me back..."
      clear
      printf "${GREEN}Connecting: "
      for i in {1..100}; do
        printf "." $i -1 $i
        sleep .033
      done
      echo_c green " 100%${NORMAL}"
      sleep 1
      clear
      ssh $remote_user@$remote_ip
    fi
    sleep 1
  done
}

main()
{
  save_input
  auto_connect
}

main

 

Hope this helps.

autossh.sh

  • Like 4
Link to comment
Share on other sites

3 hours ago, LostKobrakai said:

If you've control over the server there's also mosh, which is a more stable alternative to ssh with mobile connections in mind.

Actually, mobile shell is what I'm using at this moment not mine script. But mosh is in heavily development and it denied to work with mouse scroll then in few hosting providers, they doesn't allow you to white list port range (scaleway.com for example).

That is why I have to write this to use it in few case. Like SSH tunneling or NAT....

Link to comment
Share on other sites

1 minute ago, BitPoet said:

Picking "autossh" as command name is a bit of a bad choice in my option, since a similarly named command (and *nix package) with an identical use case has been around for more than 12 years.

I know that package, but seems people forgot about them nowadays so I pick that name :D 

Link to comment
Share on other sites

8 hours ago, Hector Nguyen said:

I know that package, but seems people forgot about them nowadays so I pick that name :D 

I've been using autossh on a CentOS 7 server for a year.  autossh has been in the repositories for fedora/centos for many years and is definitely not forgotten.  Just the other day there were two threads about autossh at the linuxquestions.org forums

I'd pick another name to prevent name conflicts.

 

 

  • Like 2
Link to comment
Share on other sites

 Share

×
×
  • Create New...