Могу ли я автоматически добавить новый хост к 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 или что-то еще, чтобы ответить на интерактивное приглашение, если смогу.
15 ответов
Установите для параметра StrictHostKeyChecking
значение no
, либо в файле конфигурации, либо через -o
:
ssh -o StrictHostKeyChecking=no [email protected]
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-адреса, а также для хэш-вывода, дополнительной меры безопасности.
Для ленивых:
ssh-keyscan <host> >> ~/.ssh/known_hosts
Как уже упоминалось, использование 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 становится раздутым ...
Вы можете использовать команду ssh-keyscan
, чтобы захватить открытый ключ и добавить его в ваш файл known_hosts
.
Вот как вы можете включить 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 }}'
это будет полное решение, впервые принимающее ключ хоста
#!/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([]) }}'
Итак, я искал мирский способ обойти нестандартное взаимодействие с ручным взаимодействием клонирования 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; сети обычно увеличивают вашу способность доверять подключению.
У меня была аналогичная проблема, и я обнаружил, что некоторые из предоставленных ответов позволили мне частично перейти к автоматическому решению. Следующее - это то, что я использовал, надеюсь, что это поможет:
ssh -o "StrictHostKeyChecking no" -o PasswordAuthentication=no 10.x.x.x
Он добавляет ключ к known_hosts
и не запрашивает пароль.
Я выполняю однострочный скрипт, немного длинный, но полезный для выполнения этой задачи для хостов с множественными 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
Ниже следует избегать дублирования записей в ~ /.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
Чтобы сделать это правильно, то, что вы действительно хотите сделать, это собирать общедоступные ключи хоста виртуальных машин при их создании и переносить их в файл в формате known_hosts
. Затем вы можете использовать -o GlobalKnownHostsFile=...
, указывая на этот файл, чтобы убедиться, что вы подключаетесь к хосту, к которому, по вашему мнению, следует подключаться. Однако, как вы это делаете, это зависит от того, как вы настраиваете виртуальные машины, но, если это возможно, просто отключите виртуальную файловую систему или даже получите хост для печати содержимого /etc/ssh/ssh_host_rsa_key.pub
во время настройки может сделать трюк.
Тем не менее, это может быть нецелесообразно, в зависимости от того, в какой среде вы работаете, и кто ваши ожидаемые противники. Выполнение простого «хранилища при первом подключении» (через сканирование или просто во время первого «реального» соединения), как описано в нескольких других вышеприведенных ответах, может быть значительно проще и по-прежнему обеспечивать некоторую степень безопасности. Однако, если вы это сделаете, я настоятельно рекомендую вам изменить файл известных пользователей (-o UserKnownHostsFile=...
) для конкретного файла
для этой конкретной тестовой установки; это позволит избежать заражения вашего личного файла хостов с помощью тестовой информации и упростить очистку существующих бесполезных открытых ключей при удалении ваших виртуальных машин.
Все это
- 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
Как вы строите эти машины? вы можете запустить сценарий обновления 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. Вы действительно хотите продолжить подключение (да /нет)? нет
Вот как сделать коллекцию хостов
определить коллекцию хостов
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}}"