【问题标题】:Connecting to a remote server and switching user with bash/expect连接到远程服务器并使用 bash/expect 切换用户
【发布时间】:2012-01-13 16:05:04
【问题描述】:

第一次发帖,在此先感谢您的帮助。

总的来说,我对脚本编写有点陌生,但我已经设法在 bash 中构建了一个很好的包装器,旨在收集一些变量,然后与几个远程框建立一些连接,并做一些与网络统计相关的事情系统并启动一些hadoop进程。基本上是我试图自动化的一系列乏味任务。 (不必要的细节已完成)。

我遇到的问题是找到一种方法来有效地连接到那些删除服务器,以普通用户身份进行身份验证,然后切换用户执行各种任务。以下是相关代码:

    #!/bin/sh
    #Script's run as root. this asks for the sudoers pass
    read -p "Enter password for $SUDO_USER: " -s password
    #Defines some testing commands I want to pass to a remote box
    CMD="hostname; id; sudo su -; id; pwd;"
    #launches an expect script with some defined variables as arguments.
    /home/ME/scripts/derp.expect $SUDO_USER $definedremoteserver "$command" "$password"

现在使用的期望脚本:

    #!/usr/bin/expect
    #expect script to help with SSH connections for the urchinizer bash script
    set arg1 [lindex $argv 0]
    set arg2 [lindex $argv 1]
    set arg3 [lindex $argv 2]
    set arg4 [lindex $argv 3]
    spawn ssh -oStrictHostKeyChecking=no $arg1@$arg2 "$arg3"
    expect "password:"
    send "$arg4\r"
    interact
    expect "password"
    send "$arg4\r"
    interact

我无法确定失败的原因。我已经研究了很多,并尝试了许多代码变体。基本上,当我运行它时,它需要我的通行证并且我能够建立初始连接。然后脚本尝试切换用户,第二个期望失败。第一个 'id' 和 'hostname' 输出成功。当用户切换发生时,第二个期望不起作用,我只剩下一个密码提示。无论如何我输入了我的通行证(由于某种原因以纯文本显示)并且脚本只是挂起而不输出我试图用来验证它是否有效的第二个'id'和'pwd'命令。

如果我真的登录到该框并执行 sudo -i 或 sudo su - 这就是密码提示的样子:

    [sudo] password for my.name:

所以对于第二个(不工作的)期望,我尝试了一些不同的变体,结果有些不同,但没有成功。

抱歉,帖子太长了。这一直让人发疯。我正在尝试做的事情可能吗?有没有更聪明的方法来处理这个问题?有人发现任何明显的错误吗?另外,第二个问题......通配符如何在那些期望行中工作?

【问题讨论】:

  • 当您标记这个 bash 时,我假设是 Linux/Unix,而不是寡妇。您是否尝试在期望脚本中将 '\r' 替换为 '\n' ?这对于linux来说会更标准。您确定您的 remote sudoers 文件、用户权限等设置正确吗?祝你好运。

标签: bash ssh expect


【解决方案1】:

如果可以,请使用一些脚本语言,如 Perl、Python 或 Ruby,以及一些用于 SSH 的模块。

例如,使用 Perl 和 Net::OpenSSH 模块:

use Net::OpenSSH;

my $ssh = Net::OpenSSH->new($host, user => $user, password => $password);
my $output = $ssh->capture({stdin_data => "$sudo_password\n"},
                           'sudo', '-Sk', '-p', '', '--',
                           'ls', '/');

【讨论】:

    【解决方案2】:

    您应该在 OpenSSH 中使用“公钥验证”而不是“密码验证”。

    1:使用此命令为您要登录的用户创建私钥/公钥对:

    ssh-keygen -t rsa
    

    不提供密码,选择默认路径(回车、回车、回车)。 这应该为您的每台 SSH 机器(客户端和服务器)完成。

    2:从您要登录的每台客户端计算机上,将您的新公钥文件内容复制到您喜欢的文本编辑器(记事本、gvim 等)

    cat ~/.ssh/id_rsa.pub
    

    您现在应该将所有客户的公钥粘贴到您的编辑器中,如下所示:

    ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt9sGP1PKR1XzpozHQc9ufyzOnePHCnRzUhdfSvfQTzJO28CgnHwhANdaBeOrLq5b+VOoPJFj5NquYXmJ6YikSJCwHlvfewA/5p0IkucsJLxqYQMDRhyeXb9fCk85MoNRJjAd+Cst+gI9Cwpp1ysLMDY77k/a9eT3ExkgbGd6mdtfjAlP/o/rRMcqNwp9Pdhh6kkxrM0v1ceNSTbTeO7XCLvekqtRiwjWImhQs56JVbB/RLySNKtqjbpr7Zhn1m+p6+vmBmgwF3xBBvzziYfMm/vG1ZvvGIsI3dxRDWuSZ8+o63w7Y20M9NQn4QkqV6NFjX3conBiDGtDBKain2zj6Q== dino@blackbigone
    ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0JR6d9LWgvPCbvBajrbVly3cxX7ZkbH4+MUBu+ak2G5SGLbGBcwdi3JquBAT1+U/hl+TKKUUw1XjjjazdjgYCHWIguDWzmqoyT4bQN2aymNoqD35T+LWAaqwC36m95fRfJh3HSOtx7KXpsBZjvR40rg901f8ReIjBoL7G620rrsRDqaDS08Mm6TjThBrCeTYX2YzugodpUNP2evwFOBMrYw/TIcX5Lza8xRCctm8MRodsx/yvuYuZJSanVLs3Q6sJ/n9o20L8Jt1Fu1cnyxJTs9THiLOnZyrTBXvbKJymit6p3hfDpDlWtO/crNeyt0H8jJcZfiCnhQwfib2VMMqJw== erica@blackbigone
    

    3:将您在文本编辑器中的 ascii 铠装公钥粘贴到您要登录的每个 SSH 服务器上的 ~/.ssh/authorized_keys 文件中。您必须是要登录的用户。如果文件不存在,则创建该文件。 这样,您就可以向所有使用给定公钥的用户授予登录到您创建authorized_keys 文件的服务器的权限。 如果用户拥有正确匹配的私钥,则登录成功。

    在远程服务器上登录后,您可以使用 sudo(您必须先使用 visudo 命令配置 /etc/sudoers 文件)来执行其他用户的命令。 为避免 sudo 请求密码(因为您在 /etc/sudoers... 中进行了身份验证),您必须设置 NOPASSWD 标志,如下行:

    %admin ALL=(ALL) NOPASSWD: ALL
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 2010-12-28
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多