ฉันสามารถเพิ่มโฮสต์ใหม่ให้กับ known_hosts โดยอัตโนมัติได้หรือไม่


249

นี่คือสถานการณ์ของฉัน: sshฉันตั้งค่าเทียมทดสอบที่จะจากลูกค้ากลางเปิดจำนวนของกรณีเครื่องเสมือนแล้วรันคำสั่งบนพวกเขาผ่านทาง เครื่องเสมือนจะมีชื่อโฮสต์และที่อยู่ IP ที่ไม่ได้ใช้ก่อนหน้านี้ดังนั้นพวกเขาจะไม่อยู่ใน~/.ssh/known_hostsไฟล์บนไคลเอนต์ส่วนกลาง

ปัญหาที่ฉันมีอยู่คือsshคำสั่งแรกที่ทำงานกับอินสแตนซ์เสมือนใหม่มักจะเกิดขึ้นพร้อมกับการโต้ตอบ:

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

มีวิธีที่ฉันสามารถหลีกเลี่ยงสิ่งนี้และทำให้โฮสต์ใหม่เป็นที่รู้จักในเครื่องไคลเอนต์แล้วหรือไม่โดยการใช้กุญแจสาธารณะที่อบเข้าไปในอิมเมจเครื่องเสมือนแล้ว ฉันต้องการหลีกเลี่ยงการใช้งาน Expect หรืออะไรก็ตามที่จะตอบรับคำสั่งการโต้ตอบถ้าฉันทำได้


5
สำหรับสภาพแวดล้อมการทดสอบที่มีอยู่ในตัวและมีความปลอดภัยทางร่างกายการยอมรับคีย์อัตโนมัติอาจทำงานได้ดี แต่การยอมรับกุญแจสาธารณะโดยอัตโนมัติในสภาพแวดล้อมที่ใช้งานจริงหรือผ่านเครือข่ายที่ไม่น่าเชื่อถือ (เช่นอินเทอร์เน็ต) จะข้ามการป้องกันใด ๆ จากการโจมตีแบบ Man-in-the-middle ที่ SSH จะจ่ายได้อย่างสมบูรณ์ เพียงวิธีการที่ถูกต้องเพื่อให้แน่ใจว่าคุณปลอดภัยจากการโจมตี MITM คือการตรวจสอบคีย์สาธารณะของโฮสต์ผ่านบางช่องออกจากวงดนตรีที่เชื่อถือได้ ไม่มีวิธีที่ปลอดภัยในการทำให้เป็นอัตโนมัติโดยไม่ต้องตั้งค่าโครงสร้างพื้นฐานการเซ็นกุญแจที่ซับซ้อนพอสมควร
Eil

คำตอบ:


141

ตั้งค่าStrictHostKeyCheckingตัวเลือกเป็นnoไม่ว่าจะในไฟล์ปรับแต่งหรือผ่าน-o:

ssh -o StrictHostKeyChecking=no username@hostname.com


62
สิ่งนี้ทำให้คุณเปิดรับผู้ชายในการโจมตีระดับกลางอาจไม่ใช่ความคิดที่ดี
JasperWallace

9
@JasperWallace ในขณะนี้มักเป็นคำแนะนำที่ดีกรณีการใช้งานเฉพาะ (การปรับใช้การทดสอบ VM และการส่งคำสั่งไปยังพวกเขา) ควรจะปลอดภัยเพียงพอ
Massimo

8
สิ่งนี้จะให้คำสั่งWarning: Permanently added 'hostname,1.2.3.4' (RSA) to the list of known hosts.เพื่อหลีกเลี่ยงคำเตือนและเพื่อหลีกเลี่ยงรายการที่ถูกเพิ่มลงในไฟล์ known_hosts ใด ๆ ฉันทำได้:ssh -o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null username@hostname.com
Peter V. Mørch

11
Downvoting เนื่องจากไม่ได้ตอบคำถามและเปิดรับช่องโหว่ด้านความปลอดภัยที่ร้ายแรง
marcv81

