Skip to content

Commit

Permalink
新增选择本地文件上传密钥,上传后将密钥信息保存到数据库,连接时从数据库读取 (#1303)
Browse files Browse the repository at this point in the history
* # 新增 pkey 目录挂载

* # 修改显示名称,引导用户填写 pkey 文件的名称

* # 新增 ssh tunnel keys 默认存放文件夹

* # 将数据库的 pkey 名字与 pkey 目录拼接

* # 后台 django q 菜单改为中文

* # 对应增加 pkey 文本框

* # 通过 form 读取秘钥信息

* # 新增 pkey 字段存储密钥信息

* # 改为使用 pkey 文件对象进行登录

* # 新增 pkey 字段存储密钥信息

* #

* # 改为传入 pkey

* # 新增本地保存 pkey 的路径

* Update models.py

* # 设置为相对路径

* #

* #

* # 修复当填写了秘钥路径,秘钥文件不存在时的异常

* # pkey 字段改为 EncryptedTextField

* # ssh 隧道功能修改

Co-authored-by: 小圈圈 <rtttte@qq.com>
  • Loading branch information
issacmark and hhyo authored Jan 13, 2022
1 parent c996a87 commit d9763eb
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 9 deletions.
8 changes: 8 additions & 0 deletions archery/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,11 @@
# },
}
}

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
if not os.path.exists(MEDIA_ROOT):
os.mkdir(MEDIA_ROOT)

PKEY_ROOT = os.path.join(MEDIA_ROOT, 'keys')
if not os.path.exists(PKEY_ROOT):
os.mkdir(PKEY_ROOT)
7 changes: 5 additions & 2 deletions sql/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
WorkflowAudit, WorkflowLog, ParamTemplate, ParamHistory, InstanceTag, \
Tunnel, AuditEntry

from sql.form import TunnelForm


# 用户管理
@admin.register(Users)
Expand Down Expand Up @@ -87,13 +89,14 @@ class TunnelAdmin(admin.ModelAdmin):
search_fields = ('id', 'tunnel_name')
fieldsets = (
None,
{'fields': ('tunnel_name', 'host', 'port', 'user', 'password', 'pkey_path', 'pkey_password',), }),
{'fields': ('tunnel_name', 'host', 'port', 'user', 'password', 'pkey_path', 'pkey_password', 'pkey'), }),
ordering = ('id',)
# 添加页显示内容
add_fieldsets = (
('隧道信息', {'fields': ('tunnel_name', 'host', 'port')}),
('连接信息', {'fields': ('user', 'password', 'pkey_path', 'pkey_password')}),
('连接信息', {'fields': ('user', 'password', 'pkey_path', 'pkey_password', 'pkey')}),
)
form = TunnelForm

def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name in ['password', 'pkey_password']:
Expand Down
4 changes: 2 additions & 2 deletions sql/engines/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(self, instance=None):
instance.tunnel.port,
instance.tunnel.user,
instance.tunnel.password,
instance.tunnel.pkey_path,
instance.tunnel.pkey,
instance.tunnel.pkey_password,
)
self.host,self.port = self.ssh.get_ssh()
Expand All @@ -48,7 +48,7 @@ def remote_instance_conn(self, instance=None):
instance.tunnel.port,
instance.tunnel.user,
instance.tunnel.password,
instance.tunnel.pkey_path,
instance.tunnel.pkey,
instance.tunnel.pkey_password,
)
self.remote_host, self.remote_port = self.remotessh.get_ssh()
Expand Down
32 changes: 32 additions & 0 deletions sql/form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
"""
---------------------------------------------------------
@project: issacmarkArchery
@file: form
@date: 2021/12/30 17:43
@author: mayp
---------------------------------------------------------
"""
from django.forms import ModelForm, Textarea
from sql.models import Tunnel
from django.core.exceptions import ValidationError


class TunnelForm(ModelForm):
class Meta:
model = Tunnel
fields = "__all__"
widgets = {
'PKey': Textarea(attrs={'cols': 40, 'rows': 8}),
}

