несоответствие версий протокола — ваша оболочка чиста?

Вопрос или проблема

Следуя инструкциям по созданию резервных копий с помощью rsync, приведенным здесь: http://troy.jdmz.net/rsync/index.html

Я получаю ошибку “несоответствие версии протокола — ваш шелл чист?”

Я где-то читал, что нужно отключить приглашение (PS1=””) и отображение мотд (.hushlogin), чтобы справиться с этим. Я это сделал, приглашение и информационный баннер (MOTD) больше не отображаются, но ошибка все равно появляется, когда я запускаю:

rsync -avvvz -e "ssh -i /home/thisuser/cron/thishost-rsync-key" remoteuser@remotehost:/remote/dir /this/dir/

Как клиент ssh, так и сервер sshd используют версию 2 протокола.

В чем может быть проблема?

[ИЗМЕНЕНИЕ]
Я нашел http://www.eng.cam.ac.uk/help/jpmg/ssh/authorized_keys_howto.html
в котором говорится, что иногда необходимо “принудительно использовать v2 с помощью флага -2 для ssh или slogin

ssh -2 -i ~/.ssh/my_private_key remotemachine"

Неясно, решило ли это проблему, так как я изменил это лишь ПОСЛЕ изменения ошибки, но факт в том, что ошибка изменилась на что-то другое. Я обновлю это, когда узнаю больше. И я определенно попробую предложение запустить это в оболочке emacs –

Одна из ваших скриптов входа (.bashrc/.cshrc и т.д.), вероятно, выводит данные в терминал (когда не должна). Это вызывает ошибку ssh при подключении и подготовке к копированию, так как она начинает получать дополнительные данные, которые не ожидает. Удалите вывод, который генерируется в скриптах запуска.

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

if shopt -q login_shell; then
    [любой код, который выводит текст здесь]
fi

или, альтернативно, так как специальный параметр - содержит i, когда оболочка интерактивная:

if echo "$-" | grep i > /dev/null; then
    [любой код, который выводит текст здесь]
fi

Дополнительную информацию можно найти здесь: rsync через ssh с linux на windows sbs 2003 несоответствие протокола

Чтобы диагностировать это, убедитесь, что следующий вывод вы получаете, когда подключаетесь к хосту через ssh:

USER@HOSTNAME's password: 
Последний вход: Пн Ноя  7 22:54:30 2011 от YOURIP
[USER@HOSTNAME ~]$ 

Если вы получаете любые пустые строки или другие данные, вы знаете, что отправляется дополнительный вывод. Вы можете переименовать свои файлы .bashrc/.cshrc/.profile/etc. во что-то другое, чтобы они не выводили дополнительный вывод. Конечно, все еще есть системные файлы, которые могут это вызвать. В этом случае проверьте с вашим системным администратором, чтобы системные файлы не выводили данные.

Устранение этой проблемы:

Существует простой способ проверить, чист ли ваш шелл для ssh-соединения: запустите команду из соединения ssh, а не запускайте интерактивный шелл. Команда false немедленно завершится без какого-либо вывода, поэтому это хорошее тестирование:

bash$ ssh remotehost false
Введите пароль для ключа '/home/user/.ssh/my_private_key': 
bash$

Если эта командная строка выдает какой-либо вывод, один из ваших скриптов запуска виноват:

bash$ ssh remotehost false
Введите пароль для ключа '/home/user/.ssh/my_private_key': 
Добро пожаловать на RemoteHost!

Эта система является собственностью компании и предоставляется только для авторизованного использования, 
как указано в применимых письменных политиках. Неавторизованное использование запрещено 
и может подлежать дисциплине, гражданскому иску и уголовному преследованию.
 
С возвращением - Вы в последний раз входили 16 дней назад...
bash$

Еще одна вещь, которую следует проверить, если вы получаете эту ошибку, это установлена ли rsync и доступна ли она для ssh:

bash$ ssh remotehost "rsync --version"
Введите пароль для ключа '/home/user/.ssh/my_private_key': 
rsync  версия 3.0.9  версия протокола 30
Copyright (C) 1996-2011 by Andrew Tridgell, Wayne Davison и др.
Веб-сайт: http://rsync.samba.org/
Возможности:
    64-разрядные файлы, 64-разрядные inums, 64-разрядные временные метки, 64-разрядные длинные целые числа,
    сокетные пары, жесткие ссылки, символические ссылки, IPv6, пакетные файлы, 
    на месте, добавление, ACL, xattrs, iconv, symtimes

rsync полностью БЕЗ ГАРАНТИЙ. Это бесплатное программное обеспечение, и вы
можете распространять его при определенных условиях. См. Общую лицензию GNU для подробностей.
bash$

Если rsync не в пути, вы вместо этого увидите что-то вроде:

bash$ ssh remotehost "rsync --version"
Введите пароль для ключа '/home/user/.ssh/my_private_key': 
bash: rsync: команда не найдена
bash$

