У меня есть машина за брандмауэром. Я подключаюсь к нему удаленно, используя VPN-туннелирование с переадресацией порта через ssh. Для подключения к машине я использую внешний IP-адрес VPN и свой личный и временно назначенный порт. Я использую следующую команду:
ssh USER@VPN_IP -p PORT
Поскольку VPN_IP
и PORT
часто меняются, я не могу получить преимущества сохранения ключа хоста в known_host
, чтобы избавиться от человека-посредника атаки, но в то же время ключ хоста мне хорошо известен, и я мог бы предоставить его ssh, чтобы использовать его для текущей комбинации VPN_IP
и PORT
. Это возможно? Как?
Файл known_hosts
предназначен для предоставления этих ключей, а прямой альтернативы командной строке нет (и это было бы не очень удобно в любом случае). Однако, ваша цель полностью возможна с помощью файла known_hosts
!
Прочитайте файл формата man sshd
ssh_known_hosts
.
При выполнении аутентификации хоста принимается аутентификация, если таковая имеется. Соответствующая строка имеет соответствующий ключ; либо точно совпадающий, либо, если сервер представил сертификат для аутентификации, то ключ центра сертификации, подписавшего сертификат.
Подстановочные знаки можно использовать в ~/.ssh/known_hosts
(и /etc/ssh/ssh_known_hosts
):
Каждая строка в этих файлах содержит следующие поля: маркеры (необязательно), имена хостов, тип ключа, ключ в базовой 64-кодировке, комментарий. Поля разделены пробелами.
Имена хостов - это разделенный запятыми список шаблонов (
*
) и?
выступают в качестве подстановочные знаки); каждый шаблон, в свою очередь, сопоставляется с каноническим хозяином. имя (при аутентификации клиента) или против имени, предоставленного пользователем (при аутентификации сервера). Шаблону также может предшествовать!
. чтобы указать на отрицание: если имя хоста совпадает с отрицательным шаблоном, то оно не принимается (по этой линии), даже если она совпадает с другим рисунком на линия. Имя или адрес хоста по желанию может быть приложен в пределах[
]. и]
скобки, за которыми следует ':' и нестандартный номер порта.
Можно сделать ключ доверенным для
сетевого диапазона, если он известен, например, для TEST-NET-2
:
198.51.100.* ssh-rsa AAAAB3Nza...2iQ==.
множественные диапазоны (например, все TEST-NET
s) с использованием разделенного запятыми списка:
192.0.2.*,198.51.100.*,203.0.113.* ssh-rsa AAAAB3Nza...2iQ==
или даже при соединении в любом месте:
* ssh-rsa AAAAB3Nza...2iQ==
Если этот ключ отсутствует, он все равно предупредит вас о подлинности других ключей, покажет отпечаток пальца и добавит его автоматически, если вы ответите да
. Сравнение производится построчно
Используя полезный ответ Эсы Йокинен и автоматизируя процесс здесь, мое решение:
#!/bin/sh
previous_IP_OR_known_host_key_line=$1
current_IP=$2
user=$3
port=$4
#random extension to avoid collision by multiple script execution
temp_file="/tmp/temp_host_file.$(hexdump -n 2 -e '/2 "%u"' /dev/urandom)"
if [ "$(echo "$previous_IP_OR_known_host_key_line"|wc -w)" -gt 1 ]; then
echo "$previous_IP_OR_known_host_key_line"|sed "s/^[^ ]*/$current_IP/">"$temp_file"
else
ssh-keygen -F "$previous_IP_OR_known_host_key_line"|grep -v "^#"|sed "s/^[^ ]*/$current_IP/">"$temp_file"
fi
ssh "$user"@"$current_IP" -p "$port" -o UserKnownHostsFile="$temp_file"
rm "$temp_file"
Сценарий генерирует временный файл known_host для предоставления ssh. Сценарию требуется следующий параметр (в соответствии с порядком):
- IP-адрес назначения, который был у машины в предыдущих принятых соединениях, ИЛИ соответствующая строка RAW с ключом из файла known_host.
- текущий IP (за VPN / межсетевой экран).
-пользователь.
-порт.