如何在Python中的http代理的ssh?(How to ssh over http proxy

2019-06-24 06:09发布

我适应一个Python脚本是独立于操作系统和在Windows上运行。 我已经改变了SSH的系统调用来调用的paramiko功能。 我坚持HTTP代理验证的问题。 在UNIX(实际上Cygwin的)环境中我会使用的〜/ .ssh / config中

Host *
    ProxyCommand corkscrew http-proxy.example.com 8080 %h %p

有没有一种方法来获得使用的paramiko相同(或Python的SSH模块)或者使用或不使用开瓶器? 这篇文章似乎表明,但我不知道怎么办。

注:我是一个防火墙,让我只使用端口80。我需要控制的Amazon EC2实例,所以我配置在这些机器上sshd服务器监听端口80。一切都在我的cygwin +开瓶器原型做工精细的背后,却我想有一个Python脚本,没有Cygwin的工作。

Answer 1:

你可以使用任何预建立的会话通过到的paramiko sock参数SSHClient.connect(hostname,username,password,...,sock)

下面是一个代码段,其经由HTTP代理隧道(HTTP-CONNECT)隧道SSH。 起初的代理连接建立和代理指示连接到本地主机:22。 其结果是在其通常用于隧道SSL,但可以用于任何基于TCP协议所建立的会话的TCP隧道。

此方案具有的默认安装工程tinyproxyAllow <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

这里 是如何通过代理隧道一些其他资源。 只要做到无论是需要建立的隧道和插座传递给SSHClient.connect(...,sock)



Answer 2:

有paraproxy ,它实现了的paramiko代理支持。

后您链接到suggets说的paramiko可以在运行任意插座,但不会出现这种情况。 事实上,paraproxy作品完成更换里面的paramiko具体的方法,因为现有的代码只需调用socket.socket()来获得一个套接字并没有提供在代理挂钩的任何方式。



文章来源: How to ssh over http proxy in Python?