Я хочу обновить свой ~/.ssh/known_hosts
с информацией о ключе хоста для вновь созданного экземпляра GCE. Но я не знаю, как безопасно получить эту информацию.
Я думал что-то вроде
gcloud compute ssh <GCEUSER>@<GCEHOST> --command='ssh-keyscan 127.0.0.1'
может работать. Но это (согласно gcloud compute ssh документация) кажется просто оберткой для ssh
(и, основываясь на наблюдении StrictHostKeyChecking=no
в параметрах, перечисленных в связанном файле журнала в $ HOME / .config / gcloud / logs /, по-видимому, не выполняет никаких проверок личности хоста).
Кажется, есть способ использовать веб-консоль для запуска сеанса ssh в браузере (и интерактивно / вручную запускать ssh-keyscan
), но 1) я не вижу внутренних компонентов, чтобы узнать, действительно ли он настолько безопасен, как должен быть, и 2) не является эффективным API для интеграции скриптов.
Есть ли API /gcloud
механизм для безопасного получения ключа хоста экземпляра GCE?
OP связан с ошибка 35907612 (первоначально упомянутый Рахи), который был помечен как «исправлено» со ссылкой на документацию Хранение ключей хоста.
Чтобы получить ключ хоста, вам необходимо включить «гостевые атрибуты» перед или в течение создание экземпляра GCE. Я включил его для всего проекта (не уверен, почему он был отключен по умолчанию). Кроме того, у вас есть возможность включить его при создании экземпляра.
Согласно документации, gcloud
требуется для заполнения атрибутов гостя, но, похоже, я могу перейти к шагу «Подтверждение того, что ключи хоста хранятся как гостевые атрибуты»Сразу после загрузки экземпляра.
На шаге 2 (подтверждение ключей) я выбрал вариант 2, потому что не спрашивал gcloud
заселять ~/.ssh/google_compute_known_hosts
на последнем этапе, поэтому я хочу видеть ключи, а не просто проверять, что они «где-то».
Когда ты бежишь get-guest-attributes
подкоманда, обе --project
и --zone
флаги являются необязательными и по умолчанию используются в конфигурации, установленной с помощью gcloud config
.
Чтобы получить хэш SHA-256 для ключей хоста прямо из get-guest-attributes
, с помощью jq
:
gcloud compute instances get-guest-attributes my-instance --format json | jq -r '.[] | "\(.key) \(.value) my-server-name"' | ssh-keygen -l -f -
Объясните: -r
средства --raw-output
в jq
. -l
означает перечисление ключей с хешами. -f -
означает файл из stdin
. my-server-name
необязательный комментарий, который появляется в выводе (иначе вы увидите no comment
).
Нет, нет простого способа сделать это (есть открытая проблема для устранения этой угрозы безопасности).
«Команда gcloud» или «API» будет извлекать только информацию, относящуюся к конкретному проекту или продуктам Google, такие как метаданные экземпляра из экземпляра GCE. Невозможно получить конфигурацию экземпляра, например ключи хоста, с помощью команды gcloud или API.
Обновить
Пара ключей хоста SSH, закрытый и открытый ключи хранятся на сервере SSH. Открытый ключ передается клиенту SSH при каждом подключении. Это используется для аутентификации сервера SSH для клиента. После первого подключения ключ «известного хоста» обычно сохраняется в ~ / .ssh / known_hosts на SSH-клиенте (например, на вашем компьютере), хотя gcloud хранит его в другом месте.
Когда вы используете gcloud compute ssh, ваш SSH-клиент ведет себя несколько иначе: публичный ключ хоста сервера автоматически принимается для вас при первом подключении, и вместо этого он записывается в ~ / .ssh / google_compute_known_hosts.
Каждый раз, когда вы подключаетесь к серверу SSH, он отправляет свой открытый ключ хоста. В большинстве случаев открытый ключ хоста сервера не меняется. После того, как вы подключились один раз и сохранили открытый ключ первого подключения, ваш SSH-клиент может проверить, не отличается ли открытый ключ хоста сервера. Если другое, вы увидите сообщение:
Ошибка проверки ключа хоста.
Когда вы видите это сообщение, имеет место одно из следующих событий:
По умолчанию gcloud compute ssh не выполняет строгую проверку ключа хоста. На это есть причины; однако вы можете включить строгую проверку ключа хоста, добавив параметр --oStrictHostKeyChecking = yes в gcloud compute ssh. Вот пример:
gcloud compute ssh [INSTANCE_NAME] --zone [ZONE] - -oStrictHostKeyChecking = yes
Это хороший пример того, как вы можете добавлять произвольные аргументы SSH в gcloud compute ssh.
Пропуск проверки ключа хоста - не проблема. Предположим, вы создали новый экземпляр, к которому никогда не подключались. Как вы узнаете, что подключаетесь к этому экземпляру, а не где-то еще?
Рассмотрим следующий пример. Предположим, у вас нет пары пользовательских ключей SSH для использования gcloud. (Если вы переместите и ~ / .ssh / google_compute_engine, и ~ / .ssh / google_compute_engine.pub в сторону, вы можете проверить это.) Предположим, вы не вошли в gcloud. Вы можете выйти из системы с помощью gcloud auth revoke.
Теперь попробуйте подключиться к экземпляру по SSH с помощью gcloud compute ssh. Сначала вам нужно будет пройти аутентификацию в gcloud. Итак, запустите gcloud auth login и войдите в систему. Теперь ваша система имеет токен доступа, хранящийся в ~ / .config / gcloud /. Этот токен используется для аутентификации каждый раз, когда вы делаете вызов API с помощью gcloud.
Теперь попробуйте снова подключиться к тому же экземпляру по SSH, используя gcloud compute ssh. Без пары пользовательских ключей SSH он вызовет ssh-keygen от вашего имени для создания новой пары пользовательских ключей SSH. Закрытый (пользовательский) ключ будет храниться в ~ / .ssh / google_compute_engine, а открытый (пользовательский) ключ будет храниться в ~ / .ssh / google_compute_engine.pub. Закрытый ключ остается на вашем компьютере, и вы несете ответственность за его защиту. Содержимое открытого ключа отправляется через вызов API в projects.setCommonInstanceMetadata или instance.setMetadata. По умолчанию gcloud добавит ваш открытый ключ в метаданные проекта (для всех экземпляров), если только экземпляр, к которому вы подключаетесь, не настроен для блокировки SSH-ключей проекта; в этом случае он добавит открытый ключ к метаданным экземпляра. Оба вызова API аутентифицируются с помощью токена, который вы получили при входе в систему gcloud auth. Открытый ключ зашифровывается при передаче, потому что команды gcloud выполняются через вызовы API по HTTPS.
На этом этапе у вас есть новый закрытый ключ пользователя SSH. Если вы не скопировали его в другое место, он находится на вашем компьютере. То же самое верно и для соответствующего открытого ключа, за исключением того, что вы поделились им с Google, отправив его с помощью аутентифицированной команды gcloud по HTTPS. Таким образом, единственные системы, которые должны иметь доступ к открытому ключу, - это те, которые вы используете в своем проекте GCP.
Только носитель закрытого ключа пользователя SSH может успешно пройти аутентификацию на серверах SSH, работающих в GCP. Только серверы SSH, работающие в GCP, имеют копию вашего открытого ключа пользователя SSH. Таким образом, можно безопасно принять открытый ключ хоста автоматически. Если бы вы подключались к мошенническому серверу вместо своего SSH-сервера GCP, процесс аутентификации завершился бы ошибкой, потому что этот другой сервер не имел бы вашего открытого ключа пользователя SSH.
В определенных ситуациях GCP автоматически воссоздает пару ключей хоста SSH-сервера. Например, если вы используете экземпляр для создания шаблона, на основе которого будут созданы другие экземпляры в группе. В каждом случае необходимо обновить ключ хоста SSH. По этой причине выполнение строгой проверки ключа хоста SSH может генерировать вводящие в заблуждение сообщения об ошибках.
обновить 5 сентября 2018 г.
Можно подключиться к экземпляру без "glcoud", и команда GCP знает об этом и работает над этим. Зарегистрирована публичная ошибка Вот. Там можно увидеть какой-то прогресс.
Ключи хоста уже загружены для вас в компьютер, который вы используете gcloud
в ~ / .ssh / google_compute_known_hosts.
Per --help, поведение проверки ключа хоста выглядит следующим образом:
--strict-host-key-checking=STRICT_HOST_KEY_CHECKING Override the default behavior of StrictHostKeyChecking for the connection. By default, StrictHostKeyChecking is set to 'no' the first time you connect to an instance, and will be set to 'yes' for all subsequent connections. STRICT_HOST_KEY_CHECKING must be one of: yes, no, ask.
Каково поведение в файле журнала, если вы посмотрите на последующие соединения.
2018-08-04 14:48:29,222 DEBUG root Running command [/usr/bin/ssh -t -i /home/john/.ssh/google_compute_engine -o CheckHostIP=no -o HostKeyAlias=compute.1520573357386694112 -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/home/john/.ssh/google_compute_known_hosts john@35.188.181.248].
2018-08-04 14:51:06,249 DEBUG root Executing command: [u'/usr/bin/ssh', u'-t', u'-i', u'/home/john/.ssh/google_compute_engine', u'-o', u'CheckHostIP=no', u'-o', u'HostKeyAlias=compute.1520573357386694112', u'-o', u'IdentitiesOnly=yes', u'-o', u'StrictHostKeyChecking=yes', u'-o', u'UserKnownHostsFile=/home/john/.ssh/google_compute_known_hosts', u'john@35.188.181.248']
Это удобство, поэтому при первом подключении не будет спрашиваться о хосте, но будут проверяться будущие.
Фактически это то же самое, что пользователь видит неизвестный ключ хоста от своего клиента и принимает его, не читая ключ. С некоторой уверенностью в имени хоста соединения это разумно делать в большинстве сценариев.
В этом случае ваше доверие к системе должно заключаться в том, насколько вы доверяете службе метаданных GCE, которая направит вас на правильный хост и отправит на него свой ssh-ключ.