Skip to content

Commit

Permalink
channel 实现堡垒机ssh代理访问
Browse files Browse the repository at this point in the history
  • Loading branch information
YoLoveLife committed Jan 12, 2018
1 parent c2a8848 commit 4d79164
Show file tree
Hide file tree
Showing 21 changed files with 2,987 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ travis & django TestCase</br>
本开发自运维平台致力于IT资源信息的整合与自动化运维,通过服务、应用配置的信息整合来运维提供帮助。</br>
devEops正在不断成长
- 所有运维操作都基于信息整合的正确性和一致性(资产信息管理) :floppy_disk: </br>
- 基于WebSocket以及SSHProxy的软件堡垒机 </br>
- :bar_chart: 提供资产信息的统计,应用系统的占比、脚本|剧本的调用次数等</br>
- ~~可临时搜集应用上的信息(如MySQL的status等信息)~~</br>
- ~~所有运维操作(脚本 | 剧本)在提交的时候会自动注入资产信息并通过ansible远程执行~~</br>
Expand Down
2 changes: 1 addition & 1 deletion apps/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "deveops.settings")
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(PROJECT_DIR)

print(sys.path)
try:
from django.core.management import execute_from_command_line
except ImportError:
Expand Down
43 changes: 27 additions & 16 deletions apps/manager/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,41 @@
# Time 18-1-11
# Author Yo
# Email [email protected]
from paramiko import SSHClient
from channels.handler import AsgiHandler
from channels.generic.websockets import WebsocketConsumer
import paramiko
class ManagerConsumer(WebsocketConsumer):
# http_user = True
# http_user_and_session = True
# channel_session = True
# channel_session_user = True

http_user_and_session = True

def connection_groups(self, **kwargs):
return ["test"]
target = paramiko.SSHClient()
jumper = paramiko.SSHClient()
# def connection_groups(self, **kwargs):
# return ["test"]

def connect(self, message, **kwargs):
print('connect')
# target = paramiko.SSHClient()

#DEMO
self.target.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.target.connect('114.55.126.93', username='root', key_filename='/root/.ssh/id_rsa', port=52000)
targettransport = self.target.get_transport()
dest_addr = ('10.101.30.188', 22)
local_addr = ('114.55.126.93', 52000)
targetchannel = targettransport.open_channel("direct-tcpip", dest_addr, local_addr)

self.jumper.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.jumper.connect('10.101.30.188', username='root', key_filename='/root/.ssh/id_rsa', sock=targetchannel,port=22)
print(self.jumper,'connect')
self.message.reply_channel.send({"accept": True})

def receive(self, text=None, bytes=None, **kwargs):
import os, commands
(status, output) = commands.getstatusoutput(text)
# list = output.split('\n')
# print(list)
# for i in list:
self.send(text=u'1', bytes=bytes)
self.send(text=u'2', bytes=bytes)
self.send(text=u'3', bytes=bytes)
(stdin, stdout, stderr) = self.jumper.exec_command(text)
print(self.jumper,'recevie')
self.send(text=stdout.read(), bytes=bytes)

def disconnect(self, message, **kwargs):
print('disconnect')
pass
self.jumper.close()
self.target.close()
2 changes: 2 additions & 0 deletions apps/manager/templates/manager/detail_host.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
{% block single-css %}
<link rel="stylesheet" type="text/css" href="{% static 'plugins/select2/select2.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'less/manager.less' %}">
<link rel="stylesheet" type="text/css" href="{% static 'plugins/xterm/xterm.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'plugins/xterm/addons/fullscreen/fullscreen.css' %}">
{% endblock %}
{% block content %}
<!--Content Header-->
Expand Down
43 changes: 43 additions & 0 deletions apps/manager/templates/manager/manager_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{% extends '_modal.html' %}
{% block modal_js %}
<script src="{% static 'plugins/xterm/xterm.js' %}"></script>
<script src="{% static 'plugins/xterm/addons/fullscreen/fullscreen.js' %}"></script>
<script>
function make_yoshell(ele,size){
var tem = new Terminal({
cols:40,
rows:120,
screenKeys: true,
useStyle: true,
cursorBlink: true
});
tem.open(ele,false);
var socket = new WebSocket("ws://" + "192.168.122.244:9999/host/{{ object.id }}/");
socket.onmessage = function (e) {

}
}
</script>
{% endblock %}
{% block modal_id %}
manager_modal
{% endblock %}
{% block modal_class %}
{% endblock %}
{% block modal_style %}
{% endblock %}
{% block modal_title %}
YoShell
{% endblock %}
{% block modal_body %}
<div class="row">
<div class="col-md-5">
<div id="yoshell">

</div>
</div>
</div>
{% endblock %}
{% block modal_confirm_id %}
manager_modal_btn
{% endblock %}
7 changes: 4 additions & 3 deletions apps/templates/_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ <h4 class="modal-title">{% block modal_title %}{% endblock %}</h4>
{% endblock %}
</div>
<div class="modal-footer">
<button data-dismiss="modal" class="btn btn-white" type="button">Close</button>
<button class="btn btn-primary" type="button" id="{% block modal_confirm_id %}{% endblock %}">Confirm</button>
<button data-dismiss="modal" class="btn btn-white" type="button">关闭</button>
<button class="btn btn-primary" type="button" id="{% block modal_confirm_id %}{% endblock %}">提交</button>
</div>
</div>
</div>
</div>
{% block modal_js %}{% endblock %}
{% block modal_js %}
{% endblock %}
130 changes: 130 additions & 0 deletions static/plugins/xterm/addons/attach/attach.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* Implements the attach method, that attaches the terminal to a WebSocket stream.
* @module xterm/addons/attach/attach
* @license MIT
*/

