免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2173 | 回复: 1
打印 上一主题 下一主题

[网络相关] [求助]Expect做ssh代理中转站的用法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-30 23:29 |只看该作者 |倒序浏览
本帖最后由 npc_hp110 于 2014-08-31 10:07 编辑

【问题介绍】
一般的Linux系统可以通过ssh user@ip command远程执行命令
但某些特殊的定制化系统,ssh登录后会进入定制化的人机交互进程(非shell环境),无法通过上述方式远程管理
通过expect可以实现ssh登录后的自动化控制,但是要事先把交互逻辑写入expect脚本中,通用性差。

【解决方法】
expect脚本采用tcl语法,原生态地支持socket。因此考虑用expect做一个ssh中转服务器
1,中转服务器先ssh登录系统,进入人机交互环境
2,然后启动一个socket服务器等待客户端的连接
3,当客户端发来交互命令时直接转发给spawn的ssh子进程处理
4,并将命令处理结果发送回客户端
以下是一段简单的代码,服务器端代码:
  1. #!/usr/bin/expect -f
  2. set timeout 60
  3. set user XXX
  4. set ip XXX
  5. set passwd XXX
  6. set prompt XXX

  7. set sent_passwd 0
  8. spawn ssh $user@$ip
  9. expect {
  10.         "yes/no" { send "yes\r";exp_continue }
  11.         "passwd" {
  12.                 if { $send_passwd == 0 } {
  13.                         send "$passwd\r";
  14.                         set send_passwd 1
  15.                         exp_continue
  16.                 } else {
  17.                         puts "passwd may be wrong"
  18.                         exit 1
  19.                 }
  20.         }
  21.         "$prompt" {  }
  22. }

  23. #以上代码实现ssh登录系统
  24. set ssh_agent [ socket -server accept 12345 ]
  25. proc accept { client addr port } {
  26.         puts "new client connected($addr:$port)"
  27.         gets $client cmd
  28.         send "$cmd\r"
  29.         expect "(.*)$prompt"
  30.         set result_list [ split $expect_out(1,string) "\n" ]
  31.         for line $result_list { #似乎puts每次只能发送一行内容??
  32.                 puts $client $line
  33.         }
  34.         puts $client "<result_end>" #发送结束标识
  35.         flush $client
  36.         close $client
  37. }
  38. vwait forever
复制代码
客户端代码:
  1. #!/usr/bin/expect -f
  2. set cmd [join $argv " "]
  3. set client [socket 127.0.0.1 12345]
  4. puts $client $cmd
  5. flush $client
  6. while { 1 == 1 } {
  7.         gets $client line
  8.         if { $line == "<result_end>" } {
  9.                 break
  10.         }
  11.         puts $line
  12. }
  13. close $client
复制代码
上述代码没有经过严格测试(其实没有经过任何测试^_^),请大家批评指正。

【遗留问题】
expect中启动的socket服务器,当有客户端连接时,会执行accept函数。不同的客户端的accept函数似乎是并行执行的(可能是在不同线程中)
因此如果有多个客户端同时发送命令到服务器端,可能会有多个accept函数同时运行,会产生一些问题:
1,有可能会同时发送多条命令到ssh子进程,多条命令组合可能形成非法命令
2,输出结果混在一起,无法区分是那个客户端的命令执行结果
请问大神们,如何在accept函数上加上互斥锁的机制,让它同一时刻只能处理一个客户端的命令请求?
我现在想到的方法是在shell脚本中调用客户端,调用的时候用woodie大神的脚本串行化方法加锁
http://bbs.chinaunix.net/forum.p ... st%3D1%26digest%3D1

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
2 [报告]
发表于 2014-09-01 14:13 |只看该作者
回复 1# npc_hp110


1. 原意是...
  是解决问题还是增加问题...

2. sshpass
    sshpass -p passwrod ssh ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP