python通过ssh配置交换机_如何在Python中通过ssh进行SSH交换?

I am adapting a Python script to be OS independent and run on Windows. I have changed its ssh system calls to calls to paramiko functions. I am stuck with the issue of http proxy authentication. In Unix (actually Cygwin) environment I would use ~/.ssh/config

Host *

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

Is there a way to obtain the same using paramiko (or the Python ssh module) either using or not using corkscrew? This post seems to suggest that, but I don't know how.

Note: I am behind a firewall that allows me to use only port 80. I need to control Amazon ec2 instances so I configured the sshd server on those machines to listen to port 80. Everything is working fine in my cygwin+corkscrew prototype, but I would like to have a Python script that works without Cygwin.

解决方案

You can use any pre-established session to paramiko via the sock parameter in SSHClient.connect(hostname,username,password,...,sock).

Below is a code-snippet that tunnels SSH via HTTP-Proxy-Tunnel (HTTP-CONNECT). At first the connection to the proxy is established and the proxy is instructed to connect to localhost:22. The result is a TCP tunnel over the established session that is usually used to tunnel SSL but can be used for any tcp based protocol.

This scenario works with a default installation of tinyproxy with Allow and ConnectPort 22 being set in /etc/tinyproxy.conf. The proxy and the sshd are running on the same host in my example but all you need is any proxy that allows you to CONNECT to your ssh port. Usually this is restricted to port 443 (hint: if you make your sshd listen on 443 this will work with most of the public proxies even thought I do not recommend to do this for interop and security reasons). If this ultimately allows you to bypass your firewall depends on what kind of firewall is employed. If there's no DPI/SSL-Interception features involved, you should be fine. If there's SSL-Interception involved you could still try to tunnel it via ssl or as part of HTTP payload :)

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("

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()

output:

DEBUG:xxx:--start--

DEBUG:xxx:connected

DEBUG:xxx:--> 'CONNECT 192.168.139.128:22 HTTP/1.1\r\n\r\n'

DEBUG:xxx:

#> whoami

root

here are some other resources on how to tunnel through proxies. Just do whatever is needed to establish your tunnel and pass the socket to SSHClient.connect(...,sock)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值