1. 程式人生 > >Python 利用socket 實現 ssh 跳轉

Python 利用socket 實現 ssh 跳轉

socket python squid

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對用戶名和密碼編碼。

本文出自 “linux運維” 博客,請務必保留此出處http://germanygu.blog.51cto.com/3574209/1952670

Python 利用socket 實現 ssh 跳轉