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

Вот моя ситуация: я настраиваю тестовый жгут, который от центрального клиента запускает несколько экземпляров виртуальной машины, а затем выполняет команды на них с помощью 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 или что-то еще, чтобы ответить на интерактивное приглашение, если смогу.

212 голосов | спросил gareth_bowles 16 AMpFri, 16 Apr 2010 08:15:11 +040015Friday 2010, 08:15:11

15 ответов


123

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

ssh -o StrictHostKeyChecking=no [email protected]

ответил Ignacio Vazquez-Abrams 16 AMpFri, 16 Apr 2010 08:34:11 +040034Friday 2010, 08:34:11
202

IMO, лучший способ сделать это:

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-адреса, а также для хэш-вывода, дополнительной меры безопасности.

ответил yardena 28 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 28 Sep 2011 00:51:21 +0400 2011, 00:51:21
71

Для ленивых:

ssh-keyscan <host> >> ~/.ssh/known_hosts
ответил fivef 25 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 25 Sep 2014 14:03:53 +0400 2014, 14:03:53
37

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

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 6 MarpmTue, 06 Mar 2012 13:00:20 +04002012-03-06T13:00:20+04:0001 2012, 13:00:20
18

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

ответил Alex 16 AMpFri, 16 Apr 2010 09:09:40 +040009Friday 2010, 09:09:40
6

Вот как вы можете включить 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 3 FebruaryEurope/MoscowbWed, 03 Feb 2016 06:12:46 +0300000000amWed, 03 Feb 2016 06:12:46 +030016 2016, 06:12:46
5

это будет полное решение, впервые принимающее ключ хоста

#!/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([]) }}'
ответил mazac 23 32016vEurope/Moscow11bEurope/MoscowWed, 23 Nov 2016 16:51:31 +0300 2016, 16:51:31
4

Итак, я искал мирский способ обойти нестандартное взаимодействие с ручным взаимодействием клонирования git repo, как показано ниже:

[email protected]:~$ git clone [email protected]: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 над SSH и просто связанными с SSH вещами вообще ...

[email protected]:~$ 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. Но вернемся к тому, что мы делаем.

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

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

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

[email protected]:~$ 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.

[email protected]:~$ 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. Поскольку он теперь будет идентифицирован как известный хост, я не получу подсказку, упомянутую выше, когда вы были молодым человеком.

Спасибо, что присоединился ко мне, вот и все. Я добавляю ключ RSA bitbucket, чтобы я мог взаимодействовать с моими репозиториями 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 = no hostname [команда]

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

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

ответил BradChesney79 6 +03002016-10-06T00:18:00+03:00312016bEurope/MoscowThu, 06 Oct 2016 00:18:00 +0300 2016, 00:18:00
3

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

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

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

ответил VenomFangs 21 +04002014-10-21T21:27:56+04:00312014bEurope/MoscowTue, 21 Oct 2014 21:27:56 +0400 2014, 21:27:56
3

Я выполняю однострочный скрипт, немного длинный, но полезный для выполнения этой задачи для хостов с множественными 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
ответил Felipe Alcacibar 19 AMpWed, 19 Apr 2017 00:01:35 +030001Wednesday 2017, 00:01:35
3

Ниже следует избегать дублирования записей в ~ /.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
ответил Amadu Bah 2 J000000Sunday17 2017, 14:41:47
2

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

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

ответил Curt J. Sampson 12 MonEurope/Moscow2016-12-12T05:27:10+03:00Europe/Moscow12bEurope/MoscowMon, 12 Dec 2016 05:27:10 +0300 2016, 05:27:10
2

Все это

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

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

Один скрипт для их всех

Это вариант сценария на https://askubuntu.com/a/949731/129227 с помощью Amadu Ответ Баха https://serverfault.com/a/858957/162693 в цикле.

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

./sshcheck somedomain site1 site2 site3

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

скрипт 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
ответил Wolfgang Fahl 25 PM00000040000001331 2017, 16:16:13
2

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

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

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

ssh-keygen -r jersey.jacobdevans.com

  

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

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

Если /Когда google решит перевернуть DNSSEC, вы можете включить ssh без приглашения на главную страницу.

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. Вы действительно хотите продолжить подключение (да /нет)? нет

ответил Jacob Evans 6 +03002016-10-06T01:07:33+03:00312016bEurope/MoscowThu, 06 Oct 2016 01:07:33 +0300 2016, 01:07:33
1

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

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

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}}"
ответил Vackar Afzal 23 Jpm1000000pmTue, 23 Jan 2018 13:51:06 +030018 2018, 13:51:06

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132