Czy mogę automatycznie dodać nowy host do znanych hostów?

249

Oto moja sytuacja: konfiguruję wiązkę testową, która od klienta centralnego uruchamia wiele instancji maszyn wirtualnych, a następnie wykonuje na nich polecenia ssh. Maszyny wirtualne będą miały wcześniej nieużywane nazwy hostów i adresy IP, więc nie będą one znajdować się w ~/.ssh/known_hostspliku na kliencie centralnym.

Problem, który mam, polega na tym, że pierwsze sshpolecenie uruchomione przeciwko nowej instancji wirtualnej zawsze pojawia się z interaktywnym monitem:

The authenticity of host '[hostname] ([IP address])' can't be established.
RSA key fingerprint is [key fingerprint].
Are you sure you want to continue connecting (yes/no)?

Czy istnieje sposób na obejście tego i sprawienie, by nowy host był już znany maszynie klienckiej, może za pomocą klucza publicznego, który jest już zapisany w obrazie maszyny wirtualnej? Naprawdę chciałbym uniknąć konieczności korzystania z funkcji Oczekiwanie lub czegokolwiek, aby odpowiedzieć na interaktywny monit, jeśli mogę.

gareth_bowles
źródło
5
W przypadku niezależnego i fizycznie bezpiecznego środowiska testowego automatyczna akceptacja klucza może działać dobrze. Ale automatyczne przyjmowanie kluczy publicznych w środowisku produkcyjnym lub w niezaufanej sieci (takiej jak Internet) całkowicie omija wszelką ochronę przed atakami typu man-in-the-middle, na które w przeciwnym razie SSH mógłby sobie pozwolić. Tylko ważny sposób, aby upewnić się, że jesteś bezpieczny przed atakami MiTM jest sprawdzenie klucza publicznego hosta przez niektóre out-of-band zaufanego kanału. Nie ma bezpiecznego sposobu na automatyzację bez skonfigurowania umiarkowanie skomplikowanej infrastruktury podpisywania kluczy.
Eil

Odpowiedzi:

141

Ustaw StrictHostKeyCheckingopcję na noalbo w pliku konfiguracyjnym, albo poprzez -o:

ssh -o StrictHostKeyChecking=no [email protected]

Ignacio Vazquez-Abrams
źródło
62
To pozostawia cię otwartym na ataki w środku, prawdopodobnie nie jest to dobry pomysł.
JasperWallace,
9
@JasperWallace, chociaż jest to zwykle dobra rada, konkretny przypadek użycia (wdrażanie testowych maszyn wirtualnych i wysyłanie do nich poleceń) powinien być wystarczająco bezpieczny.
Massimo,
8
To daje Warning: Permanently added 'hostname,1.2.3.4' (RSA) to the list of known hosts.Aby uniknąć ostrzeżenia i aby uniknąć dodawania wpisu do dowolnego pliku znanego_hosta, robię:ssh -o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null [email protected]
Peter V. Mørch
11
Głosowanie w dół, ponieważ nie odpowiada na pytanie i otwiera się na poważne luki w zabezpieczeniach.
marcv81,
12
@Mnebuerquo: Jeśli martwisz się o bezpieczeństwo, nie masz nic wspólnego z tym pytaniem. Miałbyś przed sobą prawidłowy klucz hosta, zebrany z konsoli systemu, z którym chcesz się połączyć, i sprawdziłbyś go ręcznie przy pierwszym połączeniu. Na pewno nie zrobiłbyś niczego „automatycznie”.
Ignacio Vazquez-Abrams,
230

IMO, najlepszym sposobem na to jest:

ssh-keygen -R [hostname]
ssh-keygen -R [ip_address]
ssh-keygen -R [hostname],[ip_address]
ssh-keyscan -H [hostname],[ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [hostname] >> ~/.ssh/known_hosts

To sprawi, że nie będzie żadnych zduplikowanych wpisów, że jesteś objęty zarówno nazwą hosta, jak i adresem IP, a także haszuje dane wyjściowe, dodatkowy środek bezpieczeństwa.

yardena
źródło
4
Dlaczego potrzebujesz wszystkich 3 ssh-keyscan? Nie możesz sobie poradzić z pierwszym, ponieważ działa on zarówno dla nazwy hosta, jak i adresu IP?
Robert
6
Czy możesz być pewien, że maszyna odpowiadająca na żądanie ssh-keyscan jest naprawdę tym, z którym chcesz porozmawiać? Jeśli nie, otworzyłeś się na mężczyznę w środkowym ataku.
JasperWallace,
2
@JasperWallace Tak, do tego potrzebujesz przynajmniej odcisku palca, a nawet klucza publicznego, w którym to przypadku możesz dodać go bezpośrednio do znanych_hostów, zmieniając to pytanie w wątpliwość. Jeśli masz tylko odcisk palca, będziesz musiał napisać dodatkowy krok, który weryfikuje pobrany klucz publiczny za pomocą odcisku palca ...
1
Połączenia z ssh-keyscannami nie powiodły się, ponieważ mój docelowy host nie obsługuje domyślnego typu klucza wersji 1. Dodanie -t rsa,dsado polecenia naprawiło to.
faza dwudziesta
5
To chyba zły pomysł. Uaktualniasz te klucze, otwierając się na atak człowieka w środku. Aby uniknąć powielania wpisów, sprawdź ssh-keygen -F [address]zamiast tego status zwrotu . medium.com/@wblankenship/…
retrohacker
93

Dla leniwych:

ssh-keyscan -H <host> >> ~/.ssh/known_hosts

-H haszy nazwę hosta / adres IP

fivef
źródło
2
„ssh-keyscan -H <host> >> ~ / .ssh / known_hosts” tworzy wpis bardziej podobny do tego, co ssh robi z interakcją użytkownika. (H-hashuje nazwę zdalnego hosta).
Sarah Messer
3
Podatne na ataki MITM. Nie sprawdzasz odcisku palca klucza.
Mnebuerquo,
8
@Mnebuerquo Mówisz, co robić, ale nie jak, co byłoby pomocne.
Ray
4
@ jameshfisher Tak, jest podatny na ataki MITM, ale czy kiedykolwiek porównywałeś odcisk palca RSA, który został Ci pokazany z rzeczywistym serwerem, gdy robiłeś to ręcznie? Nie? Ta odpowiedź jest więc sposobem na zrobienie tego za Ciebie. Jeśli tak, to nie powinno się używać tej odpowiedzi i zrobić to ręcznie lub wprowadzenie innych środków ochrony ...
fivef
2
@Mnebuerquo Byłbym bardzo zadowolony, jeśli dasz nam również znać lepszy sposób na poradzenie sobie z tym, kiedy musimy sklonować repo przy użyciu skryptów wsadowych bez udziału i chcemy pominąć ten monit. Rzuć nieco światła na prawdziwe rozwiązanie, jeśli uważasz, że to nie jest właściwe!
Waqas Shah
42

Jak wspomniano, użycie skanu klucza byłoby właściwym i dyskretnym sposobem na zrobienie tego.

ssh-keyscan -t rsa,dsa HOST 2>&1 | sort -u - ~/.ssh/known_hosts > ~/.ssh/tmp_hosts
mv ~/.ssh/tmp_hosts ~/.ssh/known_hosts

Powyższe załatwi sprawę, aby dodać hosta, TYLKO jeśli nie został jeszcze dodany. Nie jest również bezpieczny dla współbieżności; nie wolno wykonywać fragmentu kodu na tym samym komputerze źródłowym więcej niż raz w tym samym czasie, ponieważ plik tmp_hosts może zostać zablokowany, co ostatecznie prowadzi do wzdęcia pliku znanego hosta ...

ysawej
źródło
Czy istnieje sposób, aby sprawdzić, czy klucz jest w known_hosts przed ssh-keyscan ? Powodem jest to, że wymaga to trochę czasu i dodatkowego połączenia sieciowego.
utapyngo
1
Plik tego oryginalnego plakatu miał cat ~/.ssh/tmp_hosts > ~/.ssh/known_hosts, ale późniejsza zmiana go zmieniła na >>. Używanie >>jest błędem. Pokonuje cel wyjątkowości w pierwszym wierszu i powoduje, że zrzuca nowe wpisy przy known_hostskażdym uruchomieniu. (Właśnie opublikowałem edycję, aby go zmienić.)
paulmelnikow
1
Jest to przedmiotem tych samych ataków MITM, co innych.
Mnebuerquo
@utapyngo ssh-keygen -F da ci bieżący odcisk palca. Jeśli wróci z pustym kodem powrotu 1, oznacza to, że go nie masz. Jeśli coś wydrukuje, a kod powrotu to 0, oznacza to, że jest już obecny.
Bogaty L
1
Jeśli tak bardzo troszczysz się o MITM, wdrażaj rekordy DNSSEC i SSHFP lub użyj innych bezpiecznych sposobów dystrybucji kluczy, a to rozwiązanie kludge będzie nieistotne.
Zart
19

Możesz użyć ssh-keyscanpolecenia, aby pobrać klucz publiczny i dołączyć go do known_hostspliku.

Alex
źródło
3
Sprawdź odcisk palca, aby upewnić się, że jest to prawidłowy klucz. W przeciwnym razie otworzysz się na ataki MITM.
Mnebuerquo,
3
@Mnebuerquo Uczciwy punkt w ogólnym kontekście, ale dlaczego ktoś miałby próbować programowo zbierać klucze, skoro już wiedział, jaki jest prawidłowy klucz?
Brian Cline,
To nie jest sposób, aby to zrobić. MITM.
jameshfisher
8

Oto jak możesz włączyć ssh-keyscan do swojej gry:

---
# ansible playbook that adds ssh fingerprints to known_hosts
- hosts: all
  connection: local
  gather_facts: no
  tasks:
  - command: /usr/bin/ssh-keyscan -T 10 {{ ansible_host }}
    register: keyscan
  - lineinfile: name=~/.ssh/known_hosts create=yes line={{ item }}
    with_items: '{{ keyscan.stdout_lines }}'
Zart
źródło
1
Czy przesyłasz znany znany plik znane_hostowie, czy wykonujesz ssh-keyscan i zrzucasz dane wyjściowe do znanych hostów bez sprawdzania odcisków palców?
Mnebuerquo
1
To po prostu zrzuca wyjście z keycan, tak. W efekcie jest to to samo, co StrictHostKeyChecking = nie, tylko z cichą aktualizacją znanych_hostów bez konieczności korzystania z opcji ssh. To rozwiązanie również nie działa dobrze, ponieważ ssh-keyscan zwraca wiele wierszy, co powoduje, że to zadanie jest zawsze oznaczone jako „zmienione”
Zart
To nie jest sposób, aby to zrobić. MITM.
jameshfisher
3
@ jameshfisher Byłbym bardzo zadowolony, jeśli dasz nam również znać lepszy sposób na poradzenie sobie z tym problemem, gdy musimy sklonować repo przy użyciu skryptów wsadowych bez udziału i chcemy pominąć ten monit. Rzuć nieco światła na prawdziwe rozwiązanie, jeśli uważasz, że to nie jest właściwe! Daj nam znać, jak to zrobić, jeśli uważasz, że nie jest to właściwy sposób!
Waqas Shah
Jest to całkowicie poprawna metoda dodawania wartości do znanych hostów, ale tak, jest ona podatna na MITM. Jednak do użytku wewnętrznego jest w porządku.
Cameron Lowell Palmer
7

byłoby to kompletne rozwiązanie, przyjmujące klucz hosta tylko po raz pierwszy

#!/usr/bin/env ansible-playbook
---
- name: accept ssh fingerprint automatically for the first time
  hosts: all
  connection: local
  gather_facts: False

  tasks:
    - name: "check if known_hosts contains server's fingerprint"
      command: ssh-keygen -F {{ inventory_hostname }}
      register: keygen
      failed_when: keygen.stderr != ''
      changed_when: False

    - name: fetch remote ssh key
      command: ssh-keyscan -T5 {{ inventory_hostname }}
      register: keyscan
      failed_when: keyscan.rc != 0 or keyscan.stdout == ''
      changed_when: False
      when: keygen.rc == 1

    - name: add ssh-key to local known_hosts
      lineinfile:
        name: ~/.ssh/known_hosts
        create: yes
        line: "{{ item }}"
      when: keygen.rc == 1
      with_items: '{{ keyscan.stdout_lines|default([]) }}'
mazak
źródło
1
To nie jest sposób, aby to zrobić. MITM.
jameshfisher
6

Miałem podobny problem i stwierdziłem, że niektóre z udzielonych odpowiedzi pomogły mi tylko częściowo zautomatyzować rozwiązanie. Skończyło się na tym, mam nadzieję, że to pomoże:

ssh -o "StrictHostKeyChecking no" -o PasswordAuthentication=no 10.x.x.x

Dodaje klucz known_hostsi nie monituje o hasło.

VenomFangs
źródło
2
Podatne na ataki MITM. Nie sprawdzasz odcisku palca.
Mnebuerquo
6
Nikt nie sprawdza odcisku palca.
Brendan Byrd
To nie jest sposób, aby to zrobić. MITM.
jameshfisher
5

Szukałem więc przyziemnego sposobu na ominięcie ręcznej interakcji nieznanego hosta klonowania repozytorium git, jak pokazano poniżej:

brad@computer:~$ git clone [email protected]:viperks/viperks-api.git
Cloning into 'viperks-api'...
The authenticity of host 'bitbucket.org (104.192.143.3)' can't be established.
RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)?

