Bisakah saya secara otomatis menambahkan host baru ke known_hosts?

249

Inilah situasi saya: Saya sedang menyiapkan test harness yang akan, dari klien pusat, meluncurkan sejumlah mesin virtual dan kemudian menjalankan perintah pada mereka melalui ssh. Mesin virtual sebelumnya akan memiliki nama host dan alamat IP yang tidak digunakan, sehingga mereka tidak akan ada di ~/.ssh/known_hostsfile pada klien pusat.

Masalah yang saya alami adalah bahwa sshperintah pertama dijalankan terhadap instance virtual baru selalu muncul dengan prompt interaktif:

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)?

Apakah ada cara saya bisa mem-bypass ini dan membuat host baru sudah dikenal oleh mesin klien, mungkin dengan menggunakan kunci publik yang sudah dimasukkan ke dalam citra mesin virtual? Saya benar-benar ingin menghindari penggunaan Expect atau apa pun untuk menjawab prompt interaktif jika saya bisa.

gareth_bowles
sumber
5
Untuk lingkungan pengujian yang mandiri dan aman secara fisik, penerimaan kunci otomatis dapat bekerja dengan baik. Tetapi secara otomatis menerima kunci publik di lingkungan produksi atau di seluruh jaringan yang tidak terpercaya (seperti Internet) benar-benar mem-bypass perlindungan terhadap serangan manusia-di-tengah yang seharusnya dilakukan SSH. Satu- satunya cara yang valid untuk memastikan Anda aman terhadap serangan MITM adalah memverifikasi kunci publik host melalui beberapa saluran tepercaya di luar band. Tidak ada cara aman untuk mengotomatiskannya tanpa menyiapkan infrastruktur penandatanganan kunci yang cukup rumit.
Eil

Jawaban:

142

Setel StrictHostKeyCheckingopsi menjadi no, baik dalam file konfigurasi atau via -o:

ssh -o StrictHostKeyChecking=no [email protected]

Ignacio Vazquez-Abrams
sumber
62
Ini membuat Anda terbuka untuk pria dalam serangan tengah, mungkin bukan ide yang baik.
JasperWallace
9
@JasperWallace, meskipun ini biasanya saran yang baik, kasus penggunaan khusus (menggunakan VM uji dan mengirim perintah kepada mereka) harus cukup aman.
Massimo
8
Ini memberikan Warning: Permanently added 'hostname,1.2.3.4' (RSA) to the list of known hosts.Untuk menghindari peringatan, dan untuk menghindari entri yang ditambahkan ke file diketahui_hosts, saya lakukan:ssh -o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null [email protected]
Peter V. Mørch
11
Mengundurkan diri karena ini tidak menjawab pertanyaan dan membuka kerentanan keamanan serius.
marcv81
12
@Mnebuerquo: Jika Anda khawatir tentang keamanan maka Anda tidak akan ada hubungannya sama sekali dengan pertanyaan ini. Anda akan memiliki kunci host yang benar di depan Anda, dikumpulkan dari konsol sistem yang ingin Anda sambungkan, dan Anda akan memverifikasinya secara manual saat pertama kali terhubung. Anda tentu tidak akan melakukan apa pun "secara otomatis".
Ignacio Vazquez-Abrams
230

IMO, cara terbaik untuk melakukan ini adalah sebagai berikut:

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

Itu akan memastikan tidak ada entri duplikat, bahwa Anda dilindungi untuk kedua nama host dan alamat IP, dan juga akan hash output, langkah keamanan tambahan.