12
@Mebuerquo: หากคุณกังวลเกี่ยวกับความปลอดภัยคุณไม่ต้องกังวลเกี่ยวกับคำถามนี้เลย คุณจะต้องมีรหัสโฮสต์ที่ถูกต้องต่อหน้ารวบรวมจากคอนโซลของระบบที่คุณต้องการเชื่อมต่อและคุณจะตรวจสอบด้วยตนเองเมื่อทำการเชื่อมต่อครั้งแรก แน่นอนคุณจะไม่ทำอะไร "อัตโนมัติ"
Ignacio Vazquez-Abrams

230

IMO วิธีที่ดีที่สุดในการทำเช่นนี้คือ:

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

ที่จะทำให้แน่ใจว่าไม่มีรายการที่ซ้ำกันที่คุณได้รับความคุ้มครองทั้งชื่อโฮสต์และที่อยู่ IP และจะแฮชเอาท์พุทซึ่งเป็นมาตรการรักษาความปลอดภัยเพิ่มเติม


4
ทำไมคุณถึงต้องการ ssh-keyscan ทั้ง 3 ตัว? คุณไม่สามารถผ่านได้ด้วยชื่อแรกเพราะมันใช้ได้กับทั้งชื่อโฮสต์และไอพี
Robert

6
คุณแน่ใจหรือไม่ว่าเครื่องที่ตอบกลับคำขอ ssh-keyscan นั้นเป็นสิ่งที่คุณต้องการคุยด้วยจริงหรือไม่? หากคุณไม่ได้เปิดตัวเองให้กับผู้ชายคนหนึ่งในการโจมตีกลาง
JasperWallace

2
@JasperWallace ใช่แล้วสำหรับสิ่งที่คุณต้องการอย่างน้อยลายนิ้วมือหรือดีกว่ากุญแจสาธารณะซึ่งในกรณีนี้คุณสามารถเพิ่มโดยตรงไปที่ known_hosts เปลี่ยนคำถามนี้สงสัย หากคุณมีลายนิ้วมือเพียงอย่างเดียวคุณจะต้องเขียนขั้นตอนเพิ่มเติมที่ยืนยันรหัสสาธารณะที่ดาวน์โหลดด้วยลายนิ้วมือของคุณ ...

1
การโทรหาssh-keyscanล้มเหลวสำหรับฉันเนื่องจากโฮสต์เป้าหมายของฉันไม่สนับสนุนประเภทคีย์รุ่น 1 ที่เป็นค่าเริ่มต้น การเพิ่ม-t rsa,dsaคำสั่งแก้ไขสิ่งนี้
phasetwenty

5
นี่อาจเป็นความคิดที่ไม่ดี คุณกำลังเปิดการโจมตีแบบคนกลางคนด้วยการอัปเดตคีย์เหล่านี้ หากต้องการหลีกเลี่ยงรายการที่ซ้ำกันให้ตรวจสอบสถานะการส่งคืนssh-keygen -F [address]แทน medium.com/@wblankenship/…
retrohacker

93

สำหรับคนขี้เกียจ:

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

-H แฮชชื่อโฮสต์ / ที่อยู่ IP


2
"ssh-keyscan -H <host> >> ~ / .ssh / known_hosts" สร้างรายการเพิ่มเติมเช่นที่ ssh ทำกับการโต้ตอบกับผู้ใช้ (-H แฮชชื่อโฮสต์ระยะไกล)
Sarah Messer

3
เสี่ยงต่อการถูกโจมตีจาก MITM คุณไม่ได้ตรวจสอบลายนิ้วมือที่สำคัญ
Mnebuerquo

8
@Mebuerquo คุณพูดว่าต้องทำอะไร แต่ไม่ใช่ว่าจะเป็นประโยชน์อย่างไร
Ray

4
@jameshfisher ใช่มันมีความเสี่ยงต่อการโจมตีของ MITM แต่คุณเคยเปรียบเทียบลายนิ้วมือ RSA ซึ่งแสดงให้คุณเห็นด้วยหนึ่งในเซิร์ฟเวอร์จริงเมื่อคุณทำสิ่งนี้ด้วยตนเองหรือไม่? ไม่มี? ดังนั้นคำตอบนี้เป็นวิธีที่ทำเพื่อคุณ ถ้าใช่คุณไม่ควรใช้คำตอบนี้และทำด้วยตนเองหรือใช้มาตรการรักษาความปลอดภัยอื่น ๆ ...
5

