Могу ли я автоматически добавить новый хост в known_hosts?

249

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

У меня проблема в том, что первая sshкоманда, запущенная для нового виртуального экземпляра, всегда выдает интерактивное приглашение:

The authenticity of host '[hostname] ([IP address])' can't be established.
RSA key fingerprint is [key fingerprint].
Are you sure you want to continue connecting (yes/no)?

Есть ли способ, которым я могу обойти это и сделать так, чтобы новый хост уже был известен клиентской машине, возможно, с помощью открытого ключа, уже встроенного в образ виртуальной машины? Я действительно хотел бы избежать использования Expect или чего-либо еще, чтобы ответить на интерактивное приглашение, если смогу.

gareth_bowles
источник
5
Для тестовой среды, которая является автономной и физически безопасной, автоматическое принятие ключей может работать просто отлично. Но автоматическое принятие открытых ключей в производственной среде или в ненадежной сети (например, в Интернете) полностью обходит любую защиту от атак «человек посередине», которые иначе мог бы предоставить SSH. Только действительный способ , чтобы убедиться , что вы защищены от MITM атак для проверки открытого ключа хоста через некоторый вне зоны доверенного канала. Не существует безопасного способа автоматизировать его, не настроив умеренно сложную инфраструктуру подписывания ключей.
Eil

Ответы:

142

Установите StrictHostKeyCheckingопцию no, либо в файле конфигурации, либо через -o:

ssh -o StrictHostKeyChecking=no username@hostname.com

Игнасио Васкес-Абрамс
источник
62
Это оставляет вас открытым для человека в середине атаки, вероятно, не очень хорошая идея.
Джаспер Уоллес
9
@JasperWallace, хотя обычно это хороший совет, конкретный вариант использования (развертывание тестовых виртуальных машин и отправка им команд) должен быть достаточно безопасным.
Массимо
8
Это дает Warning: Permanently added 'hostname,1.2.3.4' (RSA) to the list of known hosts.Во избежание предупреждения и во избежание добавления записи в любой файл known_hosts, я делаю:ssh -o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null username@hostname.com
Peter V. Mørch
11
Пониженное голосование не отвечает на этот вопрос и открывает серьезные уязвимости безопасности.
marcv81
12
@Mnebuerquo: Если бы вы беспокоились о безопасности, то у вас не было бы ничего общего с этим вопросом. Перед вами будет правильный ключ хоста, собранный с консоли системы, к которой вы хотите подключиться, и вы вручную проверите его при первом подключении. Вы, конечно, ничего не сделаете "автоматически".
Игнасио Васкес-Абрамс
230

ИМО, лучший способ сделать это заключается в следующем:

ssh-keygen -R [hostname]
ssh-keygen -R [ip_address]
ssh-keygen -R [hostname],[ip_address]
ssh-keyscan -H [hostname],[ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [hostname] >> ~/.ssh/known_hosts

Это позволит убедиться, что нет повторяющихся записей, что вы застрахованы как для имени хоста, так и для IP-адреса, а также будет хэшировать вывод, что является дополнительной мерой безопасности.

Ярдена
источник
4
Зачем вам все 3 ssh-keyscan? Разве вы не можете обойтись только с первым, так как он работает как для имени хоста, так и для ip?
Роберт
6
Можете ли вы быть уверены, что машина, отвечающая на запрос ssh-keyscan, действительно является той, с которой вы хотите поговорить? Если нет, то вы открыли себя человеку в середине атаки.
Джаспер Уоллес
2
@JasperWallace Да, для этого вам понадобится как минимум отпечаток или, что еще лучше, открытый ключ, и в этом случае вы можете добавить его непосредственно в known_hosts, что делает этот вопрос спорным. Если у вас есть только отпечаток пальца, вам придется написать дополнительный шаг, который проверяет загруженный открытый ключ по вашему отпечатку пальца ...
1
Звонки ssh-keyscanмне не удавались, потому что мой целевой хост не поддерживает тип ключа версии 1 по умолчанию. Добавление -t rsa,dsaв команду исправило это.
phasetwenty
5
Это, наверное, плохая идея. Вы открываете себя атаке «человек посередине», обновляя эти ключи. Чтобы избежать повторяющихся записей, проверьте статус возврата ssh-keygen -F [address]вместо. medium.com/@wblankenship/...
retrohacker
93

Для ленивых:

ssh-keyscan -H <host> >> ~/.ssh/known_hosts

-H хеширует имя хоста / IP-адрес

fivef
источник
2
"ssh-keyscan -H <host> >> ~ / .ssh / known_hosts" создает запись, более похожую на то, что ssh делает с взаимодействием с пользователем. (-H хэширует имя удаленного хоста.)
Сара Мессер
3
Уязвим к атакам MITM. Вы не проверяете отпечаток ключа.
Mnebuerquo
8
@Mnebuerquo Вы говорите, что делать, но не как, что было бы полезно.
Рэй
4
@jameshfisher Да, он уязвим к атакам MITM, но сравнивали ли вы когда-нибудь отпечаток пальца RSA, который был показан вам с фактическим изображением сервера, когда вы делали это вручную? Нет? Таким образом, этот ответ - способ сделать это для вас. Если да, вы не должны использовать этот ответ и делать это вручную или применять другие меры безопасности ...
5
2
@Mnebuerquo Я был бы очень рад, если бы вы также сообщили нам лучший способ справиться с этим, когда нам нужно клонировать репо с помощью пакетных сценариев, не посещаемых, и мы хотим обойти это приглашение. Пожалуйста, пролите некоторый свет на реальное решение, если вы считаете, что это не правильное решение!
Вакас Шах
42

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

ssh-keyscan -t rsa,dsa HOST 2>&1 | sort -u - ~/.ssh/known_hosts > ~/.ssh/tmp_hosts
mv ~/.ssh/tmp_hosts ~/.ssh/known_hosts

Вышеприведенный способ поможет добавить хост, ТОЛЬКО если он еще не добавлен. Это также не безопасно для параллелизма; Вы не должны выполнять сниппет на одном и том же компьютере-источнике более одного раза в одно и то же время, поскольку файл tmp_hosts может быть засорен, что в конечном итоге приведет к раздутию файла known_hosts ...

ysawej
источник
Есть ли способ проверить, находится ли ключ в known_hosts раньше ssh-keyscan ? Причина в том, что для этого требуется некоторое время и дополнительное сетевое соединение.
Utapyngo
1
Оригинальная версия этого файла для автора постера имела cat ~/.ssh/tmp_hosts > ~/.ssh/known_hosts, но последующее редактирование изменило его на >>. Использование >>это ошибка. Это побеждает цель уникальности в первой строке, и заставляет это выгружать новые записи в known_hostsкаждый раз, когда это выполняется. (Только что опубликовал изменения, чтобы изменить его обратно.)
paulmelnikow
1
Это подвергается тем же атакам MITM, что и другие.
Mnebuerquo
@utapyngo ssh-keygen -F даст вам текущий отпечаток. Если он возвращается пустым с кодом возврата 1, то у вас его нет. Если он что-то печатает и код возврата равен 0, то он уже присутствует.
Rich L
1
Если вы так сильно заботитесь о MITM, разверните записи DNSSEC и SSHFP или воспользуетесь какими-то другими безопасными средствами для распространения ключей, и это решение Kludge не будет иметь значения.
Зарт
19

Вы можете использовать ssh-keyscanкоманду, чтобы получить открытый ключ и добавить его в свой known_hostsфайл.

Alex
источник
3
Обязательно проверьте отпечаток пальца, чтобы убедиться, что это правильный ключ. В противном случае вы открываете себя для атак MITM.
Mnebuerquo
3
@Mnebuerquo Честная точка зрения в общем контексте, но зачем кому-то пытаться программно собирать ключи, если он уже знал, что это за правильный ключ?
Брайан Клайн
Это не способ сделать это. MITM.
jameshfisher
8

Вот как вы можете включить ssh-keyscan в свою игру:

---
# ansible playbook that adds ssh fingerprints to known_hosts
- hosts: all
  connection: local
  gather_facts: no
  tasks:
  - command: /usr/bin/ssh-keyscan -T 10 {{ ansible_host }}
    register: keyscan
  - lineinfile: name=~/.ssh/known_hosts create=yes line={{ item }}
    with_items: '{{ keyscan.stdout_lines }}'
Zart
источник
1
Вы загружаете известный действительный файл known_hosts, или вы выполняете ssh-keyscan и выводите выходные данные в known_hosts без проверки отпечатков пальцев?
Mnebuerquo
1
Да, это просто вывод данных с клавиатуры. Таким образом, по сути это то же самое, что StrictHostKeyChecking = no, только с тихим обновлением known_hosts без возни с опциями ssh. Это решение также не работает должным образом из-за того, что ssh-keyscan возвращает несколько строк, поэтому эта задача всегда помечается как «измененная»
Zart
Это не способ сделать это. MITM.
jameshfisher
3
@jameshfisher Я был бы очень рад, если бы вы также сообщили нам лучший способ справиться с этим, когда нам нужно клонировать репо с помощью пакетных сценариев, которые не посещаются, и мы хотим обойти это приглашение. Пожалуйста, пролите некоторый свет на реальное решение, если вы считаете, что это не правильное решение! Пожалуйста, дайте нам знать, «как» это сделать, если вы считаете, что это неправильный способ сделать это!
Вакас Шах
Это совершенно правильный метод добавления значений к known_hosts, но да, он подвержен MITM. Тем не менее, для внутреннего использования это хорошо.
Кэмерон Лоуэлл Палмер
7

это было бы полным решением, принимая ключ хоста только в первый раз

#!/usr/bin/env ansible-playbook
---
- name: accept ssh fingerprint automatically for the first time
  hosts: all
  connection: local
  gather_facts: False

  tasks:
    - name: "check if known_hosts contains server's fingerprint"
      command: ssh-keygen -F {{ inventory_hostname }}
      register: keygen
      failed_when: keygen.stderr != ''
      changed_when: False

    - name: fetch remote ssh key
      command: ssh-keyscan -T5 {{ inventory_hostname }}
      register: keyscan
      failed_when: keyscan.rc != 0 or keyscan.stdout == ''
      changed_when: False
      when: keygen.rc == 1

    - name: add ssh-key to local known_hosts
      lineinfile:
        name: ~/.ssh/known_hosts
        create: yes
        line: "{{ item }}"
      when: keygen.rc == 1
      with_items: '{{ keyscan.stdout_lines|default([]) }}'
Мазац
источник
1
Это не способ сделать это. MITM.
jameshfisher
6

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

ssh -o "StrictHostKeyChecking no" -o PasswordAuthentication=no 10.x.x.x

Он добавляет ключ known_hostsи не запрашивает пароль.

VenomFangs
источник
2
Уязвим к атакам MITM. Вы не проверяете отпечаток пальца.
Mnebuerquo
6
Никто не проверяет отпечаток пальца.
Брендан Берд
Это не способ сделать это. MITM.
jameshfisher
5

Итак, я искал простой способ обойти неизвестное взаимодействие с хостом при клонировании git-репо, как показано ниже:

brad@computer:~$ git clone git@bitbucket.org:viperks/viperks-api.git
Cloning into 'viperks-api'...
The authenticity of host 'bitbucket.org (104.192.143.3)' can't be established.
RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)?