Вы можете исправить это, либо установив rsync, либо, если он установлен, но находится в нестандартном месте, передав это расположение в командной строке rsync:

rsync -avvvz -e "ssh -i /home/thisuser/cron/thishost-rsync-key" \
    --rsync-path="/usr/local/bin/rsync" \
    remoteuser@remotehost:/remote/dir /this/dir/

Это обычно вызвано тем, что ваша оболочка выводит что-то в неинтерактивной оболочке. Вы можете проверить, так ли это, выполнив:

ssh username@host "/bin/true" > testfile
ls -l testfile

Если testfile не 0 байт, тогда проблема в том, что ваша оболочка что-то выводит. Проверьте /etc/profile, .profile, .bashrc, .cshrc и т.д. Если это так, вы можете изменить его, чтобы проверить, является ли ваш терминал интерактивным и выводить только текст, используя следующий код в .bashrc. Подобное существует и для других оболочек:

if shopt -q login_shell; then
    [любой код, который выводит текст здесь]
fi

или, альтернативно, так как специальный параметр - содержит i, когда оболочка интерактивная:

if echo "$-" | grep i > /dev/null; then
    [любой код, который выводит текст здесь]
fi

Тем не менее, если тестовый файл фактически 0 байт, тогда ваша оболочка работает правильно, но возможно, что у вас просто устаревшая версия rsync. Вы можете сказать клиентской стороне (предполагая, что это новая сторона), чтобы не рекламировать такую высокую версию, которую старая версия сервера rysnc не распознает. Вы можете сделать это с помощью параметра --protocol=. В моем случае использование --protocol=30 решило проблему.

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

Это особый случай из других ответов, но не очень отличается от них.

Чтобы выполнить rsync через ssh, вам нужен доступ к оболочке в ssh, чтобы запустить команду удаленного rsync. Если ваша учетная запись ssh позволяет только scp/sftp, вы не сможете запустить удаленный rsync, что приведет к этой ошибке.

Это можно протестировать тем же самым командой, что и выше

ssh remotehost false

Эта команда должна завершиться неудачей, а эта успешно

sftp remotehost

Это доказывает, что у вас есть только доступ sftp.

Если вы хотите и имеете разрешение сделать это, вы можете отключить доступ только sftp для этого пользователя, изменив /etc/ssh/sshd_config и проверив записи match и forcecommand.

Вы также можете проверить этот пост

Я получил несоответствие версии протокола -- ваш шелл чист? просто потому, что не установил rsync на другом конце. sudo yum install rsync решило проблему.

Я также наблюдаю эту ошибку, когда перетаскиваю файлы с экземпляра с версией rsync 2.5.7 версия протокола 26 на версию 3.1.1:

несоответствие версии протокола - ваш шелл чист?
(см. страницу man rsync для объяснения)
ошибка rsync: несоответствие протокола (код 2) в compat.c(62)
ошибка rsync: соединение неожиданно закрыто (0 байт получено до сих пор) [Получатель]
ошибка rsync: ошибка в потоке данных протокола rsync (код 12) в io.c(226) [Получатель=3.1.1]

Но на удаленной оболочке не было баннера входа. Вместо этого решение заключалось в указании более старого протокола (ссылка):

rsync --protocol=29 ...

При непосредственном выполнении команды приглашение вообще не будет отображаться, и это будет неинтерактивным. Простое гугление дает первый результат: http://marc.info/?l=rsync&m=100263876212594&w=2
И поскольку оболочка может потенциально быть вызвана, она не должна отображать ничего в неинтерактивном режиме — например, когда вы просто вводите “bash” в существующее приглашение, должно появиться только новое приглашение.

Это может быть вызвано сообщением о входе на удаленном хосте, таким как “Ваш пароль истечет через 6 дней”, что RSYNC не ожидает

Я нашел еще один случай: если ваша оболочка по умолчанию на сервере – это zsh, тогда вам нужно проверить другие файлы, такие как .zshenv, .zprofile, .zshrc и т.д. Избегайте, чтобы в них было “echo”

Используйте метод @Stabledog для отладки.

В моем случае решение было так же простым, как удалить строку cat /etc/motd в ~/.bashrc.

Спасибо Азендаль, запустив ваш тест, я обнаружил, что файл не 0 байт. Поэтому я прошел через все свои скрипты запуска, особенно .bashrc и закомментировал…

#echo -e "Добро пожаловать в $LLVER ${USER}"
#echo " "
#date "+%A %d %B %Y, %T"
#free -m | awk 'NR==2{printf "Использование памяти: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }'
#df -h | awk '$NF=="/"{printf "Использование диска: %d/%dGB (%s)\n", $3,$2,$5}'
#echo "Поддержка - https://www.linuxliteos.com/forums/ (Щелкните правой кнопкой, откройте ссылку)"
#echo "

Я также удалил (ну, я скопировал их для резервного копирования) все файлы в /etc/update-motd перед этим, но я не могу точно сказать, оказало ли это влияние на решение. Все, что я знаю, это что scp наконец работает так, как и должно, и я доволен.

