2012-05-07 4 views
1

저는 Python 스크립트를 OS 독립적으로 적용하고 Windows에서 실행합니다. 나는 ssh 시스템 호출을 paramiko 함수 호출로 변경했다. 나는 http 프록시 인증 문제에 봉착했다. 유닉스 (실제로 Cygwin에서) 환경에서 나는 같은 사용 paramiko (또는 파이썬 SSH 모듈) 중 하나를 사용하거나 코르크를 사용하지를 얻을 수있는 방법이 있나요 ~/스푸핑/설정파이썬에서 http 프록시를 통해 ssh하는 방법은 무엇입니까?

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

사용해야합니까? This post 그걸 제안하는 것 같지만, 어떻게해야할지 모르겠다.

참고 : 방화벽으로 인해 포트 80 만 사용할 수 있습니다. Amazon ec2 인스턴스를 제어해야 포트 80을 수신 대기하도록 해당 시스템에서 sshd 서버를 구성 할 수 있습니다. Cygwin + 코르크 따개 프로토 타입,하지만 Cygwin없이 작동하는 Python 스크립트를 갖고 싶습니다.

답변

1

Paramiko에 대한 프록시 지원을 구현하는 paraproxy이 있습니다.

당신이 Paramiko가 임의의 소켓을 통해 작동 할 수있는 suggets에 링크 된 게시물이지만 그 경우는 아닌 것으로 보입니다. 실제로, paraproxy는 paramiko 내부의 특정 메소드를 대체함으로써 완성됩니다. 기존 코드는 소켓을 얻기 위해 socket.socket()을 호출하기 만하고 프록시에 연결하는 방법을 제공하지 않기 때문입니다.

+0

OP는 Windows 지원을 요청했지만 Paraproxy 1.2 README : Portability 에 따르면 유닉스 도메인 소켓은 마술을해야합니다. 결과적으로 Linux 및 MacOS에서만 에 대한 지원이 가능합니다 (Win32 지원 요구에 따라 변경 될 수 있음). –

+0

프록시 지원을 사용하여 Paramiko를 패치하는 기술을 여전히 보여줍니다. 다행히 누군가가 더 좋은 대답을 찾을 것입니다. – larsks

4

SSHClient.connect(hostname,username,password,...,sock)sock 매개 변수를 통해 paramiko에 미리 설정된 세션을 사용할 수 있습니다.

다음은 HTTP 프록시 터널 (HTTP-CONNECT)을 통해 SSH를 터널하는 코드 스 니펫입니다. 처음에는 프록시에 대한 연결이 설정되고 프록시는 localhost : 22에 연결하도록 지시됩니다. 그 결과 SSL을 터널링하는 데 일반적으로 사용되는 설정된 세션에 대한 TCP 터널이 있지만 모든 TCP 기반 프로토콜에 사용할 수 있습니다.

이 시나리오는 /etc/tinyproxy.conf에 설정되는 Allow <yourIP>ConnectPort 22tinyproxy의 기본 설치와 함께 작동합니다. 프록시와 sshd는 예제에서 동일한 호스트에서 실행되지만, 사용자가 필요로하는 것은 ssh 포트에 CONNECT을 허용하는 프록시입니다. 대개 이것은 포트 443으로 제한됩니다 (힌트 : sshd가 443을 듣게하면 대부분의 공개 프록시에서 작동합니다. interop 및 보안상의 이유로 권장하지 않습니다). 궁극적으로 방화벽을 우회 할 수있는 경우 어떤 종류의 방화벽이 사용되는지에 따라 다릅니다. 관련된 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에 다른 자원을 어떻게 프록시를 통해 터널 . 터널을 설정하고 소켓을 넘기는 데 필요한 것은 무엇이든 할 수 있습니다.

관련 문제