yardena
sumber
4
Mengapa Anda perlu semua 3 ssh-keyscan? Tidak bisakah kamu bertahan dengan yang pertama karena itu berfungsi untuk nama host dan ip?
Robert
6
Dapatkah Anda yakin bahwa mesin yang membalas permintaan ssh-keyscan benar-benar yang ingin Anda ajak bicara? Jika tidak, Anda sudah membuka diri untuk seorang pria di tengah serangan.
JasperWallace
2
@JasperWallace Ya, untuk itu Anda memerlukan setidaknya sidik jari atau kunci publik yang lebih baik, dalam hal ini Anda dapat menambahkannya langsung ke known_hosts, mengubah pertanyaan ini diperdebatkan. Jika Anda hanya memiliki sidik jari, Anda harus menulis langkah ekstra yang memverifikasi kunci publik yang diunduh dengan sidik jari Anda ...
1
Panggilan ke ssh-keyscansaya gagal karena host target saya tidak mendukung tipe kunci versi 1 yang standar. Menambahkan -t rsa,dsake perintah memperbaiki ini.
phasetwenty
5
Ini mungkin ide yang buruk. Anda membuka diri terhadap serangan man-in-the-middle dengan memperbarui kunci-kunci ini. Untuk menghindari entri duplikat, periksa status pengembalian ssh-keygen -F [address]sebagai gantinya. medium.com/@wblankenship/…
retrohacker
93

Untuk yang malas:

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

-H hash nama host / alamat IP

limaf
sumber
2
"ssh-keyscan -H <host> >> ~ / .ssh / known_hosts" menghasilkan entri lebih seperti yang dilakukan ssh dengan interaksi pengguna. (The -H hash nama host jarak jauh.)
Sarah Messer
3
Rentan terhadap serangan MITM. Anda tidak memeriksa sidik jari kunci.
Mnebuerquo
8
@Mnebuerquo Anda mengatakan apa yang harus dilakukan tetapi tidak bagaimana, yang akan sangat membantu.
Ray
4
@ jameshfisher Ya rentan terhadap serangan MITM, tetapi apakah Anda pernah membandingkan sidik jari RSA, yang ditunjukkan kepada Anda dengan server yang sebenarnya, ketika Anda melakukan ini secara manual? Tidak? Jadi jawaban ini adalah cara untuk melakukannya untuk Anda. Jika ya, Anda sebaiknya tidak menggunakan jawaban ini dan melakukannya secara manual atau menerapkan langkah-langkah keamanan lainnya ...
Fivef
2
@Mnebuerquo Saya akan sangat senang jika Anda juga memberi tahu kami cara yang lebih baik untuk menangani ini, ketika kami perlu mengkloning repo menggunakan skrip batch yang tidak dihadiri dan kami ingin mem-by-pass prompt ini. Tolong jelaskan solusi nyata jika Anda pikir ini bukan yang tepat!
Waqas Shah
42

Seperti disebutkan, menggunakan pemindaian kunci akan menjadi cara yang tepat & tidak mencolok untuk melakukannya.

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

Hal di atas akan melakukan trik untuk menambahkan host, HANYA jika belum ditambahkan. Itu juga tidak aman konkurensi; Anda tidak boleh mengeksekusi snippet pada mesin asal yang sama lebih dari satu kali pada saat yang sama, karena file tmp_hosts dapat musnah, akhirnya mengarah ke file known_hosts menjadi membengkak ...

ysawej
sumber
Apakah ada cara untuk memeriksa apakah kuncinya ada di known_hosts sebelumnya ssh-keyscan ? Alasannya adalah karena memerlukan beberapa waktu dan koneksi jaringan tambahan.
utapyngo
1
Versi poster asli dari file ini sudah cat ~/.ssh/tmp_hosts > ~/.ssh/known_hosts, tetapi edit berikutnya mengubahnya menjadi >>. Menggunakan >>adalah kesalahan. Itu mengalahkan tujuan keunikan di baris pertama, dan menyebabkannya membuang entri baru ke known_hostssetiap kali berjalan. (Baru saja mengirim suntingan untuk mengubahnya kembali.)
paulmelnikow
1
Ini tunduk pada serangan MITM yang sama dengan yang lain.
Mnebuerquo
@utapyngo ssh-keygen -F akan memberi Anda sidik jari saat ini. Jika kembali kosong dengan kode pengembalian 1, maka Anda tidak memilikinya. Jika mencetak sesuatu dan mengembalikan kode 0, maka sudah ada.
Rich L
1
Jika Anda sangat peduli tentang MITM, gunakan data DNSSEC dan SSHFP atau gunakan cara aman lainnya untuk mendistribusikan kunci dan solusi kludge ini tidak akan relevan.
Zart
19

Anda bisa menggunakan ssh-keyscanperintah untuk mengambil kunci publik dan menambahkannya ke known_hostsfile Anda .

Alex
sumber
3
Pastikan Anda memeriksa sidik jari untuk memastikan itu adalah kunci yang benar. Kalau tidak, Anda membuka diri terhadap serangan MITM.
Mnebuerquo
3
@Mnebuerquo Fair menunjukkan dalam konteks umum, tetapi mengapa seseorang mencoba secara terprogram mengumpulkan kunci jika mereka sudah tahu apa kunci yang benar?
Brian Cline
Ini bukan cara untuk melakukannya. MITM.
jameshfisher
8

Ini adalah bagaimana Anda dapat memasukkan ssh-keyscan ke dalam permainan Anda:

---
# 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
sumber
1
Apakah Anda mengunggah file dikenal_hosts valid yang dikenal, atau Anda melakukan ssh-keyscan dan membuang output ke known_hosts tanpa memverifikasi sidik jari?
Mnebuerquo
1
Ini hanya membuang output dari keyscan, ya. Jadi efeknya sama dengan StrictHostKeyChecking = tidak, hanya dengan memperbarui silent_hosted silent tanpa mengotak-atik opsi ssh. Solusi ini juga tidak berfungsi dengan baik karena ssh-keyscan dapat mengembalikan beberapa baris yang menyebabkan tugas ini selalu ditandai sebagai 'diubah'
Zart
Ini bukan cara untuk melakukannya. MITM.
jameshfisher
3
@ jameshfisher Saya akan sangat senang jika Anda juga memberi tahu kami cara yang lebih baik untuk menangani ini, ketika kami perlu mengkloning repo menggunakan skrip batch yang tidak dihadiri dan kami ingin mem-by-pass prompt ini. Tolong jelaskan solusi nyata jika Anda pikir ini bukan yang tepat! Beri tahu kami "bagaimana" melakukannya, jika menurut Anda ini bukan cara yang tepat untuk melakukannya!
Waqas Shah
Ini adalah metode yang benar-benar valid untuk menambahkan nilai ke known_hosts, tapi ya itu rentan terhadap MITM. Namun, untuk penggunaan internal tidak masalah.
Cameron Lowell Palmer
7

ini akan menjadi solusi lengkap, menerima kunci host untuk pertama kalinya saja

#!/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([]) }}'
mazac
sumber
1
Ini bukan cara untuk melakukannya. MITM.
jameshfisher
6

Saya memiliki masalah serupa dan menemukan bahwa beberapa jawaban yang diberikan hanya membuat saya berpisah untuk solusi otomatis. Berikut ini adalah apa yang akhirnya saya gunakan, semoga membantu:

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

Itu menambah kunci known_hostsdan tidak meminta kata sandi.

VenomFangs
sumber
2
Rentan terhadap serangan MITM. Anda tidak memeriksa sidik jari.
Mnebuerquo
6
Tidak ada yang memeriksa sidik jari.
Brendan Byrd
Ini bukan cara untuk melakukannya. MITM.
jameshfisher
5

Jadi, saya sedang mencari cara biasa untuk mem-bypass interaksi manual host yang tidak dikenal dalam mengkloning git repo seperti yang ditunjukkan di bawah ini:

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)?

Perhatikan sidik jari kunci RSA ...

Jadi, ini adalah hal SSH, ini akan bekerja untuk git atas SSH dan hanya hal-hal terkait SSH secara umum ...

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

Pertama, instal nmap pada driver harian Anda. nmap sangat membantu untuk hal-hal tertentu, seperti mendeteksi port terbuka dan ini-- memverifikasi sidik jari SSH secara manual. Tapi, kembali ke apa yang kita lakukan.