2
@Mebuerquo ฉันจะดีใจจริง ๆ ถ้าคุณแจ้งให้เราทราบวิธีที่ดีกว่าในการจัดการเมื่อเราต้องการโคลน repo โดยใช้ชุดสคริปต์ที่ไม่เข้าร่วมและเราต้องการผ่านพรอมต์นี้ โปรดแสดงความคิดเห็นเกี่ยวกับทางออกที่แท้จริงหากคุณคิดว่านี่ไม่ใช่สิ่งที่ถูกต้อง!
Waqas Shah

42

ดังกล่าวการใช้การสแกนคีย์จะเป็นวิธีที่ถูกต้องและไม่เป็นการรบกวน

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

ด้านบนจะทำเคล็ดลับในการเพิ่มโฮสต์เท่านั้นหากยังไม่ได้เพิ่ม มันยังไม่ปลอดภัยพร้อมกัน; คุณต้องไม่เรียกใช้ส่วนย่อยบนเครื่องต้นทางเดียวกันมากกว่าหนึ่งครั้งในเวลาเดียวกันเนื่องจากไฟล์ tmp_hosts สามารถปิดบังได้ในที่สุดนำไปสู่ไฟล์ known_hosts กลายเป็น bloated ...


มีวิธีตรวจสอบว่าคีย์อยู่ใน known_hosts มาก่อน ssh-keyscanหรือไม่? เหตุผลก็คือมันต้องใช้เวลาและการเชื่อมต่อเครือข่ายเพิ่มเติม
utapyngo

1
รุ่นโปสเตอร์เดิมของไฟล์นี้มีแต่การแก้ไขที่ต่อมาเปลี่ยนไปcat ~/.ssh/tmp_hosts > ~/.ssh/known_hosts >>การใช้>>เป็นข้อผิดพลาด มันเอาชนะวัตถุประสงค์ของความเป็นเอกลักษณ์ในบรรทัดแรกและทำให้มันทิ้งรายการใหม่ลงในknown_hostsทุกครั้งที่มันทำงาน (เพิ่งโพสต์การแก้ไขเพื่อเปลี่ยนกลับ)
paulmelnikow

1
เรื่องนี้เป็นการโจมตีของ MITM เหมือนกับคนอื่น ๆ
Mnebuerquo

@utapyngo ssh-keygen -F จะให้ลายนิ้วมือคุณในปัจจุบัน ถ้ามันกลับมาว่างเปล่าด้วยรหัสส่งคืนที่ 1 คุณก็ไม่มี หากพิมพ์บางอย่างและรหัสส่งคืนเป็น 0 แสดงว่ามีอยู่แล้ว
รวย L

1
หากคุณสนใจเรื่อง MITM มากให้ปรับใช้ DNSSEC และบันทึก SSHFP หรือใช้วิธีการรักษาความปลอดภัยอื่น ๆ ในการกระจายกุญแจและโซลูชัน kludge นี้จะไม่เกี่ยวข้อง
Zart

19

คุณสามารถใช้ssh-keyscanคำสั่งเพื่อคว้ากุญแจสาธารณะและผนวกเข้ากับknown_hostsไฟล์ของคุณ


3
ตรวจสอบให้แน่ใจว่าคุณตรวจสอบลายนิ้วมือเพื่อให้แน่ใจว่าเป็นรหัสที่ถูกต้อง มิฉะนั้นคุณจะเปิดการโจมตีของ MITM
Mnebuerquo

3
@Mebuerquo จุดที่เป็นธรรมในบริบททั่วไป แต่ทำไมบางคนจะพยายามรวบรวมคีย์โดยทางโปรแกรมหากพวกเขารู้ว่าคีย์ที่ถูกต้องคืออะไร
Brian Cline

นี่ไม่ใช่วิธีที่จะทำ MITM
jameshfisher

8

นี่คือวิธีที่คุณสามารถรวมssh-keyscanเข้ากับการเล่นของคุณ:

---
# 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 }}'

1
คุณกำลังอัปโหลดไฟล์รู้จัก known_hosts หรือไม่หรือคุณกำลังทำ ssh-keyscan และดัมพ์เอาต์พุตไปยัง known_hosts โดยไม่ตรวจสอบลายนิ้วมือ?
Mnebuerquo

1
นี่เป็นเพียงการดัมพ์เอาต์พุตของคีย์สแกนใช่ ดังนั้นในความเป็นจริงมันก็เหมือนกับ StrictHostKeyChecking = no เพียงแค่ปิดใช้งานการรู้จัก known_hosts โดยไม่ต้องเล่นซอกับตัวเลือก ssh การแก้ปัญหานี้ยังไม่ได้ผลดีเนื่องจาก SSH-KeyScan กลับมาหลายบรรทัดซึ่งทำให้เกิดงานนี้มักจะถูกจัดเป็น 'เปลี่ยน'
Zart

นี่ไม่ใช่วิธีที่จะทำ MITM
jameshfisher

3
@ jameshfisher ฉันจะดีใจจริง ๆ ถ้าคุณแจ้งให้เราทราบวิธีที่ดีกว่าในการจัดการเมื่อเราต้องการโคลน repo โดยใช้ชุดสคริปต์ที่ไม่ได้เข้าร่วมและเราต้องการผ่านพรอมต์นี้ โปรดแสดงความคิดเห็นเกี่ยวกับทางออกที่แท้จริงหากคุณคิดว่านี่ไม่ใช่สิ่งที่ถูกต้อง! โปรดแจ้งให้เราทราบว่า "ทำอย่างไร" ถ้าคุณคิดว่านี่ไม่ใช่วิธีที่ถูกต้อง!
Waqas Shah

มันเป็นวิธีที่ถูกต้องสมบูรณ์ในการเพิ่มค่าให้กับ known_hosts แต่ใช่มันไวต่อ MITM อย่างไรก็ตามสำหรับการใช้งานภายในก็ถือว่าใช้ได้
คาเมรอนโลเวลล์พาลเมอร์

7

นี่จะเป็นโซลูชันที่สมบูรณ์โดยยอมรับรหัสโฮสต์เป็นครั้งแรกเท่านั้น

#!/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([]) }}'

1
นี่ไม่ใช่วิธีที่จะทำ MITM
jameshfisher

6

ฉันมีปัญหาที่คล้ายกันและพบว่าคำตอบที่ให้ไว้บางส่วนทำให้ฉันได้รับส่วนวิธีแก้ไขปัญหาอัตโนมัติเท่านั้น ต่อไปนี้เป็นสิ่งที่ฉันใช้โดยหวังว่าจะช่วยได้:

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

มันเพิ่มกุญแจสำคัญไปknown_hostsและไม่พร้อมท์ให้ใส่รหัสผ่าน


2
เสี่ยงต่อการถูกโจมตีจาก MITM คุณไม่ได้ตรวจสอบลายนิ้วมือ
Mnebuerquo

6
ไม่มีใครตรวจสอบลายนิ้วมือ
Brendan Byrd

นี่ไม่ใช่วิธีที่จะทำ MITM
jameshfisher

5

ดังนั้นฉันกำลังค้นหาวิธีการทางโลกีย์เพื่อข้ามการโต้ตอบด้วยตนเองของโฮสต์ที่ไม่เป็นที่รู้จักของการโคลน repo git ดังแสดงด้านล่าง:

brad@computer:~$ git clone git@bitbucket.org: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)?

จดจำลายนิ้วมือคีย์ RSA ...

ดังนั้นนี่คือสิ่ง SSH นี้จะทำงานเพื่อคอมไพล์ SSH และเพียงแค่สิ่งที่เกี่ยวข้องกับ 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

ก่อนอื่นให้ติดตั้ง nmap บนไดรเวอร์รายวันของคุณ nmap มีประโยชน์อย่างมากสำหรับบางสิ่งเช่นการตรวจจับพอร์ตที่เปิดอยู่และนี่คือการตรวจสอบลายนิ้วมือ SSH ด้วยตนเอง แต่กลับไปที่สิ่งที่เรากำลังทำ

