Как установить пользовательскую строку ответа для SSH-соединения?

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

Возможно ли изменить строку, которую сервер OpenSSH отображает при установлении сырого соединения?

Речь идет не о текстовом баннере, который отображается после установления соединения и который можно настроить с помощью параметра Banner в sshd_config, а о сыром выводе, который SSH-сервер отправляет при попытке подключения до начала обмена данными.

Например, при установлении сырого соединения telnet:

$ telnet localhost 22
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.2p2

Есть ли способ сократить идентифицирующую информацию до минимально необходимого?

Я понимаю, что SSH-2.0- должен присутствовать, потому что это требуется SSH-протоколом, но строка, которая следует за ним – OpenSSH_7.2p2 – скорее всего не обязательна по требованиям протокола, и я не вижу способа изменить или удалить ее без повторной компиляции.

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

Нет. Строка версии определяется в version.h исходного кода OpenSSH как

#define SSH_VERSION "OpenSSH_7.4".

Вы можете изменить ее, но это требует компиляции.

Она затем отправляется формируется с помощью:

snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION)

(ssh_api.c строка 381, в функции _ssh_send_banner)

Смотрите также: Предотвратить SSH от рекламы номера своей версии.

Недавние версии OpenSSH позволяют добавлять пользовательский текст через VersionAddendum, но не позволяют удалять имя продукта/версии. Для этого вам придется изменить исходный код.

Проблема

OpenSSH (и на самом деле каждая другая реализация SSH) раскрывает важную информацию о безопасности для каждого входящего соединения. Обратите внимание:

# telnet localhost 22
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3

Это раскрывает версию OpenSSH и версию операционной системы для всех, кто пытается подключиться.

Это вызывает проблемы с двух сторон: безопасность и конфиденциальность.

Безопасность

(Утомительно) часто повторяемое замечание тех, кто не понимает фразы, состоит в том, что воздержание от выдачи информации о системе является “безопасностью за счет неясности”. Это не так. Эта фраза относится только к идее, что если криптографический примитив безопасен только тогда, когда алгоритм неизвестен, то он не является безопасным. Эта фраза не имеет, и никогда не имела намерения касаться концепции, что воздержание от выдачи информации о вашей криптосистеме, реализации или операционной системе – это плохая вещь. Все, что увеличивает активационную энергию, необходимую для того, чтобы противник взломал систему, является хорошей вещью. На самом деле это, в единственном числе, всё, что любой замок (криптографический или физический) делает в любом случае. Идея о том, что усилия по повышению сложности для противника ошибочны, является неправильным применением иначе важного принципа обеспечения безопасности (среди прочих способов) с помощью правильной криптографии.

Конфиденциальность

Предположим, вы поддерживаете частный VPS, который мы назовем JOURNALISTHAVEN в скрытом месте. Допустим, вы хотите скрыть факт подключения к нему, но при этом иметь возможность подключаться к нему через ssh откуда угодно. Вы переадресовываете порт с другого VPS, PUBLICVILLE, через коммерческий VPN на JOURNALISTHAVEN. Теперь вы можете использовать любой компьютер где угодно, чтобы подключиться к вашему частному VPS, не делая очевидным, что вы подключаетесь к нему. Теперь представьте, что версия реализации ssh на PUBLICVILLE отличается от версии JOURNALISTHAVEN – теперь становится очевидным, что переадресованный порт – это не просто еще один порт, на котором слушает демона ssh PUBLICVILLE, а что он идет куда-то еще. Да, есть и другие способы, которыми эта информация может быть раскрыта понимающим и сосредоточенным противником, но действительно ли нам нужно выдавать эту информацию каждому новичку? Никто не может утверждать, что конфиденциальность за счет неясности – это нечто, кроме единственного вида конфиденциальности, который существует.

Вопрос

Возможно ли изменить строку, которую сервер OpenSSH отображает при установлении сырого соединения?

Ответ, в основном, да – 50% через конфигурационные средства. Остальное – путем повторной компиляции или изменения вашего двоичного файла.

Строка подключения

RFC 4253, раздел 4.2 требует, чтобы строка подключения имела:

SSH-2.0-softwareversion

…где softwareversion не содержит пробелов и символа -. Поэтому его нельзя полностью исключить, и он не может быть просто пробелом или -. Это должно быть хотя бы один печатный символ. К сожалению, OpenSSH педантичен в этом, поэтому если вы полностью удалите softwareversion, клиент OpenSSH откажется подключаться к серверу.

Сервер OpenSSH

