Skip to content

Commit

Permalink
ver1.1.0 支持ssh和telnet协议连接远程主机
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed Jul 31, 2019
1 parent a111937 commit 6fde80d
Show file tree
Hide file tree
Showing 85 changed files with 1,128 additions and 177 deletions.
224 changes: 151 additions & 73 deletions .idea/workspace.xml

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ python3 manage.py runserver
![效果](https://github.com/leffss/devops/blob/master/screenshots/6.PNG?raw=true)
![效果](https://github.com/leffss/devops/blob/master/screenshots/7.PNG?raw=true)
![效果](https://github.com/leffss/devops/blob/master/screenshots/8.PNG?raw=true)
![效果](https://github.com/leffss/devops/blob/master/screenshots/9.PNG?raw=true)


# TODO LISTS
- [x] 用户登陆
- [ ] 查看用户信息
- [ ] 修改用户信息
- [ ] 修改用户密码
- [x] 修改用户密码
- [ ] 重置用户密码
- [x] 查看用户
- [x] 查看用户组
Expand All @@ -50,9 +51,12 @@ python3 manage.py runserver
- [ ] 修改主机用户
- [ ] 删除主机
- [ ] 删除主机用户
- [ ] 主机信息自动获取
- [ ] 主机监控信息查看(zabbix调用)
- [ ] 批量命令
- [ ] 批量脚本
- [x] web终端
- [x] webssh终端
- [x] webtelnet终端
- [ ] 文件上传
- [ ] 文件下载
- [x] 用户日志审计
Expand Down
Binary file modified db.sqlite3
Binary file not shown.
Binary file modified devops/__pycache__/routing.cpython-37.pyc
Binary file not shown.
Binary file modified devops/__pycache__/settings.cpython-37.pyc
Binary file not shown.
Binary file modified devops/__pycache__/urls.cpython-37.pyc
Binary file not shown.
34 changes: 27 additions & 7 deletions devops/routing.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from webssh import routing as websshrouting
from websocket import routing as websocketrouting
from webssh.websocket import WebSSH
from webtelnet.websocket import WebTelnet
from django.urls import path

application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
websshrouting.websocket_urlpatterns,

application = ProtocolTypeRouter(
{
'websocket': AuthMiddlewareStack(
URLRouter(
websocketrouting.websocket_urlpatterns
)
)
),
})
}
)

# or like this
# application = ProtocolTypeRouter(
# {
# 'websocket': AuthMiddlewareStack(
# URLRouter(
# [
# path('webssh/', WebSSH),
# path('webtelnet/', WebTelnet),
# ]
# )
# )
# }
# )
1 change: 1 addition & 0 deletions devops/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
'server',
'user',
'webssh',
'webtelnet',
]

MIDDLEWARE = [
Expand Down
1 change: 1 addition & 0 deletions devops/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
path('server/', include('server.urls')),
path('user/', include('user.urls')),
path('webssh/', include('webssh.urls')),
path('webtelnet/', include('webtelnet.urls')),
]
Binary file modified screenshots/6.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/9.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified server/__pycache__/models.cpython-37.pyc
Binary file not shown.
Binary file modified server/__pycache__/views.cpython-37.pyc
Binary file not shown.
23 changes: 23 additions & 0 deletions server/migrations/0004_auto_20190730_1544.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.2.3 on 2019-07-30 15:44

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('server', '0003_auto_20190730_0956'),
]

operations = [
migrations.AddField(
model_name='host',
name='protocol',
field=models.SmallIntegerField(choices=[(0, '其他'), (1, 'ssh'), (2, 'telnet'), (3, 'rdp'), (4, 'vnc'), (5, 'sftp'), (6, 'ftp')], default=1, verbose_name='协议'),
),
migrations.AlterField(
model_name='remoteuser',
name='enabled',
field=models.BooleanField(default=False, verbose_name='登陆后是否su跳转超级用户'),
),
]
17 changes: 17 additions & 0 deletions server/migrations/0005_auto_20190730_1704.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 2.2.3 on 2019-07-30 17:04

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('server', '0004_auto_20190730_1544'),
]