Обратите внимание на отпечаток ключа RSA ...

Итак, это SSH, это будет работать для git over SSH и просто для SSH в целом ...

brad@computer:~$ nmap bitbucket.org --script ssh-hostkey

Starting Nmap 7.01 ( https://nmap.org ) at 2016-10-05 10:21 EDT
Nmap scan report for bitbucket.org (104.192.143.3)
Host is up (0.032s latency).
Other addresses for bitbucket.org (not scanned): 104.192.143.2 104.192.143.1 2401:1d80:1010::150
Not shown: 997 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh
| ssh-hostkey:
|   1024 35:ee:d7:b8:ef:d7:79:e2:c6:43:9e:ab:40:6f:50:74 (DSA)
|_  2048 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 (RSA)
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 42.42 seconds

Сначала установите nmap на свой ежедневный драйвер. Nmap очень полезен для определенных вещей, таких как обнаружение открытых портов и это - ручная проверка отпечатков SSH. Но вернемся к тому, что мы делаем.

Хороший. Я либо скомпрометирован в нескольких местах и ​​машинах, которые я проверил, либо более правдоподобным объяснением того, что все происходит так, как надо, является то, что происходит.

Этот «отпечаток пальца» - это просто строка, сокращенная с помощью одностороннего алгоритма для удобства человека, и существует риск того, что более одной строки будут преобразованы в один и тот же отпечаток пальца. Бывает, они называются столкновениями.

Независимо от этого, вернемся к исходной строке, которую мы можем увидеть в контексте ниже.

brad@computer:~$ ssh-keyscan bitbucket.org
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-128
no hostkey alg
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-129
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-123
no hostkey alg

Итак, заблаговременно, у нас есть способ запросить форму идентификации у оригинального хоста.

На данный момент мы вручную так же уязвимы, как и автоматически: строки совпадают, у нас есть базовые данные, которые создают отпечаток, и мы можем запросить эти базовые данные (предотвращая столкновения) в будущем.

Теперь, чтобы использовать эту строку таким образом, чтобы не спрашивать о подлинности хостов ...

Файл known_hosts в этом случае не использует незашифрованные записи. Вы увидите хэшированные записи, когда увидите их, они выглядят как хэши со случайными символами вместо xyz.com или 123.45.67.89.

brad@computer:~$ ssh-keyscan -t rsa -H bitbucket.org
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-128
|1|yr6p7i8doyLhDtrrnWDk7m9QVXk=|LuKNg9gypeDhfRo/AvLTAlxnyQw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==

Первая строка комментария выводит из себя, но вы можете избавиться от нее простым перенаправлением через соглашение «>» или «>>».

Поскольку я сделал все возможное, чтобы получить незапятнанные данные, которые будут использоваться для идентификации "хоста" и доверия, я добавлю эту идентификацию в мой файл known_hosts в моем каталоге ~ / .ssh. Поскольку теперь он будет определен как известный хост, я не получу подсказку, упомянутую выше, когда вы были ребенком.

Спасибо, что остались со мной, вот и все. Я добавляю ключ bitbucket RSA, чтобы я мог взаимодействовать со своими репозиториями git неинтерактивным способом как часть рабочего процесса CI, но независимо от того, что вы делаете, что хотите.

#!/bin/bash
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.old && echo "|1|yr6p7i8doyLhDtrrnWDk7m9QVXk=|LuKNg9gypeDhfRo/AvLTAlxnyQw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==" >> ~/.ssh/known_hosts

Итак, вот как ты остаешься девственницей на сегодня. Вы можете сделать то же самое с GitHub, следуя аналогичным инструкциям в свое время.

Я видел так много сообщений о переполнении стека, в которых говорилось, что вы должны программно добавлять ключ вслепую без какой-либо проверки. Чем больше вы проверяете ключ на разных машинах в разных сетях, тем больше вы можете быть уверены, что хост - это тот, о котором он говорит, - и это лучшее, на что вы можете надеяться на этом уровне безопасности.

НЕПРАВИЛЬНО ssh -oStrictHostKeyChecking = нет имени хоста [команда]

НЕПРАВИЛЬНО ssh-keyscan -t rsa -H имя хоста >> ~ / .ssh / known_hosts

Не делайте ничего из вышеперечисленного, пожалуйста. Вам предоставляется возможность повысить ваши шансы избежать того, чтобы кто-то подслушивал ваши передачи данных через человека, находящегося в середине атаки - воспользуйтесь этой возможностью. Разница заключается в том, что вы в буквальном смысле проверяете, что у вас есть ключ RSA, принадлежащий добросовестному серверу, и теперь вы знаете, как получить эту информацию для сравнения, чтобы вы могли доверять соединению. Просто помните, что больше сравнений с разных компьютеров и сетей, как правило, увеличит вашу способность доверять соединению.

BradChesney79
источник
Я думаю, что это лучшее решение этой проблемы. Тем не менее, будьте очень осторожны при использовании Nmap на чем-то вроде Amazon EC2, я получил предупреждение о сканировании портов, которое делает Nmap! Заполните их форму перед сканированием портов!
Вакас Шах
...Ну, да. Я не знаю, почему вы бы сделали сканирование портов из EC2. Если вы вошли в свою учетную запись, вы можете просто получить ключи от реальных компьютеров. Это больше для машин, которые вы не можете контролировать. Я предполагаю, что у вас будет локальный компьютер, на который не распространяются ограничения на сканирование портов AWS. Но если вы находитесь в ситуации, когда вы должны запустить nmap с AWS, я полагаю, это предупреждение было бы полезно.
BradChesney79
Использование nmap для чтения ключа хоста SSH с рабочей станции, а затем доверие к этому значению ничем не отличается от соединения через SSH с отключенным StructHostKeyChecking. Это так же уязвимо для атаки «человек посередине».
Мика Р Ледбеттер
... @ MicahRLedbetter, поэтому я предположил, что «больше сравнений с разных компьютеров и сетей, как правило, увеличат вашу способность доверять соединению». Но это моя точка зрения. Если вы когда-либо проверяете свой целевой хост только из одного набора условий среды, то как вы узнаете о любых расхождениях? У вас были предложения получше?
BradChesney79
1
Это театр безопасности. Делать что-то сложное, чтобы создать видимость большей безопасности. Неважно, сколько разных методов вы используете, чтобы запросить у хоста свой ключ. Например, несколько раз спрашивать одного и того же человека о том, можете ли вы ему доверять (возможно, вы звоните, отправляете электронное письмо, отправляете текстовое сообщение и получаете обычную почту). Они всегда говорят «да», но если вы спрашиваете не того человека, это не имеет значения.
Чрезвычайно высший человек
5

Я делаю однострочный скрипт, немного длинный, но полезный, чтобы выполнить эту задачу для хостов с несколькими IP-адресами, используя digиbash

(host=github.com; ssh-keyscan -H $host; for ip in $(dig @8.8.8.8 github.com +short); do ssh-keyscan -H $host,$ip; ssh-keyscan -H $ip; done) 2> /dev/null >> .ssh/known_hosts
Фелипе Алькасибар
источник
5

Следующее избегает повторяющихся записей в ~ / .ssh / known_hosts:

if ! grep "$(ssh-keyscan github.com 2>/dev/null)" ~/.ssh/known_hosts > /dev/null; then
    ssh-keyscan github.com >> ~/.ssh/known_hosts
fi
Амаду Бах
источник
1
Это не способ сделать это. MITM.
jameshfisher
Мне больше нравится этот ответ. Для сценариев начальной настройки случайного VPS, не имеющего значения ни для кого, кроме меня, риск MITM исчезающе мал. Инфинитезимальная болтовня ... первая строка должна бытьmkdir -p ~/.ssh/known_hosts;
Мартин Брамвелл
5

Как вы строите эти машины? Вы можете запустить скрипт обновления DNS? Вы можете присоединиться к домену IPA?

FreeIPA делает это автоматически, но по сути все, что вам нужно - это записи SSHFP dns и DNSSEC в вашей зоне (freeipa предоставляет в качестве настраиваемых параметров (dnssec отключен по умолчанию)).

Вы можете получить существующие записи SSHFP с вашего хоста, запустив.

ssh-keygen -r jersey.jacobdevans.com

jersey.jacobdevans.com В SSHFP-1 4d8589de6b1a48e148d8fc9fbb967f1b29f53ebc jersey.jacobdevans.com В SSHFP-2 6503272a11ba6d7fec2518c02dfed88f3d455ac7786ee5dbd72df63307209d55 jersey.jacobdevans.com В SSHFP-1 5a7a1e8ab8f25b86b63c377b303659289b895736> jersey.jacobdevans.com В SSHFP-2 1f50f790117dfedd329dbcf622a7d47551e12ff5913902c66a7da28e47de4f4b

затем, после публикации, вы добавите VerifyHostKeyDNS yesв свой ssh_config или ~ / .ssh / config

Если / когда Google решит включить DNSSEC, вы можете войти в ssh без запроса hostkey.

ssh jersey.jacobdevans.com

НО мой домен еще не подписан, так что пока вы увидите ....

debug1: ключ хоста сервера: ecdsa-sha2-nistp256 SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s

debug1: найдено 4 небезопасных отпечатка в DNS

debug1: соответствующий отпечаток ключа хоста

найдено в DNS. Невозможно установить подлинность хоста «jersey.jacobdevans.com (2605: 6400: 10: 434 :: 10)». Отпечаток ключа ECDSA - SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s. Соответствующий отпечаток ключа хоста найден в DNS. Вы уверены, что хотите продолжить подключение (да / нет)? нет

Джейкоб Эванс
источник
4

Чтобы сделать это правильно, вы действительно хотите собрать открытые ключи хоста виртуальных машин по мере их создания и поместить их в файл в known_hostsформате. Затем вы можете использовать -o GlobalKnownHostsFile=...указатель на этот файл, чтобы убедиться, что вы подключаетесь к хосту, к которому, по вашему мнению, вы должны подключаться. Однако то, как вы это сделаете, зависит от того, как вы настраиваете виртуальные машины, но чтение этой информации из виртуальной файловой системы, если это возможно, или даже получение хоста для печати содержимого /etc/ssh/ssh_host_rsa_key.pubво время конфигурации может помочь.

Тем не менее, это может не стоить того, в зависимости от того, в какой среде вы работаете и кто ваши предполагаемые противники. Выполнение простого «сохранения при первом подключении» (посредством сканирования или просто во время первого «реального» подключения), как описано в нескольких других ответах выше, может быть значительно проще и все же обеспечивает некоторую степень безопасности. Тем не менее, если вы сделаете это, я настоятельно рекомендую вам изменить файл hosts ( -o UserKnownHostsFile=...), известный пользователю, на файл, специфичный для этой конкретной тестовой установки; это позволит избежать загрязнения вашего личного известного хост-файла тестовой информацией и упростит очистку теперь бесполезных открытых ключей при удалении ваших виртуальных машин.

Курт Дж. Сэмпсон
источник
4

Весь этот

  • SSH-ключ-сканирования
  • SSH-копия-идентификатор
  • Предупреждение ключа ECSDA

бизнес продолжал раздражать меня, поэтому я выбрал

Один сценарий, чтобы управлять ими всеми

Это вариант сценария на https://askubuntu.com/a/949731/129227 с ответом Амаду Баха https://serverfault.com/a/858957/162693 в цикле.

пример вызова

./sshcheck somedomain site1 site2 site3

Сценарий зацикливает имена сайтов, изменяет файлы .ssh / config и .ssh / known_hosts и выполняет ssh-copy-id по запросу - для последней функции только вызовы теста let ssh завершатся неудачно, например, нажав 3 раза на enter запрос пароля.

скрипт sshcheck

#!/bin/bash
# WF 2017-08-25
# check ssh access to bitplan servers

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'  
red='\033[0;31m'  
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}