def clean(self):
cleaned_data = super().clean()
if cleaned_data.get('pkey_path'):
try:
pkey_path = cleaned_data.get('pkey_path').read()
if pkey_path:
cleaned_data['pkey'] = str(pkey_path, 'utf-8').replace(r'\r', '').replace(r'\n', '')
except IOError:
raise ValidationError("秘钥文件不存在, 请勾选秘钥路径的清除选项再进行保存")
11 changes: 9 additions & 2 deletions sql/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,21 @@ class Tunnel(models.Model):
port = models.IntegerField('端口', default=0)
user = fields.EncryptedCharField(verbose_name='用户名', max_length=200, default='', blank=True, null=True)
password = fields.EncryptedCharField(verbose_name='密码', max_length=300, default='', blank=True, null=True)
pkey_path = fields.EncryptedCharField(verbose_name='密钥地址', max_length=300, default='', blank=True, null=True)
pkey = fields.EncryptedTextField(verbose_name="密钥", blank=True, null=True)
pkey_path = models.FileField(verbose_name="密钥地址", blank=True, null=True, upload_to='keys/')
pkey_password = fields.EncryptedCharField(verbose_name='密钥密码', max_length=300, default='', blank=True, null=True)
create_time = models.DateTimeField('创建时间', auto_now_add=True)
update_time = models.DateTimeField('更新时间', auto_now=True)

def __str__(self):
return self.tunnel_name

def short_pkey(self):
if len(str(self.pkey)) > 20:
return '{}...'.format(str(self.pkey)[0:19])
else:
return str(self.pkey)

class Meta:
managed = True
db_table = 'ssh_tunnel'
Expand Down Expand Up @@ -878,4 +885,4 @@ def __unicode__(self):

def __str__(self):
return '{0} - {1} - {2} - {3} - {4}'.format(self.user_id, self.user_name, self.ip
, self.action, self.action_time)
, self.action, self.action_time)
11 changes: 8 additions & 3 deletions sql/utils/ssh_tunnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@
"""
from sshtunnel import SSHTunnelForwarder
from paramiko import RSAKey
import io


class SSHConnection(object):
"""
ssh隧道连接类,用于映射ssh隧道端口到本地,连接结束时需要清理
"""
def __init__(self, host, port, tun_host, tun_port, tun_user, tun_password, pkey_path, pkey_password):
def __init__(self, host, port, tun_host, tun_port, tun_user, tun_password, pkey, pkey_password):
self.host = host
self.port = int(port)
self.tun_host = tun_host
self.tun_port = int(tun_port)
self.tun_user = tun_user
self.tun_password = tun_password

if pkey_path:
self.private_key = RSAKey.from_private_key_file(pkey_path, password=pkey_password)
if pkey:
private_key_file_obj = io.StringIO()
private_key_file_obj.write(pkey)
private_key_file_obj.seek(0)
self.private_key = RSAKey.from_private_key(private_key_file_obj, password=pkey_password)
self.server = SSHTunnelForwarder(
ssh_address_or_host=(self.tun_host, self.tun_port),
ssh_username=self.tun_user,
Expand Down
1 change: 1 addition & 0 deletions src/docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ services:
- "./archery/downloads:/opt/archery/downloads"
- "./archery/sql/migrations:/opt/archery/sql/migrations"
- "./archery/logs:/opt/archery/logs"
- "./archery/keys:/opt/archery/keys"
entrypoint: "dockerize -wait tcp://mysql:3306 -wait tcp://redis:6379 -timeout 60s /opt/archery/src/docker/startup.sh"
environment:
NGINX_PORT: 9123
3 changes: 3 additions & 0 deletions src/init_sql/v1.8.3.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ CREATE TABLE `audit_log` (
-- 新增my2sql菜单权限
set @content_type_id=(select id from django_content_type where app_label='sql' and model='permission');
INSERT INTO auth_permission (name, content_type_id, codename) VALUES ('菜单 My2SQL', @content_type_id, 'menu_my2sql');

-- ssh 隧道功能修改
ALTER TABLE `ssh_tunnel` ADD COLUMN pkey longtext NULL AFTER password DEFAULT CHARSET=utf8mb4 COMMENT='密钥信息';

0 comments on commit d9763eb

Please sign in to comment.