У меня есть машина за брандмауэром. Подключаюсь к нему удаленно, используя 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
):
Каждая строка в этих файлах содержит следующие поля: маркеры (необязательно), имена хостов, тип ключа, ключ в кодировке 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 / межсетевым экраном).
-Пользователь.
-порт.