我想要将scp
文件发送到远程主机,然后从那里对该文件运行命令,然后退出远程会话。如果我编写一个通常的脚本,调用scp
然后ssh
,系统会提示我输入两个密码。有没有一种方法可以使用ssh
一个密码在远程计算机上复制、运行命令?
另外,如何编写需要与用户交互以输入密码的脚本?
我不想使用“读取”,因为它不安全。我不想使用passwordless ssh
,因为我的私钥文件可能会被泄露,这更糟糕。我读过一些有关“期望”的内容,但不确定它是否是正确的工具。
答案1
我不想使用无密码 ssh,因为我的私钥文件可能会被泄露,这更糟糕。
不,这是错误的。私钥文件比密码提供更高的安全性。使用私钥文件。私钥文件用密码加密;如果有人获得密钥文件,他们仍然需要您的密码。如果您使用密码身份验证,那么任何掌握密码的人都可以逍遥法外。
ssh-agent
在会话期间运行。在使用特定密钥之前,请输入密码ssh-add
(或通过某些 GUI 提示)。这样使用该键连接时就不会出现提示了。
答案2
有没有一种方法可以使用一个密码在远程计算机上复制、ssh 并运行命令?
有两种方法,其便利性和权衡各不相同。
一种是内联传输文件。除了文件内容之外,您还需要输入吗?如果没有,ssh example.com 'cat > the_file ; process the_file' < the_file
就会做你想做的事。
另一个是做一些重用 SSH 连接的事情。 ControlMaster
和 ssh 的朋友可能会有所帮助 - 请参阅ssh_config(1)
详细信息,或者有各种包装器,或各种编程语言的 SSH 实现可以提供帮助。
另外,如何编写需要与用户交互以输入密码的脚本?
从 TTY 中读取。一般来说,最好的策略是允许 ssh 直接与用户交互而不妨碍,因为它以这种方式进行交互的实现经过了更好的测试和验证。
我不想使用 read,因为它不安全。
我认为是为了与用户交互。实际上,从安全性角度来说,这与仅让 SSH 询问并没有本质上的不同,但最好不要妨碍。
我不想使用无密码 ssh,因为我的私钥文件可能会被泄露,这更糟糕。
...并且我认为出于同样的原因,SSH 代理也是不可接受的。
答案3
使用“expect”来表达你的要求是可能的,有些人仍然使用它。 Expect 脚本可以“捕获”命令输出,您可以根据其输出“回答”。您的脚本将如下所示:
spawn scp some_file user@host:/destination
expect "*?assword:*"
send -- "Your Super Secret Password Here\r"
send -- "\r"
当然,这可行,但会带来另一个问题。您的密码将以纯文本形式保存,任何阅读此文件的人都可以看到您的密码。
我个人的观点是,最安全的非交互方式是私钥认证。
答案4
您可以使用ssh
键,但将它们分配给远程系统上的自定义用户,该用户的 shell 不是设置为实际的 shell,而是设置为您想要运行的命令。效果是在登录时执行该命令,然后终端将关闭。因此,如果密码被泄露,他们将无法交互式地输入命令,而只能作为 shell 运行一个命令集。