3

Я делаю постоянную переадресацию портов через SSH. Это в основном

while true; do
        ssh <somewhere> \
                -R <dst-port>:localhost:<src-port> \
                -N -n -o ExitOnForwardFailure=yes
        sleep 10
done

Однако это не очень надежно. Иногда порт вообще не переадресовывается (я не уверен, правильно ли установлено соединение, но я вижу процесс на клиенте, и он работает уже в течение нескольких часов), иногда соединение наверняка больше не работает (потому что сетевой интерфейс отключен), но тайм-аут занимает очень много времени (иногда до 30-60 минут).

Как я могу сделать это более надежным? Я хочу иметь время ожидания, может быть, минуту.


Я только что нашел этот очень связанный / похожий вопрос. Тем не менее, первый ответ указывает, что ExitOnForwardFailure должен решить эту проблему, но у меня уже есть это, и это не так (сейчас я вижу запущенный процесс ssh с этой опцией, но порт не пересылается).

5 ответов5

4

Я положил их в файл config клиента SSH:

ServerAliveInterval = 60
ServerAliveCountMax = 3

В качестве альтернативы, эти опции могут быть переданы в командной строке ssh через -o .

Некоторые клиенты могут не иметь этого элемента управления конфигурацией, например, различные скудные клиенты для мобильных устройств. В этом случае все еще возможно настроить его глобально на каждом подключаемом сервере, что, конечно, требует привилегий на сервере. Реализация OpenSSHD, похоже, не позволяет пользователям настраивать параметры сервера (файл ~/.ssh/sshd_config не читается там, где можно настроить выбранные параметры со стороны сервера).

3

Я использую autossh на своей рабочей машине для настройки удаленной веб-разработки:

autossh -M0 -N -R \*:8080:localhost:80 -R \*:5051:localhost:22 home

autossh - это программа, которая продолжает перезапускать ssh, если происходит сбой или остановка по любой причине, кроме «kill -9». Приведенная выше команда устанавливает два туннеля: один для переадресации порта 80 на моей рабочей машине на 8080 на моей домашней машине, другая - для туннелирования сервера ssh на моей рабочей машине на мою домашнюю машину. Знак * перед портом позволяет работать с любым именем хоста, а не только с localhost. Возможно, вам придется установить "GatewayPorts yes" в вашем sshd_config, чтобы это работало. У меня есть хосты в ~/.ssh/config и /etc /hosts на моей домашней машине, чтобы сделать это еще более прозрачным. Для других систем необходимо использовать ProxyCommand (http://sshmenu.sourceforge.net/articles/transparent-mulithop.html), но у меня нет хоста, на котором я сейчас использую эту команду, чтобы включить его.

~/.Ssh /конфигурации:

Host work
    hostname localhost
    port 5051

Тогда это просто

autossh -M0 -t home 'ssh work'

с любого хоста для подключения.

1

Эта версия часто отправляет некоторые данные на сервер. Если соединение оборвалось, труба рано или поздно должна разорваться.

while true; do
        { while true; do echo echo ping; sleep 10; done } | \
        ssh <somewhere> \
                -R <something> \
                -o ExitOnForwardFailure=yes \
                >/dev/null
        sleep 10
done
0

Вы можете попробовать изменить команду SSH на:

ssh SOMEWHERE -R DSTPORT:localhost:SRCPORT -n -o ExitOnForwardFailure=yes \
    "while true; do echo ping; sleep 10; done" >/dev/null

Это приводит к тому, что через TCP-соединение каждые 10 секунд отправляется небольшой объем данных (не стесняйтесь изменять этот период). Этого может быть достаточно для поддержания связи.

0

Как цитировалось ранее Kaz, соединение не требует какого-либо явного трафика для поддержания жизнедеятельности. Что-то вроде:

ssh you@there 'read ANYTHING' < $PIPE

просто работает. $ PIPE - это именованный канал, в который вы напишите, когда закончите.

Что ж, давайте прямо скажем - $ PIPE более сложен, чем 'read any' и заслуживает подробного примера. Вот код, который я использую для rdesktop машины в сети, к которой у меня нет прямого доступа:

p_user=myself
p_bridge=me@there
p_host=192.168.xxx.yyy
p_port=9999

p_size=100%      # or: p_size=1280x1024
p_trace=stderr   # or: p_trace=null

s_trace() {  echo "$*" > /dev/$p_trace; }

PIPE=$TEMP/${0##*/}.$$
mkfifo $PIPE.0
mkfifo $PIPE.1

trap 'rm $PIPE.0 $PIPE.1' 0

# ----------------------------------------------------
ssh $p_bridge \
    -L $p_port:$p_host:3389 \
    'read CONNECT; date; read QUIT' \
  < $PIPE.1 \
  > $PIPE.0 \
  & 
# ----------------------------------------------------

# note: "type -p" is somehow required with xinit
# note: "-p -" reads password from stdin
DESKCMD="$(type -p rdesktop) -P -z -u $p_user -p - -g $p_size localhost:$p_port"

{
  echo connect >&3; read CONNECT <&4; s_trace "CONNECTED: $CONNECT"
  $DESKCMD -f    # or: xinit $DESKCMD -- :1
  echo quit >&3
} \
  3> $PIPE.1 \
  4< $PIPE.0

wait

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .