
Давайте представим себе следующую ситуацию.
У меня есть ключ хоста ABCDEF1234
для заданного имени хоста, поэтому мой known_hosts
файл выглядит так (нехешированная версия):
example.com ssh-rsa ABCDEF1234
Теперь я подключаюсь к нему, и имена хостов разрешаются в 10.11.12.13. У меня есть такое сообщение
Warning: Permanently added the ECDSA host key for IP address '10.11.12.13' to the list of known hosts.
А мой known_hosts выглядит вот так
example.com ssh-rsa ABCDEF1234
192.0.2.1 ssh-rsa ABCDEF1234
Теперь, несколько месяцев спустя, example.com
администратор говорит мне, что ключ RSA удален и изменен в пользу 1234ABCDEF
ключа. Поэтому я удаляю проблемный ключ с помощью ssh-keygen -R example.com
, затем подключаюсь в первый раз, принимаю ключ и знаю, что мой known_host
выглядит так:
192.0.2.1 ssh-rsa ABCDEF1234
example.com ssh-rsa 1234ABCDEF
И каждый раз при подключении я получаю это приятное предупреждающее сообщение:
Warning: the ECDSA host key for 'example.com' differs from the key for the IP address '192.0.2.1'
Offending key for IP in /home/jenkins/.ssh/known_hosts:162
Matching host key in /home/jenkins/.ssh/known_hosts:182
Теперь представьте, что для этого конкретного имени хоста есть десятки или сотни IP, это довольно много строк для очистки. Одним из решений является использование sed
для удаления соответствующих строк, но разве цель не в том, ssh-keygen -R
чтобы избежать путаницы с sed
?
sed -i '/ABCDEF1234/d' known_hosts
Есть ли другое решение, которое удалит все записи из known_host
файла, связанные с заданным ключом, а не с именем хоста или IP-адресом?
решение1
Цель ssh-keygen -R
не в том, чтобы избежать использования sed
, а в том, чтобы удалить хэшированные хосты, которые, например, sed
не удалось найти. Изssh-keygen(1):
-R hostname
Удаляет все ключи, принадлежащие к
hostname
изknown_hosts
файла. Эта опция полезна для удаления хэшированных хостов (см.-H
опцию выше).
-H
Хэшировать
known_hosts
файл. Это заменяет все имена хостов и адреса хэшированными представлениями в указанном файле; исходное содержимое перемещается в файл с суффиксом.old
. Эти хэши могут использоваться обычным образомssh
иsshd
, но они не раскрывают идентифицирующую информацию, если содержимое файла будет раскрыто. Эта опция не изменяет существующие хэшированные имена хостов и поэтому безопасна для использования в файлах, которые смешивают хэшированные и нехэшированные имена.
Соображения
Избегайте столкновений
Обратите внимание, что лучше всего использовать полный открытый ключ, закодированный в Base64, чтобы избежать удаления других ключей. Например, если вы используете только частизаголовокв итоге вы удалите все ключи одного типа:
Base64 | ASCII | Ссылка. |
---|---|---|
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY AAAAIbmlzdHAyNTYAAABBB |
....ecdsa-sha2-nistp256 ....nistp256...A |
RFC 5656, 3.1 |
AAAAC3NzaC1lZDI1NTE5AAAAIFKy |
....ssh-ed25519... R² |
RFC 8709, 4 |
AAAAB3NzaC1yc2EAAAADAQABAAABAQ |
...ssh-rsa........... |
RFC 4253, 6.6 |
Настройте sed
для Base64
Открытый ключ в кодировке Base64 содержит символы A-Za-z0-9+/=
. Поскольку он может содержать /
используемый в вашем sed
примере, вы хотели бы использовать другой символ, например :
.
Рабочие примеры
В примерах:
- Это
AAAA+OLD/KEY=
заполнитель дляполныйстарый открытый ключ. - Это
AAAA+NEW/KEY=
заполнитель дляполныйновый открытый ключ.
Удалить все хосты с одинаковым ключом
Используйте полный старый ключ, чтобы удалить все строки, содержащие его:
sed -i ':AAAA+OLD/KEY=:d' ~/.ssh/known_hosts
Замените старый ключ на новый
Используйте полные ключи (старый и новый) для замены во всех строках, содержащих старый ключ:
sed -i 's:AAAA+OLD/KEY=:AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
Если тип ключа также изменится, вам придется включить его, например,
sed -i 's:ssh-rsa AAAA+OLD/KEY=:ecdsa-sha2-nistp256 AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
Удалить ключи для имени хоста или IP
Это единственный случай, когда следует использовать ssh-keygen
.
ssh-keygen -R example.com
ssh-keygen -R 192.0.2.1
решение2
Избегать проблемы изначально — хорошее решение. Если бы known_hosts не был заполнен записями для каждого IP-адреса для данного имени хоста, не было бы необходимости возиться с sed. ssh_keygen -R hostname
было бы достаточно выполнить ротацию ключей.
Поэтому мое решение этой проблемы — установить CheckHostIP
в no
конфигурации ssh.