From 57155c246999d693a6e9bf9f9cf53e85b8b23e5a Mon Sep 17 00:00:00 2001
From: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com>
Date: Wed, 8 Jan 2020 12:17:56 +0800
Subject: [PATCH 1/4] =?UTF-8?q?[Update]=20=E6=9B=B4=E6=96=B0=20Readme=20(#?=
=?UTF-8?q?3608)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* [Update] readme 1
* [Update] readme 2
* [Update] readme 3
* [Update] readme 4
* [Update] readme 5
---
README.md | 301 +++++++++++++++++++++++++++---------------------------
1 file changed, 150 insertions(+), 151 deletions(-)
diff --git a/README.md b/README.md
index 37a703847..595677321 100644
--- a/README.md
+++ b/README.md
@@ -17,157 +17,156 @@ Jumpserver 采纳分布式架构,支持多机房跨区域部署,支持横向
## 核心功能列表
-
-
- 身份验证 Authentication |
- 登录认证
- |
- 资源统一登录和认证
- |
-
-
- LDAP 认证
- |
-
-
- 支持 OpenID,实现单点登录
- |
-
-
- 多因子认证
- |
- MFA(Google Authenticator)
- |
-
-
- 账号管理 Account |
- 集中账号管理
- |
- 管理用户管理
- |
-
-
- 系统用户管理
- |
-
-
- 统一密码管理
- |
- 资产密码托管
- |
-
-
- 自动生成密码
- |
-
-
- 密码自动推送
- |
-
-
- 密码过期设置
- |
-
-
- 批量密码变更(X-PACK)
- |
- 定期批量修改密码
- |
-
-
- 生成随机密码
- |
-
-
- 多云环境的资产纳管(X-PACK)
- |
- 对私有云、公有云资产统一纳管
- |
-
-
- 授权控制 Authorization |
- 资产授权管理
- |
- 资产树
- |
-
-
- 资产或资产组灵活授权
- |
-
-
- 节点内资产自动继承授权
- |
-
-
- RemoteApp(X-PACK)
- |
- 实现更细粒度的应用级授权
- |
-
-
- 组织管理(X-PACK)
- |
- 实现多租户管理,权限隔离
- |
-
-
- 多维度授权
- |
- 可对用户、用户组或系统角色授权
- |
-
-
- 指令限制
- |
- 限制特权指令使用,支持黑白名单
- |
-
-
- 统一文件传输
- |
- SFTP 文件上传/下载
- |
-
-
- 文件管理
- |
- Web SFTP 文件管理
- |
-
-
- 安全审计 Audit |
- 会话管理
- |
- 在线会话管理
- |
-
-
- 历史会话管理
- |
-
-
- 录像管理
- |
- Linux 录像支持
- |
-
-
- Windows 录像支持
- |
-
-
- 指令审计
- |
- 指令记录
- |
-
-
- 文件传输审计
- |
- 上传/下载记录审计
- |
-
+
+
+ 身份认证 Authentication |
+ 登录认证 |
+ 资源统一登录与认证 |
+
+
+ LDAP/AD 认证 |
+
+
+ RADIUS 认证 |
+
+
+ OpenID 认证(实现单点登录) |
+
+
+ MFA认证 |
+ MFA 二次认证(Google Authenticator) |
+
+
+ RADIUS 二次认证 |
+
+
+ 登录复核(X-PACK) |
+ 用户登录行为受管理员的监管与控制 |
+
+
+ 账号管理 Account |
+ 集中账号 |
+ 管理用户管理 |
+
+
+ 系统用户管理 |
+
+
+ 统一密码 |
+ 资产密码托管 |
+
+
+ 自动生成密码 |
+
+
+ 自动推送密码 |
+
+
+ 密码过期设置 |
+
+
+ 批量改密(X-PACK) |
+ 定期批量改密 |
+
+
+ 多种密码策略 |
+
+
+ 多云纳管(X-PACK) |
+ 对私有云、公有云资产自动统一纳管 |
+
+
+ 收集用户(X-PACK) |
+ 自定义任务定期收集主机用户 |
+
+
+ 密码匣子(X-PACK) |
+ 统一对资产主机的用户密码进行查看、更新、测试操作 |
+
+
+ 授权控制 Authorization |
+ 多维授权 |
+ 对用户、用户组、资产、资产节点、应用以及系统用户进行授权 |
+
+
+ 资产授权 |
+ 资产以树状结构进行展示 |
+
+
+ 资产和节点均可灵活授权 |
+
+
+ 节点内资产自动继承授权 |
+
+
+ 子节点自动继承父节点授权 |
+
+
+ 应用授权 |
+ 实现更细粒度的应用级授权 |
+
+
+ MySQL 数据库应用、RemoteApp 远程应用(X-PACK) |
+
+
+ 动作授权 |
+ 实现对授权资产的文件上传、下载以及连接动作的控制 |
+
+
+ 时间授权 |
+ 实现对授权资源使用时间段的限制 |
+
+
+ 特权指令 |
+ 实现对特权指令的使用(支持黑白名单) |
+
+
+ 命令过滤 |
+ 实现对授权系统用户所执行的命令进行控制 |
+
+
+ 文件传输 |
+ SFTP 文件上传/下载 |
+
+
+ 文件管理 |
+ 实现 Web SFTP 文件管理 |
+
+
+ 工单管理(X-PACK) |
+ 支持对用户登录请求行为进行控制 |
+
+
+ 组织管理(X-PACK) |
+ 实现多租户管理与权限隔离 |
+
+
+ 安全审计 Audit |
+ 操作审计 |
+ 用户操作行为审计 |
+
+
+ 会话审计 |
+ 在线会话内容审计 |
+
+
+ 历史会话内容审计 |
+
+
+ 录像审计 |
+ 支持对 Linux、Windows 等资产操作的录像进行回放审计 |
+
+
+ 支持对 RemoteApp(X-PACK)、MySQL 等应用操作的录像进行回放审计 |
+
+
+ 指令审计 |
+ 支持对资产和应用等操作的命令进行审计 |
+
+
+ 文件传输 |
+ 可对文件的上传、下载记录进行审计 |
+
## 安装及使用指南
From 1c9be184fd7f50d38fa0d93d7fe42df8c13d31e0 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 9 Jan 2020 11:16:13 +0800
Subject: [PATCH 2/4] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9LDAP=E8=AE=A4?=
=?UTF-8?q?=E8=AF=81=E9=80=BB=E8=BE=91=EF=BC=8C=E5=AF=86=E7=A0=81=E4=B8=BA?=
=?UTF-8?q?=E7=A9=BA=E6=97=B6=E8=AE=A4=E8=AF=81=E5=A4=B1=E8=B4=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/backends/ldap.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/apps/authentication/backends/ldap.py b/apps/authentication/backends/ldap.py
index bd1ce68b8..e01803707 100644
--- a/apps/authentication/backends/ldap.py
+++ b/apps/authentication/backends/ldap.py
@@ -27,13 +27,16 @@ class LDAPAuthorizationBackend(LDAPBackend):
is_valid = getattr(user, 'is_valid', None)
return is_valid or is_valid is None
- def pre_check(self, username):
+ def pre_check(self, username, password):
if not settings.AUTH_LDAP:
return False
logger.info('Authentication LDAP backend')
if not username:
logger.info('Authenticate failed: username is None')
return False
+ if not password:
+ logger.info('Authenticate failed: password is None')
+ return False
if settings.AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS:
user_model = self.get_user_model()
exist = user_model.objects.filter(username=username).exists()
@@ -44,7 +47,7 @@ class LDAPAuthorizationBackend(LDAPBackend):
return True
def authenticate(self, request=None, username=None, password=None, **kwargs):
- match = self.pre_check(username)
+ match = self.pre_check(username, password)
if not match:
return None
ldap_user = LDAPUser(self, username=username.strip(), request=request)
From ff1828bdd61d141da129bfbc0be65803e935293d Mon Sep 17 00:00:00 2001
From: Bai
Date: Fri, 10 Jan 2020 11:42:53 +0800
Subject: [PATCH 3/4] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9Swift=E5=BD=95?=
=?UTF-8?q?=E5=83=8F=E5=AD=98=E5=82=A8=E5=88=9B=E5=BB=BA=E5=8F=82=E6=95=B0?=
=?UTF-8?q?=E5=8F=8AAPI=E8=BF=94=E5=9B=9E=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/const.py | 1 +
apps/terminal/forms/storage.py | 6 ++++++
apps/terminal/models.py | 13 +++++++++----
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index b412c1624..4d19d007c 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -35,6 +35,7 @@ REPLAY_STORAGE_TYPE_SWIFT_FIELDS = [
{'name': 'SECRET_KEY', 'write_only': True},
{'name': 'REGION'},
{'name': 'ENDPOINT'},
+ {'name': 'PROTOCOL'},
]
REPLAY_STORAGE_TYPE_OSS_FIELDS = [
{'name': 'BUCKET'},
diff --git a/apps/terminal/forms/storage.py b/apps/terminal/forms/storage.py
index 28092380e..a94375e81 100644
--- a/apps/terminal/forms/storage.py
+++ b/apps/terminal/forms/storage.py
@@ -145,6 +145,12 @@ class ReplayStorageSwiftForm(BaseReplayStorageForm):
swift_endpoint = forms.CharField(
max_length=128, label=_('Endpoint'), required=False,
)
+ swift_protocol = forms.ChoiceField(
+ choices=(
+ ('HTTP', 'http'),
+ ('HTTPS', 'https')
+ ), initial='http', label=_('Protocol'), required=True,
+ )
class CommandStorageTypeESForm(BaseCommandStorageForm):
diff --git a/apps/terminal/models.py b/apps/terminal/models.py
index 6ad820563..04bc74c67 100644
--- a/apps/terminal/models.py
+++ b/apps/terminal/models.py
@@ -362,18 +362,23 @@ class ReplayStorage(CommonModelMixin):
return self.name
def convert_type(self):
- s3_type_list = [
- const.REPLAY_STORAGE_TYPE_CEPH, const.REPLAY_STORAGE_TYPE_SWIFT
- ]
+ s3_type_list = [const.REPLAY_STORAGE_TYPE_CEPH]
tp = self.type
if tp in s3_type_list:
tp = const.REPLAY_STORAGE_TYPE_S3
return tp
+ def get_extra_config(self):
+ extra_config = {'TYPE': self.convert_type()}
+ if self.type == const.REPLAY_STORAGE_TYPE_SWIFT:
+ extra_config.update({'signer': 'S3SignerType'})
+ return extra_config
+
@property
def config(self):
config = self.meta
- config.update({'TYPE': self.convert_type()})
+ extra_config = self.get_extra_config()
+ config.update(extra_config)
return config
def in_defaults(self):
From 14581ac7754484f819873e1432d1e0761e24587f Mon Sep 17 00:00:00 2001
From: Bai
Date: Fri, 10 Jan 2020 16:46:18 +0800
Subject: [PATCH 4/4] =?UTF-8?q?[Update]=20=E8=B5=84=E4=BA=A7=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E6=B7=BB=E5=8A=A0=E8=B5=84=E4=BA=A7=E6=97=B6=EF=BC=8C?=
=?UTF-8?q?=E7=A5=96=E5=85=88=E8=8A=82=E7=82=B9=E6=8E=88=E6=9D=83=E7=9A=84?=
=?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E5=85=B3=E8=81=94=E5=AF=B9?=
=?UTF-8?q?=E5=BA=94=E8=B5=84=E4=BA=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/signals_handler.py | 13 ++++++++++---
apps/assets/utils.py | 6 +++++-
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/apps/assets/signals_handler.py b/apps/assets/signals_handler.py
index 594da38b7..3b23de31b 100644
--- a/apps/assets/signals_handler.py
+++ b/apps/assets/signals_handler.py
@@ -10,6 +10,7 @@ from django.dispatch import receiver
from common.utils import get_logger, timeit
from common.decorator import on_transaction_commit
from .models import Asset, SystemUser, Node, AuthBook
+from .utils import TreeService
from .tasks import (
update_assets_hardware_info_util,
test_asset_connectivity_util,
@@ -131,16 +132,22 @@ def on_asset_nodes_add(sender, instance=None, action='', model=None, pk_set=None
if action != "post_add":
return
logger.debug("Assets node add signal recv: {}".format(action))
- queryset = model.objects.filter(pk__in=pk_set).values_list('id', flat=True)
+ queryset = model.objects.filter(pk__in=pk_set).values_list('key', flat=True)
if model == Node:
nodes = queryset
assets = [instance]
else:
nodes = [instance]
assets = queryset
- # 节点资产发生变化时,将资产关联到节点关联的系统用户, 只关注新增的
+ # 节点资产发生变化时,将资产关联到节点及祖先节点关联的系统用户, 只关注新增的
+ nodes_ancestors_keys = set()
+ node_tree = TreeService.new()
+ for node in nodes:
+ ancestors_keys = node_tree.ancestors_ids(nid=node)
+ nodes_ancestors_keys.update(ancestors_keys)
+ system_users = SystemUser.objects.filter(nodes__key__in=nodes_ancestors_keys)
+
system_users_assets = defaultdict(set)
- system_users = SystemUser.objects.filter(nodes__in=nodes)
for system_user in system_users:
system_users_assets[system_user].update(set(assets))
for system_user, _assets in system_users_assets.items():
diff --git a/apps/assets/utils.py b/apps/assets/utils.py
index e0b316ad7..eaf3d502a 100644
--- a/apps/assets/utils.py
+++ b/apps/assets/utils.py
@@ -84,11 +84,15 @@ class TreeService(Tree):
children_ids = self.all_children_ids(nid, with_self=with_self)
return [self.get_node(i, deep=deep) for i in children_ids]
- def ancestors(self, nid, with_self=False, deep=False):
+ def ancestors_ids(self, nid, with_self=True):
ancestor_ids = list(self.rsearch(nid))
ancestor_ids.pop()
if not with_self:
ancestor_ids.pop(0)
+ return ancestor_ids
+
+ def ancestors(self, nid, with_self=False, deep=False):
+ ancestor_ids = self.ancestors_ids(nid, with_self=with_self)
return [self.get_node(i, deep=deep) for i in ancestor_ids]
def get_node_full_tag(self, nid):