ฉันจะเผยแพร่คีย์ SSH ของฉันไปยังรายการเซิร์ฟเวอร์ได้อย่างไรโดยไม่ต้องพิมพ์รหัสผ่านซ้ำแล้วซ้ำอีก?


26

เมื่อเร็ว ๆ นี้ฉันได้รับชื่อผู้ใช้ / รหัสผ่านเพื่อเข้าถึงรายการเซิร์ฟเวอร์และต้องการเผยแพร่รหัสสาธารณะ SSH ของฉันไปยังเซิร์ฟเวอร์เหล่านี้เพื่อให้ฉันสามารถเข้าสู่ระบบได้ง่ายขึ้น

เพื่อให้ชัดเจน:

  • ไม่มีคีย์สาธารณะที่มีอยู่แล้วบนเซิร์ฟเวอร์ระยะไกลที่ฉันสามารถใช้เพื่อทำสิ่งนี้โดยอัตโนมัติ
  • นี่ถือเป็นครั้งแรกที่ฉันเข้าสู่เซิร์ฟเวอร์เหล่านี้และฉันไม่ต้องการพิมพ์ข้อมูลประจำตัวของฉันในการเข้าถึงพวกเขา
  • ฉันไม่ต้องการพิมพ์รหัสผ่านของฉันซ้ำแล้วซ้ำอีกโดยใช้ssh-copy-idใน for for loop

1
เป็นชื่อผู้ใช้และรหัสผ่านเดียวกันสำหรับเซิร์ฟเวอร์ทั้งหมดหรือไม่
roaima

@roaima - yup! รายละเอียดนั้นทำให้ฉันประหลาดใจเช่นกัน แต่นั่นเป็นวิธีการตั้งค่าศูนย์ข้อมูลเฉพาะนี้และนั่นคือวิธีที่พวกเขาทำ
slm

@ ott-- - ตรวจสอบอีกครั้ง Q. ฉันระบุอย่างชัดเจนว่าฉันไม่ต้องการวนซ้ำผ่านssh-copy-idปั๊มรหัสผ่านของฉันซ้ำไปซ้ำมา
slm


2
นี่เป็นกรณีการใช้งานที่สมบูรณ์แบบสำหรับการจัดการการกำหนดค่า ดูหุ่นเชิดพ่อครัวสัตว์น้ำเค็มหรือเกลือ
spuder

คำตอบ:


31

แทนที่จะพิมพ์รหัสผ่านของคุณหลายครั้งคุณสามารถใช้psshและ-Aสวิตช์เพื่อแจ้งรหัสผ่านครั้งเดียวแล้วป้อนรหัสผ่านไปยังเซิร์ฟเวอร์ทั้งหมดในรายการ

หมายเหตุ:ใช้วิธีนี้ไม่ได้ช่วยให้คุณใช้ssh-copy-idแต่เพื่อให้คุณจะต้องม้วนวิธีการของคุณเองสำหรับการผนวก SSH ไฟล์คีย์ผับของคุณกับบัญชีระยะไกลของ~/.ssh/authorized_keysไฟล์

ตัวอย่าง

นี่คือตัวอย่างที่ทำงาน:

$ cat ~/.ssh/my_id_rsa.pub                    \
    | pssh -h ips.txt -l remoteuser -A -I -i  \
    '                                         \
      umask 077;                              \
      mkdir -p ~/.ssh;                        \
      afile=~/.ssh/authorized_keys;           \
      cat - >> $afile;                        \
      sort -u $afile -o $afile                \
    '
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 23:03:58 [SUCCESS] 10.252.1.1
[2] 23:03:58 [SUCCESS] 10.252.1.2
[3] 23:03:58 [SUCCESS] 10.252.1.3
[4] 23:03:58 [SUCCESS] 10.252.1.10
[5] 23:03:58 [SUCCESS] 10.252.1.5
[6] 23:03:58 [SUCCESS] 10.252.1.6
[7] 23:03:58 [SUCCESS] 10.252.1.9
[8] 23:03:59 [SUCCESS] 10.252.1.8
[9] 23:03:59 [SUCCESS] 10.252.1.7

สคริปต์ข้างต้นมีโครงสร้างโดยทั่วไปเช่น:

$ cat <pubkey> | pssh -h <ip file> -l <remote user> -A -I -i '...cmds to add pubkey...'

psshรายละเอียดระดับสูง

  • cat <pubkey> เอาต์พุตไฟล์พับลิกคีย์ไปที่ pssh
  • psshใช้-Iสวิตช์เพื่อนำเข้าข้อมูลผ่าน STDIN
  • -l <remote user> คือบัญชีของเซิร์ฟเวอร์ระยะไกล (เราสมมติว่าคุณมีชื่อผู้ใช้เดียวกันทั่วเซิร์ฟเวอร์ในไฟล์ IP)
  • -Aบอกpsshให้ถามรหัสผ่านของคุณแล้วนำมาใช้ซ้ำสำหรับเซิร์ฟเวอร์ทั้งหมดที่เชื่อมต่อ
  • -iบอกpsshให้ส่งเอาต์พุตใด ๆ ไปยัง STDOUT แทนที่จะเก็บไว้ในไฟล์ (พฤติกรรมเริ่มต้น)
  • '...cmds to add pubkey...'- นี่คือส่วนที่ยากที่สุดของสิ่งที่เกิดขึ้นดังนั้นฉันจะทำลายมันด้วยตัวเอง(ดูด้านล่าง)

