Python 利用socket 实现 s

发布时间:2019-09-18 07:22:09编辑:auto阅读(1475)

    1.场景描述:


    主机A主机B主机C

    10.13.170.76

    172.28.117.156(squid)10.95.113.131

        主机A---->主机B(80)--->主机C(22), A通过B的80访问主机C131 


    2.Python代码;

    import paramiko
    import socket
    import logging
    from base64 import b64encode
    import time
    
    logging.basicConfig(loglevel=logging.DEBUG)
    LOG = logging.getLogger("squid")
    
    
    def http_proxy(proxy,target,auth=None, 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" % target
        if auth is not None:
            cmd_connect += " : basic %s\r\n" % b64encode('%s:%s' % auth)
        cmd_connect += "\r\n"
        LOG.debug("--> %s" % str(cmd_connect))
        sock.sendall(cmd_connect)
        response = []
        sock.settimeout(2)  
        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: 
                    break
                response.append(chunk)
                if "\r\n\r\n" in chunk: 
                    break
        except socket.error,se:
            if "timed out" not in se:
                response = [se]
        response = ''.join(response)
        LOG.debug("<-- %s" % str(response))
        if "200 connection established" not in response.lower():
            raise Exception("Unable to establish HTTP-Tunnel: %s" % str(response))
        return sock
    
    
    if __name__ == "__main__":
        LOG.setLevel(logging.DEBUG)
        LOG.debug("--start--")
        sock = http_proxy(proxy=("172.28.117.157", 80),
                          target=("10.95.113.131", 22),
                          auth=('germany', 'germany'),
                          timeout=50)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname="10.95.113.131", sock=sock, username="root", password="123")
        # time.sleep(100)
        print "#> login users \n%s" % ssh.exec_command("w")[1].read()

    运行结果:

    /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/germany/workspace/python2_study/python_squid.py
    DEBUG:squid:--start--
    DEBUG:squid:connected
    DEBUG:squid:--> CONNECT 10.95.113.131:22 HTTP/1.1
    proxy-authorization: basic Z2VybWFueTpnZXJtYW55
    
    
    DEBUG:squid:<-- HTTP/1.0 200 Connection established
    
    
    #> login user 
     15:23:01 up 102 days,  7:57,  1 user,  load average: 0.04, 0.09, 0.14
    USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    172.28.117.157   15:03   11:20   0.01s  0.01s -bash
    
    
    Process finished with exit code 0

    3.总结:

        主要在于生成paramiko中connect连接中需要的代理sock,其中连接squid是采用http tunnel,http tunnel 有connect报文,socket中拼接相对应的报文格式  就能与squid建立连接。由于squid使用的是Basic auth 因此需要使用 b64encode对用户名和密码编码。

关键字