mar*_*opa 1 python ssh paramiko http-tunneling
我正在调整Python脚本以独立于操作系统并在Windows上运行.我已将其ssh系统调用更改为调用paramiko函数.我遇到了http代理身份验证的问题.在Unix(实际上是Cygwin)环境中,我会使用〜/ .ssh/config
Host *
ProxyCommand corkscrew http-proxy.example.com 8080 %h %p
Run Code Online (Sandbox Code Playgroud)
有没有办法使用或不使用开瓶器使用paramiko(或Python ssh模块)获得相同的?这篇文章似乎暗示了,但我不知道如何.
注意:我位于允许我仅使用端口80的防火墙后面.我需要控制Amazon ec2实例,因此我在这些机器上配置sshd服务器以侦听端口80.在我的cygwin + corkscrew原型中一切正常,但是我想有一个没有Cygwin的Python脚本.
您可以通过sock参数in 使用任何预先建立的会话到paramiko SSHClient.connect(hostname,username,password,...,sock).
下面是通过HTTP-Proxy-Tunnel(HTTP-CONNECT)隧道SSH的代码片段.首先建立与代理的连接,并指示代理连接到localhost:22.结果是建立会话上的TCP隧道,通常用于隧道SSL,但可用于任何基于tcp的协议.
此方案适用于tinyproxy使用Allow <yourIP>和ConnectPort 22设置的默认安装/etc/tinyproxy.conf.代理和sshd在我的示例中运行在同一主机上,但您只需要任何允许您访问CONNECTssh端口的代理.通常这仅限于端口443(提示:如果你使用sshd监听443,这将适用于大多数公共代理,即使我认为我不建议为了互操作和安全原因这样做).如果这最终允许您绕过防火墙取决于使用何种防火墙.如果没有涉及DPI/SSL-Interception功能,你应该没问题.如果涉及SSL-Interception,你仍然可以尝试通过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()
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
这里 有一些关于如何通过代理隧道的其他资源.只需执行建立隧道所需的任何内容并将套接字传递给SSHClient.connect(...,sock)
| 归档时间: |
|
| 查看次数: |
5335 次 |
| 最近记录: |