Opakowanie SSH, które próbuje kilku parametrów połączenia

2

Szukam opakowania SSH (lub opcji SSH, jeśli istnieje), które mogą próbować połączyć się z kilkoma adresami IP sekwencyjnie, aż jeden z nich się powiedzie. Na przykład 10.0.0.1wtedy my_machine.example.comi na końcu my_machine.example.com -J me@other_machine.example.com.

Czy jest na to narzędzie?

sześcian
źródło

Odpowiedzi:

2

To jest moje sshopakowanie ogólnego przeznaczenia . Żadna opcja ani adres nie są zapisane na stałe. Jedyne, co może wymagać dostosowania, to ścieżka do sshpliku wykonywalnego w linii 3 (możesz użyć executable=ssh, wybrałem pełną ścieżkę). Mój pełny kod znajdziesz poniżej.

Powiedzmy, że zapisałeś go jako sshmt(„ssh, multi target”) w miejscu, w którym twoje $PATHpunkty, wykonałeś chmod. Następnie zapoznaj się ze składnią:

sshmt -h

Fragment:

STOSOWANIE

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

STRESZCZENIE

Wywołuje sshpolecenie z pierwszym zestawem argumentów ARGS i typowymi argumentami COMMON. Jeśli to polecenie zwraca status wyjścia 255i ARGS istnieje drugi zestaw argumentów , wówczas drugi sshzostanie wywołany z tymi nowymi ARGSi COMMON; potem trzeci i tak dalej.

W twoim przykładzie chcesz wywołać go w następujący sposób:

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

lub lepiej z pewnymi dogodnymi limitami czasu:

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

Aby wykonać zdalnie df -hw prosty sposób, wywołaj:

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

ale nie chcesz się powtarzać, więc użyj tego:

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

Rury powinny również działać:

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"

W praktyce możesz chcieć zdefiniować 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 --'

następnie zaloguj się za pomocą

myssh

lub wykonaj polecenie takie jak

myssh uptime

To jest kod. Cała jego logika po prostu analizuje wiersz poleceń.

#!/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 "$@"
Kamil Maciorowski
źródło
2

O ile mi wiadomo, nie ma takiej wbudowanej funkcji. Można to jednak łatwo skrypty:

#!/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

Z następującym .ssh/configplikiem:

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

Pamiętaj, że połączenie może zająć dużo czasu, na przykład w przypadku użycia konfiguracji proxy. W rzeczywistości połączenie może nastąpić po 2 przekroczeniach limitu czasu.

Vera
źródło
0

Okazuje się, że coś całkiem podobnego można zrobić dość łatwo, używając ProxyCommandopcji w konfiguracji ssh. W moim przypadku pominąłem najpierw wymaganie połączenia z 10.0.0.1 i skończyłem na tym:

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

Łącząc to z połączeniami mistrzowskich ( ControlMaster, ControlPathi ControlPersist) ta technika robi 95%, co chciałem na pierwszym miejscu i jest bardzo szybki na wielokrotnych połączeń (pierwszy jest zawsze nieco powolny jeśli ma przejść skoku).

sześcian
źródło