Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增选择本地文件上传密钥,上传后将密钥信息保存到数据库,连接时从数据库读取 #1303

Merged
merged 27 commits into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6d0bab6
# 新增 pkey 目录挂载
issacmark Dec 28, 2021
31e00e6
# 修改显示名称,引导用户填写 pkey 文件的名称
issacmark Dec 28, 2021
cce914c
# 新增 ssh tunnel keys 默认存放文件夹
issacmark Dec 28, 2021
0902cfb
# 将数据库的 pkey 名字与 pkey 目录拼接
issacmark Dec 28, 2021
5b71dd7
# 后台 django q 菜单改为中文
issacmark Dec 29, 2021
88821c4
# 对应增加 pkey 文本框
issacmark Dec 30, 2021
beb2112
# 通过 form 读取秘钥信息
issacmark Dec 30, 2021
32e2422
# 新增 pkey 字段存储密钥信息
issacmark Dec 31, 2021
c33d6c1
Merge remote-tracking branch 'origin/new_pr' into new_pr
issacmark Dec 31, 2021
a34d3e1
# 改为使用 pkey 文件对象进行登录
issacmark Dec 31, 2021
166ac3b
# 新增 pkey 字段存储密钥信息
issacmark Dec 31, 2021
a2cdf04
#
issacmark Dec 31, 2021
a24f90c
# 改为传入 pkey
issacmark Dec 31, 2021
0ce4f40
# 新增本地保存 pkey 的路径
issacmark Dec 31, 2021
aa420a7
Update models.py
issacmark Dec 31, 2021
a4d66a8
Merge branch 'master' into new_pr
issacmark Dec 31, 2021
2b59a0f
# 设置为相对路径
issacmark Jan 4, 2022
d9f2ddf
Merge remote-tracking branch 'origin/new_pr' into new_pr
issacmark Jan 4, 2022
e88478c
#
issacmark Jan 4, 2022
5e31b8c
Merge branch 'master' into new_pr
issacmark Jan 4, 2022
99e262d
#
issacmark Jan 6, 2022
7eee255
Merge branch 'master' into new_pr
hhyo Jan 11, 2022
fd128c0
# 修复当填写了秘钥路径,秘钥文件不存在时的异常
issacmark Jan 12, 2022
ca9f519
# pkey 字段改为 EncryptedTextField
issacmark Jan 12, 2022
3b78bea
# ssh 隧道功能修改
issacmark Jan 12, 2022
6793607
Merge remote-tracking branch 'origin/new_pr' into new_pr
issacmark Jan 12, 2022
fe7fe9c
Merge branch 'master' into new_pr
hhyo Jan 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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='密钥信息';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个语句存在语法错误,还有pkey_path变成了filefield,确认下是否需要调整字段格式