К сожалению, нельзя заставить сервер OpenSSH молчать о своей версии или настроить его с помощью параметра конфигурации. Вы можете заставить его молчать о системе с помощью параметра /etc/ssh/sshd_config.d/*:

DebianBanner no

Это только частично решает задачу. Это все равно оставляет OpenSSH, объявляющим о своей версии и даже уровне патча для каждого желающего.

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

Редактировать исходный код и перекомпилировать

OpenSSH доступен по адресу https://www.openssh.com/. Полные инструкции по сборке выходят за рамки этого, но вы можете найти строку версии для редактирования в version.h:

#define SSH_VERSION "OpenSSH_9.9"

Вы можете изменить это по своим требованиям. Строка “SSH” достаточно обобщенная.

Редактировать бинарный файл

ПРЕДУПРЕЖДЕНИЕ: Это имеет последствия.

Недавние версии бинарного файла OpenSSH можно редактировать. Для этого:

  1. Узнайте точную строку подключения, которую нужно отредактировать. sshd -x – это на самом деле неправильная команда, но это единственный способ заставить sshd напечатать использование и строку версии подключения (sshd -V не печатает ту же строку)
  2. Используйте шестнадцатеричный редактор (hexcurse или аналогичный) на копии /usr/sbin/sshd и найдите ВТОРОЕ вхождение строки.
  3. Замените первые три символа на ‘SSH’, за которыми следует нулевой символ.
  4. mv /usr/sbin/sshd /usr/sbin/sshd.orig
  5. Скопируйте отредактированный бинарный файл в /usr/sbin/sshd
  6. Перезапустите службу. Для большинства это будет systemctl restart sshd
  7. Проверьте новую версию. systemctl status sshd, чтобы убедиться, что служба работает, и telnet localhost 22 для тестирования строки версии. Если вы редактируете бинарный файл, вам все равно нужно будет отключить DebianBanner.

Если вы не хотите редактировать бинарный файл в шестнадцатеричном формате, то этот скрипт сделает то же самое для большинства недавних версий sshd на Linux:

# VERSION="OpenSSH_9.2p1" NEW="SSH" perl -0777 -pe 'BEGIN { $version = $ENV{VERSION}; $new = $ENV{NEW} . "\0"; } 
    $pos = index($_, $version, index($_, $version) + 1);
    substr($_, $pos, length($new), $new) if $pos != -1;' /usr/sbin/sshd > sshd_patched

VERSION должен быть установлен на точную строку версии, полученную на этапе 1 выше. NEW должен быть установлен на то, что вы хотите отобразить вместо этого.

Следуйте шагам 5, 6 и 7, перечисленным выше.

Последствия редактирования бинарного файла
  • Менеджеры пакетов могут иметь проблемы с обновлением sshd в будущем. Перед обновлением пакета sshd вы должны:
    1. systemctl stop sshd
    2. mv /usr/sbin/sshd.orig /usr/sbin/sshd
    3. systemctl start sshd
  • Указанный выше метод редактирования в шестнадцатеричном формате или скрипт могут не сработать на будущих версиях sshd или очень старых версиях. Это следует тестировать, прежде чем полагаться на это.

Заключение

Многие другие ответы и городские мифы предполагают, что информация о версии программного обеспечения SSH в строке подключения необходима для корректного подключения клиентов. Сегодня это универсально неверно. В прошлом были некоторые ошибки, которые обходились подобным образом клиентами, и это совершенно неизвестно на сегодня. Нет информации, необходимой клиенту в строке версии программного обеспечения – вся информация о соединении SSH содержится в дальнейших обменах данными.

RFC 4253 на самом деле подразумевает требование строки версии программного обеспечения в ssh-соединениях для диагностических целей. Что-то, что клиент, испытывающий трудности с подключением к серверу, может использовать telnet и просмотреть, чтобы диагностировать, если возникли проблемы с совместимостью. Это не было так уже в течение некоторого времени. Это было сомнительной полезностью 18 лет назад, когда был написан RFC, и тогда не было такой военной обстановки, как сегодня. Вы не можете запустить ssh-сервер на новом IP-адресе более чем на две минуты, не привлекая к нему ботнеты. Когда бомбы падают, выключите свет и закройте занавески. Если, конечно, некоторые крипто-воины с дивана не хотят назвать это безопасностью через неясность тоже. В таком случае им будет хорошо поднять голову над окопом и закурить сигарету. Или включить свет во время воздушной тревоги.

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

Конечно, изменение строки ответа, которую сервер OpenSSH отображает при установлении соединения, является важной задачей, особенно с точки зрения безопасности и конфиденциальности. Давайте разберем этот вопрос подробнее.

Возможность изменения строки версии OpenSSH

По умолчанию при установлении подключения к OpenSSH серверу клиент получает строку в формате:

SSH-2.0-OpenSSH_<версия>

Изменение строки версии

  1. Строка версии обязательна: Согласно RFC 4253, строка версии должна начинаться с SSH-2.0- и содержать по крайней мере один печатаемый символ после этого. Это означает, что строка не может быть полностью удалена.

  2. Конфигурация через sshd_config: В последние версии OpenSSH добавлена возможность использования директивы VersionAddendum в конфигурационном файле sshd_config, но она не позволяет удалить или изменить строку версии, а только добавить дополнительный текст. Таким образом основной текст OpenSSH_<версия> остается неизменным.

  3. Редактирование исходного кода: Для изменения текста версии или его удаления необходимо редактировать исходный код OpenSSH. Строка, ответственный за вывод версии, определяется в файле version.h в исходном коде. Например:

    #define SSH_VERSION "OpenSSH_9.2"

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

  4. Редактирование бинарного файла: Существует также возможность редактирования бинарного файла OpenSSH, чтобы изменить строку версии, но это требует дополнительных шагов и обращает внимание на следующие нюансы:

    • Используйте двоичный редактор, чтобы отредактировать файл /usr/sbin/sshd, заменив строку с версией на желаемую.
    • Можете также воспользоваться скриптом на Perl, который позволит изменять строку без редактирования вручную.
    # VERSION="OpenSSH_9.2" NEW="SSH" perl -0777 -pe 'BEGIN { $version = $ENV{VERSION}; $new = $ENV{NEW} . "\0"; } 
       $pos = index($_, $version, index($_, $version) + 1);
       substr($_, $pos, length($new), $new) if $pos != -1;' /usr/sbin/sshd > sshd_patched

Последствия редактирования

  • Проблемы с обновлением: При редактировании бинарного файла могут возникнуть трудности с обновлением OpenSSH через менеджер пакетов. Перед обновлением необходимо восстановить оригинальный файл.

  • Тестирование изменений: Перед внедрением изменений протестируйте работу SSH-сервера, используя команду telnet localhost 22 для проверки новой строки версии.

Заключение

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

Если у вас возникнут дополнительные вопросы или потребуется помощь, не стесняйтесь обращаться!

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

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