无法获得bash脚本以满足期望的提示

时间:2018-02-13 13:55:45

标签: bash shell expect

我的ssh访问仅限于Google身份验证器验证码提示。我想要一个以编程方式回答该提示的脚本。

上下文

  • 变量 ($ 1)正确传递给脚本 - 它是验证码。
  • sshfs命令在终端中工作。
  • 提示符Verification code:附带空格和末尾的关键符号。

[编辑]为了确保我们不在此处切换到安全性讨论,请注意当然我还使用SSH密钥,此外还有Google身份验证器。由于身份验证器验证码每x秒到期,其他人可以拦截它并不重要。

结果

磁盘安装(我可以使用df -h看到它),但是为空...有类似于验证代码错误的行为,或者它没有时间执行?

外壳脚本

    #!/bin/bash

    expect_sh=$(expect -c "
        spawn /usr/local/bin/sshfs username@123.123.1.123:/path/to/folder/RAID1 /Users/username/Desktop/RAID1 -o defer_permissions -o volname=RAID1
        expect \"Verification code:\"
        send \"$1\r\";
    ")

    echo "$expect_sh"

由于

3 个答案:

答案 0 :(得分:3)

我害怕,我必须回答 no

有一些问题:

  1. 拥有密码参数可以通过简单的

    向其他用户显示您的密码
    ps axw
    
  2. 将密码存储到变量中可以通过简单的

    向其他用户显示您的密码
    ps axeww
    
  3. 通过 STDIN 传送密码可能很容易追踪。

  4. 出于这个原因以及很多其他原因,ssh(和sftp)拒绝通过参数,变量或 STDIO 传递秘密。

    在要求输入密码之前,需要进行大量验证,然后使用安全对话框(使用直接TTY或X DISPLAY上的某些框)。

    因此expect无法直接使用ssh或传递秘密作为参数。

    但是

    您可以使用密钥连接ssh服务器:

    ssh-keygen -b 4096
    Enter file in which to save the key (/home/user/.ssh/id_rsa): 
    Generating public/private rsa key pair.
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/user/.ssh/id_rsa.
    Your public key has been saved in /home/user/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:q/2fX/Hello/World/Lorem/Ipsum/Dolor/Sit/Amet user@localhst
    The key's randomart image is:
    +---[RSA 4096]----+
    |          .=o=E.o|
    |      .. o= o    |
    |     o+ +=...    |
    |     .o+ o+o.    |
    |   . +.oS.oo     |
    |  . *.= .  ...   |
    |   o =.     oo.  |
    |  ...        +o. |
    | .ooo       oooo.|
    +----[SHA256]-----+
    

    然后,您必须将/home/user/.ssh/id_rsa.pub发送到您尝试连接的服务器中的authorized_keys文件中(此文件位于$HOME/.ssh/或{{1}但是,可能位于其他位置,具体取决于服务器中的/etc

答案 1 :(得分:2)

这不起作用的原因是您在命令替换中的子shell中运行expect

如果不是因为你希望并期望这个过程保持活力,这将是一个无害的常规useless use of echo

只需取出变量捕获并运行expect作为当前脚本的直接后代。如果确实要求输出在变量完成后可用作变量,可以尝试类似

#!/bin/bash

t=$(mktemp -t gauthssh.XXXXXXXXXX) || exit
trap 'rm -f "$t"' EXIT ERROR INT HUP TERM  # clean up temp file when done
expect -c "
    spawn /usr/local/bin/sshfs username@123.123.1.123:/path/to/folder/RAID1 /Users/username/Desktop/RAID1 -o defer_permissions -o volname=RAID1
    expect \"Verification code:\"
    send \"$1\r\";
" | tee "$t"
expect_sh=$(<"$t")

答案 2 :(得分:0)

您可以使用screen(1)

构建解决方案

我测试了下面的脚本。它不是特别健壮,而且 你需要根据你的环境做一些改变。

#!/bin/sh

screen -d -m -S sshtest sh -c "ssh -l postgres localhost id > output"

pass="77c94046"
ret="$(printf '\n')"

while true; do
        screen -S sshtest -X hardcopy
        grep -q 'password:' hardcopy.0 && break
        sleep 1
done

grep -v '^$' hardcopy.0
echo -n "$passenter" | xxd
screen -S sshtest -X stuff "$pass"
screen -S sshtest -X stuff "$(printf '\r')"
sleep 1
cat output

我们的想法是设置一个运行您重定向命令的屏幕 它的输出到本地文件。然后你在一个循环和屏幕抓取 用grep查找你的预期提示。找到后,使用 &#39;东西&#39;在屏幕上命令将密码输入终端 输入(即屏幕的pty)。然后你等一下,收集你的 如果需要输出。这只是概念代码的证明,非常强大 解决方案会做更多错误检查和清理,并等待 屏幕实际退出。