Zanotuj odcisk palca klucza RSA ...

Więc to jest sprawa SSH, to zadziała dla git nad SSH i ogólnie po prostu rzeczy związane z SSH ...

brad@computer:~$ nmap bitbucket.org --script ssh-hostkey

Starting Nmap 7.01 ( https://nmap.org ) at 2016-10-05 10:21 EDT
Nmap scan report for bitbucket.org (104.192.143.3)
Host is up (0.032s latency).
Other addresses for bitbucket.org (not scanned): 104.192.143.2 104.192.143.1 2401:1d80:1010::150
Not shown: 997 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh
| ssh-hostkey:
|   1024 35:ee:d7:b8:ef:d7:79:e2:c6:43:9e:ab:40:6f:50:74 (DSA)
|_  2048 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 (RSA)
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 42.42 seconds

Najpierw zainstaluj nmap w swoim codziennym sterowniku. nmap jest bardzo pomocny w przypadku niektórych rzeczy, takich jak wykrywanie otwartych portów, a to - ręczna weryfikacja odcisków palców SSH. Wróćmy jednak do tego, co robimy.

Dobry. Jestem narażony na kompromis w wielu miejscach i maszynach, które sprawdziłem - albo bardziej prawdopodobne jest to, że dzieje się bardziej prawdopodobne wyjaśnienie, że wszystko jest jak przystojniak.

Ten „odcisk palca” jest po prostu łańcuchem skróconym za pomocą algorytmu jednokierunkowego dla naszej ludzkiej wygody, na ryzyko, że więcej niż jeden ciąg rozdzieli się na ten sam odcisk palca. Zdarza się, że nazywane są zderzeniami.

Niezależnie od tego, wracamy do oryginalnego ciągu, który możemy zobaczyć w kontekście poniżej.

brad@computer:~$ ssh-keyscan bitbucket.org
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-128
no hostkey alg
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-129
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-123
no hostkey alg

Tak więc z wyprzedzeniem możemy poprosić o formę identyfikacji od pierwotnego hosta.

W tym momencie jesteśmy ręcznie tak samo narażeni jak automatycznie - ciągi pasują do siebie, mamy podstawowe dane, które tworzą odcisk palca, i możemy poprosić o te podstawowe dane (zapobiegające kolizjom) w przyszłości.

Teraz użyj tego ciągu w sposób, który zapobiega pytaniu o autentyczność hosta ...

Plik znane_hosty w tym przypadku nie używa wpisów w postaci zwykłego tekstu. Poznasz skróty, gdy je zobaczysz, wyglądają jak skróty z losowymi znakami zamiast xyz.com lub 123.45.67.89.

brad@computer:~$ ssh-keyscan -t rsa -H bitbucket.org
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-128
|1|yr6p7i8doyLhDtrrnWDk7m9QVXk=|LuKNg9gypeDhfRo/AvLTAlxnyQw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==

Pierwszy wiersz komentarza pojawia się irytująco - ale możesz się go pozbyć za pomocą prostego przekierowania za pomocą konwencji „>” lub „>>”.

Ponieważ dołożyłem wszelkich starań, aby uzyskać nieskażone dane do identyfikacji „hosta” i zaufania, dodam tę identyfikację do mojego pliku znane_hosty w moim katalogu ~ / .ssh. Ponieważ będzie on teraz identyfikowany jako znany gospodarz, nie otrzymam wspomnianego wyżej monitu, gdy byłeś młodszy.

Dzięki za trzymanie się mnie, proszę bardzo. Dodam klucz RSA bitbucket, abym mógł tam wchodzić w interakcje z moimi repozytoriami git w sposób nieinteraktywny w ramach przepływu pracy CI, ale cokolwiek robisz, co chcesz.

#!/bin/bash
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.old && echo "|1|yr6p7i8doyLhDtrrnWDk7m9QVXk=|LuKNg9gypeDhfRo/AvLTAlxnyQw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==" >> ~/.ssh/known_hosts

W ten sposób pozostajesz dziś dziewicą. Możesz zrobić to samo z github, postępując według podobnych wskazówek we własnym czasie.

Widziałem tak wiele postów przepełnienia stosu, mówiących o programowym dodawaniu klucza na ślepo bez żadnego sprawdzania. Im bardziej sprawdzasz klucz z różnych komputerów w różnych sieciach, tym większe masz zaufanie, że host jest tym, o którym mówi, że jest - i to najlepsze, czego możesz oczekiwać od tej warstwy bezpieczeństwa.

ŹLE ssh -oStrictHostKeyChecking = brak nazwy hosta [polecenie]

ŹLE ssh-keyscan -t rsa -H nazwa hosta >> ~ / .ssh / known_hosts

Proszę nie rób żadnej z powyższych rzeczy. Masz możliwość zwiększenia szansy na uniknięcie podsłuchiwania twoich transferów danych przez człowieka w środku ataku - skorzystaj z okazji. Różnicą jest dosłownie sprawdzenie, czy posiadany klucz RSA jest serwerem bona fide, a teraz wiesz, jak uzyskać te informacje, aby je porównać, abyś mógł zaufać połączeniu. Pamiętaj tylko, że więcej porównań z różnych komputerów i sieci zwykle zwiększy twoją zdolność do zaufania połączenia.

BradChesney79
źródło
Myślę, że to najlepsze rozwiązanie tego problemu. Jednak bądź bardzo ostrożny podczas używania Nmapa na czymś takim jak Amazon EC2, dostałem ostrzeżenie o skanowaniu portów, które robi Nmap! Wypełnij formularz przed skanowaniem portów!
Waqas Shah
... no tak. Nie wiem, dlaczego miałbyś skanować port z EC2. Jeśli jesteś zalogowany na swoje konto, możesz po prostu pobrać klucze z rzeczywistych komputerów. Jest to więcej w przypadku maszyn, nad którymi nie masz kontroli. Zakładam, że masz lokalny komputer niepodlegający ograniczeniom skanowania portów AWS. Ale jeśli jesteś w takiej sytuacji krawędzi, w której musisz uruchomić nmap z AWS, przypuszczam, że to ostrzeżenie byłoby pomocne.
BradChesney79
Użycie nmap do odczytania klucza hosta SSH ze stacji roboczej, a następnie zaufanie do tej wartości nie różni się od połączenia przez SSH z wyłączonym StructHostKeyChecking. Jest równie podatny na atak człowieka w środku.
Micah R Ledbetter
... @ MicahRLedbetter, dlatego zasugerowałem, że „więcej porównań z różnych komputerów i sieci zwykle zwiększa twoją zdolność do zaufania do połączenia”. Ale o to mi chodzi. Jeśli kiedykolwiek sprawdzisz docelowego hosta tylko z jednego zestawu warunków środowiskowych, to skąd miałbyś wiedzieć o jakichkolwiek rozbieżnościach? Czy masz jakieś lepsze sugestie?
BradChesney79
1
To jest teatr bezpieczeństwa. Robienie czegoś skomplikowanego, aby stworzyć wrażenie większego bezpieczeństwa. Nie ma znaczenia, ile różnych metod używasz, aby poprosić hosta o klucz. Jak wielokrotne pytanie tej samej osoby, czy możesz jej zaufać (może dzwonisz, e-mail, SMS i pocztę ślimakową). Zawsze będą mówić tak, ale jeśli pytasz niewłaściwą osobę, to nie ma znaczenia.
vastlysuperiorman
5

Robię skrypt jednowierszowy, nieco długi, ale przydatny, aby wykonać to zadanie dla hostów z wieloma adresami IP, używając digibash

(host=github.com; ssh-keyscan -H $host; for ip in $(dig @8.8.8.8 github.com +short); do ssh-keyscan -H $host,$ip; ssh-keyscan -H $ip; done) 2> /dev/null >> .ssh/known_hosts
Felipe Alcacibar
źródło
5

Następujące unikają powielania wpisów w ~ / .ssh / known_hosts:

if ! grep "$(ssh-keyscan github.com 2>/dev/null)" ~/.ssh/known_hosts > /dev/null; then
    ssh-keyscan github.com >> ~/.ssh/known_hosts
fi
Amadu Bah
źródło
1
To nie jest sposób, aby to zrobić. MITM.
jameshfisher
Najbardziej podoba mi się ta odpowiedź. Dla skryptu wstępnej konfiguracji losowego VPS nieistotnego dla nikogo oprócz mnie ryzyko MITM jest znikomo małe. Nieskończona sprzeczka ... pierwsza linia musi byćmkdir -p ~/.ssh/known_hosts;
Martin Bramwell
5

Jak budujesz te maszyny? czy możesz uruchomić skrypt aktualizacji dns? czy możesz dołączyć do domeny IPA?

FreeIPA robi to automatycznie, ale zasadniczo wszystko, czego potrzebujesz, to rekordy dns SSHFP i DNSSEC w twojej strefie (freeipa zapewnia konfigurowalne opcje (domyślnie wyłączone dnssec)).

Możesz uzyskać istniejące rekordy SSHFP od swojego hosta, uruchamiając.

ssh-keygen -r jersey.jacobdevans.com

jersey.jacobdevans.com W SSHFP 1 1 4d8589de6b1a48e148d8fc9fbb967f1b29f53ebc jersey.jacobdevans.com W SSHFP 1 2 6503272a11ba6d7fec2518c02dfed88f3d455ac7786ee5dbd72df63307209d55 jersey.jacobdevans.com W SSHFP 3 1 5a7a1e8ab8f25b86b63c377b303659289b895736> jersey.jacobdevans.com W SSHFP 3 2 1f50f790117dfedd329dbcf622a7d47551e12ff5913902c66a7da28e47de4f4b

a następnie po opublikowaniu dodasz VerifyHostKeyDNS yesdo swojego ssh_config lub ~ / .ssh / config

Jeśli / Kiedy Google zdecyduje się włączyć DNSSEC, możesz ssh wejść bez pytania o klucz hosta.

ssh jersey.jacobdevans.com

ALE moja domena nie jest jeszcze podpisana, więc na razie zobaczysz ....

debug1: Klucz hosta serwera: ecdsa-sha2-nistp256 SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s

debug1: znaleziono 4 niezabezpieczone odciski palców w DNS

debug1: pasujący odcisk palca klucza hosta

znalezione w DNS Nie można ustalić autentyczności hosta „jersey.jacobdevans.com (2605: 6400: 10: 434 :: 10)”. Odcisk klucza ECDSA to SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s. Odpowiedni odcisk palca klucza hosta znaleziony w DNS. Czy na pewno chcesz kontynuować łączenie (tak / nie)? Nie

Jacob Evans
źródło
4

Aby to zrobić poprawnie, tak naprawdę chcesz zebrać klucze publiczne hosta maszyn wirtualnych podczas ich tworzenia i upuścić w known_hostsformacie pliku. Następnie możesz użyć przycisku -o GlobalKnownHostsFile=..., wskazując na ten plik, aby upewnić się, że łączysz się z hostem, z którym Twoim zdaniem powinieneś się połączyć. To, jak to zrobisz, zależy jednak od konfiguracji maszyn wirtualnych, ale odczytywanie go z wirtualnego systemu plików, jeśli to możliwe, lub nawet nakłonienie hosta do wydrukowania zawartości /etc/ssh/ssh_host_rsa_key.pubpodczas konfiguracji może załatwić sprawę.

To powiedziawszy, może to nie być opłacalne, w zależności od tego, w jakim środowisku pracujesz i kim są twoi spodziewani przeciwnicy. Wykonanie prostego „przechowywania przy pierwszym połączeniu” (przez skanowanie lub po prostu podczas pierwszego „rzeczywistego” połączenia), jak opisano w kilku innych odpowiedziach powyżej, może być znacznie łatwiejsze i nadal zapewniać pewien stopień bezpieczeństwa. Jednak jeśli to zrobisz, zdecydowanie sugeruję zmianę znanego pliku hosts ( -o UserKnownHostsFile=...) na plik specyficzny dla tej konkretnej instalacji testowej; pozwoli to uniknąć zanieczyszczenia twojego znanego pliku hosts informacjami testowymi i ułatwi wyczyszczenie niepotrzebnych teraz kluczy publicznych po usunięciu maszyn wirtualnych.

Curt J. Sampson
źródło
4

To wszystko

  • ssh-key-scan
  • ssh-copy-id
  • Ostrzeżenie klucza ECSDA

biznes ciągle mnie denerwował, więc wybrałem

Jeden skrypt do rządzenia nimi wszystkimi

Jest to wariant skryptu ze strony https://askubuntu.com/a/949731/129227 z odpowiedzią Amadu Baha https://serverfault.com/a/858957/162693 w pętli.

przykładowe połączenie

./sshcheck somedomain site1 site2 site3

Skrypt zapętli nazwy witryn i zmodyfikuje plik .ssh / config i .ssh / known_hosts i wykona ssh-copy-id na żądanie - dla ostatniej funkcji pozwól, by wywołania testowe ssh zawiodły, np. Naciskając 3 razy prośba o hasło.

skrypt sshcheck

#!/bin/bash
# WF 2017-08-25
# check ssh access to bitplan servers

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'  
red='\033[0;31m'  
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}

