Linux ssh 自动输入

2018-08-31 10:24:24 +08:00
 helloworld12

我有一段脚本 里面的一个函数需要用到 ssh 譬如

f() {
	    ssh -tt $ser << EOF
		echo "do something"
    EOF
    }

我要怎样把密码传给 ssh ( ssh 的秘钥是需要密码的)

用 expect 的方案好像不行,我有许多命令需要再 bash 环境下里面进行,且密码不能直接写在脚本里,只能运行的时候输入进来

2592 次点击
所在节点    问与答
19 条回复
xinhangliu
2018-08-31 10:30:52 +08:00
SSH 免密登录?
xinhangliu
2018-08-31 10:33:26 +08:00
或者 `read -s -p "Password: "`?
jasonyang9
2018-08-31 10:35:13 +08:00
设定下 rsa 密钥登录,并用`-i`指定私钥
jasonyang9
2018-08-31 10:35:38 +08:00
看错了,请忽略
helloworld12
2018-08-31 10:53:53 +08:00
@xinhangliu 要密码,怕秘钥外流

或者 `read -s -p "Password: "`? xxx
现在的问题,是要怎么把 xxx 传给 ssh 命令
Goooogle
2018-08-31 11:00:52 +08:00
Expect 也是可以的
我从自己的配置里复制出来一部分 应该能满足你需求

```

# 提醒用户输入密码
send "'$PROMPT_FOR_PASSWORD'";

# 将用户输入的密码保存到临时变量中
stty -echo;
expect_user -timeout 3600 -re "(.*)\n";
set PASSWORD $expect_out(1,string);
stty echo;

# 登录
spawn ssh -i '$SSH_PEM_FILE' \
'$SSH_USER_NAME'@'$SSH_JUMP_SERVER';
expect {
# 自动输入密码
-re "Enter passphrase for key" {
if {$PASSWORD == ""} {
exit;
}
send "$PASSWORD\n";
exp_continue;
}
}

```
kikyous
2018-08-31 11:01:48 +08:00
sshagent
Goooogle
2018-08-31 11:03:43 +08:00
这段配置的原始用途是配合 iterm2 的 Trigger 和 Password Manager 免输入密码登录 JumpServer 并自动选择对应的机器并 attach 到 tmux
ysc3839
2018-08-31 11:06:03 +08:00
sshpass
ysc3839
2018-08-31 11:07:40 +08:00
@ysc3839 我好像理解错了?是密钥需要密码而不是远程服务器需要密码?那 sshpass 不适用。
kinnveeee
2018-08-31 11:29:48 +08:00
sshpass -P "Enter passphrase for key" -p 密钥密码 ssh -i 密钥 用户名 @主机名 /ip -P 端口
helloworld12
2018-08-31 15:29:01 +08:00
@Goooogle 谢谢 嗯, 脚本里面还有其他内容,需要 bash 环境, 所以 expect 不合适
@kinnveeee
@ysc3839 sshpass 不适用 秘钥密码
msg7086
2018-08-31 15:43:33 +08:00
你换个思路。如果你私钥都能泄露了,那你写在脚本里的密码会不泄露吗。

所以为什么不直接用无密码密钥呢。只要不带出这台机器不就没事了么。
Goooogle
2018-08-31 15:47:51 +08:00
@helloworld12
"脚本里面还有其他内容,需要 bash 环境" 这句话什么意思,不是很理解。
连上后还需要在服务器上手动 /自动执行脚本?


如果需要自动执行 在 expect 登陆后 send 命令就好
如果需要手动操作 可以 expect 登陆后 interact
zhangjn
2018-08-31 16:03:05 +08:00
putty 的 pageant 有管理密钥的功能,只要一开始输入一次 key 的密码就行。
openssh 有个对应的 ssh-agent

直接用密码的时候为了不用输入密码,我魔改了 openssh,用环境变量当密码, 比改称用参数稍微安全一丁点
PS: 用 LFS ( linux from scratch )就是这点方便,就是全构建一次要几个小时

魔改 patch 如下, 你可以照猫画虎把 key 密码的读取也改成这样的
```
diff -urz openssh-7.7p1.orig/readpass.c openssh-7.7p1/readpass.c
--- openssh-7.7p1.orig/readpass.c
+++ openssh-7.7p1/readpass.c
@@ -47,9 +47,17 @@
#include "ssh.h"
#include "uidswap.h"

+static char *_env_pass(void)
+{
+ return getenv("_SSH_PASS"); // 运行的时候 _SSH_PASS=<password> ssh username@host 就行了
+}
+
static char *
ssh_askpass(char *askpass, const char *msg)
{
+ if(_env_pass())
+ return xstrdup(_env_pass());
+
pid_t pid, ret;
size_t len;
char *pass;
@@ -118,6 +126,13 @@ ssh_askpass(char *askpass, const char *m
char *
read_passphrase(const char *prompt, int flags)
{
+ if (_env_pass()) {
+ if (strstr(prompt, "Please type 'yes'")) {
+ return xstrdup("yes");
+ }
+ return xstrdup(_env_pass());
+ }
+
char *askpass = NULL, *ret, buf[1024];
int rppflags, use_askpass = 0, ttyfd;

@@ -169,6 +184,9 @@ read_passphrase(const char *prompt, int
int
ask_permission(const char *fmt, ...)
{
+ if(_env_pass())
+ return 1;
+
va_list args;
char *p, prompt[1024];
int allowed = 0;

```
zhangjn
2018-08-31 16:03:51 +08:00
回复不支持 makrdown 啊, 格式乱了
helloworld12
2018-08-31 16:21:44 +08:00
@zhangjn 谢谢, 搜了下 ssh-agent 学到了新知识

不过不适用, 因为希望每次运行脚本的时候,都去输入密码(即使对本机也不信任。。。)
zhangjn
2018-08-31 16:34:37 +08:00
@helloworld12 #17 用的 VPS 么,pageant 和 ssh-agent 还能支持链式转发, 即这两个软件运行在本地,被 ssh 登录的机器也可以使用本地的 keys,但是这样依然解决不了对 vps 的信任问题,顶多在本地的 ssh-agent 里面加上日志然后审计。

合理的解决方法是密码不能在不信任的机器上出现,如果只是为了使用不信任机器的网络可以用 vpn 或者其他的代理软件
helloworld12
2018-08-31 21:23:25 +08:00
@zhangjn 对本机不信任是因为, 老板说, 有人家里在运行的电脑被黑了,然后顺着电脑把服务器也给黑了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/484813

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX