您可以通過SSHClient.connect(hostname,username,password,...,sock)
中的sock
參數將任何預先建立的會話使用到paramiko。
下面是通過HTTP-Proxy-Tunnel(HTTP-CONNECT)隧道SSH的代碼片段。首先建立與代理的連接,並指示代理連接到本地主機:22。結果是建立會話上的TCP隧道通常用於隧道SSL,但可用於任何基於tcp的協議。
此方案適用於默認安裝tinyproxy
,其中Allow <yourIP>
和ConnectPort 22
設置爲/etc/tinyproxy.conf
。在我的例子中,代理和sshd在同一主機上運行,但所有您需要的是允許您將CONNECT
加入到ssh端口的代理。通常這隻限於端口443(提示:如果你讓你的sshd在443上進行監聽,這將與大多數公共代理一起工作,即使我認爲我不建議這樣做是爲了互操作和安全的原因)。如果這最終允許您繞過防火牆,則取決於使用何種防火牆。如果沒有DPI/SSL攔截功能,你應該沒問題。如果有SSL攔截參與,你還可以通過SSL或HTTP有效載荷:)的一部分,它試圖隧道
import paramiko
import socket
import logging
logging.basicConfig(loglevel=logging.DEBUG)
LOG = logging.getLogger("xxx")
def http_proxy_tunnel_connect(proxy, target,timeout=None):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
sock.connect(proxy)
LOG.debug("connected")
cmd_connect = "CONNECT %s:%d HTTP/1.1\r\n\r\n"%target
LOG.debug("--> %s"%repr(cmd_connect))
sock.sendall(cmd_connect)
response = []
sock.settimeout(2) # quick hack - replace this with something better performing.
try:
# in worst case this loop will take 2 seconds if not response was received (sock.timeout)
while True:
chunk = sock.recv(1024)
if not chunk: # if something goes wrong
break
response.append(chunk)
if "\r\n\r\n" in chunk: # we do not want to read too far ;)
break
except socket.error, se:
if "timed out" not in se:
response=[se]
response = ''.join(response)
LOG.debug("<-- %s"%repr(response))
if not "200 connection established" in response.lower():
raise Exception("Unable to establish HTTP-Tunnel: %s"%repr(response))
return sock
if __name__=="__main__":
LOG.setLevel(logging.DEBUG)
LOG.debug("--start--")
sock = http_proxy_tunnel_connect(proxy=("192.168.139.128",8888),
target=("192.168.139.128",22),
timeout=50)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="192.168.139.128",sock=sock, username="xxxx", password="xxxxx")
print "#> whoami \n%s"% ssh.exec_command("whoami")[1].read()
輸出:
DEBUG:xxx:--start--
DEBUG:xxx:connected
DEBUG:xxx:--> 'CONNECT 192.168.139.128:22 HTTP/1.1\r\n\r\n'
DEBUG:xxx:<-- 'HTTP/1.0 200 Connection established\r\nProxy-agent: tinyproxy/1.8.3\r\n\r\n'
#> whoami
root
hereare一些其他資源如何通過代理隧道。只需做任何需要建立你的隧道,並通過套接字SSHClient.connect(...,sock)
該OP要求Windows支持,但根據Paraproxy 1.2自述:可移植性 Paraproxy需要unix域套接字來做它的魔力。 因此,支持僅適用於Linux和MacOS (這可能會根據對Win32支持的需求而改變)。 –
它仍然演示了一種用代理支持修補Paramiko的技術。希望有人會有更好的答案。 – larsks