#
# error
#
#   show an error message and exit
#
#   params:
#     1: l_msg - the message to display
error() {
  local l_msg="$1"
  # use ansi red for error
  color_msg $red "Error: $l_msg" 1>&2
  exit 1
}

#
# show the usage
#
usage() {
  echo "usage: $0 domain sites"
  exit 1 
}

#
# check known_hosts entry for server
#
checkknown() {
  local l_server="$1"
  #echo $l_server
  local l_sid="$(ssh-keyscan $l_server 2>/dev/null)" 
  #echo $l_sid
  if (! grep "$l_sid" $sknown) > /dev/null 
  then
    color_msg $blue "adding $l_server to $sknown"
    ssh-keyscan $l_server >> $sknown 2>&1
  fi
}

#
# check the given server
#
checkserver() {
  local l_server="$1"
  grep $l_server $sconfig > /dev/null
  if [ $? -eq 1 ]
  then
    color_msg $blue "adding $l_server to $sconfig"
    today=$(date "+%Y-%m-%d")
    echo "# added $today by $0"  >> $sconfig
    echo "Host $l_server" >> $sconfig
    echo "   StrictHostKeyChecking no" >> $sconfig
    echo "   userKnownHostsFile=/dev/null" >> $sconfig
    echo "" >> $sconfig
    checkknown $l_server
  else
    color_msg $green "$l_server found in $sconfig"
  fi
  ssh -q $l_server id > /dev/null
  if [ $? -eq 0 ]
  then
    color_msg $green "$l_server accessible via ssh"
  else
    color_msg $red "ssh to $l_server failed" 
    color_msg $blue "shall I ssh-copy-id credentials to $l_server?"
    read answer
    case $answer in
      y|yes) ssh-copy-id $l_server
    esac
  fi
}