#
# error
#
#   show an error message and exit
#
#   params:
#     1: l_msg - the message to display
error() {
  local l_msg="$1"
  # use ansi red for error
  color_msg $red "Error: $l_msg" 1>&2
  exit 1
}

#
# show the usage
#
usage() {
  echo "usage: $0 domain sites"
  exit 1 
}

#
# check known_hosts entry for server
#
checkknown() {
  local l_server="$1"
  #echo $l_server
  local l_sid="$(ssh-keyscan $l_server 2>/dev/null)" 
  #echo $l_sid
  if (! grep "$l_sid" $sknown) > /dev/null 
  then
    color_msg $blue "adding $l_server to $sknown"
    ssh-keyscan $l_server >> $sknown 2>&1
  fi
}

#
# check the given server
#
checkserver() {
  local l_server="$1"
  grep $l_server $sconfig > /dev/null
  if [ $? -eq 1 ]
  then
    color_msg $blue "adding $l_server to $sconfig"
    today=$(date "+%Y-%m-%d")
    echo "# added $today by $0"  >> $sconfig
    echo "Host $l_server" >> $sconfig
    echo "   StrictHostKeyChecking no" >> $sconfig
    echo "   userKnownHostsFile=/dev/null" >> $sconfig
    echo "" >> $sconfig
    checkknown $l_server
  else
    color_msg $green "$l_server found in $sconfig"
  fi
  ssh -q $l_server id > /dev/null
  if [ $? -eq 0 ]
  then
    color_msg $green "$l_server accessible via ssh"
  else
    color_msg $red "ssh to $l_server failed" 
    color_msg $blue "shall I ssh-copy-id credentials to $l_server?"
    read answer
    case $answer in
      y|yes) ssh-copy-id $l_server
    esac
  fi
}

