当前位置:  开发笔记 > 编程语言 > 正文

使用用户/密码进行身份验证*一次*用于多个命令?(会话多路复用)

如何解决《使用用户/密码进行身份验证*一次*用于多个命令?(会话多路复用)》经验,为你挑选了1个好方法。

我从Solaris文档获得了这个技巧,用于将ssh公钥复制到远程主机(ssh-copy-id在Solaris上不可用).

$ cat some_data_file | ssh user@host "cat >/tmp/some_data_file; some_shell_cmd"

似乎它可以适应更多涉及的事情.具体来说,我想some_shell_command成为一个从本地发送到远程端执行的脚本,它将与本地键盘进行交互.

我尝试了stdin从多个来源发送多个东西的方法.但是在本地shell中工作的一些东西不适用于ssh,而下面的一些东西并没有完全符合我的要求:

$ echo "abc" | cat <(echo "def")     # echoes: def  (I wanted abc\ndef)
$ echo "abc" | cat  < <(echo "def")  # echoes: def  (I wanted abc\ndef)

$ echo "abc" | cat <<-EOF
> echo $( EOF

# messed with eval for the above but that was a problem too.

@chepner总结说,在一个ssh命令中完成所有这些操作是不可行的,并解释了一个替代方案,这对我来说不适用于研究和调整他的答案.(我记录了这个帖子中的结果).没有它,必须运行多个ssh,scp默认情况下命令需要多次提示输入密码,这是一个主要障碍,因为我不能指望我在多用户环境中编写的脚本的所有用户都配置公钥授权也不会让他们不得不一遍又一遍地输入密码.



1> clearlight..:

                                OpenSSH会话多路复用


    即使在使用该
    ControlPersist选项不可用的早期版本的OpenSSH时,此解决方案仍然有效.(本回答结束时的工作bash示例)


OpenSSH 3.9通过"控制主连接" (2005年)引入了会话多路复用.
但是,ControlPersist直到OpenSSH 5.6(2010年发布)才推出该选项 .

会话多路复用对于最小化认证开销很有用.例如,如果您有一个脚本ssh使用OpenSSH会话多路复用的任意组合运行多个不同的任务,则"控制主会话"进行一次身份验证,保持其连接打开,并且ssh相关命令通过引用来共享该连接其命名套接字在文件系统中的位置.通过会话多路复用,您可以避免多次输入密码(例如,在某些情况下,您无法依赖配置了公钥认证的用户).


在此输入图像描述


大多数当前的解决方案(例如@Chepner的答案)需要使用scp告知sftp来保持控制主连接无限期地打开,或者持续一段特定的秒数,但是因为具有OpenSSH之前的系统没有该选项,并且升级它们可能不可行,要做什么?不幸的是,似乎没有太多关于它的文档或讨论在线.

OpenSSH迟到会话多路复用场景,这意味着必须有一种替代方法来配置会话多路复用而不依赖于该ControlPersist选项.我试图弄清楚如何,但最初遇到ssh会话过早终止并关闭所需的控制连接客户端会话的问题,或者,如果我保持连接打开(保持ssh控制主机处于活动状态),终端I/O被阻止,我的脚本会挂起!最终我发现了完成它的旗帜.


OpenSSH option            ssh flag          Purpose
-------------------       ---------         -----------------------------
-o ControlMaster=yes      -M                Establishes sharable connection
-o ControlPath=path       -S path           Specifies path of connection's named socket
-o ControlPersist=600                       Keep shareable connection open 10 min.
-o ControlPersist=yes                       Keep shareable connection open indefinitely
                          -N                Don't create shell or run a command
                          -f                Go into background after authenticating
                          -O exit           Closes persistent connection
ControlPersist form       Equivalent        Purpose
-------------------       ----------------  -------------------------
-o ControlPersist=yes     ssh -Nf           Keep control connection open indefinitely
-o ControlPersist=300     ssh -f sleep 300  Keep control connection open 5 min.

注:sshControlPersist实施ControlPersist不同的标志,而scp不是在所有,所以,对于这些命令,标志sftp总是必需的形式.


粗略的操作概述:
注意:此不完整的示例不会如图所示执行.

ctl=
ssh -fNMS $ctl user@host      # open control master connection
ssh -S $ctl …                 # example of ssh over connection
scp  -o ControlPath=$ctl …    # example of scp over connection
sftp -o ControlPath=$ctl …    # example of sftp over connection
ssh -S $ctl -O exit           # close control master connection

会话多路复用演示 (工作示例 - 仅验证一次):
注意:以下代码的样式很糟糕,例如"压缩和压缩",以避免回答中的滚动条.如果您精通shell并复制/粘贴/执行此示例,并且无法访问远程主机,请在"Host ...?"处输入localhost.提示.

#!/bin/bash       # This script demonstrates ssh session multiplexing

trap "[ -z "$ctl" ] || ssh -S $ctl -O exit $user@$host" EXIT # closes conn, deletes fifo

read -p "Host to connect to? " host
read -p "User to login with? " user

BOLD="\n$(tput bold)"; NORMAL="$(tput sgr0)"
echo -e "${BOLD}Create authenticated persistent control master connection:${NORMAL}"
sshfifos=~/.ssh/controlmasters
[ -d $sshfifos ] || mkdir -p $sshfifos; chmod 755 $sshfifos
ctl=$sshfifos/$user@$host:22 # ssh stores named socket for open ctrl conn here

ssh -fNMS $ctl $user@$host  # Control Master: Prompts passwd then persists in background

lcldir=$(mktemp -d /tmp/XXXX);                           echo -e "\nLocal  dir: $lcldir"
rmtdir=$(ssh -S $ctl $user@$host "mktemp -d /tmp/XXXX"); echo      "Remote dir: $rmtdir"

echo -e "${BOLD}Copy self to remote with scp:${NORMAL}"
scp -o ControlPath=$ctl ${BASH_SOURCE[0]} $user@$host:$rmtdir 

echo -e "${BOLD}Display 4 lines of remote script, with ssh:${NORMAL}"
echo "====================================================================="
echo $rmtdir | ssh -S $ctl $user@$host "dir=$(

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有