Linux ssh 自动输入 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
helloworld12
V2EX    问与答

Linux ssh 自动输入

  •  
  •   helloworld12 2018-08-31 10:24:24 +08:00 3006 次点击
    这是一个创建于 2598 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    19 条回复    2018-08-31 21:23:25 +08:00
    xinhangliu
        1
    xinhangliu  
       2018-08-31 10:30:52 +08:00 via Android
    SSH 免密登录?
    xinhangliu
        2
    xinhangliu  
       2018-08-31 10:33:26 +08:00 via Android
    或者 `read -s -p "Password: "`?
    jasonyang9
        3
    jasonyang9  
       2018-08-31 10:35:13 +08:00
    设定下 rsa 密钥登录,并用`-i`指定私钥
    jasonyang9
        4
    jasonyang9  
       2018-08-31 10:35:38 +08:00
    看错了,请忽略
    helloworld12
        5
    helloworld12  
    OP
       2018-08-31 10:53:53 +08:00
    @xinhangliu 要密码,怕秘钥外流

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

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


    如果需要自动执行 在 expect 登陆后 send 命令就好
    如果需要手动操作 可以 expect 登陆后 interact
    zhangjn
        15
    zhangjn  
       2018-08-31 16:03:05 +08:00   1
    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
        16
    zhangjn  
       2018-08-31 16:03:51 +08:00
    回复不支持 makrdown 啊, 格式乱了
    helloworld12
        17
    helloworld12  
    OP
       2018-08-31 16:21:44 +08:00
    @zhangjn 谢谢, 搜了下 ssh-agent 学到了新知识

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

    合理的解决方法是密码不能在不信任的机器上出现,如果只是为了使用不信任机器的网络可以用 vpn 或者其他的代理软件
    helloworld12
        19
    helloworld12  
    OP
       2018-08-31 21:23:25 +08:00
    @zhangjn 对本机不信任是因为, 老板说, 有人家里在运行的电脑被黑了,然后顺着电脑把服务器也给黑了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5250 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 09:19 PVG 17:19 LAX 02:19 JFK 05:19
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86