operations = [
migrations.AlterUniqueTogether(
name='host',
unique_together={('ip', 'protocol', 'port')},
),
]
24 changes: 24 additions & 0 deletions server/migrations/0006_auto_20190731_0834.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 2.2.3 on 2019-07-31 08:34

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('server', '0005_auto_20190730_1704'),
]

operations = [
migrations.AlterField(
model_name='remoteuserbindhost',
name='host',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='server.Host'),
),
migrations.AlterField(
model_name='remoteuserbindhost',
name='remote_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='server.RemoteUser'),
),
]
23 changes: 23 additions & 0 deletions server/migrations/0007_auto_20190731_0925.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.2.3 on 2019-07-31 09:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('server', '0006_auto_20190731_0834'),
]

operations = [
migrations.AddField(
model_name='host',
name='type',
field=models.SmallIntegerField(choices=[(0, '其他'), (1, '服务器'), (2, '防火墙'), (3, '路由器'), (4, '二层交换机'), (5, '三层交换机'), (6, '虚拟机'), (7, 'PC机')], default=1, verbose_name='类型'),
),
migrations.AlterField(
model_name='host',
name='release',
field=models.CharField(default='CentOS', max_length=255, verbose_name='系统/型号'),
),
]
18 changes: 18 additions & 0 deletions server/migrations/0008_host_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.3 on 2019-07-31 15:38

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('server', '0007_auto_20190731_0925'),
]

operations = [
migrations.AddField(
model_name='host',
name='env',
field=models.SmallIntegerField(choices=[(0, '其他'), (1, '正式环境'), (2, '测试环境')], default=1, verbose_name='环境'),
),
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
37 changes: 32 additions & 5 deletions server/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,38 @@

# Create your models here.
class Host(models.Model):
PROTOCOL_CHOICES = ( # 目前支持ssh, telnet
(0, '其他'),
(1, 'ssh'),
(2, 'telnet'),
(3, 'rdp'),
(4, 'vnc'),
(5, 'sftp'),
(6, 'ftp'),
)
TYPE_CHOICES = (
(0, '其他'),
(1, '服务器'),
(2, '防火墙'),
(3, '路由器'),
(4, '二层交换机'),
(5, '三层交换机'),
(6, '虚拟机'),
(7, 'PC机'),
)
ENV_CHOICES = (
(0, '其他'),
(1, '正式环境'),
(2, '测试环境'),
)
hostname = models.CharField(max_length=128, unique=True, verbose_name='主机名')
type = models.SmallIntegerField(default=1, choices=TYPE_CHOICES, verbose_name='类型')
ip = models.GenericIPAddressField(verbose_name='主机IP') # 做了ip映射,ip可能重复,ip:port 不会重复
wip = models.GenericIPAddressField(verbose_name='公网IP', blank=True, null=True)
protocol = models.SmallIntegerField(default=1, choices=PROTOCOL_CHOICES, verbose_name='协议')
env = models.SmallIntegerField(default=1, choices=ENV_CHOICES, verbose_name='环境')
port = models.SmallIntegerField(default=22, verbose_name='端口')
release = models.CharField(max_length=255, default='CentOS', verbose_name='发行版本')
release = models.CharField(max_length=255, default='CentOS', verbose_name='系统/型号')
memo = models.TextField(blank=True, null=True, verbose_name='备注')
create_time = models.DateTimeField('添加时间', auto_now_add=True)

Expand All @@ -18,7 +45,7 @@ class Meta:
ordering = ["-create_time"]
verbose_name = '主机'
verbose_name_plural = '主机'
unique_together = ('ip', 'port')
unique_together = ('ip', 'protocol', 'port')


class RemoteUser(models.Model):
Expand All @@ -44,9 +71,9 @@ class Meta:


class RemoteUserBindHost(models.Model):
# on_delete当RemoteUser记录被删时,本表的对应记录也会被删除或者设置为NULL
remote_user = models.ForeignKey('RemoteUser', blank=True, null=True, on_delete=models.SET_NULL)
host = models.ForeignKey('Host', on_delete=models.CASCADE)
# on_delete当Host, RemoteUser记录被删时,阻止其操作
host = models.ForeignKey('Host', on_delete=models.PROTECT)
remote_user = models.ForeignKey('RemoteUser', blank=True, null=True, on_delete=models.PROTECT)
enabled = models.BooleanField(default=True, verbose_name='是否启用')
create_time = models.DateTimeField('添加时间', auto_now_add=True)

Expand Down
4 changes: 4 additions & 0 deletions server/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from django.shortcuts import render
from util.tool import login_required, admin_required
from .models import RemoteUserBindHost, RemoteUser
from user.models import User, Group
# Create your views here.


@login_required
def index(request):
host_count = RemoteUserBindHost.objects.all().count()
user_count = User.objects.all().count()
group_count = Group.objects.all().count()
return render(request, 'server/index.html', locals())


Expand Down
2 changes: 1 addition & 1 deletion static/adminlte/dist/css/adminlte.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion static/adminlte/dist/css/adminlte.min.css

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions static/webssh/webssh.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,14 @@ function websocket() {
}
),
protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://',
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') +
'/webssh/?' + connect_info + '&width=' + cols + '&height=' + rows;
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/webssh/?' + connect_info + '&width=' + cols + '&height=' + rows;

