Як я можу розповсюдити свій паб-ключ SSH до списку серверів, не вводячи свій пароль знову і знову?


26

Нещодавно мені було надано ім'я користувача / пароль до списку серверів і хочу розповсюдити свій відкритий ключ SSH на цих серверах, щоб я міг легше входити в систему.

Щоб було зрозуміло:

  • На віддалених серверах не існує жодного відкритого відкритого ключа, який би я міг використовувати для автоматизації цього
  • Це є найпершим випадком, коли я входжу на ці сервери, і мені хочеться не постійно вводити свої облікові дані для доступу до них
  • Також я не хочу вводити свій пароль знову і знову, використовуючи ssh-copy-idцикл for.

1
Це однакове ім'я користувача та пароль для всіх серверів?
roaima

@roaima - так! Ця деталь мене також здивувала, але саме таким є налаштування центру обробки даних, і саме так вони роблять.
slm

@ ott-- - двічі перевірте Q. Я чітко заявляю, що не хочу робити цикл ssh-copy-id, перекачуючи свій пароль знову і знову.
slm


2
Це ідеальний випадок використання для управління конфігурацією. Подивіться на лялечку, шеф-кухаря, анси або солі.
спудер

Відповіді:


31

Замість того, щоб вводити свій пароль кілька разів, ви можете скористатися psshі його -Aперемикачем, щоб запросити його один раз, а потім подати пароль на всі сервери в списку.

ПРИМІТКА: Використання цього методу не дозволяє використовувати ssh-copy-id, однак, вам потрібно буде прокрутити свій власний метод для додавання файлу ключа SSH pub до файлу віддаленого облікового запису ~/.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із шляхом до файлу санкціонованих_ ключів
  • cat - >> $afile - взяти вхід зі STDIN та додати до файла дозволених ключів
  • sort -u $afile -o $afile - унікально сортує файл санкціонованого_кейса та зберігає його

ПРИМІТКА. Останнім бітом є обробка випадку, коли ви запускаєте вищезазначені кілька разів на одних і тих же серверах. Це дозволить уникнути додавання вашого віскі кілька разів.

Помітьте одиночні кліщі!

Також зверніть особливу увагу на те, що всі ці команди вкладені всередині одиничних лапок. Це важливо, оскільки ми не хочемо $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перемикачів «s, -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) Після генерації ключів ви можете розповсюдити ключі "все-до-всіх", скопіювавши всі відкриті ключі в циклі на локальну машину, зібравши їх у загальний authorized_keysі скопіювавши їх на кожну машину. ssh_agent/ ssh_addможе допомогти з паролями.
lcd047

@ lcd047 - спасибі, я включу їх у A пізніше сьогодні!
slm

1
Я думаю, що цей скрипт відповідає марному використанню catнагород (старого): щоб почати конвеєр із вмістом файлу, ви можете просто перенаправити вхід із цього файлу.
Марк ван Левен

1
@MarcvanLeeuwen - Я схильний би погодитися, але хотів, щоб тим, хто може зіткнутися з цим за допомогою майбутніх пошуків, було легше, щоб чітко зрозуміти, як проходить пабкі pssh.
slm

1
Чи не @MarcvanLeeuwen: Це вже не марно , якщо ви робите це так: cat ~/.ssh/*.pub | .... Це може бути, а може і не бути тим, що ви хочете в цій ситуації.
lcd047

7

Альтернатива використання xargs, sshpassі ssh-copy-id:

Припустимо, що ваші облікові дані проживають у форматі vjerodajnica.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
І якщо це одне і те ж ім’я користувача та пароль для всіх серверів, ви можете просто жорстко кодувати його безпосередньо та лише читати список IP-адрес :-)
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

Кілька речей, які потенційно можуть відповідати рахунку:

Як було сказано в інших відповідях, 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

Що повністю суперечить вимогам ОП: "Я також не хочу вводити свій пароль знову і знову, використовуючи ssh-copy-idцикл for".
OldTimer

Я не думаю, що існує інший спосіб, якщо ОП не бажає фізично скопіювати всі сервери.
Тольга Озсес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.