SSH known_hosts с динамическим IP
У меня есть машина за брандмауэром. Я подключаюсь к нему удаленно, используя VPN-туннелирование с переадресацией порта через ssh. Для подключения к машине я использую внешний IP-адрес VPN и свой персональный и временный назначенный порт. Команда, которую я использую:
ssh USER@VPN_IP -p PORT
поскольку VPN_IP
а также PORT
часто меняются, я не могу получить преимущества от сохранения ключа хоста в known_host
избавиться от атак "человек посередине", но в то же время ключ хоста мне хорошо известен, и я могу предоставить его ssh, чтобы использовать его для текущей VPN_IP
а также PORT
сочетание. Это возможно? Как?
2 ответа
known_hosts
Файл предназначен для предоставления этих ключей, и прямой альтернативы командной строке нет (и в любом случае это было бы не очень удобно). Тем не менее, ваша цель вполне возможна с known_hosts
файл!
Прочитать man sshd
"s ssh_known_hosts
формат файла.
При выполнении аутентификации хоста аутентификация принимается, если любая совпадающая строка имеет правильный ключ; либо тот, который точно соответствует, либо, если сервер предоставил сертификат для аутентификации, ключ центра сертификации, подписавшего сертификат.
Можно использовать подстановочные знаки в ~/.ssh/known_hosts
(а также /etc/ssh/ssh_known_hosts
):
Каждая строка в этих файлах содержит следующие поля: маркеры (необязательно), имена хостов, тип ключа, ключ в кодировке base64, комментарий. Поля разделены пробелами.
Имена хостов - это список шаблонов, разделенных запятыми (
*
а также?
действовать как символы подстановки); каждый шаблон в свою очередь сопоставляется с каноническим именем хоста (при аутентификации клиента) или с предоставленным пользователем именем (при аутентификации сервера). Шаблону также может предшествовать!
для обозначения отрицания: если имя хоста соответствует отрицательному шаблону, оно не принимается (этой строкой), даже если оно соответствует другому шаблону в строке. Имя хоста или адрес могут быть дополнительно заключены в[
а также]
затем в скобках следует ":" и нестандартный номер порта.
Можно сделать ключ доверенным для
диапазон сети, если известен, например, для
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==
Если этот ключ отсутствует, он все равно предупредит вас о подлинности других ключей, покажет отпечаток пальца и добавит его автоматически, если вы ответите yes
, Сравнение делается построчно.
Используя полезный ответ Эсы Йокинена и автоматизируя процесс, вот мое решение:
#!/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/ межсетевым экраном).
-Пользователь.
-порт.