2010-08-26 39 views
2

從用Python編寫的HTTP RPC服務器啓動SSH隧道時,我遇到了麻煩。關於使用Python啓動SSH隧道的問題

有一個簡單的基於Python的BaseHTTPServer的Python編寫的HTTP RPC服務器。 作爲其中一項服務的一部分,我希望啓動從RPC服務器到遠程機器的SSH隧道。我以前使用os.system開始由RPC調用

os.system("ssh -f -n -N -L 127.0.0.1:%d:localhost:%d [email protected]%s" % (6800, 9000, "remote.machine")) 

調用一見鍾情Python腳本的SSH隧道一切似乎如隧道開始,我可以用它來很好,但有一件事我注意到。除了在端口6800上偵聽外,SSH也開始偵聽端口8001(運行HTTP RPC服務器的端口)。

下面是關於RPC服務器和SSH lsof的輸出:

rpc.py 27763 usern 5u IPv4 102130428  TCP 127.0.0.1:8001 (LISTEN) 
ssh  1951 usern 14u IPv4 102149728  TCP 127.0.0.1:6800 (LISTEN) 
ssh  1951 usern 5u IPv4 102130428  TCP 127.0.0.1:8001 (LISTEN) 

一切正常,直到RPC服務器的重啓。在重新啓動期間,RPC服務器被強制關閉與監聽套接字的連接,但SSH的連接保持打開狀態,並且RPC服務器無法再次在同一端口上啓動。

看來,SSH隧道也不知何故與RPC服務器的監聽套接字的FD本身相關聯。

任何人可以給出提示如何從腳本建立SSH隧道只假定端口(6800在這個例子中)上偵聽。

回答

0

我懷疑這事做與派生,然後告訴SSH從調用進程分離(「F」)。

而且,不知道這是否會幫助,但你應該使用的子模塊,如果你的Python是足夠現代的擁有它。

1

你有沒有使用paramiko你的SSH考慮? (取決於PyCrypto,但純Python)

這會使管理連接變得更簡單,並且根據服務器處理套接字的方式,您可能只需設置一個paramiko通道,然後讓服務器處理它就像任何其他監聽套接字一樣。

(中的paramiko,運輸對象表示基本SSH2連接,併爲每個傳輸,你可以創建多個頻道的對象,每個作爲一個下拉更換爲常規的Python插座)

這裏有在某些情況下,資源要看一看:

+0

有沒有進展?如果他們提供狀態更新,我們通常會更好地幫助人們。 – ssokolow 2010-09-20 09:39:07

2

代替使用os.system的(),嘗試使用subprocess.Popen(),並設置close_fds =真(可在Python 2.4和更高)。

import subprocess  
subprocess.Popen("ssh -f -n -N -L 127.0.0.1:%d:localhost:%d [email protected]%s" % (6800, 9000, "remote.machine"), shell=True, close_fds=True) 

從理論上講,我相信你也應該能夠使用的fcntl來設置監聽套接字的文件描述符的close-on-EXEC調用使用os.system(FD_CLOEXEC)前()。

+0

Popen列表。如果你.split()那個字符串你應該有效。 – 2014-09-16 16:17:35

+0

從文檔:「參數應該是一個字符串或程序參數序列」「在UNIX上,使用shell = True:如果args是一個字符串,它指定要通過shell執行的命令字符串。」 – abonet 2014-09-17 17:05:33

+0

你說得對。當我使用這種方法時,我出於不同原因出錯。 – 2014-09-17 20:33:50