#
# check all servers
#
checkservers() {
me=$(hostname -f)
for server in $(echo $* | sort)
do
  os=`uname`
  case $os in
   # Mac OS X
   Darwin*)
     pingoption=" -t1";;
    *) ;;
  esac

  pingresult=$(ping $pingoption -i0.2 -c1 $server)
  echo $pingresult | grep 100 > /dev/null
  if [ $? -eq 1 ]
  then 
    checkserver $server
    checkserver $server.$domain
  else
    color_msg $red "ping to $server failed"
  fi
done
}

#
# check configuration
#
checkconfig() {
#https://askubuntu.com/questions/87449/how-to-disable-strict-host-key-checking-in-ssh
  if [ -f $sconfig ]
  then
    color_msg $green "$sconfig exists"
    ls -l $sconfig
  fi
}

sconfig=~/.ssh/config
sknown=~/.ssh/known_hosts

case  $# in
  0) usage ;;
  1) usage ;;
  *) 
    domain=$1 
    shift 
    color_msg $blue "checking ssh configuration for domain $domain sites $*"
    checkconfig
    checkservers $* 
    #for server in $(echo $* | sort)
    ##do
    #  checkknown $server 
    #done
    ;;
esac
Вольфганг Фаль
источник
2

Вот как сделать коллекцию хостов

