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对用户名和密码编码。