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
原文地址:http://germanygu.blog.51cto.com/3574209/1952670