определить коллекцию хостов

ssh_hosts:
  - server1.domain.com
  - server2.domain.com
  - server3.domain.com
  - server4.domain.com
  - server5.domain.com
  - server6.domain.com
  - server7.domain.com
  - server8.domain.com
  - server9.domain.com

Затем определите две задачи для добавления ключей к известным хостам:

- command: "ssh-keyscan {{item}}"
   register: known_host_keys
   with_items: "{{ssh_hosts}}"
   tags:
     - "ssh"

 - name: Add ssh keys to know hosts
   known_hosts:
     name: "{{item.item}}"
     key: "{{item.stdout}}"
     path: ~/.ssh/known_hosts
   with_items: "{{known_host_keys.results}}"
Вакар Афзал
источник
0

Лучше всего, вы проверите отпечаток каждого нового сервера / хоста. Это единственный способ аутентификации сервера. Без этого ваше SSH-соединение может подвергнуться атаке «человек посередине» .

Если вы действительно уверены, что хотите игнорировать проверку отпечатка пальца, то используйте второй лучший, менее безопасный вариант StrictHostKeyChecking=accept-new, который был представлен в версии 7.6 OpenSSH (2017-10-03) :

Первый «accept-new» автоматически примет ранее невидимые ключи, но откажет в соединениях для измененных или недействительных ключей хоста.

Не используйте старое значение, StrictHostKeyChecking=noкоторое никогда не проверяет подлинность сервера вообще. (Хотя значение этого =noпараметра будет изменено позже ).

Dominik
источник