ดี. ฉันถูกประนีประนอมในหลาย ๆ สถานที่และเครื่องจักรที่ฉันตรวจสอบแล้ว - หรือคำอธิบายที่เป็นไปได้มากขึ้นสำหรับทุกสิ่งที่เกิดขึ้นคือสิ่งที่กำลังเกิดขึ้น

'ลายนิ้วมือ' นั้นเป็นเพียงสตริงที่สั้นลงด้วยอัลกอริทึมแบบทางเดียวเพื่อความสะดวกของมนุษย์เราที่มีความเสี่ยงที่จะมีการแก้ไขมากกว่าหนึ่งสายเป็นลายนิ้วมือเดียวกัน มันเกิดขึ้นพวกเขาถูกเรียกว่าการชน

โดยไม่คำนึงถึงกลับไปที่สตริงดั้งเดิมซึ่งเราสามารถดูได้ในบริบทด้านล่าง

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

ดังนั้นก่อนเวลาเรามีวิธีขอรูปแบบการระบุจากโฮสต์เดิม

ณ จุดนี้เรามีความเสี่ยงด้วยตนเองโดยอัตโนมัติ - การจับคู่สตริงเรามีข้อมูลพื้นฐานที่สร้างลายนิ้วมือและเราสามารถขอข้อมูลฐานนั้น (ป้องกันการชน) ในอนาคต

ทีนี้ให้ใช้สายนั้นในวิธีที่ป้องกันการถามเกี่ยวกับความถูกต้องของโฮสต์ ...

ไฟล์ known_hosts ในกรณีนี้ไม่ใช้รายการข้อความธรรมดา คุณจะรู้ว่ารายการที่ถูกแฮชเมื่อคุณเห็นพวกมันดูเหมือนแฮ็คที่มีตัวอักษรสุ่มแทน xyz.com หรือ 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==

บรรทัดความคิดเห็นแรกแสดงขึ้นอย่างไม่พอใจ - แต่คุณสามารถกำจัดมันได้โดยการเปลี่ยนเส้นทางแบบง่าย ๆ ผ่านการประชุม ">" หรือ ">>"

เนื่องจากฉันได้พยายามอย่างเต็มที่เพื่อให้ได้ข้อมูลที่ไม่ทาสีเพื่อใช้ระบุ "โฮสต์" และความน่าเชื่อถือฉันจะเพิ่มการระบุนี้ไปยังไฟล์ known_hosts ของฉันในไดเรกทอรี ~ / .ssh ของฉัน เนื่องจากตอนนี้มันจะถูกระบุว่าเป็นโฮสต์ที่รู้จักกันฉันจะไม่ได้รับแจ้งดังกล่าวข้างต้นเมื่อคุณเป็นเด็ก

ขอบคุณที่ติดกับฉันไปเลย ฉันกำลังเพิ่มคีย์ bitbucket RSA เพื่อให้ฉันสามารถโต้ตอบกับที่เก็บคอมไพล์ของฉันในแบบที่ไม่ต้องมีการโต้ตอบซึ่งเป็นส่วนหนึ่งของเวิร์กโฟลว์ CI แต่สิ่งที่คุณทำในสิ่งที่คุณต้องการ

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

นั่นคือวิธีที่คุณยังคงบริสุทธิ์ในวันนี้ คุณสามารถทำเช่นเดียวกันกับ GitHub โดยทำตามคำแนะนำที่คล้ายกันในเวลาของคุณเอง

ฉันเห็นโพสต์โอเวอร์โฟลว์จำนวนมากที่บอกให้คุณเพิ่มคีย์แบบสุ่มโดยไม่มีการตรวจสอบใด ๆ ยิ่งคุณตรวจสอบกุญแจจากเครื่องที่แตกต่างกันในเครือข่ายที่ต่างกันก็ยิ่งเชื่อใจได้มากขึ้นว่าเครื่องแม่ข่ายนั้นเป็นเครื่องที่บอกว่าเป็น - และนั่นคือสิ่งที่ดีที่สุดที่คุณคาดหวังจากการรักษาความปลอดภัยระดับนี้

