我需要自动化的方式分发文件到许多服务器。 问题当然是我需要使用一个安全的协议(SSH或SCP),每个服务器上的用户名/密码是不同的。
场景是我们有一个主服务器a,用户a_prod,我们需要发送更新的脚本/configuration等服务器b,c,d,…在这些服务器上的用户名是说b_dev,c_test,d_prod与每个都有唯一的密码。
由于以下几个原因,用户名需要在各个环境中是唯一的,从而处理DB2和企业安全性。
共享密钥在这种情况下将不起作用,所以我需要通过脚本传递用户名和密码。 这是一个AIX环境,我没有安装expect的能力。
有任何想法吗?
共享密钥在下面的多个响应中提到:我已经尝试了几种方法来做到这一点,我认为主要的问题是远程用户ID不存在于任何其他主机上,所以我不能为他们做一个ssh-keygen主机我想ssh根据目标主机(b_dev,c_test_d_prod)与主用户(a_prod)执行共享密钥实现具有多个身份。 需要在主机a上为远程用户生成这些用户的私钥,然后将他们的公钥复制到目标主机。
“企业S(愚蠢)”:-)
SSH / SCP通常与我认为的UNIX哲学领域一致。 Unix应用程序的devise者故意使得pipe理员不能轻易做出一些愚蠢的事情,这是非常罕见的。 一般会有这样的警告:“你可能不想这样做,因为…但是,如果你真的想的话,好的!”
在脚本中传递密码到ssh的情况下,他们故意使这个很难,因为它只是一个坏主意 。
在这一点上,我甚至不打扰SSH。 你真的需要和公司安全人员交谈,为这个情景提出一个真正的解决scheme。 如果他们不想使用密钥,问他们你应该做什么。 如果这不起作用,请告诉您的pipe理人员,由于公司安全限制,他们不能完成的任务。 如果pipe理者确实坚持这样做, 那就写下来,否则就是你的屁股
插入关于公司政策的标准声明,以及为什么在这里放入用户/传入脚本是不好的。
但是我们都在现实世界中工作,有时候这是没有意义的。 喔..有很多工具可以让你这样做。 壳牌没有一个内置的方式来得到这个工作。 对于这种性质非常快速和肮脏的脚本,我select的武器是Expect。 运行起来非常容易。
#!/usr/bin/expect set nodename "hostname" set username "user" set password "pass" set prompt "your prompt on the remote system" eval spawn ssh -x $user@$nodeaddy set timeout 15 expect "password:" { send "$password\r" } expect "$prompt" { send "script\r" } exit 0
显然,这可能会或可能不会为你工作,但你可以从语法中看到,工作是多么简单。
首先是一个警告:小心不要以权宜之计创造安全问题。 凯文和凯尔提出好点。 在一个文件(甚至是一个encryption的数据库)中存储一堆用户名/密码组合可能是一个非常糟糕的主意,可能会违反公司政策。
解决您的问题可能是客户端证书。 请参阅以下文章以获取更多信息:
假设企业政策允许公用密钥对,这并不难实现。 要获得与运行ssh的用户不同的用户名(脚本),请使用username@host 。 更难的部分是获得适当的私钥工作。 假设由于某种虚假的安全感,每个主机必须使用不同的密钥对(否则就更简单),您应该创build一个configuration文件,告诉客户端哪个主机使用哪个配对(您也可以实际指定用户名在文件中)。
对于openssh文件看起来像
host a_prod user usera IdentityFile ~/.ssh/keyfora_prod host b_dev user userb IdentityFile ~/.ssh/keyforb_prod
等等
只要记住,这个设置实际上并不安全。 如果有人可以在这台计算机上访问这个用户,他可以读取所有的私钥(如果事情必须是安全的,那么不能有密码,或者你必须用ssh_agent破解密码)以及硬编码的密码。 由于没有任何理由让私钥文件生存在其他地方,但是在这个用户的ssh目录下(丢失的时候,人们可以很容易地创build一个新的密钥),从安全的angular度来看,拥有四个文件和没有任何区别。
好的 – 我终于得到这个工作如下:
ssh -i b_dev_id_dsa_2048_a b_dev@b 和中提琴,它终于奏效
感谢大家的帮助,最后是niXar最后的荷马辛普森DUH的时刻,因为这样做是完全相反,如果用户在所有的主机相同。
没有私钥或期望或类似的东西,我不明白你怎么能做到这一点automagically。 有些事情要付出
你有什么合作的吗? 我假设你没有Perl,因为你可以使用Expect.pm? python? 什么? 只是普通的老丑陋的ksh? 请告诉我们更多。
如果您不允许使用编程语言,则需要手动input密码。 在这种情况下,您可以使用:
scp myfile b_dev@b_prod:/path/to/dest
如果涉及批次,请考虑使用SFTP。 您可以使用lftp,而不必input密码,在这里直接从手册页:
lftp [-d] [-e cmd] [-p port] [-u user[,pass]] [site]
但是,如果你不能期待,我怀疑你可以使用lftp。 你可以吗?
/哦,我讨厌专有的Unix废话
这不是一个好主意,但如果你真的需要这样做,sshpass可以帮助你: http : //sourceforge.net/projects/sshpass/
我不得不做类似的事情,只能倒退。 我们正在从一堆服务器上取出文件,这就是我们这样做的方式。
awk '{FS="|"; printf("rsync %s:%s %s &\n", $1, $2, $3)}' config | sh
创build一个名为config的文件,并在其中放置要运行的行。 (请注意:你需要插入一个空行开始)。
现在,你可以把[email protected]|(folder on remote server)|(folder on local server)放到configuration文件中,它将rsync同步两者。 您将需要在awk命令中切换rsync命令来做相反的事情。
这对ssh-key auth很有效,这是我们使用的。
我还build议为身份validation创buildSSH密钥,并使用像unison或lsyncd(取决于您的需要)的工具来保持文件同步。
如果基于密钥的authentication不是一个选项,你可以使用“expect”( http://linux.die.net/man/1/expect )来编写脚本。 期望检查一个定义的outupt(可以说是密码的问题),并且相关的input一个定义的string(在这个例子中是密码)。
但正如所暗示的,我更喜欢ssh-key解决scheme。