স্বয়ংক্রিয়ভাবে ssh-copy-id


30

আমার একই ব্যবহারকারী / পাস সংমিশ্রণ সহ কিছু সংখ্যক সার্ভার রয়েছে। আমি একটি স্ক্রিপ্ট লিখতে চাই (যা আমি একবার কল করি) যাতে

ssh-copy-id user@myserver

প্রতিটি সার্ভারের জন্য বলা হয়। যেহেতু তাদের সকলেরই একই ব্যবহারকারী / পাস রয়েছে তবে এটি সহজ হওয়া উচিত তবে ssh-copy-idপ্রতিবারই আমি আলাদাভাবে পাসওয়ার্ড টাইপ করতে চাই যা আমার স্ক্রিপ্টের উদ্দেশ্যকে হারাবে। পাসওয়ার্ড দেওয়ার জন্য কোনও বিকল্প নেই, অর্থাত্‍ ssh-copy-id -p mypassword user@myserver

আমি কীভাবে এমন কোনও স্ক্রিপ্ট লিখতে পারি যা পাসওয়ার্ড ক্ষেত্রে ssh-copy-idজিজ্ঞাসা করা হয় তা স্বয়ংক্রিয়ভাবে পূরণ হয় ?


আপনি কেন ব্যবহারকারী / পাবলিককি সনাক্তকরণের পরিবর্তে ব্যবহারকারীর / পাস পরিচয় ব্যবহার করবেন?
কাগলি-সান

16
কারণ আমি ব্যবহারকারী / পাবলিককি সেট আপ করতে এই স্ক্রিপ্টটি ব্যবহার করছি।
ডিভাইন

উত্তর:


28

Sshpassএকবার দেখুন । আপনার পাসওয়ার্ড একটি পাঠ্য ফাইলে রাখুন এবং এর মতো কিছু করুন:

$ sshpass -f password.txt ssh-copy-id user@yourserver

এটি Centos7 এ কাজ করছে না কেবল ত্রুটি ছাড়াই চালানো হয় এবং রিমোট সার্ভারে কোনও কী নেই
ইমরানরাজাখান

19

আপনি পাসওয়ার্ড প্রম্পট শুনতে এবং আপনার পাসওয়ার্ড প্রেরণ প্রত্যাশা ব্যবহার করতে পারেন:

#!/usr/bin/expect -f
spawn ssh-copy-id $argv
expect "password:"
send "YOUR_PASSWORD\n"
expect eof

স্ক্রিপ্টটি সংরক্ষণ করুন, সম্পাদনযোগ্য করে তুলুন এবং এটিকে কল করুন: ./login.expect user@myserver


আপনার কি ব্যাশের নতুন সংস্করণটি ব্যবহার করতে হবে spawn? কারণে আমি নিয়ন্ত্রণ করতে পারি না আমি ব্যাশ v3.2 এর সাথে আটকে আছি।
ডিভাইন

বাশ সংস্করণ কোনও বিষয় নয়। আমি প্রত্যাশা 5.44.1.15 দিয়ে পরীক্ষা করেছি, তবে আমি প্রত্যাশার পুরানো সংস্করণগুলির সাথে একই ব্যবহার করেছি। স্ক্রিপ্টটি ব্যবহার করতে আপনার কি সমস্যা হচ্ছে?
Monkeeage

spawn: command not found
Devin

spawnএকটি প্রত্যাশিত কীওয়ার্ড (প্রত্যাশা (1) ম্যানুয়াল দেখুন)। স্ক্রিপ্টের মতো শব্দগুলি প্রত্যাশার চেয়ে শেল হিসাবে ব্যাখ্যা করা হচ্ছে। আপনি কি ইনস্টল আশা করেন? আপনি যদি সরাসরি প্রত্যাশা চালান তবে কী হয়:expect -f login.expect user@myserver
MonkeeSage

1
@ এনভেক আমি কেবল এটি যুক্ত করতে যাচ্ছিলাম তবে এটি দেখতে ভাল লাগল যে শেষ মন্তব্যটি যে জিনিসটি লিখতে চলেছি তার প্রত্যক্ষ প্রশ্ন। পরিবর্তে এই লাইনটি ব্যবহার করুন:spawn ssh-copy-id -o StrictHostKeyChecking=no $argv
স্টিভেন লু

4

কোয়ান্টার উত্তরটি বেশ ভাল তবে এটি আপনাকে আপনার পাসওয়ার্ডটি একটি পাঠ্য ফাইলে রাখা দরকার।

"Sshpass" ম্যান পৃষ্ঠা থেকে:

যদি কোনও বিকল্প দেওয়া না হয়, তবে এসএসপাস স্ট্যান্ডার্ড ইনপুট থেকে পাসওয়ার্ডটি পড়ে।

