Python使用SocksiPy使paramiko庫通過Socks代理SSH連線伺服器
近期有使用Python通過SSH連線伺服器進行維護的需求,通過搜尋發現使用paramiko庫的居多,因此決定使用該庫。經過短時間的使用後發現paramiko沒有如Ruby的net/ssh一般很方便使用Socks代理的方法(可能有,出於自己初學的水平沒有發現吧,從Agent相關的類發現有一些轉發的痕跡,看程式碼依賴於具體的平臺,而且還訪問到環境變數,並且不確定能通過這些方法使用代理連線),希望只有寄託給其它的庫,通過再次搜尋發現有一些代理庫,只是用起來不順手,沒有試驗成功。最後在官方庫發現SocksiPy,可惜這個庫連最基本的“蟒蛇蛋”都沒有,從http://downloads.sourceforge.net/project/socksipy/socksipy/SocksiPy%201.00/SocksiPy.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fsocksipy%2Ffiles%2F&ts=1336581819&use_mirror=nchc
按照文件說明覆制socks.py到site-packages後開始使用,由於Socks5代理帶有使用者名稱口令認證,於是乎寫如下程式碼進行測試:
import socks import socket import paramiko socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, 'socks5.proxy.com', 1080, False, 'proxy_user', 'proxy_passwd') socket.socket = socks.socksocket client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('apps.server.com',22,username='appuser',password='apppasswd',timeout=20) stdin,stdout,stderr = client.exec_command('ps -ef | grep root') for std in stdout.readlines(): print std, client.close()
執行後發現報錯,內容大概是socket找不到proxy成員。通過檢視socks.py的程式碼,最後發現應該將proxy變數改為__proxy,看來大家都不大喜歡用使用者和口令驗證Socks伺服器,居然埋了這麼個地雷,將socks.py第190行修改如下:
self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5])
接下來執行,執行成功,返回輸出root使用者的所有程序列表。
代理通過繼承通用套接字擴充套件功能,只要將具有代理功能的套接字覆蓋系統預設的套接字就可以具有設定代理配置後的套接字通訊屬性,做得比較巧妙!