ไม่ถูกต้อง ssh -oStrictHostKeyChecking = ไม่มีชื่อโฮสต์ [คำสั่ง]

ไม่ถูกต้อง ssh-keyscan -t rsa -H ชื่อโฮสต์ >> ~ / .ssh / known_hosts

กรุณาอย่าทำอย่างใดอย่างหนึ่งดังกล่าวข้างต้น คุณได้รับโอกาสในการเพิ่มโอกาสในการหลีกเลี่ยงการแอบถ่ายโอนข้อมูลของคุณผ่านชายคนหนึ่งในการโจมตีกลาง - ใช้โอกาสนั้น ข้อแตกต่างคือการตรวจสอบว่าคีย์ RSA ที่คุณมีคือเซิร์ฟเวอร์ bona fide หนึ่งและตอนนี้คุณรู้วิธีรับข้อมูลนั้นเพื่อเปรียบเทียบพวกเขาเพื่อให้คุณสามารถเชื่อถือการเชื่อมต่อ เพียงจำการเปรียบเทียบเพิ่มเติมจากคอมพิวเตอร์และเครือข่ายที่แตกต่างกันมักจะเพิ่มความสามารถในการเชื่อถือการเชื่อมต่อ


ฉันคิดว่านี่เป็นทางออกที่ดีที่สุดสำหรับปัญหานี้ อย่างไรก็ตามระวังอย่างมากในการใช้ Nmap กับบางอย่างเช่น Amazon EC2 ฉันได้รับคำเตือนเกี่ยวกับการสแกนพอร์ตที่ Nmap ทำ! กรอกแบบฟอร์มก่อนที่จะทำการสแกนพอร์ต!
Waqas Shah

... อืม ฉันไม่รู้ว่าทำไมคุณถึงสแกนพอร์ตจาก EC2 หากคุณลงชื่อเข้าใช้บัญชีของคุณคุณจะได้รับกุญแจจากเครื่องจริง นี่เป็นสิ่งที่มากกว่าสำหรับเครื่องจักรที่คุณไม่สามารถควบคุมได้ ฉันจะสมมติว่าคุณจะมีเครื่องท้องถิ่นที่ไม่มีข้อ จำกัด ในการสแกนพอร์ต AWS ที่จะใช้ แต่ถ้าคุณอยู่ในสถานการณ์กรณีขอบที่คุณต้องเรียกใช้ nmap กับ AWS ฉันคิดว่าคำเตือนนี้จะเป็นประโยชน์
BradChesney79

การใช้ nmap เพื่ออ่านคีย์โฮสต์ SSH จากเวิร์กสเตชันของคุณจากนั้นวางใจว่าค่านั้นไม่แตกต่างจากการเชื่อมต่อผ่าน SSH โดยปิดการใช้งาน StructHostKeyChecking เช่นเดียวกับความเสี่ยงต่อการถูกโจมตีจากคนกลาง
คา R Ledbetter

... @ MicahRLedbetter ซึ่งเป็นเหตุผลที่ฉันแนะนำว่า "การเปรียบเทียบเพิ่มเติมจากคอมพิวเตอร์และเครือข่ายต่าง ๆ มักจะเพิ่มความสามารถในการเชื่อถือการเชื่อมต่อของคุณ" แต่นั่นคือประเด็นของฉัน หากคุณเคยตรวจสอบโฮสต์เป้าหมายของคุณจากสภาพแวดล้อมชุดเดียวคุณจะทราบถึงความแตกต่างได้อย่างไร? คุณมีคำแนะนำที่ดีกว่านี้ไหม?
BradChesney79

1
นี่คือโรงละครรักษาความปลอดภัย ทำสิ่งที่ซับซ้อนเพื่อสร้างรูปลักษณ์ที่ปลอดภัยยิ่งขึ้น ไม่สำคัญว่าคุณใช้วิธีการต่าง ๆ มากมายในการถามโฮสต์สำหรับคีย์ของมัน เช่นเดียวกับการถามบุคคลคนเดียวกันหลาย ๆ ครั้งถ้าคุณสามารถเชื่อใจพวกเขา (คุณอาจจะโทรหาอีเมลข้อความและหอยทาก) พวกเขาจะพูดเสมอว่าใช่ แต่ถ้าคุณถามคนผิดมันไม่สำคัญ
vastlysuperiorman

