Как предотвратить «Ошибка записи: сломанный канал» в SSH-соединении?


283

Что я могу сделать, чтобы настроить SSH на клиенте и на серверах для предотвращения Write Failed: broken pipeошибок? Это часто происходит, если вы спите на своем клиентском компьютере и возобновите работу позже.


8
Не важно. Сеанс был прерван, и безопасность сеанса была нарушена. Если вы не уложите компьютер в спящий режим, вы можете установить время поддержки активности для клиента, чтобы он отправлял серверу сигнал поддержки активности, но если система перейдет в спящий режим, то с этим ничего не поделаешь.
darkdragn

3
В этом случае я ищу что-то, что позволило бы мне повторно инициировать разорванное ssh-соединение (основанное, вероятно, на коде выхода) и восстановить с помощью screen?
Сорин

4
Вы, люди, не правы: у меня есть ДВА настольных клиентских компьютера, подключающихся к ТО ЖЕ серверу. Одним из них является Ubuntu 12.10, Quantal, чей SSH-клиент работает хорошо и поддерживает соединение часами. Другой - Ubuntu 14.10, Utopic, только в стороне от другого и в новой установке; через пару минут он блокирует себя этим сообщением. Остальные сетевые функции в машине не прерываются. Так что нет, это не проблема сети и не проблема сервера, а конкретная проблема программного обеспечения SSH CLIENT, которая МОЖЕТ быть решена, в отличие от того, что «darkdragan» осмеливается сказать, что «ничего нельзя сделать».
Дэвид Л

2
И действительно, как я уже сказал: люди слишком много говорят, когда говорят, что «ничего не поделаешь», как смел @darkdragn. Я прочитал ответ Арама Кочаряна и применил его: 20 минут назад ... Я понял, что в моей старой Quantal Ubuntu 12.10 я применил эту инструкцию в этом файле [я только что проверил] два года назад, и это было причина стабильности там. Я сделал это здесь, и за последние 20 минут соединение было стабильным с тех пор. Так что, пожалуйста, люди: воздерживайтесь, когда осмеливаетесь думать, что «ничего не поделаешь», и еще больше воздерживайтесь, пытаясь передать это послание другим людям.
Дэвид Л

11
@DavidL, тебе лучше прочитать вопросы перед разглагольствованием. Ваша проблема не такая же, как у ОП, который явно упоминает о том, чтобы перевести компьютер в спящий режим. К которому, кстати, обращался только один из ответов («мош»), и он был размещен через 2 года после вопроса. Тем не менее, другие ответы делают следующую лучшую вещь, которая предлагает решения для случаев, которые могут быть решены легче, как у вас. Расслабься, не волнуйся, разглагольствования здесь не приносят пользы ...
MSB

Ответы:


266

Я пробовал это /etc/ssh/ssh_configдля Linux и Mac:

Host *
ServerAliveInterval 120

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

Вы можете установить либо ServerAliveIntervalв /etc/ssh/ssh_configклиентской машине или ClientAliveIntervalв /etc/ssh/sshd_configсерверной машине. Попробуйте уменьшить интервал, если вы все еще получаете ошибку.

Конфигурация для одного пользователя может быть задана в файле ~/.ssh/configкак на стороне сервера, так и на стороне клиента. Убедитесь, что файл имеет правильные разрешения chmod 644 ~/.ssh/config.


4
Я не на Mac, но Ubuntu 12.04 и файл для этой операционной системы также, кажется, ~ / .ssh / config.
H2ONaCl 14.12.12

5
OS X 10.8.4 выдает ошибкуBad configuration option: ClientAliveInterval
охо

3
Я получаю ту же Bad configuration optionошибку на OSX 10.8.4.
Ник Хейнер

10
Как правило, вы помещаете эти две команды в разные части системы. Только ServerAliveInterval на стороне клиента OSX ... и только ClientAliveInterval в файле конфигурации sshd ...
ftrotter

2
Моя обезьяна сказала мне: «Почему бы тебе не набрать себя» top [ENTER] »
август

85

Сеансы SSH могут прерваться из-за многочисленных и, возможно, неизбежных причин.

Полезная утилита, которая может использоваться для смягчения проблем, вызванных этим, называется screen. Screen - мощная утилита, которая позволяет вам управлять несколькими терминалами, которые будут работать независимо от сеанса ssh. Например, если вы запустите screenсеанс ssh, вы увидите, что новый терминал открыт, и вы можете использовать его для запуска заданий. Допустим, ваша сессия SSH умирает в процессе. Запуск screen -dзатем screen -rбудет вновь открыть последнюю сессию , и вы будете в состоянии продолжить оттуда. Убедитесь, что вы прочитали часть документации, прежде чем использовать ее.


