使用ssh创build隧道时,Command或Shell任务挂起

我正在使用Ansible推送configuration。 我有一个剧本里面的任务,我想在MongoDB的后台启动一个SSH隧道。 我正在使用的任务命令是

- name: Start tunnel service shell: ssh -f -N -L 27018:localhost:27017 mongo@remote-server 

但是无论我做什么,我都不可能继续下去。 相反,它会挂起或者像是在等待某个东西来返回响应。 如果我在正常情况下在shell中运行这个命令,它没有任何问题,我可以连接到远程mongo实例。

起初我以为是因为我正在build立一个新的服务器,ssh的known_hosts正在等待用户回应是/否继续前进。 在这种情况下,我尝试了两个选项。 首先,我尝试将服务器的指纹添加到known_hosts文件中。 从shell运行后,它并没有要求一个known_hosts条目,但是ansible也是挂着的。 我也试过了

 ssh -o StrictHostKeyChecking=no -f -N -L 27018:localhost:27017 mongo@remote-server 

但是,这个选项也会产生同样的问题。

我尝试在ansible的命令和shell模块之间切换,而不会对问题做任何改变。 我最近的实验是在命令前尝试nohup,但是这也不起作用。

 nohup ssh -f -N -L 27018:localhost:27017 mongo@remote-server 

也试图得到有创造力的想法,如果一个不同的过程能够运行命令,然后它会发送一个响应回合,我试图把它作为一个Upstart任务包装。 我把shell命令放在一个/etc/tunnel.sh文件中,并且把upstart脚本放在/etc/init/tunnel.conf 。 但是这也不起作用,似乎实际启动脚本时遇到麻烦。 如果我运行sudo service tunnel start它将启动,但有麻烦停止。 尽pipe通过一个命令来执行这个命令并没有做任何事情,只是像所有其他的实验一样坐在那里挂起来。

 - name: Start tunnel service command service tunnel start 

如果你使用sudo和一个键,我会打赌你不保留SSH_AUTH_SOCK环境variables。 这将是必需的,以build立从协调的机器到mongodb实例的连接。 在这种情况下,你应该在/ etc / sudoers中添加如下内容:

 Defaults env_keep+=SSH_AUTH_SOCK Defaults env_reset 

我做了同样的testing,发现是因为ssh命令在第一次使用ssh的时候请求指纹确认 ,所以无法正常工作,无法处理远程提示。

简单的方法可以调整你的SSH隧道命令如下:

 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -f -N -L 27018:localhost:27017 mongo@remote-server 

它会绕过主机检查,并把你的任务通过。

您也可以使用ansible的asynchronous操作( http://docs.ansible.com/playbooks_async.html

 - name: Start tunnel service shell: ssh -f -N -L 27018:localhost:27017 mongo@remote-server async: 15 poll: 5 

这将允许完成任务,使其最多15秒运行时间来执行并每5秒轮询完成一次。

而不是nohup,为什么不尝试使用screen呢?

 ssh user@server screen -dR command 

screen是好多了,因为你可以用CTRL-A,D分离会话,然后注销,当你需要回到会话后,用SSHlogin到服务器,然后按CTRL-A,1或者继续点击CTRL-A,直到它加载会话。