5

ฉันทำสคริปต์แบบหนึ่งบรรทัดยาวไปหน่อย แต่มีประโยชน์ในการทำภารกิจนี้ให้กับโฮสต์ที่มี IP หลายรายการโดยใช้digและbash

(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

5

รายการต่อไปนี้หลีกเลี่ยงรายการที่ซ้ำกันใน ~ / .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

1
นี่ไม่ใช่วิธีที่จะทำ MITM
jameshfisher

ฉันชอบคำตอบนี้ดีที่สุด สำหรับการตั้งค่าสคริปต์เริ่มต้นของ VPS แบบสุ่มที่ไม่มีความสำคัญกับใครนอกจากฉันความเสี่ยงของ MITM นั้นเล็กมาก เล่นลิ้นน้อย ... บรรทัดแรกจะต้องเป็นmkdir -p ~/.ssh/known_hosts;
มาร์ติน Bramwell

5

คุณสร้างเครื่องจักรเหล่านี้ได้อย่างไร คุณสามารถเรียกใช้สคริปต์การอัพเดท DNS ได้หรือไม่? คุณสามารถเข้าร่วมโดเมน IPA ได้หรือไม่

FreeIPA ทำสิ่งนี้โดยอัตโนมัติ แต่สิ่งที่คุณต้องมีคือSSHFP dns records และDNSSECในโซนของคุณ (freeipa มีตัวเลือกที่สามารถกำหนดค่าได้

คุณสามารถรับระเบียน SSHFP ที่มีอยู่จากโฮสต์ของคุณโดยการเรียกใช้

ssh-keygen -r jersey.jacobdevans.com

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

จากนั้นเมื่อเผยแพร่แล้วคุณจะเพิ่มVerifyHostKeyDNS yesssh_config หรือ ~ / .ssh / config ของคุณ

หาก / เมื่อ google ตัดสินใจที่จะพลิก DNSSEC คุณสามารถ ssh โดยไม่ต้องแจ้งให้ hostkey

ssh jersey.jacobdevans.com

แต่โดเมนของฉันยังไม่ได้ลงชื่อดังนั้นตอนนี้คุณจะเห็น ....

debug1: รหัสโฮสต์เซิร์ฟเวอร์: ecdsa-sha2-nistp256 SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s

debug1: พบลายนิ้วมือที่ไม่ปลอดภัย 4 ตัวใน DNS

debug1: จับคู่คีย์โฮสต์

พบใน DNS ความถูกต้องของโฮสต์ 'jersey.jacobdevans.com (2605: 6400: 10: 434 :: 10)' ไม่สามารถสร้างได้ ลายนิ้วมือที่สำคัญของ ECDSA คือ SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s พบลายนิ้วมือกุญแจโฮสต์ที่ตรงกันใน DNS คุณแน่ใจหรือไม่ว่าต้องการเชื่อมต่อ (ใช่ / ไม่ใช่) ไม่


4

ในการทำสิ่งนี้อย่างถูกต้องสิ่งที่คุณต้องการทำจริงๆคือการรวบรวมกุญแจสาธารณะของโฮสต์ของ VM ในขณะที่คุณสร้างมันและวางมันลงในไฟล์ในknown_hostsรูปแบบ จากนั้นคุณสามารถใช้-o GlobalKnownHostsFile=..., ชี้ไปที่ไฟล์นั้นเพื่อให้แน่ใจว่าคุณกำลังเชื่อมต่อกับโฮสต์ที่คุณเชื่อว่าคุณควรจะเชื่อมต่อ วิธีการทำเช่นนี้ขึ้นอยู่กับวิธีการตั้งค่าเครื่องเสมือน แต่อ่านจากระบบไฟล์เสมือนถ้าเป็นไปได้หรือแม้กระทั่งการให้โฮสต์พิมพ์เนื้อหา/etc/ssh/ssh_host_rsa_key.pubในระหว่างการกำหนดค่าอาจทำเคล็ดลับได้

ที่กล่าวมานี้อาจไม่คุ้มค่าขึ้นอยู่กับสภาพแวดล้อมที่คุณกำลังทำงานและศัตรูของคุณคือใคร การทำ "ร้านค้าบนการเชื่อมต่อครั้งแรก" (ผ่านการสแกนหรือเพียงแค่ระหว่างการเชื่อมต่อครั้งแรก "จริง") ตามที่อธิบายไว้ในคำตอบอื่น ๆ อีกหลายข้อด้านบนอาจง่ายกว่ามากและยังคงให้ความปลอดภัยจำนวนเล็กน้อย อย่างไรก็ตามหากคุณทำเช่นนี้ฉันขอแนะนำให้คุณเปลี่ยนไฟล์โฮสต์ที่ผู้ใช้รู้จัก ( -o UserKnownHostsFile=...) เป็นไฟล์เฉพาะสำหรับการติดตั้งทดสอบนี้ วิธีนี้จะหลีกเลี่ยงการทำให้ไฟล์โฮสต์ที่รู้จักส่วนบุคคลของคุณสกปรกด้วยข้อมูลทดสอบและทำให้ง่ายต่อการล้างค่าคีย์สาธารณะที่ไม่มีประโยชน์ในขณะนี้เมื่อคุณลบ VM ของคุณ


4

ทั้งหมดนี้

  • SSH คีย์สแกน
  • SSH คัดลอกรหัส
  • คำเตือนคีย์ ECSDA

ธุรกิจยังคงน่ารำคาญฉันดังนั้นฉันเลือกใช้

หนึ่งสคริปต์ที่จะปกครองพวกเขาทั้งหมด

นี่คือตัวแปรของสคริปต์ที่https://askubuntu.com/a/949731/129227ด้วยคำตอบของ Amadu Bah https://serverfault.com/a/858957/162693ในวง

ตัวอย่างการโทร

./sshcheck somedomain site1 ไซต์ 2 ไซต์ 3

สคริปต์จะวนซ้ำตามชื่อไซต์และแก้ไขไฟล์. ssh / config และ. ssh / known_hosts และทำ ssh-copy-id ตามคำขอ - สำหรับคุณสมบัติสุดท้ายเพียงแค่ให้การทดสอบ ssh ล้มเหลวเช่นโดยกดปุ่ม 3 ครั้ง คำขอรหัสผ่าน

สคริปต์ 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

2

นี่คือวิธีการทำชุดของโฮสต์

กำหนดชุดของโฮสต์

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

จากนั้นกำหนดภารกิจสองอย่างเพื่อเพิ่มคีย์ไปยังโฮสต์ที่รู้จัก:

- 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}}"