Baik. Saya entah dikompromikan di beberapa tempat dan mesin saya sudah memeriksanya - atau penjelasan yang lebih masuk akal dari segala sesuatu yang keren adalah apa yang terjadi.

'Sidik jari' itu hanyalah sebuah string yang dipersingkat dengan algoritma satu arah untuk kenyamanan manusia kita dengan risiko lebih dari satu string menyelesaikan ke dalam sidik jari yang sama. Itu terjadi, mereka disebut tabrakan.

Apapun, kembali ke string asli yang bisa kita lihat dalam konteks di bawah ini.

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

Jadi, sebelumnya, kami memiliki cara untuk meminta bentuk identifikasi dari tuan rumah asli.

Pada titik ini kami secara manual sama rentannya dengan otomatis - kecocokan string, kami memiliki data dasar yang membuat sidik jari, dan kami dapat meminta data dasar itu (mencegah tabrakan) di masa mendatang.

Sekarang untuk menggunakan string dengan cara yang mencegah bertanya tentang keaslian host ...

File known_hosts dalam hal ini tidak menggunakan entri plaintext. Anda akan tahu entri hash ketika Anda melihatnya, mereka terlihat seperti hash dengan karakter acak, bukan xyz.com atau 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==

Baris komentar pertama muncul dengan marah - tetapi Anda dapat menyingkirkannya dengan redirect sederhana melalui konvensi ">" atau ">>".

Karena saya sudah melakukan yang terbaik untuk mendapatkan data yang tidak ternoda untuk digunakan untuk mengidentifikasi "host" dan kepercayaan, saya akan menambahkan identifikasi ini ke file known_hosts saya di direktori ~ / .ssh saya. Karena sekarang akan diidentifikasi sebagai host yang dikenal, saya tidak akan mendapatkan prompt yang disebutkan di atas ketika Anda masih muda.

Terima kasih telah bertahan dengan saya, ini dia. Saya menambahkan kunci RSA bitbucket sehingga saya dapat berinteraksi dengan repositori git saya di sana dengan cara non-interaktif sebagai bagian dari alur kerja CI, tetapi apa pun yang Anda lakukan apa yang Anda inginkan.

#!/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

Jadi, begitulah cara Anda tetap perawan untuk hari ini. Anda dapat melakukan hal yang sama dengan github dengan mengikuti petunjuk serupa di waktu Anda sendiri.

Saya melihat begitu banyak posting stack overflow yang memberitahu Anda untuk menambahkan kunci secara terprogram tanpa memeriksa. Semakin banyak Anda memeriksa kunci dari mesin yang berbeda di jaringan yang berbeda, semakin banyak kepercayaan yang dapat Anda miliki bahwa host adalah yang dikatakannya - dan itulah yang terbaik yang dapat Anda harapkan dari lapisan keamanan ini.

SALAH ssh -oStrictHostKeyChecking = tidak ada nama host [perintah]

SALAH ssh-keyscan -t rsa -H hostname >> ~ / .ssh / known_hosts

Tolong jangan lakukan salah satu dari hal-hal di atas. Anda diberi kesempatan untuk meningkatkan peluang Anda menghindari seseorang yang menguping transfer data Anda melalui seorang pria di tengah serangan - ambil kesempatan itu. Perbedaannya adalah memverifikasi bahwa kunci RSA yang Anda miliki adalah salah satu server yang bonafid dan sekarang Anda tahu cara mendapatkan informasi itu untuk membandingkannya sehingga Anda dapat mempercayai koneksi tersebut. Ingatlah bahwa lebih banyak perbandingan dari berbagai komputer & jaringan biasanya akan meningkatkan kemampuan Anda untuk mempercayai koneksi.

