Назад | Перейти на главную страницу

SSH known_hosts с динамическим IP

У меня есть машина за брандмауэром. Подключаюсь к нему удаленно, используя 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-NETs) с использованием списка, разделенного запятыми:

    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 / межсетевым экраном).

-Пользователь.

-порт.