0

ดีที่สุดที่คุณจะตรวจสอบลายนิ้วมือของเซิร์ฟเวอร์ / โฮสต์ใหม่แต่ละเครื่อง นี่เป็นวิธีเดียวในการตรวจสอบสิทธิ์เซิร์ฟเวอร์ ก็ไม่มีการเชื่อมต่อ SSH ของคุณอาจเป็นเรื่องที่มนุษย์ในกลางโจมตี

หากคุณแน่ใจจริงๆว่าคุณไม่ต้องการตรวจสอบลายนิ้วมือตัวเลือกที่ดีที่สุดและปลอดภัยน้อยอันดับสองคือการใช้StrictHostKeyChecking=accept-newซึ่งเปิดตัวในOpenSSH เวอร์ชั่น 7.6 (2017-10-03) :

"ยอมรับใหม่" ครั้งแรกจะรับคีย์ที่ไม่สามารถมองเห็นได้ก่อนหน้านี้โดยอัตโนมัติ แต่จะปฏิเสธการเชื่อมต่อสำหรับโฮสต์ที่ถูกเปลี่ยนหรือไม่ถูกต้อง

อย่าใช้ค่าเก่าStrictHostKeyChecking=noที่ไม่เคยตรวจสอบความถูกต้องของเซิร์ฟเวอร์เลย (แม้ว่าความหมายของ=noการตั้งค่านี้จะพลิกบางรุ่นในภายหลัง )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.