5
Это, наверное, лучший ответ, я не уверен, почему за него не проголосовали выше. Другие «исправления» полезны в особом случае, когда вы на самом деле заботитесь о поддержании соединения SSH, но в большинстве случаев использования я думаю, что реальная проблема заключается в том, что намеченные процессы продолжают работать, независимо от каких-либо проблем с соединением клиент / сервер. ,
Пол МакМерди

16
Я бы также добавил Tmux в качестве альтернативы screen. Я считаю его более универсальным и стабильным, чем экран.
fridaymeetssunday

2
просто оставив это здесь для дальнейшего использования - вы можете удобно запустить, screen -d -rчтобы восстановить ваш последний сеанс.
Доплуми

2
Или просто screen -dr. Или в screen -xзависимости от того, что вы планируете делать. Дело в том, что нужно знать, что делают все эти переключатели, чтобы можно было использовать соответствующие, а не просто слепо следовать советам интернет-людей. Хорошее компактное резюме доступно здесь: ss64.com/bash/screen.html
1818

Это не ответ на проблему
user3728501

46

Конфигурация клиента

Попробуйте создать файл:

~/.ssh/config

Добавьте содержимое:

Host *
  ServerAliveInterval 30
  ServerAliveCountMax 5

Теперь зайдите на ваш сервер и посмотрите, исправлена ​​ли ваша проблема. Параметр ClientAliveInterval полезен только при настройке сервера ssh (он же sshd), он ничего не меняет на стороне клиента ssh, поэтому не используйте его в приведенном выше файле конфигурации.

Это отправит на сервер сигнал приветствия, если вы не получили пакетов в течение предыдущих 30 секунд (как указано выше). Однако, если число последовательных сигналов приветствия вас достигнет ServerAliveCountMax, тогда ssh отключится от сервера. Это значение по умолчанию равно 3 (поэтому 3 * 30 = 90 секунд без активности сервера), увеличьте его, если оно соответствует вашим потребностям. В файле .ssh / config есть много других параметров конфигурации, и вы можете прочитать:

Использование файла конфигурации SSH

Для получения дополнительной информации о других вариантах. Возможно, вы не захотите применять это к каждому серверу, к которому вы подключаетесь, к примеру. Или ограничьте его только определенным сервером, заменив строку Host *на Host <IP>(замените IP-адресом, см. Справочную страницу ssh_config).

Конфигурация сервера

Точно так же вы можете сказать серверу быть осторожным с вашими клиентами. Файл конфигурации есть /etc/ssh/sshd_config.

ClientAliveInterval 20
ClientAliveCountMax 5

Вы можете либо отключить его, установив ClientAliveIntervalна 0или настроить ClientAliveIntervalи ClientAliveCountMaxустановить максимальную SSH клиента бездеятельность , не отвечая на зондах. Одно из преимуществ этих настроек по сравнению с TCPKeepAlive заключается в том, что сигналы отправляются по зашифрованным каналам, поэтому вероятность их подделки меньше.


Не работает Я снова сталкиваюсь с той же ошибкой.
user997704

3
Попробуйте прямо из командной строки и перейдите ниже: ssh -o ServerAliveInterval = 5 пользователь @ хост
Мэтт

Пробовал это тоже .. не работает. Я действительно не знаю, что происходит с моей системой
user997704

2
Это ClientAliveCountMax, а не ClientAliveMaxCount
Дэвид Г

@ DavidG Пожалуйста, отредактируйте ответ с вашими исправлениями.
CivMeierFan

23

Я удаленно обновляю сервер Ubuntu с lucid до точного и теряю соединение ssh в середине обновления с сообщением «Ошибка записи. Сломанный канал». ClientAliveInterval и ServerAliveInterval ничего не сделали. Решение состоит в том, чтобы включить опции TCPKeepAlive в клиенте ssh:

TCPKeepAlive yes

в

/etc/ssh/ssh_config

20

Для клиента отредактируйте ваш ~/.ssh/config(или /etc/ssh/ssh_config) файл следующим образом:

Host *
  TCPKeepAlive yes
  ServerAliveInterval 120