(function (attach) {
if (typeof exports === 'object' && typeof module === 'object') {
/*
* CommonJS environment
*/
module.exports = attach(require('../../xterm'));
} else if (typeof define == 'function') {
/*
* Require.js is available
*/
define(['../../xterm'], attach);
} else {
/*
* Plain browser environment
*/
attach(window.Terminal);
}
})(function (Xterm) {
'use strict';

var exports = {};

/**
* Attaches the given terminal to the given socket.
*
* @param {Xterm} term - The terminal to be attached to the given socket.
* @param {WebSocket} socket - The socket to attach the current terminal.
* @param {boolean} bidirectional - Whether the terminal should send data
* to the socket as well.
* @param {boolean} buffered - Whether the rendering of incoming data
* should happen instantly or at a maximum
* frequency of 1 rendering per 10ms.
*/
exports.attach = function (term, socket, bidirectional, buffered) {
bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
term.socket = socket;

term._flushBuffer = function () {
term.write(term._attachSocketBuffer);
term._attachSocketBuffer = null;
clearTimeout(term._attachSocketBufferTimer);
term._attachSocketBufferTimer = null;
};

term._pushToBuffer = function (data) {
if (term._attachSocketBuffer) {
term._attachSocketBuffer += data;
} else {
term._attachSocketBuffer = data;
setTimeout(term._flushBuffer, 10);
}
};

term._getMessage = function (ev) {
if (buffered) {
term._pushToBuffer(ev.data);
} else {
term.write(ev.data);
}
};

term._sendData = function (data) {
if (socket.readyState !== 1) {
return;
}

socket.send(data);
};

socket.addEventListener('message', term._getMessage);

if (bidirectional) {
term.on('data', term._sendData);
}

socket.addEventListener('close', term.detach.bind(term, socket));
socket.addEventListener('error', term.detach.bind(term, socket));
};

/**
* Detaches the given terminal from the given socket
*
* @param {Xterm} term - The terminal to be detached from the given socket.
* @param {WebSocket} socket - The socket from which to detach the current
* terminal.
*/
exports.detach = function (term, socket) {
term.off('data', term._sendData);

socket = (typeof socket == 'undefined') ? term.socket : socket;

if (socket) {
socket.removeEventListener('message', term._getMessage);
}

delete term.socket;
};

/**
* Attaches the current terminal to the given socket
*
* @param {WebSocket} socket - The socket to attach the current terminal.
* @param {boolean} bidirectional - Whether the terminal should send data
* to the socket as well.
* @param {boolean} buffered - Whether the rendering of incoming data
* should happen instantly or at a maximum
* frequency of 1 rendering per 10ms.
*/
Xterm.prototype.attach = function (socket, bidirectional, buffered) {
return exports.attach(this, socket, bidirectional, buffered);
};

/**
* Detaches the current terminal from the given socket.
*
* @param {WebSocket} socket - The socket from which to detach the current
* terminal.
*/
Xterm.prototype.detach = function (socket) {
return exports.detach(this, socket);
};

return exports;
});
93 changes: 93 additions & 0 deletions static/plugins/xterm/addons/attach/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="../../src/xterm.css" />
<link rel="stylesheet" href="../../demo/style.css" />
<script src="../../src/xterm.js"></script>
<script src="attach.js"></script>
<style>
body {
color: #111;
}

h1, h2 {
color: #444;
border-bottom: 1px solid #ddd;
text-align: left;
}

form {
margin-bottom: 32px;
}

input, button {
line-height: 22px;
font-size: 16px;
display: inline-block;
border-radius: 2px;
border: 1px solid #ccc;
}

input {
height: 22px;
padding-left: 4px;
padding-right: 4px;
}

button {
height: 28px;
background-color: #ccc;
cursor: pointer;
color: #333;
}

.container {
max-width: 900px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">

<h1>
xterm.js: socket attach
</h1>
<p>
Attach the terminal to a WebSocket terminal stream with ease. Perfect for attaching to your
Docker containers.
</p>
<h2>
Socket information
</h2>
<form id="socket-form">
<input id="socket-url"
type="text"
placeholder="Enter socket url (e.g. ws://mysock)"
autofocus />
<button>
Attach
</button>
</form>
<div id="terminal-container"></div>

</div>
<script>
var term = new Terminal(),
container = document.getElementById('terminal-container'),
socketUrl = document.getElementById('socket-url'),
socketForm = document.getElementById('socket-form');

socketForm.addEventListener('submit', function (ev) {
ev.preventDefault();
var url = socketUrl.value,
sock = new WebSocket(url);
sock.addEventListener('open', function () {
term.attach(sock);
});
});

term.open(container);
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions static/plugins/xterm/addons/attach/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "xterm.attach",
"main": "attach.js",
"private": true
}
Loading

0 comments on commit 4d79164

Please sign in to comment.