#
# check all servers
#
checkservers() {
me=$(hostname -f)
for server in $(echo $* | sort)
do
  os=`uname`
  case $os in
   # Mac OS X
   Darwin*)
     pingoption=" -t1";;
    *) ;;
  esac

  pingresult=$(ping $pingoption -i0.2 -c1 $server)
  echo $pingresult | grep 100 > /dev/null
  if [ $? -eq 1 ]
  then 
    checkserver $server
    checkserver $server.$domain
  else
    color_msg $red "ping to $server failed"
  fi
done
}

#
# check configuration
#
checkconfig() {
#https://askubuntu.com/questions/87449/how-to-disable-strict-host-key-checking-in-ssh
  if [ -f $sconfig ]
  then
    color_msg $green "$sconfig exists"
    ls -l $sconfig
  fi
}

sconfig=~/.ssh/config
sknown=~/.ssh/known_hosts

case  $# in
  0) usage ;;
  1) usage ;;
  *) 
    domain=$1 
    shift 
    color_msg $blue "checking ssh configuration for domain $domain sites $*"
    checkconfig
    checkservers $* 
    #for server in $(echo $* | sort)
    ##do
    #  checkknown $server 
    #done
    ;;
esac
Wolfgang Fahl
źródło
2

Oto jak zrobić zbiór hostów