Просто чтобы добавить к набору ответов, в моем случае проблему вызывал файл rc SSH, который был установлен на целевом хосте.

$ rsync -avz -e "ssh -i ~/.ssh/id_rsa" --progress testfile user@target-host:/home/user/
Переменная окружения TERM не установлена.
несоответствие версии протокола -- ваш шелл чист?
(см. страницу man rsync для объяснения)
ошибка rsync: несоответствие протокола (код 2) в compat.c(608) [отправитель=3.2.4]

Перемещение файла ~/.ssh/rc на целевом хосте в расположение вне ~/.ssh позволило rsync работать.

ВКРАТЦЕ: Это также может быть вызвано содержимым файла .ssh/config на клиенте (см. ниже).

Все ответы, которые я нашел, говорят о файлах на сервере/хосте/цели, которые могут выводить вывод, который вызывает сбой ssh. Я знал, что внес изменения, чтобы заголовки в моих терминалах обновлялись в зависимости от того, в какой домен я вошел, но не мог найти эти изменения в каких-либо из конфигурационных файлов, упомянутых в ответах. Кроме того, они все начинались с безопасного возврата для неинтерактивных соединений.

В любом случае, в конце концов я осознал, что я сделал изменения на клиенте, добавив

LocalCommand printf '\033]0;%%s\007' "%r@%n"

в .ssh/config (под Host *). Закомментировав эту строку, я исправил свою проблему. Я не уверен, как мне следует добавить это, чтобы это не нарушало неинтерактивные соединения, но пока я не пойму это, я просто отключу его.

Ответ или решение

Ошибка "protocol version mismatch — is your shell clean?" возникает, когда ваша оболочка выводит что-то, когда это не ожидается, в процессе SSH-соединения для выполнения команды, такой как rsync. Вот несколько шагов, которые помогут вам устранить эту проблему:

Шаги для устранения проблемы

  1. Проверьте свою оболочку:
    Убедитесь, что ваша оболочка не генерирует ненужный вывод при неинтерактивном входе. Это может происходить, если у вас есть команды echo, cat, выводящие сообщения или приветствия в ваших инициализационных файлах (например, ~/.bashrc, ~/.bash_profile и т. д.).

    • Используйте следующий код в вашем инициализационном файле, чтобы избежать вывода в неинтерактивной оболочке:
      if [[ $- == *i* ]]; then
       # Ваши команды для интерактивной оболочки
      fi
  2. Тестирование:
    Проверьте, производит ли ваша оболочка вывод, когда подключаетесь по SSH и выполняете простую команду, которая не должна ничего выводить:

    ssh username@host "true"

    Если файл, который вы создадите, не равен 0 байтам, это означает, что ваша оболочка генерирует вывод.

  3. Проверка наличия rsync:
    Убедитесь, что rsync установлен на целевой машине и доступен в пути. Выполните:

    ssh remotehost "rsync --version"

    Если вы видите сообщение "command not found", rsync не установлен. Установите его с помощью:

    sudo yum install rsync   # Для систем на основе Red Hat
    sudo apt install rsync   # Для систем на основе Debian
  4. Проверка конфигурации SSH:
    Убедитесь, что ваш конфигурационный файл SSH (~/.ssh/config) на клиентской стороне не вызывает ненужного вывода. Например, команда LocalCommand, добавляемая в конфиг, может вызывать такой вывод:

    LocalCommand printf '\033]0;%%s\007' "%r@%n"

    Комментирование или удаление этой строки может помочь решить проблему.

  5. Проверка временных сообщений:
    Если на пути подключения к SSH настроены временные сообщения (например, уведомления о том, что пароль истекает), это также может вызвать указанное сообщение об ошибке. Убедитесь, что такие сообщения отключены.

  6. Удаление файла rc:
    Если у вас есть файл ~/.ssh/rc на удаленной стороне, который выполняет команды при соединении, попробуйте временно переместить его:

    mv ~/.ssh/rc ~/.ssh/rc.bak
  7. Использование команды false для проверки:
    Как упоминалось ранее, попробуйте выполнить:

    ssh remotehost false

    Команда false должна завершаться без вывода. Если вы видите сообщение, проверьте инициализационные файлы оболочки для вывода.

  8. Убедитесь, что SSH соединение поддерживает rsync:
    Если SSH настроен только для SFTP и не поддерживает обычный SSH доступ, это тоже может привести к проблеме с rsync. Возможно, вам нужно будет изменить настройки SSH-сервера, например, в файле /etc/ssh/sshd_config.

Заключение

Соблюдение этих рекомендаций поможет вам устранить ошибку "protocol version mismatch — is your shell clean?". Если проблемы сохраняются, проверьте документацию rsync и SSH, а также системные журналы для получения дополнительной информации.

Оцените материал
Добавить комментарий

Капча загружается...