Làm cách nào tôi có thể truyền khóa pub pub SSH của mình vào danh sách các máy chủ mà không phải nhập mật khẩu nhiều lần?


26

Gần đây tôi đã được cấp quyền truy cập tên người dùng / mật khẩu vào danh sách các máy chủ và muốn tuyên truyền khóa công khai SSH của mình đến các máy chủ này để tôi có thể đăng nhập dễ dàng hơn.

Vì vậy, nó rõ ràng:

  • Không có bất kỳ khóa công khai nào có sẵn trên các máy chủ từ xa mà tôi có thể sử dụng để tự động hóa việc này
  • Điều này tạo thành lần đầu tiên tôi đăng nhập vào các máy chủ này và tôi không muốn phải liên tục nhập thông tin đăng nhập của mình để truy cập chúng
  • Tôi cũng không muốn nhập lại mật khẩu của mình bằng cách sử dụng ssh-copy-idvòng lặp for.

1
Đó là cùng tên người dùng và mật khẩu cho tất cả các máy chủ?
roaima

@roaima - yup! Chi tiết đó cũng làm tôi ngạc nhiên, nhưng đó là cách thiết lập trung tâm dữ liệu cụ thể này và đó là cách họ thực hiện.
slm

@ ott-- - kiểm tra kỹ Q. Tôi nói rõ rằng tôi không muốn thực hiện vòng lặp for ssh-copy-id, bơm mật khẩu nhiều lần.
slm


2
Đây là một trường hợp sử dụng hoàn hảo để quản lý cấu hình. Nhìn vào con rối, đầu bếp, ansible hoặc muối.
spuder

Câu trả lời:


31

Thay vì nhập mật khẩu của bạn nhiều lần, bạn có thể sử dụng pssh-Achuyển đổi mật khẩu để nhắc nhập một lần, sau đó cung cấp mật khẩu cho tất cả các máy chủ trong danh sách.

LƯU Ý:ssh-copy-id Tuy nhiên, sử dụng phương pháp này không cho phép bạn sử dụng , do đó, bạn sẽ cần cuộn phương thức của riêng mình để nối thêm tệp khóa pub pub vào tệp tài khoản từ xa ~/.ssh/authorized_keys.

Thí dụ

Đây là một ví dụ thực hiện công việc:

$ 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

Kịch bản trên thường có cấu trúc như vậy:

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

psshChi tiết cấp cao

  • cat <pubkey> xuất tệp khóa công khai sang pssh
  • psshsử dụng -Ichuyển đổi để nhập dữ liệu qua STDIN
  • -l <remote user> là tài khoản của máy chủ từ xa (chúng tôi giả sử bạn có cùng tên người dùng trên các máy chủ trong tệp IP)
  • -Anói psshđể yêu cầu mật khẩu của bạn và sau đó tái sử dụng nó cho tất cả các máy chủ mà nó kết nối tới
  • -iyêu psshcầu gửi bất kỳ đầu ra nào đến STDOUT thay vì lưu trữ nó trong các tệp (hành vi mặc định của nó)
  • '...cmds to add pubkey...'- đây là phần khó nhất trong những gì đang diễn ra, vì vậy tôi sẽ tự mình giải quyết vấn đề này (xem bên dưới)

Các lệnh đang được chạy trên các máy chủ từ xa

Đây là các lệnh psshsẽ chạy trên mỗi máy chủ:

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
Theo thứ tự:
  • đặt ô của người dùng từ xa thành 077, điều này là để bất kỳ thư mục hoặc tệp nào chúng tôi sẽ tạo, sẽ có quyền của họ được đặt tương ứng như vậy:

    $ 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
    
  • tạo thư mục ~/.sshvà bỏ qua cảnh báo chúng tôi nếu nó đã ở đó

  • đặt một biến, $afilevới đường dẫn đến tệp ủy quyền
  • cat - >> $afile - lấy đầu vào từ STDIN và nối vào tệp ủy quyền
  • sort -u $afile -o $afile - sắp xếp duy nhất tệp ủy quyền_key và lưu nó

LƯU Ý: Bit cuối cùng đó là để xử lý trường hợp bạn chạy nhiều lần trên các máy chủ tương tự. Điều này sẽ loại bỏ pubkey của bạn khỏi bị nối thêm nhiều lần.

Chú ý các dấu hiệu đơn!

Cũng đặc biệt chú ý đến thực tế là tất cả các lệnh này được lồng bên trong các dấu ngoặc đơn. Điều đó rất quan trọng, vì chúng tôi không muốn $afileđược đánh giá cho đến khi nó thực thi trên máy chủ từ xa.

'               \
   ..cmds...    \
'

Tôi đã mở rộng ở trên để dễ đọc hơn ở đây, nhưng tôi thường chạy tất cả trên một dòng như vậy:

$ 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'

Tài liệu khen thưởng

Bằng cách sử dụng, psshbạn có thể từ bỏ việc xây dựng các tệp và cung cấp nội dung động bằng cách sử dụng -h <(...some command...)hoặc bạn có thể tạo danh sách IP bằng psshcác công tắc khác , -H "ip1 ip2 ip3".

Ví dụ:

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

Ở trên có thể được sử dụng để trích xuất một danh sách IP từ ~/.ssh/configtệp của tôi . Tất nhiên bạn cũng có thể sử dụng printfđể tạo nội dung động:

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

Ví dụ:

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

Bạn cũng có thể sử dụng seqđể tạo các chuỗi số được định dạng quá!

Tài liệu tham khảo & công cụ tương tự pssh

Nếu bạn không muốn sử dụng psshnhư tôi đã làm ở trên, có một số tùy chọn khác có sẵn.


2
Ba bổ sung nhỏ: (1) psshlà tập lệnh Python và có thể được cài đặt bằng pip install pssh. (2) Bạn cũng có thể tạo sshkhóa trên tất cả các máy chủ đồng thời bằng cách chạy ssh-keygenqua pssh. (3) Sau khi tạo các khóa, bạn có thể phân phối các khóa "tất cả cho tất cả" bằng cách sao chép tất cả các khóa chung trong một vòng lặp vào máy cục bộ, lắp ráp chúng chung authorized_keysvà sao chép chúng vào từng máy. ssh_agent/ ssh_addcó thể giúp với mật khẩu.
lcd047

@ lcd047 - cảm ơn, tôi sẽ kết hợp những thứ đó vào A sau hôm nay!
slm

1
Tôi nghĩ rằng kịch bản này đủ điều kiện cho việc sử dụng catgiải thưởng vô dụng (cũ): để bắt đầu một đường ống dẫn với nội dung của một tệp, bạn chỉ có thể chuyển hướng đầu vào từ tệp đó.
Marc van Leeuwen

1
@MarcvanLeeuwen - Tôi có xu hướng đồng ý, nhưng tôi muốn mọi người có thể bắt gặp điều này thông qua các tìm kiếm trong tương lai để hiểu rõ hơn về cách thức hoạt động của pubkey pssh.
slm

1
@MarcvanLeeuwen: Sẽ không còn vô dụng nếu bạn làm như thế này : cat ~/.ssh/*.pub | .... Nó có thể hoặc không thể là những gì bạn muốn trong tình huống này mặc dù.
lcd047

7

Thay thế sử dụng xargs, sshpassssh-copy-id:

Giả sử thông tin đăng nhập của bạn sống ở certs.txt ở định dạng user:password@server:

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

Bạn có thể làm:

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

Lưu ý: Hãy nhớ xóa thông tin xác thực sau khi sử dụng!


2
Và nếu đó là cùng tên người dùng và mật khẩu cho tất cả các máy chủ, bạn chỉ có thể mã hóa trực tiếp và chỉ đọc danh sách Địa chỉ IP :-)
Falco

6

ClusterSSH cung cấp cho bạn một cửa sổ trên mỗi máy và với một cửa sổ chung để điều khiển tất cả các cửa sổ.

Nếu chúng ta đang nói 10 máy thì nó sẽ hoạt động. Nếu chúng ta đang nói 100 máy, sẽ có nhiều cửa sổ.

Cái hay của ClusterSSH là nếu một máy không giống 100% so với phần còn lại, bạn chỉ cần nhấp vào cửa sổ và chỉ gửi tổ hợp phím đến máy đó trước khi quay lại gửi tổ hợp phím cho tất cả các máy.


6

Sử dụng Ansible khá đơn giản. Chỉ cần thay thế <USER>bằng tên đăng nhập thực sự

$ 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

Một vài điều có khả năng phù hợp với dự luật:

Như đã đề cập trong các câu trả lời khác, sshpasscó khả năng là giải pháp dễ nhất.


-1

Bạn có hai lựa chọn ở đây:

  • Bạn có thể tạo một tệp với tất cả các địa chỉ IP của máy chủ, sau đó thực hiện như bên dưới

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

Giả sử servers.txtlà tệp có IP / tên máy chủ.

  • Bạn có thể đặt tất cả IP / tên máy chủ của mình vào một vòng lặp và chạy ssh-copy-idnhư bên dưới:

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

Điều này hoàn toàn đi ngược lại các yêu cầu của OP: "Tôi cũng không muốn nhập mật khẩu của mình nhiều lần bằng cách sử dụng ssh-copy-idtrong một vòng lặp for."
OldTimer

Tôi không nghĩ có một cách khác, trừ khi OP sẵn sàng sao chép vật lý vào tất cả các máy chủ.
Tolga Ozkes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.