คำสั่งถูกเรียกใช้บนเซิร์ฟเวอร์ระยะไกล

นี่คือคำสั่งที่psshจะทำงานบนเซิร์ฟเวอร์แต่ละเครื่อง:

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
ในการสั่งซื้อ:
  • ตั้งค่า umask ของผู้ใช้ระยะไกลเป็น 077 นี่คือเพื่อให้ไดเรกทอรีหรือไฟล์ใด ๆ ที่เรากำลังจะสร้างจะมีการตั้งค่าการอนุญาตตามที่ต้องการ:

    $ ls -ld ~/.ssh ~/.ssh/authorized_keys
    drwx------ 2 remoteuser remoteuser 4096 May 21 22:58 /home/remoteuser/.ssh
    -rw------- 1 remoteuser remoteuser  771 May 21 23:03 /home/remoteuser/.ssh/authorized_keys
    
  • สร้างไดเรกทอรี~/.sshและไม่สนใจเตือนเราหากมีอยู่แล้ว

  • ตั้งค่าตัวแปรโดย$afileมีพา ธ ไปยังไฟล์ authorized_keys
  • cat - >> $afile - รับอินพุตจาก STDIN และผนวกเข้ากับไฟล์ authorized_keys
  • sort -u $afile -o $afile - จัดเรียงไฟล์ที่ได้รับอนุญาตไม่ซ้ำกันและบันทึกไว้

หมายเหตุ:บิตสุดท้ายนั้นคือการจัดการเคสที่คุณรันหลาย ๆ ครั้งด้านบนเทียบกับเซิร์ฟเวอร์เดียวกัน วิธีนี้จะกำจัด pubkey ของคุณไม่ให้ต่อท้ายหลาย ๆ ครั้ง

สังเกตุเห็บเดียว!

ยังให้ความสนใจเป็นพิเศษกับความจริงที่ว่าคำสั่งเหล่านี้ทั้งหมดจะซ้อนอยู่ในเครื่องหมายคำพูดเดี่ยว นั่นเป็นสิ่งสำคัญเนื่องจากเราไม่ต้องการ$afileรับการประเมินจนกว่าจะดำเนินการบนเซิร์ฟเวอร์ระยะไกล

'               \
   ..cmds...    \
'

ฉันได้ขยายด้านบนเพื่อให้ง่ายต่อการอ่านที่นี่ แต่โดยทั่วไปฉันจะเรียกใช้ทั้งหมดในบรรทัดเดียวเช่น:

$ cat ~/.ssh/my_id_rsa.pub | pssh -h ips.txt -l remoteuser -A -I -i 'umask 077; mkdir -p ~/.ssh; afile=~/.ssh/authorized_keys; cat - >> $afile; sort -u $afile -o $afile'

วัสดุโบนัส

เมื่อใช้psshคุณสามารถสร้างไฟล์และให้เนื้อหาแบบไดนามิกโดยใช้-h <(...some command...)หรือคุณสามารถสร้างรายการ IP โดยใช้psshสวิตช์-H "ip1 ip2 ip3"อื่น

ตัวอย่างเช่น:

$ cat .... | pssh -h <(grep -A1 dp15 ~/.ssh/config | grep -vE -- '#|--') ...

ด้านบนสามารถใช้เพื่อแยกรายการ IP จาก~/.ssh/configไฟล์ของฉัน แน่นอนคุณสามารถใช้printfเพื่อสร้างเนื้อหาแบบไดนามิกเช่นกัน:

$ cat .... | pssh -h <(printf "%s\n" srv0{0..9}) ....

ตัวอย่างเช่น:

$ printf "%s\n" srv0{0..9}
srv00
srv01
srv02
srv03
srv04
srv05
srv06
srv07
srv08
srv09

คุณยังสามารถใช้seqเพื่อสร้างลำดับตัวเลขที่จัดรูปแบบด้วย!

การอ้างอิงและเครื่องมือที่คล้ายกัน pssh

หากคุณไม่ต้องการใช้psshเพราะฉันได้ทำไปแล้วมีตัวเลือกอื่นให้เลือก


2
การเพิ่มเติมเล็กน้อยสามรายการ: (1) psshเป็นสคริปต์ Python และสามารถติดตั้งpip install psshได้ (2) นอกจากนี้คุณยังสามารถสร้างsshปุ่มบนเซิร์ฟเวอร์ทั้งหมดพร้อมกันโดยการทำงานผ่านssh-keygen pssh(3) หลังจากสร้างคีย์คุณสามารถแจกจ่ายคีย์ "all-to-all" โดยการคัดลอกกุญแจสาธารณะทั้งหมดในลูปไปยังเครื่องโลคอลรวมกันเป็นคีย์ทั่วไปauthorized_keysและคัดลอกไปยังเครื่องแต่ละเครื่อง ssh_agent/ ssh_addสามารถช่วยด้วยรหัสผ่าน
lcd047

