Назад | Перейти на главную страницу

Надежно добавьте хост (например, GitHub) в файл SSH known_hosts

Как добавить ключ хоста в SSH known_hosts файл безопасно?

Я настраиваю машину для разработки и хочу (например) предотвратить git от запроса, когда я клонирую репозиторий из github.com используя SSH.

Я знаю что могу использовать StrictHostKeyChecking=no (например. этот ответ), но это небезопасно.

Пока что нашел ...

  1. GitHub публикует их отпечатки ключей SSH на https://help.github.com/articles/github-s-ssh-key-fingerprints/

  2. я могу использовать ssh-keyscan получить ключ хоста для github.com.

Как мне совместить эти факты? Учитывая заранее составленный список отпечатков пальцев, как мне проверить, что вывод ssh-keyscan можно добавить в known_hosts файл?


Думаю, я спрашиваю следующее:

Как мне получить отпечаток ключа, возвращенного ssh-keyscan?

Предположим, я уже был MITM-ed для SSH, но я могу доверять странице HTTPS GitHub (потому что у нее есть действующая цепочка сертификатов).

Это означает, что у меня есть (подозрительные) ключи хоста SSH (от ssh-keyscan) и некоторые (доверенные) ключевые отпечатки пальцев. Как мне проверить одно против другого?


Связанный: как мне хешировать хост-часть вывода из ssh-keyscan? Или я могу смешивать хешированные / нехешированные хосты в known_hosts?

Самая важная часть "надежного" добавления ключа к known_hosts файл должен получить отпечаток ключа от администратора сервера. Отпечаток ключа должен выглядеть примерно так:

2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)

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

Ручная установка ключа

1) Возьмите копию ключа с сервера и получите его отпечаток пальца. Примечание: сделайте это перед проверка отпечатка пальца.

$ ssh-keyscan -t rsa github.com | tee github-key-temp | ssh-keygen -lf -
# github.com:22 SSH-2.0-babeld-f3847d63
2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)

2) Получите копию отпечатка ключа у администратора сервера - в этом случае перейдите на страницу с информацией на github.com

  1. Перейти на github.com
  2. Перейти к Помогите страница (в меню справа, если вы вошли в систему; в противном случае внизу главной страницы).
  3. в Начиная раздел перейти к Подключение к GitHub по SSH
  4. Перейти к Проверка вашего SSH-соединения
  5. Скопируйте отпечаток SHA256 с этой страницы в текстовый редактор для дальнейшего использования.

3) Сравните ключи из двух источников

Поместив их друг над другом в текстовом редакторе, легко увидеть, не изменилось ли что-то.

2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA) #key recovered from github website
2048 SHA256:nThbg6kXUpJ3Gl7E1InsaspRomtxdcArLviKaEsTGY8 github.com (RSA) #key recovered with keyscan

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

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

4) Если ключи сравниваются правильно, вам следует установить ключ, который вы уже скачали.

cat github-key-temp >> ~/.ssh/known_hosts

Или установить для всех пользователей системы (как root):

cat github-key-temp >> /etc/ssh/ssh_known_hosts

Автоматическая установка ключей

Если вам нужно добавить ключ во время процесса сборки, вы должны выполнить шаги 1-3 описанного выше ручного процесса.

Сделав это, изучите содержимое вашего github-key-temp файл и создайте сценарий для добавления этого содержимого в файл известных хостов.

if ! grep github.com ~/.ssh/known_hosts > /dev/null
then
     echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
fi

Ты должен сейчас избавиться от любой ssh команды, которые имеют StrictHostKeyChecking отключен.

Вы можете смешивать хешированные / немешированные записи в вашем файле known_hosts.

Итак, если вы хотите добавить ключ github, вы можете просто сделать:

ssh-keyscan github.com >> ~/.ssh/known_hosts

Если вы хотите, чтобы он был хеширован, добавьте -H

ssh-keyscan -H github.com >> ~/.ssh/known_hosts

Самый простой способ - получить ключи вручную, используя ssh-keyscan, проверьте их вручную:

$ ssh-keyscan -t rsa github.com | ssh-keygen -lf -
# github.com:22 SSH-2.0-libssh-0.7.0
2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)

И добавьте их в свой сценарий, который затем будет содержать «авторитетный» открытый ключ.

Я написал простой скрипт (add_to_known_hosts), чтобы справиться с этим:

Он не будет создавать повторяющиеся записи в known_hosts и проверит, соответствует ли отпечаток пальца одному, указанному в качестве второго аргумента.

#!/usr/bin/env bash
# First argument should be hostname (or IP)
# Second argument should be referential fingerprint
# Example: add_to_known_hosts github.com SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8

host=$1
fingerprint=$2

ip=$(getent hosts $1 | awk '{ print $1 }')
echo $ip

keys=$(ssh-keyscan -t rsa $host $ip)

# Iterate over keys (host and ip)
while IFS= read -r key; do
    # Extract Host name (or IP)
    key_host=$(echo $key | awk '{ print $1 }')

    # Extracting fingerprint of key
    key_fingerprint=$(echo $key | ssh-keygen -lf - | awk '{ print $2 }')

    # Check that fingerprint matches one provided as second parameter
    if [[ $fingerprint != $key_fingerprint ]]; then
      echo "Fingerprint match failed: '$fingerprint' (expected) != '$key_fingerprint' (got)";
      exit 1;
    fi

    # Add key to known_hosts if it doesn't exist
    if ! grep $key_host ~/.ssh/known_hosts > /dev/null
    then
       echo "Adding fingerprint $key_fingerprint for $key_host to ~/.ssh/known_hosts"
       echo $key >> ~/.ssh/known_hosts
    fi
done <<< "$keys"