ssh登录自动输入密码

现有解决方案有expect 和 sshpass 等第三方解决方案,因不想引入过多依赖决定自己实现。

通过查找资料发现以上方案是对tty直接写入来达到效果,但是我用bash脚本直接对tty写入确只能在屏幕显示,不能被程序获取,于是转入使用ruby按照以上资料来自己实现,

require 'pty'
master, slave = PTY.open
f = slave.path
Process.fork do
  Process.setsid
  sp=open(f,'r+')
  sp.close
  slave.close
  exec "/usr/bin/ssh root@10.30.3.21"
end
sleep 3

master.puts "yunzhisheng"

while true do
  p master.gets
end

发现将第6,7,8行注释掉之后报如下错误:

ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directoryPermission denied, please try again.ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directoryPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

对ssh_askpass 查找资料发现环境变量SSH_ASKPASS DISPLAY可以定义一个程序用来在ssh没有联接终端时提供密码。

**SSH_ASKPASS **设为提供密码的程序

DISPLAY 设为 :0

测试发现ssh 调用SSH_ASKPASS定义的程序时,带 参数执行,如

***# $SSH_ASKPASS *root@xx.xx.xx.xx's password:

只要程序打印正确密码,ssh即可验证通过,于是问题解决,也不需要用ruby去实现了。

示例如下:

项目GitHub地址

#!/bin/bash

SSH=/usr/bin/ssh
tmp_file=/tmp/ssh_password

if expr "$*" : ".*password:" >/dev/null
then
    touch $tmp_file
    cat $tmp_file
    rm -f $tmp_file
    exit
fi

export DISPLAY=:0
export SSH_ASKPASS=$(cd `dirname $0`;pwd)/`basename $0`

if expr "$*" : ".*--password.*" >/dev/null
then
    arg=()
    is_password=no
    for i in $*
    do
        if [ $is_password == yes ]
        then
            echo "$i" >$tmp_file
        else
            if expr "$i" : "--password" >/dev/null && [ $is_password == no ]
            then
                is_password=yes
            else
                arg[${#arg[*]}]=$i
            fi
        fi

    done
fi

setsid $SSH ${arg[*]}

这样即可自动输入密码ssh登录。

网上几乎都是expect 和 sshpass等方案来实现自动输入密码,此方法原理网上资料少有,记录之。

2016.11.24

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。