BradChesney79
sumber
Saya pikir ini adalah solusi terbaik untuk masalah ini. Namun, berhati-hatilah saat menggunakan Nmap pada sesuatu seperti Amazon EC2, saya mendapat peringatan tentang pemindaian port yang dilakukan Nmap! Isi formulir mereka sebelum melakukan portcanning!
Waqas Shah
...yah begitulah. Saya tidak tahu mengapa Anda akan melakukan pemindaian port dari EC2. Jika Anda masuk ke akun Anda, Anda bisa mendapatkan kunci dari mesin yang sebenarnya. Ini lebih untuk mesin yang tidak Anda kendalikan. Saya akan menganggap Anda akan memiliki mesin lokal yang tidak tunduk pada pembatasan pemindaian port AWS untuk digunakan. Tetapi, jika Anda berada dalam situasi tepi di mana Anda harus menjalankan nmap dengan AWS, saya kira peringatan ini akan sangat membantu.
BradChesney79
Menggunakan nmap untuk membaca kunci host SSH dari workstation Anda dan kemudian percaya bahwa nilainya tidak berbeda dari menghubungkan melalui SSH dengan StructHostKeyChecking dimatikan. Sama rentan terhadap serangan pria di tengah.
Micah R Ledbetter
... @ MicahRLedbetter, itulah sebabnya saya menyarankan bahwa "lebih banyak perbandingan dari komputer & jaringan yang berbeda biasanya akan meningkatkan kemampuan Anda untuk mempercayai koneksi". Tapi itu yang saya maksud. Jika Anda hanya memeriksa host target Anda dari satu set kondisi lingkungan, lalu bagaimana Anda mengetahui perbedaan? Apakah Anda punya saran yang lebih baik?
BradChesney79
1
Ini adalah teater keamanan. Melakukan sesuatu yang rumit untuk menciptakan penampilan keamanan yang lebih besar. Tidak masalah berapa banyak metode berbeda yang Anda gunakan untuk menanyakan kuncinya kepada tuan rumah. Seperti bertanya pada orang yang sama beberapa kali apakah Anda bisa mempercayai mereka (mungkin Anda menelepon, mengirim email, mengirim pesan teks, dan mengirim email). Mereka akan selalu mengatakan ya, tetapi jika Anda bertanya kepada orang yang salah, itu tidak masalah.
vastlysuperiorman
5

Saya membuat skrip satu baris, agak panjang tapi berguna untuk membuat tugas ini untuk host dengan banyak IP, menggunakan digdanbash

(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
sumber
5

Berikut ini menghindari entri duplikat di ~ / .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
sumber
1
Ini bukan cara untuk melakukannya. MITM.
jameshfisher
Saya suka jawaban ini. Untuk skrip penyiapan awal VPS acak yang tidak penting bagi siapa pun kecuali saya, risiko MITM semakin kecil. Berdalih sangat kecil ... baris pertama harusmkdir -p ~/.ssh/known_hosts;
Martin Bramwell
5

Bagaimana Anda membangun mesin ini? dapatkah Anda menjalankan skrip pembaruan dns? dapatkah Anda bergabung dengan Domain IPA?

FreeIPA melakukan ini secara otomatis, tetapi pada dasarnya yang Anda butuhkan adalah SSHFP catatan dns dan DNSSEC di zona Anda (freeipa menyediakan opsi yang dapat dikonfigurasi (dnssec dinonaktifkan secara default)).

Anda bisa mendapatkan catatan SSHFP yang ada dari host Anda dengan menjalankan.

ssh-keygen -r jersey.jacobdevans.com

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

kemudian setelah dipublikasikan, Anda akan menambah VerifyHostKeyDNS yesssh_config atau ~ / .ssh / config Anda

Jika / Ketika google memutuskan untuk mengaktifkan DNSSEC, Anda dapat ssh in tanpa prompt hostkey.

ssh jersey.jacobdevans.com

TETAPI domain saya belum ditandatangani, jadi untuk sekarang Anda akan melihat ....

debug1: Kunci host server: ecdsa-sha2-nistp256 SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s

debug1: menemukan 4 sidik jari tidak aman di DNS

debug1: pencocokan sidik jari kunci host

ditemukan di DNS Keaslian host 'jersey.jacobdevans.com (2605: 6400: 10: 434 :: 10)' tidak dapat dibuat. Sidik jari kunci ECDSA adalah SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s. Pencocokan sidik jari kunci host ditemukan dalam DNS. Anda yakin ingin terus terhubung (ya / tidak)? tidak

Jacob Evans
sumber
4

Untuk melakukan ini dengan benar, apa yang benar-benar ingin Anda lakukan adalah mengumpulkan kunci publik host dari VM saat Anda membuatnya dan memasukkannya ke dalam known_hostsformat file . Anda kemudian dapat menggunakan -o GlobalKnownHostsFile=..., menunjuk ke file itu, untuk memastikan bahwa Anda terhubung ke host yang Anda yakin harus Anda sambungkan. Bagaimana Anda melakukan ini tergantung pada bagaimana Anda mengatur mesin virtual, tetapi membacanya dari sistem file virtual, jika mungkin, atau bahkan membuat host untuk mencetak konten /etc/ssh/ssh_host_rsa_key.pubselama konfigurasi dapat melakukan trik.

Yang mengatakan, ini mungkin tidak bermanfaat, tergantung pada lingkungan seperti apa Anda bekerja dan siapa musuh yang Anda antisipasi. Melakukan "store on first connect" sederhana (melalui pemindaian atau hanya selama koneksi "nyata" pertama) seperti yang dijelaskan dalam beberapa jawaban lain di atas mungkin jauh lebih mudah dan masih memberikan sedikit keamanan. Namun, jika Anda melakukan ini, saya sangat menyarankan Anda mengubah file host yang dikenal pengguna ( -o UserKnownHostsFile=...) menjadi file khusus untuk instalasi pengujian khusus ini; ini akan menghindari mencemari file host dikenal pribadi Anda dengan informasi tes dan membuatnya mudah untuk membersihkan kunci publik yang sekarang tidak berguna ketika Anda menghapus VMs Anda.

Curt J. Sampson
sumber
4

Seluruh ini

  • ssh-key-scan
  • ssh-copy-id
  • Peringatan kunci ECSDA

bisnis terus mengganggu saya, jadi saya memilih

Satu skrip untuk mengatur semuanya

Ini adalah varian dari skrip di https://askubuntu.com/a/949731/129227 dengan jawaban Amadu Bah https://serverfault.com/a/858957/162693 dalam satu lingkaran.

contoh panggilan

./sshcheck somedomain site1 site2 site3

Script akan mengulangi nama-nama situs dan memodifikasi file .ssh / config dan .ssh / known_hosts dan melakukan ssh-copy-id berdasarkan permintaan - untuk fitur terakhir hanya biarkan panggilan uji coba ssh gagal misalnya dengan menekan enter 3 kali pada permintaan kata sandi.

skrip 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
sumber
2

Berikut adalah cara melakukan kumpulan host

tentukan koleksi host

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

Kemudian tentukan dua tugas untuk menambahkan kunci ke host yang dikenal:

- 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
sumber
0

Yang terbaik adalah Anda memeriksa sidik jari setiap server / host baru. Ini adalah satu-satunya cara untuk mengotentikasi server. Tanpa itu, koneksi SSH Anda dapat terkena serangan man-in-the-middle .

Jika Anda benar-benar yakin ingin mengabaikan pengecekan sidik jari, maka opsi terbaik kedua yang kurang aman adalah yang digunakan StrictHostKeyChecking=accept-new, yang diperkenalkan di OpenSSH versi 7.6 (2017-10-03) :

"Accept-new" pertama akan secara otomatis menerima kunci yang sampai sekarang tidak terlihat tetapi akan menolak koneksi untuk host host yang diubah atau tidak valid.

Jangan gunakan nilai lama StrictHostKeyChecking=noyang tidak pernah memeriksa keaslian server sama sekali. (Meskipun arti dari =nopengaturan ini akan membalik beberapa rilis nanti .)

Dominik
sumber