zdefiniuj kolekcję hostów

ssh_hosts:
  - server1.domain.com
  - server2.domain.com
  - server3.domain.com
  - server4.domain.com
  - server5.domain.com
  - server6.domain.com
  - server7.domain.com
  - server8.domain.com
  - server9.domain.com

Następnie zdefiniuj dwa zadania, aby dodać klucze do znanych hostów:

- command: "ssh-keyscan {{item}}"
   register: known_host_keys
   with_items: "{{ssh_hosts}}"
   tags:
     - "ssh"

 - name: Add ssh keys to know hosts
   known_hosts:
     name: "{{item.item}}"
     key: "{{item.stdout}}"
     path: ~/.ssh/known_hosts
   with_items: "{{known_host_keys.results}}"
Vackar Afzal
źródło
0

Najlepiej byłoby sprawdzić odcisk palca każdego nowego serwera / hosta. Jest to jedyny sposób na uwierzytelnienie serwera. Bez tego twoje połączenie SSH może zostać poddane atakowi typu man-in-the-middle .

Jeśli naprawdę masz pewność, że chcesz zignorować sprawdzenie odcisku palca, skorzystaj z drugiej najlepszej, mniej bezpiecznej opcji StrictHostKeyChecking=accept-new, która została wprowadzona w wersji OpenSSH 7.6 (2017-10-03) :

Pierwszy „zaakceptuj-nowy” automatycznie zaakceptuje niewidzialne klucze, ale odmówi połączenia dla zmienionych lub nieprawidłowych kluczy hosta.

Nie używaj starej wartości, StrictHostKeyChecking=noktóra nigdy nie sprawdza autentyczności serwera. (Chociaż znaczenie tego =noustawienia zostanie później zmienione w niektórych wydaniach ).

Dominik
źródło