সুতরাং, আপনি যা করতে পারেন তা হ'ল স্ক্রিপ্ট চলাকালীন একবার পাসওয়ার্ড ক্যাপচার করা, এটি একটি ভেরিয়েবলের মধ্যে সঞ্চয় করা, পাসওয়ার্ডটি প্রতিধ্বনিত করুন এবং পাইপটিকে এসপস হিসাবে একটি ইনপুট হিসাবে চিহ্নিত করুন।

আমি সব সময় এটি করি এবং এটি ভাল কাজ করে। উদাহরণ: echo "Please insert the password used for ssh login on remote machine:" read -r USERPASS for TARGETIP in $@; do echo "$USERPASS" | sshpass ssh-copy-id -f -i $KEYLOCATION "$USER"@"$TARGETIP" done


2

এটি ssh-copy-id নিয়ে সমস্যা; এটি প্রতিবার চালানোর সময় একটি কী যুক্ত করে। আপনি যদি প্রক্রিয়াটি স্বয়ংক্রিয়ভাবে চালিয়ে যাচ্ছেন তবে আপনার অনুমোদিত_পোকল ফাইলটি নকল কীগুলি দিয়ে খুব দ্রুত বিশৃঙ্খল হয়ে যায়। এখানে পাইথন প্রোগ্রাম রয়েছে যা উভয় সমস্যা এড়িয়ে চলে। এটি নিয়ন্ত্রণ সার্ভার থেকে চলে এবং এক দূরবর্তী সার্ভার থেকে কীগুলি অন্য দূরবর্তী সার্ভারে রাখে।

import subprocess
def Remote(cmd,IP):
    cmd = '''ssh root@%s '''%(IP)+cmd
    lines = subprocess.check_output(cmd.split())
    return '\n'.join(lines)
source = '123.456.78.90'
target = '239.234.654.123'
getkey = 'cat /root/.ssh/id_rsa.pub'
getauth = 'cat /root/.ssh/authorized_keys'
sourcekey = Remote(getkey, source).replace('\n','').strip()
authkeys = Remote(getauth, target).replace('\n','').strip()
if sourcekey not in authkeys: 
    keycmd=''' echo "%s" >>/root/.ssh/authorized_keys; 
    chmod 600 /root/.ssh/authorized_keys '''%(sourcekey) # A compound shell statement
    print 'Installed key', Remote(keycmd,target)
else: print 'Does not need key'

আমার এস-এস-কপি-আইডি এটি ইতিমধ্যে করেছে: সতর্কতা: সমস্ত কীগুলি এড়িয়ে গেছে কারণ তারা ইতিমধ্যে দূরবর্তী সিস্টেমে উপস্থিত রয়েছে। এই কি আপনার চুরি চুরি করার চেষ্টা? :)
মিহাই স্টেনিস্কু

2

বরং টাইপ চেয়ে আপনার পাসওয়ার্ড একাধিক বার আপনি ব্যবহার করতে পারেন psshএবং তার -Aএকবার এটি জন্য প্রম্পট স্যুইচ করুন, এবং তারপর একটি তালিকাতে সকল সার্ভারে পাসওয়ার্ড ভোজন।

দ্রষ্টব্য: এই পদ্ধতিটি ব্যবহার আপনাকে ব্যবহার করার অনুমতি দেয় না ssh-copy-id, সুতরাং আপনার দূরবর্তী অ্যাকাউন্টের ফাইলে আপনার এসএসএইচ পাব কী ফাইল সংযুক্ত করার জন্য আপনার নিজের পদ্ধতিটি রোল করতে ~/.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-ISTDIN এর মাধ্যমে ডেটা নিবিষ্ট করতে স্যুইচ ব্যবহার করে
  • -l <remote user> দূরবর্তী সার্ভারের অ্যাকাউন্ট (আমরা ধরে নিচ্ছি যে আইপি ফাইলের সার্ভারগুলিতে আপনার একই ব্যবহারকারীর নাম রয়েছে)
  • -Aবলে psshআপনার পাসওয়ার্ড চাইতে এবং তারপর সব সার্ভারের জন্য পুনরায় এটিকে ব্যবহার এটি সাথে সংযোগ করে থেকে
  • -ipsshকোনও আউটপুট এটি ফাইলগুলিতে সংরক্ষণের পরিবর্তে STDOUT এ প্রেরণ করতে বলে (এটির পূর্বনির্ধারিত আচরণ)
  • '...cmds to add pubkey...'- এটি যা ঘটছে তার মধ্যে সবচেয়ে জটিল অংশ, তাই আমি এটিকে নিজেই ভেঙে দেব (নীচে দেখুন)

কমান্ডগুলি দূরবর্তী সার্ভারে চলছে

এগুলি হ'ল আদেশগুলি যা psshপ্রতিটি সার্ভারে চলবে:

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
ক্রমানুসারে:
  • রিমোট ব্যবহারকারীর উমাস্ককে 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 - এসটিডিআইএন থেকে ইনপুট নিন এবং অনুমোদিত_কিগুলি ফাইলে সংযোজন করুন
  • 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...)করতে পারেন অথবা আপনি অন্যগুলির psshসুইচগুলি ব্যবহার করে আইপিগুলির একটি তালিকা তৈরি করতে পারেন -H "ip1 ip2 ip3"

উদাহরণ স্বরূপ:

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

উপরেরটি আমার ~/.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উপরে এটি কাজটি করতে না চান তবে উপরে কিছু অন্যান্য বিকল্প রয়েছে।


Ansible's authorized_key_moduleনতুন মেশিনের জন্য কাজ করে না বলে মনে হচ্ছে। আমাকে প্রথমে এসএসএইচ-কপি-আইডি এক্সএক্সএক্স করতে হবে, তাই আমি নতুন মেশিনের জন্য উত্তরসূচক অ্যাড এসএস-কী ব্যবহার করার উপায় খুঁজছি, কোনও ধারণা?
মিথিল

@ মিথ্রিল - একটি বাগের মতো শোনাচ্ছে, আমি এটি সম্পর্কিত উত্তর ফোরামে জিজ্ঞাসা করব।
slm

1

সমান্তরাল এসএসএইচ সরঞ্জামগুলির মধ্যে একটি (ক্লাস্টারশ, এমএসএসএইচ, পিএসএস) আপনার জন্য উপযুক্ত হতে পারে।

উদাহরণস্বরূপ, সমস্ত মেশিনে লগইন করতে এবং কী নিজেই সংযোজন করতে cssh ব্যবহার করুন।


1
আমার কাছে প্রয়োজনীয় সমস্ত কিছুর জন্য কাস্টম সরঞ্জামগুলির একটি সেট ইতিমধ্যে রয়েছে যা কীটি অনুলিপি করে।
ডিভাইন

হুবহু… সুতরাং যে একটি কাজ অনুপস্থিত তা করার জন্য এই একটি সরঞ্জামটি ব্যবহার করুন। যদিও এটি চলমান জিনিস হতে চলেছে, মনিকিজ যে স্ক্রিপ্ট পোস্ট করেছে (স্টিডিনের পাসওয়ার্ড পড়তে এবং একাধিক সার্ভারে কাজ করার জন্য অভিযোজিত) সম্ভবত এটি আপনার সেরা বাজি হবে।
মাইকিবি

0

বিলে মাপসই হতে পারে এমন কয়েকটি জিনিস:

অন্যান্য উত্তরে উল্লিখিত হিসাবে, sshpass সম্ভবত সবচেয়ে সহজ সমাধান।


0

আমি ধারণা করতে চাই যে এটি কতটা খারাপ তা:

  1. আপনার স্ক্রিপ্টগুলিতে একটি হার্ড-কোডেড পাসওয়ার্ড ব্যবহার করুন
  2. আপনার সমস্ত সার্ভারে একই পাসওয়ার্ড ব্যবহার করুন ... যেমন ... কেন !?
  3. আপনি যদি জেদ করেন তবে এসএসএইচ পাবলিক_কি + পাসওয়ার্ড প্রমাণীকরণ ব্যবহার করবেন না
  4. একটি পাঠ্য ফাইলে পাসওয়ার্ড সংরক্ষণ করুন

এখানে একটি বাস্তবায়ন যা কিছুটা সুরক্ষিত ...

#!/usr/bin/python3
import os
import getpass
import argparse

parser = argparse.argument_parser()
parser.add_argument('-l','--login', action='store', help='username')
parser.add_argument('-p','--port', action='store', default='22', help='port')
parser.add_argument('-L','--list', action='store', help='file list of IPs')
parser.add_argument('-i','--ip-address', action='store', nargs='+', metavar='host' help='ip or list of ips')

args = parser.parse_args()
if not args.login:
    print("You need a login, broski!")
    return 0

if args.list:
    ips = [i for i in open(args.list, 'r').readlines()]
    passwd = getpass.getpass('Password: ')

    for ip in ips:
        cmd = 'ssh-id-copy {0}@{1} -p {2}'.format(ip,args.port,passwd)            
        os.system('sshpass -p ' + passwd + ' ' + cmd)
        print("Key added: ", ip)   # prints if successful
        # ex: sshpass -p passwd ssh-id-copy login@1.1.1.1

elif args.host:
    ip = args.host
    cmd = 'ssh-id-copy {0}@{1} -p {2}'.format(ip,args.port,passwd)
    os.system('sshpass -p ' + passwd + ' ' + cmd)
    print("Key added: ", ip)   # prints if successful
else:
    print("No IP addresses were given to run script...")
    return 0 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.