SSH wrapper que tenta vários parâmetros de conexão

1

Estou procurando um wrapper SSH (ou opção SSH, se houver), que pode tentar se conectar a vários endereços IP sequencialmente até que um deles seja bem-sucedido. Por exemplo, 10.0.0.1 , depois my_machine.example.com e finalmente my_machine.example.com -J me@other_machine.example.com .

Existe alguma ferramenta que faz isso?

    
por cube 11.09.2017 / 17:14

3 respostas

1

Este é meu wrapper ssh de propósito geral. Nenhuma opção nem endereço é codificado. A única coisa que você pode precisar ajustar é o caminho para o executável ssh na linha 3 (você pode usar executable=ssh , eu escolhi o caminho completo). Você encontrará meu código completo abaixo.

Digamos que você tenha salvado como sshmt ("ssh, multi target") para o qual $PATH aponta, tornado executável com chmod . Em seguida, familiarize-se com a sintaxe:

sshmt -h

Trecho:

USAGE

sshmt [-v] ARGS [+[N] ARGS]... [-- COMMON]
sshmt -h

SYNOPSIS

Invokes ssh command with the first set of arguments ARGS and common arguments COMMON. If this command returns exit status of 255 and the second set of arguments ARGS exists, then the second ssh will be invoked with these new ARGS and COMMON; then the third and so on.

No seu caso de exemplo, você quer invocá-lo assim:

sshmt 10.0.0.1 + my_machine.example.com + my_machine.example.com -J me@other_machine.example.com

ou melhor com alguns tempos limite convenientes:

sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5

Para executar remotamente df -h de maneira simples, invoque:

sshmt 10.0.0.1 df -h +2 my_machine.example.com df -h +3 my_machine.example.com -J me@other_machine.example.com df -h +5

mas você não quer se repetir, então use isso:

sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5 -- df -h

Os tubos devem funcionar também:

echo 123 | sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5 -- sh -c "cat > /tmp/foo"

Na prática, você pode querer definir um alias:

alias myssh='sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5 --'

faça login com

myssh

ou execute um comando como

myssh uptime

Este é o código. Toda a sua lógica apenas analisa a linha de comando realmente.

#!/usr/bin/env bash

executable=/usr/bin/ssh
exename="${executable##*/}"
myname="${0##*/}"
declare -a args
declare -a seq_opts
declare -a common_opts

main () {
  split_opts "$@"
  process_seq "${seq_opts[@]}" "+"
  exit 255
}

split_opts () {
  while [ $# -ne 0 ]; do
    if [ "$1" = "--" ]; then
      shift
      common_opts=("$@")
      break
    else
      seq_opts=("${seq_opts[@]}" "$1")
      shift
    fi
  done
}

process_seq() {
  if [ "$*" = "+" ] || [ "$1" = "-h" ]; then
    print_help; exit 0
  fi

  while [ $# -ne 0 ]; do
    if [ "${1:0:1}" != "+" ]; then
      args=("${args[@]}" "$1")
    else
      timeout="${1:1}"
      [[ "$timeout" =~ ^[0-9]*$ ]] || print_error
      if [ "${#args[*]}" -ne 0 ]; then
        printf '%s\n' "${myname}: trying ${args[*]}" >&2
        "$executable" ${timeout:+-o ConnectTimeout=$timeout} "${args[@]}" "${common_opts[@]}"
        status=$?
        [ $status -ne 255 ] && exit $status
        args=()
      fi
    fi
    shift
  done
}

print_error() {
  cat >&2 << EOF
${myname}: error parsing command line
Try '$myname -h' for more information.
EOF
  exit 254
}

print_help() {
  cat << EOF
USAGE

    $myname [-v] ARGS [+[N] ARGS]... [-- COMMON]
    $myname -h

SYNOPSIS

Invokes \'${exename}' command with the first set of arguments ARGS
and common arguments COMMON. If this command returns
exit status of 255 and the second set of arguments ARGS
exists, then the second \'ssh' will be invoked with these
new ARGS and COMMON; then the third and so on.

Empty set of arguments is discarded without invoking \'ssh'.
Successful invocation of \'ssh' stops parsing the command
line and makes the script exit.

OPTIONS

    -h     print this help and exit (must be the first option)
    +, +N  execute \'ssh' with preceding ARGS and COMMON

N, if given, specifies timeout for \'ssh' invoked with
immediately preceding ARGS. This is just a convenient
alternative for \'-o ConnectTimeout=N'.

The final set of arguments may or may not have a terminating \'+'.

EXIT STATUS

The exit status is 254 in case of an error while parsing
the command line; 255, if none of \'${exename}' managed
to connect; or an exit status of successfully connected
\'${exename}' otherwise.

EXAMPLES

To try 10.0.0.1 and, if failed, the alternative address:
    $myname 10.0.0.1 + my_machine.example.com

To execute \'df -h' with timeouts:
    $myname 10.0.0.1 +3 my_machine.example.com +5 -- df -h

LICENCE
        Creative Commons CC0.
EOF
}

main "$@"
    
por 16.10.2017 / 21:03
1

Até onde eu sei, não existe esse recurso embutido. No entanto, isso pode ser facilmente roteirizado:

#!/bin/bash

usage ()
{
    echo "usage:"
    echo "  $0 MYHOST"
    echo "or"
    echo "  $0 IP DNS PROXYJUMP"
}

if [[ $# -eq 1 ]]; then
    host="$1"

    ssh ${host}_ip && exit 0
    ssh ${host}_dns && exit 0
    ssh ${host}_proxyjump && exit 0
    exit 1
else if [[ $# -eq 3 ]]; then
    ip="$1"
    dns="$2"
    proxy="$3"

    ssh "$ip" && exit 0
    ssh "$dns" && exit 0
    ssh "$dns" -J "$proxy" && exit 0
    exit 1
else
    echo "Illegal number of argument"
    usage
    exit 1
fi

Com o seguinte arquivo .ssh/config :

Host MYHOST_ip
  Hostname 10.0.0.1

Host MYHOST_dns
  Hostname my_machine.example.com

Host MYHOST_proxyjump
  Hostname my_machine.example.com
  ProxyJump me@other_machine.example.com

Observe que essa conexão pode levar muito tempo, por exemplo, no caso do uso da configuração proxyjump. Na verdade, a conexão pode ocorrer após dois tempos limite.

    
por 11.10.2017 / 09:25
0

Acontece que algo semelhante a isso pode ser feito facilmente usando a opção ProxyCommand em ssh config. No meu caso de uso, ignorei o requisito de conexão com o 10.0.0.1 primeiro e terminei com isso:

Host my_machine.example.com
    ProxyCommand nc "%h" "%p" || ssh -W "%h:%p" me@other_machine.example.com

Combinando isso com conexões mestras ( ControlMaster , ControlPath e ControlPersist ) essa técnica faz 95% do que eu queria em primeiro lugar e é muito rápida em conexões repetidas (a primeira é sempre um pouco lento se tiver que passar pelo salto).

    
por 15.12.2017 / 11:49

Tags