var sock;
sock = new WebSocket(socketURL);

// 打开 websocket 连接, 打开 web 终端
sock.addEventListener('open', function () {
$('#django-webssh-terminal').removeClass('hide');
//$('#django-webssh-terminal').removeClass('hide');
term.open(document.getElementById('terminal'));
term.focus();
term.write('Connecting...\n\r');
Expand Down
98 changes: 98 additions & 0 deletions static/webtelnet/webtelnet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
function checkwindow() {
event.returnValue=false;
}

function get_connect_info() {
var hostid = $.trim($('#hostid').text());
var connect_info = 'hostid=' + hostid;
return connect_info
}


function get_term_size() {
var init_width = 9;
var init_height = 17;

var windows_width = $(window).width();
var windows_height = $(window).height();

return {
cols: Math.floor(windows_width / init_width),
rows: Math.floor(windows_height / init_height),
}
}


function websocket() {
var cols = get_term_size().cols;
var rows = get_term_size().rows;
var connect_info = get_connect_info();

var term = new Terminal(
{
cols: cols,
rows: rows,
useStyle: true,
cursorBlink: true
}
),
protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://',
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/webtelnet/?' + connect_info;

var sock;
sock = new WebSocket(socketURL);

// 打开 websocket 连接, 打开 web 终端
sock.addEventListener('open', function () {
//$('#django-webtelnet-terminal').removeClass('hide');
term.open(document.getElementById('terminal'));
term.focus();
term.write('Connecting...\n\r');
$("body").attr("onbeforeunload",'checkwindow()'); //增加刷新关闭提示属性

});

// 读取服务器端发送的数据并写入 web 终端
sock.addEventListener('message', function (recv) {
var data = JSON.parse(recv.data);
var message = data.message;
var status = data.status;
if (status === 0) {
term.write(message)
} else {
//window.location.reload() 端口连接后刷新页面
//term.clear()
term.write(message)
$("body").removeAttr("onbeforeunload"); //删除刷新关闭提示属性

//$(document).keyup(function(event){ // 监听回车按键事件
// if(event.keyCode == 13){
//window.location.reload();
// }
//});
//term.dispose()
//$('#django-webssh-terminal').addClass('hide');
//$('#form').removeClass('hide');
}
});

/*
* status 为 0 时, 将用户输入的数据通过 websocket 传递给后台, data 为传递的数据, 忽略 cols 和 rows 参数
*/
var message = {'status': 0, 'data': null, 'cols': null, 'rows': null};

// 向服务器端发送数据
term.on('data', function (data) {
message['status'] = 0;
message['data'] = data;
var send_data = JSON.stringify(message);
sock.send(send_data)
});

// 监听浏览器窗口, 根据浏览器窗口大小修改终端大小
$(window).resize(function () {
var cols = get_term_size().cols;
var rows = get_term_size().rows;
term.resize(cols, rows)
})
}
Loading

0 comments on commit 6fde80d

Please sign in to comment.