Проверьте содержимое файла .ssh / known_hosts - PullRequest
4 голосов
/ 14 мая 2019

Есть ли какой-нибудь инструмент cli, который я могу использовать для проверки содержимого known_hosts? Может быть, попытаться пропинговать все хосты и посмотреть, смогу ли я подключиться к каждому?

Возможно использовать либо ssh-keygen, либо ssh-keyscan?

Ответы [ 2 ]

3 голосов
/ 16 мая 2019

Если у вас есть список всех доступных хостов, вы можете сделать это так:

ssh-keyscan -t rsa,dsa -f hosts_list > ~/.ssh/known_hosts_revised

Это создаст новый known_hosts_revised, который вы можете сделать diff с вашим текущим know_hosts, чтобы увидеть различия.

Если вам не нужно сравнивать его, вы можете просто сделать ... > ~/.ssh/known_hosts, чтобы перезаписать его ( ВНИМАНИЕ: оригинал known_hosts будет потерян!)

Источником информации являются справочные страницы OpenBSD для ssh-keyscan (1) .

Редактировать hosts_list ожидается в течение:

1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
1 голос
/ 22 мая 2019

По крайней мере, для моей установки, использование ssh-keyscan невозможно из-за моего обширного ~/.ssh/config файла. Я использую множество прокси-команд, хостов перехода и альтернативных объявлений Hostname.

Например:

# Connect to Tor nodes
Host *.onion
  ProxyCommand socat - SOCKS4A:localhost:%h:%p,socksport=9050

# Work jump box
Host bastion
  Hostname bastion.work.com

# Office system, e.g. bob.office -> bastion -> bob.work.com
Host *.office
  ProxyCommand ssh bastion nc -w600s $(echo "%h" |sed 's/\.office$/work.com/') %p

# Home system, e.g. adam -> home.com -> adam-laptop.local
Host adam
  Hostname adam-laptop.local
  ProxyJump home.com

Ничто из перечисленного не будет работать.

Вот скрипт, который должен работать для остальных:

#!/usr/bin/awk -f

!/^#/ && NF > 2 {
  split($1, hosts, ",")
  key_type = $2
  gsub(/^ssh-/, "", key_type)
  gsub(/-.*/, "", key_type)
  for (h in hosts) {
    p = index(hosts[h], "]:")   # [host]:port (supports raw IPv6 hosts)
    if (!p && hosts[h] ~ /^[^:]+:[0-9]+$/) p = index(hosts[h], ":")  # host:port
    if (p > 0) {
      port = substr(hosts[h], p + 2)
      gsub("\[|\]?:" port, "", hosts[h])
    } else {
      port = 22
    }
    if (seen[key_type,port,hosts[h]]++) next  # prevent duplicate lookups
    if (port_list[key_type,port]) { comma = "," } else { comma = "" }
    port_list[key_type,port] = port_list[key_type,port] comma hosts[h]
  }
}
END {
  for (tp in port_list) {
    split(tp, a, SUBSEP)
    system("echo ssh-keyscan -t " a[1] " -p " a[2] " " port_list[tp])
  }
}

Снимите echo детали для запуска, как только вы убедитесь, что это сделает то, что вы хотите.

Анализирует строки без комментариев и с полями 3+ (так как формат host_list key_type key_hash). Он разделяет список хостов, так как он может быть разделен запятыми, и требуется дальнейший анализ, потому что он может содержать порты, но ssh-keyscan не может принимать хосты в формате, используемом known_hosts.

Существует два способа указания порта:

  1. Старый стиль, который не работает с голыми адресами IPv6, это host:port
  2. Новый стиль, который требуется для пустых адресов IPv6, - [host]:port

p устанавливается в положение ]:, если присутствует (новый стиль). Если эта строка отсутствует, мы проверяем старый стиль и сбрасываем p.

Если p положительно, у нас есть спецификация порта. Извлеките порт и удалите (это и квадратные скобки) из имени хоста. В противном случае порт равен 22.

На всякий случай, если есть повторяющиеся записи, мы проверяем их и продолжаем, если уже видели комбинацию типа, порта, хоста (x++ имеет значение false (0) только при первом запуске). Наконец, мы помещаем хост в разделенную запятыми строку списка в массиве port_list, как указано кортежем типа и порта.

После прочтения всего файла known_hosts, мы перебираем пары кортежей type,port, которые задают массив port_list, разделяем их на массив с именем a и запускаем на них ssh-keyscan.

Запустите это как awk -f 'this_script.awk' ~/.ssh/known_hosts и, если вам нравятся ssh-keyscan команды, которые он выплевывает, удалите echo из системной команды и повторите запуск.

Не передавайте эти выходные данные в ~/.ssh/known_hosts! Вы можете вручную просмотреть результаты (и, возможно, отфильтровать комментарии). Кроме того, вы не можете перенаправить вывод на один из файлов, используемых во вводе.

...