@ lcd047 - ขอบคุณฉัน "จะรวมสิ่งเหล่านี้เข้ากับ A ภายหลังวันนี้!
slm

1
ฉันคิดว่าสคริปต์นี้มีคุณสมบัติเหมาะสมสำหรับการใช้catรางวัล (เก่า) ที่ไม่มีประโยชน์: เพื่อเริ่มต้นไพพ์ไลน์ด้วยเนื้อหาของไฟล์คุณสามารถเปลี่ยนเส้นทางอินพุตจากไฟล์นั้น
Marc van Leeuwen

1
@MarcvanLeeuwen - ฉันมักจะเห็นด้วย แต่ฉันต้องการให้มันง่ายขึ้นสำหรับทุกคนที่อาจเจอสิ่งนี้ผ่านการค้นหาในอนาคตเพื่อทำความเข้าใจอย่างชัดเจนว่า pubkey นั้นถูกส่งผ่านไปยังpsshอย่างไร
slm

1
@MarcvanLeeuwen: cat ~/.ssh/*.pub | ...มันไม่ได้ไร้ประโยชน์ถ้าคุณทำเช่นนี้ อาจหรือไม่เป็นสิ่งที่คุณต้องการในสถานการณ์เช่นนี้ว่า
lcd047

7

ทางเลือกใช้xargs, sshpassและssh-copy-id:

สมมติว่าข้อมูลรับรองของคุณอยู่ในหนังสือรับรอง. txtในรูปแบบ user:password@server:

$ cat credentials.txt
root:insecure@192.168.0.1
foo:insecure@192.168.0.2
bar:realsecure@192.168.0.3

คุณสามารถทำได้:

tr ':@' '\n' < credentials.txt \
| xargs -L3 sh -c 'sshpass -p $1 ssh-copy-id $0@$2'

หมายเหตุ: อย่าลืมลบหนังสือรับรอง txtหลังการใช้งาน!


2
และถ้าเป็นชื่อผู้ใช้และรหัสผ่านเดียวกันสำหรับเซิร์ฟเวอร์ทั้งหมดคุณสามารถ hardcode ได้โดยตรงและอ่านรายชื่อ IP-Adresses :-) เท่านั้น
Falco

6

ClusterSSH ให้หน้าต่างในแต่ละเครื่องและมีหน้าต่างทั่วไปเพื่อควบคุมหน้าต่างทั้งหมด

หากเรากำลังพูดถึง 10 เครื่องสิ่งนี้จะใช้งานได้ ถ้าเราพูดถึง 100 เครื่องจะมีหลายหน้าต่าง

ความสวยงามของ ClusterSSH คือหากเครื่องหนึ่งไม่เหมือน 100% ที่เหลือคุณสามารถคลิกที่หน้าต่างและส่งการกดแป้นไปที่เครื่องก่อนที่คุณจะกลับไปส่งการกดแป้นพิมพ์ไปยังเครื่องทั้งหมด


6

การใช้Ansibleนั้นค่อนข้างง่าย เพียงแทนที่<USER>ด้วยชื่อเข้าสู่ระบบจริง

$ cd /path/to/public/key

$ cat<<END > hosts
  host1.example.com
  10.10.10.10
  END

$ ansible -i hosts all --ask-pass -u <USER> -m authorized_key \
      -a "user=<USER> key='$(cat id_rsa.pub)'"        

0

สองสิ่งที่อาจเหมาะสมกับใบเสร็จ:

  • หน้าที่คำถามเดียวกันยังถามที่ ServerFault: อัตโนมัติ SSH
  • มีโมดูล Perl แต่ก็ดูเหมือนจะไม่ได้รับการรักษามาก: https://github.com/Ruyk/pssh-copy-id

ดังกล่าวในคำตอบอื่น ๆsshpassน่าจะเป็นทางออกที่ง่ายที่สุด


-1

คุณมีสองตัวเลือกที่นี่:

  • คุณสามารถสร้างไฟล์ที่มีที่อยู่ IP ของเซิร์ฟเวอร์ทั้งหมดจากนั้นทำด้านล่าง

    while read -r ip;do
      ssh-copy-id -i .ssh/id_rsa.pub $ip
    done < servers.txt
    

สมมติว่าservers.txtเป็นไฟล์ที่มี IP / ชื่อโฮสต์

  • คุณสามารถใส่ IP / ชื่อโฮสต์ทั้งหมดของคุณในการวนซ้ำและเรียกใช้ssh-copy-idดังนี้:

    for i in hostname1 hostname2
      do ssh-copy-id -i .ssh/id_rsa.pub $i
    done
    

ซึ่งขัดกับข้อกำหนดของ OP: "ฉันไม่ต้องการพิมพ์รหัสผ่านซ้ำไปssh-copy-idซ้ำมา"
OldTimer

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