TCPKeepAlive - указывает, должна ли система отправлять сообщения поддержки активности TCP другой стороне. Если они отправлены, смерть соединения или сбой одной из машин будут замечены должным образом. Однако это означает, что соединения прекратят свое существование, если маршрут временно не работает, и некоторые люди считают это раздражающим (по умолчанию «да»).

ServerAliveInterval - устанавливает интервал ожидания в секундах, после которого, если с сервера не было получено никаких данных, ssh (1) отправит сообщение по зашифрованному каналу для запроса ответа от сервера. По умолчанию 0, что означает, что эти сообщения не будут отправлены на сервер.


Для сервера отредактируйте ваш /etc/ssh/sshd_configкак:

ClientAliveInterval 600
ClientAliveCountMax 0

Если вы хотите, чтобы клиент ssh автоматически выходил (тайм-аут) через 10 минут (600 секунд).

ClientAliveCountMax - указывает общее количество контрольных сообщений, отправленных сервером ssh без получения ответа от клиента ssh. По умолчанию 3.

ClientAliveInterval - указывает время ожидания в секундах. Через x секунд ssh-сервер отправит клиенту сообщение с просьбой ответить. Значение по умолчанию равно 0 (сервер не отправляет сообщение клиенту для проверки.).


Смотрите также: Что конкретно делают опции ServerAliveIntervalи ClientAliveIntervalв sshd_config?


Установка значения ServerAliveCountMax выше, чем значение по умолчанию на клиенте, также должно помочь поддерживать работоспособность соединения для медленных соединений.
Джонниендзл

17

Я очень люблю Моша. Я часто захожу на сервер, закрываю свой ноутбук и иду в кафе, открываю его и продолжаю, как будто ничего не изменилось.

Mosh (мобильная оболочка)

Приложение для удаленного терминала, которое позволяет осуществлять роуминг , поддерживает прерывистое соединение и обеспечивает интеллектуальное локальное эхо и редактирование строк пользовательских нажатий клавиш.

Mosh - это замена SSH. Он более надежный и отзывчивый, особенно по Wi-Fi, сотовой связи и междугородной связи.

Mosh - бесплатное программное обеспечение, доступное для GNU / Linux, FreeBSD, Solaris, Mac OS X и Android.


6

Для меня, я получал, Write failed: Broken pipeдаже когда я активно набирал vim или в приглашении оболочки. Я тоже не мог просматривать интернет локально некоторое время. (Я подключался удаленно к Ubuntu через терминал.)

Другие в моей сети транслируют много видео из Netflix и других мест. Я не могу доказать это, но я подозреваю, что это проблема с интернет-провайдером или маршрутизатором. Например, Verizon и Netflix указывают пальцем друг на друга из-за проблем своих клиентов в сети.

Если у вас есть подключение удаленного доступа и потоковое видео или музыка с одновременным подключением через SSH или telnet, в какой-то момент вы неизбежно получите сообщение о разрыве канала. Модернизация широкополосного пакета моего интернет-провайдера, казалось, делала мое разорванное соединение менее частым.



3

У меня есть скрипт на удаленном сервере, который, кажется, никогда не выходит из строя, независимо от конфигурации клиента или сервера SSH.

#!/bin/bash
while true; do date; sleep 10; done;

Сохраните его в некотором файле dummy.sh и быстро запустите, прежде чем свернуть окно или отойти от него. Он будет продолжать печатать текущую метку времени на сервере и поддерживать ваше соединение в активном состоянии до тех пор, пока соединение не будет прервано по какой-либо другой причине. Когда вы вернетесь к этому терминалу, просто нажмите CTRL + C и продолжайте работать.


9
или просто оставить topработать
Эбен Гир

1

Вы можете добавлять эти аргументы каждый раз, когда вызываете ssh: -o ServerAliveInterval=15 -o ServerAliveCountMax=3

Вам не нужно редактировать файлы конфигурации / etc / ssh / *, если вы это делаете.

Вы можете создать псевдоним bash или функцию или скрипт, чтобы сделать это легко.

Например, эти функции bash вы можете добавить в свой .bashrc, do_ssh используется вручную для включения keepalive. do_ssh_pty используется в скриптах, чтобы установить pty и избегать подсказок.

do_ssh() {
    ssh -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $*
}

do_ssh_pty() {
    ssh -tt -o "BatchMode=yes" -o "StrictHostKeyChecking=no" -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $*
}

Теперь do_ssh user@hostможно использовать или, do_ssh user@host <args> <command>и keepalive будет активен.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.