feat(terminal):危险命令告警功能

pull/4975/head
peijianbo 2020-10-27 11:35:31 +08:00 committed by 老广
parent 50a4735b07
commit 79b5aa68c8
14 changed files with 373 additions and 183 deletions

View File

@ -10,13 +10,15 @@ UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
def reverse(view_name, urlconf=None, args=None, kwargs=None,
current_app=None, external=False):
current_app=None, external=False, api_to_ui=False):
url = dj_reverse(view_name, urlconf=urlconf, args=args,
kwargs=kwargs, current_app=current_app)
if external:
site_url = settings.SITE_URL
url = site_url.strip('/') + url
if api_to_ui:
url = url.replace('api/v1', 'ui/#').rstrip('/')
return url

View File

@ -245,6 +245,9 @@ class Config(dict):
'SECURITY_LOGIN_CHALLENGE_ENABLED': False,
'SECURITY_LOGIN_CAPTCHA_ENABLED': True,
'SECURITY_DATA_CRYPTO_ALGO': 'aes',
'SECURITY_INSECURE_COMMAND': False,
'SECURITY_INSECURE_COMMAND_LEVEL': 5,
'SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER': '',
'HTTP_BIND_HOST': '0.0.0.0',
'HTTP_LISTEN_PORT': 8080,

View File

@ -55,6 +55,9 @@ SECURITY_SERVICE_ACCOUNT_REGISTRATION = DYNAMIC.SECURITY_SERVICE_ACCOUNT_REGISTR
SECURITY_LOGIN_CAPTCHA_ENABLED = CONFIG.SECURITY_LOGIN_CAPTCHA_ENABLED
SECURITY_LOGIN_CHALLENGE_ENABLED = CONFIG.SECURITY_LOGIN_CHALLENGE_ENABLED
SECURITY_DATA_CRYPTO_ALGO = CONFIG.SECURITY_DATA_CRYPTO_ALGO
SECURITY_INSECURE_COMMAND = DYNAMIC.SECURITY_INSECURE_COMMAND
SECURITY_INSECURE_COMMAND_LEVEL = CONFIG.SECURITY_INSECURE_COMMAND_LEVEL
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = DYNAMIC.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER
# Terminal other setting
TERMINAL_PASSWORD_AUTH = DYNAMIC.TERMINAL_PASSWORD_AUTH

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-10-27 10:29+0800\n"
"POT-Creation-Date: 2020-11-10 15:38+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -17,18 +17,30 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: applications/const.py:53
#: applications/const.py:53 applications/models/application.py:34
msgid "Custom"
msgstr "自定义"
#: applications/models/application.py:61 applications/models/database_app.py:29
#: applications/serializers/database_app.py:16
#: applications/serializers/remote_app.py:69
#: users/templates/users/user_granted_database_app.html:37
msgid "Database"
msgstr "数据库"
#: applications/models/application.py:62
msgid "Remote app"
msgstr "远程应用"
#: applications/models/application.py:122
#: applications/models/database_app.py:18 applications/models/k8s_app.py:11
#: applications/models/remote_app.py:21 assets/models/asset.py:149
#: assets/models/base.py:232 assets/models/cluster.py:18
#: assets/models/cmd_filter.py:21 assets/models/domain.py:21
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
#: orgs/models.py:23 perms/models/base.py:48 settings/models.py:27
#: terminal/models.py:27 terminal/models.py:348 terminal/models.py:380
#: terminal/models.py:417 users/forms/profile.py:20 users/models/group.py:15
#: terminal/models.py:28 terminal/models.py:356 terminal/models.py:388
#: terminal/models.py:425 users/forms/profile.py:20 users/models/group.py:15
#: users/models/user.py:505 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_asset_permission.html:37
#: users/templates/users/user_asset_permission.html:154
@ -46,30 +58,33 @@ msgstr "自定义"
msgid "Name"
msgstr "名称"
#: applications/models/application.py:123 assets/models/asset.py:198
#: assets/models/domain.py:27 assets/models/domain.py:54
msgid "Domain"
msgstr "网域"
#: applications/models/application.py:124
#: applications/serializers/application.py:16 assets/models/label.py:21
#: perms/models/application_permission.py:19
#: perms/serializers/application/permission.py:16
#: perms/serializers/application/user_permission.py:33
msgid "Category"
msgstr "分类"
#: applications/models/application.py:125
#: applications/models/database_app.py:22 applications/models/k8s_app.py:14
#: assets/models/cmd_filter.py:52 terminal/models.py:382 terminal/models.py:419
#: tickets/models/ticket.py:40
#: applications/serializers/application.py:17 assets/models/cmd_filter.py:52
#: perms/models/application_permission.py:20
#: perms/serializers/application/permission.py:17
#: perms/serializers/application/user_permission.py:34 terminal/models.py:390
#: terminal/models.py:427 tickets/models/ticket.py:40
#: users/templates/users/user_granted_database_app.html:35
msgid "Type"
msgstr "类型"
#: applications/models/database_app.py:25 ops/models/adhoc.py:146
#: users/templates/users/user_granted_database_app.html:36
msgid "Host"
msgstr "主机"
#: applications/models/database_app.py:27 assets/models/asset.py:195
#: assets/models/domain.py:52
msgid "Port"
msgstr "端口"
#: applications/models/database_app.py:29
#: users/templates/users/user_granted_database_app.html:37
msgid "Database"
msgstr "数据库"
# msgid "Date created"
# msgstr "创建日期"
#: applications/models/application.py:128
#: applications/models/database_app.py:33 applications/models/k8s_app.py:18
#: applications/models/remote_app.py:45 assets/models/asset.py:154
#: assets/models/asset.py:230 assets/models/base.py:237
@ -77,8 +92,8 @@ msgstr "数据库"
#: assets/models/cmd_filter.py:57 assets/models/domain.py:22
#: assets/models/domain.py:55 assets/models/group.py:23
#: assets/models/label.py:23 ops/models/adhoc.py:37 orgs/models.py:26
#: perms/models/base.py:56 settings/models.py:32 terminal/models.py:37
#: terminal/models.py:387 terminal/models.py:424 tickets/models/ticket.py:43
#: perms/models/base.py:56 settings/models.py:32 terminal/models.py:38
#: terminal/models.py:395 terminal/models.py:432 tickets/models/ticket.py:43
#: users/models/group.py:16 users/models/user.py:538
#: users/templates/users/user_detail.html:115
#: users/templates/users/user_granted_database_app.html:38
@ -91,6 +106,22 @@ msgstr "数据库"
msgid "Comment"
msgstr "备注"
#: applications/models/database_app.py:25
#: applications/serializers/database_app.py:13 ops/models/adhoc.py:146
#: users/templates/users/user_granted_database_app.html:36
msgid "Host"
msgstr "主机"
#: applications/models/database_app.py:27
#: applications/serializers/database_app.py:14
#: applications/serializers/database_app.py:21
#: applications/serializers/database_app.py:25
#: applications/serializers/database_app.py:29
#: applications/serializers/remote_app.py:68 assets/models/asset.py:195
#: assets/models/domain.py:52
msgid "Port"
msgstr "端口"
#: applications/models/database_app.py:41
#: perms/forms/database_app_permission.py:44
#: perms/models/database_app_permission.py:18
@ -105,7 +136,8 @@ msgstr "数据库应用"
msgid "Kubernetes"
msgstr ""
#: applications/models/k8s_app.py:16 assets/models/cluster.py:40
#: applications/models/k8s_app.py:16 applications/serializers/k8s_app.py:9
#: assets/models/cluster.py:40
msgid "Cluster"
msgstr "集群"
@ -114,14 +146,14 @@ msgstr "集群"
msgid "KubernetesApp"
msgstr "Kubernetes应用"
#: applications/models/remote_app.py:23 assets/models/asset.py:364
#: applications/models/remote_app.py:23 assets/models/asset.py:363
#: assets/models/authbook.py:26 assets/models/gathered_user.py:14
#: assets/serializers/admin_user.py:32 assets/serializers/asset_user.py:47
#: assets/serializers/asset_user.py:84 assets/serializers/system_user.py:46
#: assets/serializers/asset_user.py:84 assets/serializers/system_user.py:45
#: assets/serializers/system_user.py:186 audits/models.py:38
#: perms/forms/asset_permission.py:89 perms/models/asset_permission.py:92
#: templates/index.html:82 terminal/backends/command/models.py:19
#: terminal/backends/command/serializers.py:13 terminal/models.py:188
#: terminal/backends/command/serializers.py:13 terminal/models.py:192
#: users/templates/users/user_asset_permission.html:40
#: users/templates/users/user_asset_permission.html:70
#: users/templates/users/user_granted_remote_app.html:36
@ -177,6 +209,77 @@ msgstr "创建日期"
msgid "RemoteApp"
msgstr "远程应用"
#: applications/serializers/remote_app.py:36 assets/models/user.py:99
#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:52
msgid "Assets"
msgstr "资产管理"
#: applications/serializers/remote_app.py:37
#: applications/serializers/remote_app.py:58
#: applications/serializers/remote_app.py:66
#: applications/serializers/remote_app.py:76
msgid "Remote App path"
msgstr "远程应用列表"
#: applications/serializers/remote_app.py:59
#: applications/serializers/remote_app.py:77
msgid "Target URL"
msgstr "目标URL"
#: applications/serializers/remote_app.py:60
#: applications/serializers/remote_app.py:70
#: applications/serializers/remote_app.py:78
#: applications/serializers/remote_app.py:85 assets/models/base.py:233
#: assets/models/gathered_user.py:15 audits/models.py:99
#: authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:101
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:503
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15
#: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:279
msgid "Username"
msgstr "用户名"
#: applications/serializers/remote_app.py:61
#: applications/serializers/remote_app.py:71
#: applications/serializers/remote_app.py:79
#: applications/serializers/remote_app.py:86 assets/models/base.py:234
#: assets/serializers/asset_user.py:71 authentication/forms.py:13
#: authentication/templates/authentication/login.html:29
#: authentication/templates/authentication/xpack_login.html:109
#: users/forms/user.py:22 users/forms/user.py:193
#: users/templates/users/user_otp_check_password.html:13
#: users/templates/users/user_password_update.html:43
#: users/templates/users/user_password_verify.html:18
#: users/templates/users/user_profile_update.html:41
#: users/templates/users/user_pubkey_update.html:41
#: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:68
#: xpack/plugins/change_auth_plan/models.py:191
#: xpack/plugins/change_auth_plan/models.py:286
msgid "Password"
msgstr "密码"
#: applications/serializers/remote_app.py:67 assets/models/asset.py:190
#: assets/models/domain.py:51 assets/serializers/asset_user.py:46
#: settings/serializers/settings.py:52
#: users/templates/users/_granted_assets.html:26
#: users/templates/users/user_asset_permission.html:156
msgid "IP"
msgstr "IP"
#: applications/serializers/remote_app.py:83
msgid "Operating parameter"
msgstr "运行参数"
#: applications/serializers/remote_app.py:84
msgid "Target url"
msgstr "目标URL"
#: assets/api/admin_user.py:46
msgid "Deleted failed, There are related assets"
msgstr "删除失败,存在关联资产"
@ -222,13 +325,6 @@ msgstr "内部的"
msgid "Platform"
msgstr "系统平台"
#: assets/models/asset.py:190 assets/models/domain.py:51
#: assets/serializers/asset_user.py:46 settings/serializers/settings.py:52
#: users/templates/users/_granted_assets.html:26
#: users/templates/users/user_asset_permission.html:156
msgid "IP"
msgstr "IP"
#: assets/models/asset.py:191 assets/serializers/asset_user.py:45
#: assets/serializers/gathered_user.py:20 settings/serializers/settings.py:51
#: tickets/serializers/request_asset_perm.py:25
@ -238,21 +334,16 @@ msgid "Hostname"
msgstr "主机名"
#: assets/models/asset.py:194 assets/models/domain.py:53
#: assets/models/user.py:97 terminal/serializers/session.py:29
#: assets/models/user.py:103 terminal/serializers/session.py:29
msgid "Protocol"
msgstr "协议"
#: assets/models/asset.py:196 assets/serializers/asset.py:69
#: perms/serializers/user_permission.py:71
#: perms/serializers/asset/user_permission.py:41
msgid "Protocols"
msgstr "协议组"
#: assets/models/asset.py:198 assets/models/domain.py:27
#: assets/models/domain.py:54
msgid "Domain"
msgstr "网域"
#: assets/models/asset.py:199 assets/models/user.py:92
#: assets/models/asset.py:199 assets/models/user.py:98
#: perms/models/asset_permission.py:93
#: xpack/plugins/change_auth_plan/models.py:56
#: xpack/plugins/gathered_user/models.py:24
@ -355,37 +446,6 @@ msgstr "版本"
msgid "AuthBook"
msgstr ""
#: assets/models/base.py:233 assets/models/gathered_user.py:15
#: audits/models.py:99 authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:101
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:503
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15
#: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:279
msgid "Username"
msgstr "用户名"
#: assets/models/base.py:234 assets/serializers/asset_user.py:71
#: authentication/forms.py:13
#: authentication/templates/authentication/login.html:29
#: authentication/templates/authentication/xpack_login.html:109
#: users/forms/user.py:22 users/forms/user.py:193
#: users/templates/users/user_otp_check_password.html:13
#: users/templates/users/user_password_update.html:43
#: users/templates/users/user_password_verify.html:18
#: users/templates/users/user_profile_update.html:41
#: users/templates/users/user_pubkey_update.html:41
#: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:68
#: xpack/plugins/change_auth_plan/models.py:191
#: xpack/plugins/change_auth_plan/models.py:286
msgid "Password"
msgstr "密码"
#: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:72
#: xpack/plugins/change_auth_plan/models.py:198
#: xpack/plugins/change_auth_plan/models.py:293
@ -446,7 +506,7 @@ msgstr "系统"
msgid "Default Cluster"
msgstr "默认Cluster"
#: assets/models/cmd_filter.py:33 assets/models/user.py:102
#: assets/models/cmd_filter.py:33 assets/models/user.py:108
msgid "Command filter"
msgstr "命令过滤器"
@ -455,7 +515,7 @@ msgid "Regex"
msgstr "正则表达式"
#: assets/models/cmd_filter.py:41 ops/models/command.py:23
#: terminal/backends/command/serializers.py:15 terminal/models.py:197
#: terminal/backends/command/serializers.py:15 terminal/models.py:201
msgid "Command"
msgstr "命令"
@ -471,7 +531,7 @@ msgstr "允许"
msgid "Filter"
msgstr "过滤器"
#: assets/models/cmd_filter.py:53 assets/models/user.py:96
#: assets/models/cmd_filter.py:53 assets/models/user.py:102
msgid "Priority"
msgstr "优先级"
@ -545,7 +605,7 @@ msgstr "默认资产组"
#: perms/forms/remote_app_permission.py:40 perms/models/asset_permission.py:169
#: perms/models/base.py:49 templates/index.html:78
#: terminal/backends/command/models.py:18
#: terminal/backends/command/serializers.py:12 terminal/models.py:186
#: terminal/backends/command/serializers.py:12 terminal/models.py:190
#: tickets/models/ticket.py:30 tickets/models/ticket.py:136
#: tickets/serializers/request_asset_perm.py:66
#: tickets/serializers/ticket.py:31 users/forms/group.py:15
@ -563,35 +623,31 @@ msgstr "默认资产组"
msgid "User"
msgstr "用户"
#: assets/models/label.py:19 assets/models/node.py:397 settings/models.py:28
#: assets/models/label.py:19 assets/models/node.py:396 settings/models.py:28
msgid "Value"
msgstr "值"
#: assets/models/label.py:21
msgid "Category"
msgstr "分类"
#: assets/models/node.py:131
msgid "New node"
msgstr "新节点"
#: assets/models/node.py:303 users/templates/users/_granted_assets.html:130
#: assets/models/node.py:302 users/templates/users/_granted_assets.html:130
msgid "empty"
msgstr "空"
#: assets/models/node.py:396 perms/models/asset_permission.py:144
#: assets/models/node.py:395 perms/models/asset_permission.py:144
msgid "Key"
msgstr "键"
#: assets/models/node.py:398
#: assets/models/node.py:397
msgid "Full value"
msgstr "全称"
#: assets/models/node.py:401 perms/models/asset_permission.py:148
#: assets/models/node.py:400 perms/models/asset_permission.py:148
msgid "Parent key"
msgstr "ssh私钥"
#: assets/models/node.py:410 assets/serializers/system_user.py:45
#: assets/models/node.py:409 assets/serializers/system_user.py:44
#: assets/serializers/system_user.py:185 perms/forms/asset_permission.py:92
#: perms/forms/asset_permission.py:99
#: users/templates/users/user_asset_permission.html:41
@ -601,73 +657,69 @@ msgstr "ssh私钥"
msgid "Node"
msgstr "节点"
#: assets/models/user.py:88
#: assets/models/user.py:94
msgid "Automatic login"
msgstr "自动登录"
#: assets/models/user.py:89
#: assets/models/user.py:95
msgid "Manually login"
msgstr "手动登录"
#: assets/models/user.py:91
#: assets/models/user.py:97
msgid "Username same with user"
msgstr "用户名与用户相同"
#: assets/models/user.py:93 templates/_nav.html:39
#: xpack/plugins/change_auth_plan/models.py:52
msgid "Assets"
msgstr "资产管理"
#: assets/models/user.py:94 templates/_nav.html:17
#: assets/models/user.py:100 templates/_nav.html:17
#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
msgid "Users"
msgstr "用户管理"
#: assets/models/user.py:95 users/templates/users/user_group_list.html:90
#: assets/models/user.py:101 users/templates/users/user_group_list.html:90
#: users/templates/users/user_profile.html:124
msgid "User groups"
msgstr "用户组"
#: assets/models/user.py:98
#: assets/models/user.py:104
msgid "Auto push"
msgstr "自动推送"
#: assets/models/user.py:99
#: assets/models/user.py:105
msgid "Sudo"
msgstr "Sudo"
#: assets/models/user.py:100
#: assets/models/user.py:106
msgid "Shell"
msgstr "Shell"
#: assets/models/user.py:101
#: assets/models/user.py:107
msgid "Login mode"
msgstr "登录模式"
#: assets/models/user.py:103
#: assets/models/user.py:109
msgid "SFTP Root"
msgstr "SFTP根路径"
#: assets/models/user.py:104 authentication/models.py:88
#: assets/models/user.py:110 authentication/models.py:88
msgid "Token"
msgstr ""
#: assets/models/user.py:105
#: assets/models/user.py:111
msgid "Home"
msgstr "家目录"
#: assets/models/user.py:106
#: assets/models/user.py:112
msgid "System groups"
msgstr "用户组"
#: assets/models/user.py:181 audits/models.py:39
#: assets/models/user.py:206 audits/models.py:39
#: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49
#: perms/models/application_permission.py:22
#: perms/models/asset_permission.py:94
#: perms/models/database_app_permission.py:22
#: perms/models/k8s_app_permission.py:22
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45
#: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:14 terminal/models.py:190
#: terminal/backends/command/serializers.py:14 terminal/models.py:194
#: tickets/serializers/request_asset_perm.py:27
#: users/templates/users/_granted_assets.html:27
#: users/templates/users/user_asset_permission.html:42
@ -725,7 +777,7 @@ msgstr "硬件信息"
msgid "Org name"
msgstr "组织名称"
#: assets/serializers/asset.py:168 assets/serializers/asset.py:199
#: assets/serializers/asset.py:166 assets/serializers/asset.py:197
msgid "Connectivity"
msgstr "连接"
@ -763,27 +815,31 @@ msgstr "密钥不合法"
msgid "value"
msgstr "值"
#: assets/serializers/node.py:36
#: assets/serializers/node.py:29
msgid "Can't contains: /"
msgstr ""
#: assets/serializers/node.py:39
msgid "The same level node name cannot be the same"
msgstr "同级别节点名字不能重复"
#: assets/serializers/system_user.py:47 assets/serializers/system_user.py:187
#: assets/serializers/system_user.py:46 assets/serializers/system_user.py:187
msgid "Login mode display"
msgstr "登录模式显示"
#: assets/serializers/system_user.py:87
#: assets/serializers/system_user.py:86
msgid "Username same with user with protocol {} only allow 1"
msgstr "用户名和用户相同的一种协议只允许存在一个"
#: assets/serializers/system_user.py:100
#: assets/serializers/system_user.py:99
msgid "* Automatic login mode must fill in the username."
msgstr "自动登录模式,必须填写用户名"
#: assets/serializers/system_user.py:108
#: assets/serializers/system_user.py:107
msgid "Path should starts with /"
msgstr "路径应该以 / 开头"
#: assets/serializers/system_user.py:119
#: assets/serializers/system_user.py:118
msgid "Password or private key required"
msgstr "密码或密钥密码需要一个"
@ -835,25 +891,25 @@ msgstr "更新节点资产硬件信息: {}"
msgid "Gather assets users"
msgstr "收集资产上的用户"
#: assets/tasks/push_system_user.py:178
#: assets/tasks/push_system_user.py:183
#: assets/tasks/system_user_connectivity.py:89
msgid "System user is dynamic: {}"
msgstr "系统用户是动态的: {}"
#: assets/tasks/push_system_user.py:209
#: assets/tasks/push_system_user.py:214
msgid "Start push system user for platform: [{}]"
msgstr "推送系统用户到平台: [{}]"
#: assets/tasks/push_system_user.py:210
#: assets/tasks/push_system_user.py:215
#: assets/tasks/system_user_connectivity.py:81
msgid "Hosts count: {}"
msgstr "主机数量: {}"
#: assets/tasks/push_system_user.py:228 assets/tasks/push_system_user.py:244
#: assets/tasks/push_system_user.py:233 assets/tasks/push_system_user.py:251
msgid "Push system users to assets: {}"
msgstr "推送系统用户到入资产: {}"
#: assets/tasks/push_system_user.py:236
#: assets/tasks/push_system_user.py:241
msgid "Push system users to asset: {}({}) => {}"
msgstr "推送系统用户到入资产: {}({}) => {}"
@ -933,7 +989,7 @@ msgid "Symlink"
msgstr "建立软链接"
#: audits/models.py:37 audits/models.py:60 audits/models.py:71
#: terminal/models.py:193
#: terminal/models.py:197
msgid "Remote addr"
msgstr "远端地址"
@ -951,7 +1007,7 @@ msgid "Success"
msgstr "成功"
#: audits/models.py:43 ops/models/command.py:28 perms/models/base.py:52
#: terminal/models.py:200 tickets/serializers/request_asset_perm.py:29
#: terminal/models.py:204 tickets/serializers/request_asset_perm.py:29
#: xpack/plugins/change_auth_plan/models.py:177
#: xpack/plugins/change_auth_plan/models.py:308
#: xpack/plugins/gathered_user/models.py:76
@ -1205,7 +1261,7 @@ msgstr "登录复核 {}"
msgid "SSO auth closed"
msgstr "SSO 认证关闭了"
#: authentication/errors.py:218 authentication/views/login.py:246
#: authentication/errors.py:218 authentication/views/login.py:247
msgid "Your password is too simple, please change it for security"
msgstr "你的密码过于简单,为了安全,请修改"
@ -1358,6 +1414,10 @@ msgstr "正在使用其他认证服务器,请联系管理员"
msgid "One-time password"
msgstr "一次性密码"
#: authentication/templates/authentication/login_otp.html:23
#: users/templates/users/user_verify_mfa.html:13
msgid "Open MFA Authenticator and enter the 6-bit dynamic code"
msgstr "请打开MFA验证器输入6位动态码"
#: authentication/templates/authentication/login_otp.html:26
#: users/templates/users/user_otp_check_password.html:15
@ -1396,7 +1456,7 @@ msgstr "欢迎回来,请输入用户名和密码登录"
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
#: authentication/views/login.py:192
#: authentication/views/login.py:193
msgid ""
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
" Don't close this page"
@ -1404,19 +1464,19 @@ msgstr ""
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
" 不要关闭本页面"
#: authentication/views/login.py:197
#: authentication/views/login.py:198
msgid "No ticket found"
msgstr "没有发现工单"
#: authentication/views/login.py:229
#: authentication/views/login.py:230
msgid "Logout success"
msgstr "退出登录成功"
#: authentication/views/login.py:230
#: authentication/views/login.py:231
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
#: authentication/views/login.py:245
#: authentication/views/login.py:246
msgid "Please change your password"
msgstr "请修改密码"
@ -1488,7 +1548,7 @@ msgstr ""
msgid "Marshal data to text field"
msgstr ""
#: common/fields/model.py:165
#: common/fields/model.py:150
msgid "Encrypt field using Secret Key"
msgstr ""
@ -1516,7 +1576,7 @@ msgstr "字段必须唯一"
msgid "Should not contains special characters"
msgstr "不能包含特殊字符"
#: jumpserver/conf.py:471 templates/_base_only_msg_content.html:27
#: jumpserver/conf.py:477 templates/_base_only_msg_content.html:27
#: xpack/plugins/interface/api.py:18 xpack/plugins/interface/models.py:36
msgid "Welcome to the JumpServer open source fortress"
msgstr "欢迎使用JumpServer开源堡垒机"
@ -1707,11 +1767,11 @@ msgstr "更新任务内容: {}"
msgid "Disk used more than 80%: {} => {}"
msgstr "磁盘使用率超过 80%: {} => {}"
#: orgs/api.py:60
#: orgs/api.py:61
msgid "Organization contains undeleted resources"
msgstr "组织包含未删除的资源"
#: orgs/api.py:64
#: orgs/api.py:65
msgid "The current organization cannot be deleted"
msgstr "当前组织不能被删除"
@ -1736,7 +1796,7 @@ msgstr "组织审计员"
msgid "Role"
msgstr "角色"
#: perms/const.py:7 perms/utils/user_asset_permission.py:28
#: perms/const.py:7 perms/utils/asset/user_permission.py:28
msgid "Ungrouped"
msgstr "未分组"
@ -1785,6 +1845,14 @@ msgstr "资产和节点至少选一个"
msgid "System users"
msgstr "系统用户"
#: perms/models/application_permission.py:21 users/models/user.py:160
msgid "Application"
msgstr "应用程序"
#: perms/models/application_permission.py:26
msgid "Application permission"
msgstr "应用管理"
#: perms/models/asset_permission.py:37 settings/serializers/settings.py:56
msgid "All"
msgstr "全部"
@ -1846,11 +1914,17 @@ msgstr "Kubernetes应用授权"
msgid "RemoteApp permission"
msgstr "远程应用授权"
#: perms/utils/user_asset_permission.py:30
#: perms/serializers/application/permission.py:53
msgid ""
"The application list contains applications that are different from the "
"permission type. ({})"
msgstr ""
#: perms/utils/asset/user_permission.py:30
msgid "Favorite"
msgstr "收藏夹"
#: perms/utils/user_asset_permission.py:514
#: perms/utils/asset/user_permission.py:526
msgid "Please wait while your data is being initialized"
msgstr "数据正在初始化,请稍等"
@ -2522,63 +2596,63 @@ msgstr "风险等级"
msgid "Bulk create not support"
msgstr "不支持批量创建"
#: terminal/models.py:28
#: terminal/models.py:29
msgid "Remote Address"
msgstr "远端地址"
#: terminal/models.py:29
#: terminal/models.py:30
msgid "SSH Port"
msgstr "SSH端口"
#: terminal/models.py:30
#: terminal/models.py:31
msgid "HTTP Port"
msgstr "HTTP端口"
#: terminal/models.py:31
#: terminal/models.py:32
msgid "Command storage"
msgstr "命令存储"
#: terminal/models.py:32
#: terminal/models.py:33
msgid "Replay storage"
msgstr "录像存储"
#: terminal/models.py:155
#: terminal/models.py:156
msgid "Session Online"
msgstr "在线会话"
#: terminal/models.py:156
#: terminal/models.py:157
msgid "CPU Usage"
msgstr "CPU使用"
#: terminal/models.py:157
#: terminal/models.py:158
msgid "Memory Used"
msgstr "内存使用"
#: terminal/models.py:158
#: terminal/models.py:159
msgid "Connections"
msgstr "连接数"
#: terminal/models.py:159
#: terminal/models.py:160
msgid "Threads"
msgstr "线程数"
#: terminal/models.py:160
#: terminal/models.py:161
msgid "Boot Time"
msgstr "运行时间"
#: terminal/models.py:192
#: terminal/models.py:196
msgid "Login from"
msgstr "登录来源"
#: terminal/models.py:196
#: terminal/models.py:200
msgid "Replay"
msgstr "回放"
#: terminal/models.py:201
#: terminal/models.py:205
msgid "Date end"
msgstr "结束日期"
#: terminal/models.py:349
#: terminal/models.py:357
msgid "Args"
msgstr "参数"
@ -2586,37 +2660,73 @@ msgstr "参数"
msgid "Not found"
msgstr "没有发现"
#: tickets/api/request_asset_perm.py:48
#: terminal/utils.py:73
#, python-format
msgid ""
"Insecure Command Alert: [%(name)s->%(login_from)s@%(remote_addr)s] $"
"%(command)s"
msgstr "危险命令告警: [%(name)s->%(login_from)s@%(remote_addr)s] $%(command)s"
#: terminal/utils.py:83
#, python-format
msgid ""
"\n"
" Command: %(command)s\n"
" <br>\n"
" Asset: %(host_name)s (%(host_ip)s)\n"
" <br>\n"
" User: %(user)s\n"
" <br>\n"
" Level: %(risk_level)s\n"
" <br>\n"
" Session: <a href=\"%(session_detail_url)s\">session detail</a>\n"
" <br>\n"
" "
msgstr ""
"\n"
" 命令: %(command)s\n"
" <br>\n"
" 资产: %(host_name)s (%(host_ip)s)\n"
" <br>\n"
" 用户: %(user)s\n"
" <br>\n"
" 等级: %(risk_level)s\n"
" <br>\n"
" 会话: <a href=\"%(session_detail_url)s\">会话详情</a>\n"
" <br>\n"
" "
#: tickets/api/request_asset_perm.py:47
#, python-format
msgid "Ticket has %s"
msgstr "工单已%s"
#: tickets/api/request_asset_perm.py:94
#: tickets/api/request_asset_perm.py:81
msgid "Confirm assets first"
msgstr "请先确认资产"
#: tickets/api/request_asset_perm.py:97
#: tickets/api/request_asset_perm.py:84
msgid "Confirmed assets changed"
msgstr "确认的资产变更了"
#: tickets/api/request_asset_perm.py:101
#: tickets/api/request_asset_perm.py:88
msgid "Confirm system-users first"
msgstr "请先确认系统用户"
#: tickets/api/request_asset_perm.py:105
#: tickets/api/request_asset_perm.py:92
msgid "Confirmed system-users changed"
msgstr "确认的系统用户变更了"
#: tickets/api/request_asset_perm.py:111 tickets/api/request_asset_perm.py:118
#: tickets/api/request_asset_perm.py:98 tickets/api/request_asset_perm.py:105
#: xpack/plugins/cloud/models.py:211
msgid "Succeed"
msgstr "成功"
#: tickets/api/request_asset_perm.py:125
#: tickets/api/request_asset_perm.py:112
msgid "From request ticket: {} {}"
msgstr "来自工单申请: {} {}"
#: tickets/api/request_asset_perm.py:127
#: tickets/api/request_asset_perm.py:114
msgid "{} request assets, approved by {}"
msgstr "{} 申请资产,通过人 {}"
@ -2928,10 +3038,6 @@ msgstr "系统管理员"
msgid "System auditor"
msgstr "系统审计员"
#: users/models/user.py:160
msgid "Application"
msgstr "应用程序"
#: users/models/user.py:427 users/templates/users/user_profile.html:90
msgid "Force enable"
msgstr "强制启用"
@ -3428,8 +3534,8 @@ msgstr "绑定一次性密码验证器"
#: users/templates/users/user_otp_enable_bind.html:13
msgid ""
"Use the MFA Authenticator application to scan the following qr "
"code for a 6-bit verification code"
"Use the MFA Authenticator application to scan the following qr code for a 6-"
"bit verification code"
msgstr "使用MFA验证器应用扫描以下二维码获取6位验证码"
#: users/templates/users/user_otp_enable_bind.html:22
@ -3531,10 +3637,6 @@ msgid ""
"operations according to the prompts"
msgstr "账号保护已开启,请根据提示完成以下操作"
#: users/templates/users/user_verify_mfa.html:13
msgid "Open MFA Authenticator and enter the 6-bit dynamic code"
msgstr "请打开MFA验证器输入6位动态码"
# msgid "Update user"
# msgstr "更新用户"
#: users/utils.py:24
@ -4252,9 +4354,6 @@ msgstr "社区版"
#~ msgid "Auditors cannot be join in the user group"
#~ msgstr "审计员不能被加入到用户组"
#~ msgid "Target URL"
#~ msgstr "目标URL"
#~ msgid "Login username"
#~ msgstr "登录账号"
@ -4276,9 +4375,6 @@ msgstr "社区版"
#~ msgid "Target address"
#~ msgstr "目标地址"
#~ msgid "Operating parameter"
#~ msgstr "运行参数"
#~ msgid "Detail"
#~ msgstr "详情"
@ -4308,9 +4404,6 @@ msgstr "社区版"
#~ msgid "My DatabaseApp"
#~ msgstr "我的数据库应用"
#~ msgid "RemoteApp list"
#~ msgstr "远程应用列表"
#~ msgid "Update RemoteApp"
#~ msgstr "更新远程应用"

View File

@ -82,6 +82,8 @@ class SecuritySettingSerializer(serializers.Serializer):
SECURITY_PASSWORD_LOWER_CASE = serializers.BooleanField(required=False)
SECURITY_PASSWORD_NUMBER = serializers.BooleanField(required=False)
SECURITY_PASSWORD_SPECIAL_CHAR = serializers.BooleanField(required=False)
SECURITY_INSECURE_COMMAND = serializers.BooleanField(required=False)
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = serializers.CharField(max_length=8192, required=False)
class SettingsSerializer(serializers.Serializer):

View File

@ -1,25 +1,28 @@
# -*- coding: utf-8 -*-
#
import time
from django.conf import settings
from django.utils import timezone
from django.shortcuts import HttpResponse
from rest_framework import viewsets
from rest_framework import generics
from rest_framework.fields import DateTimeField
from rest_framework.response import Response
from rest_framework import status
from django.template import loader
from orgs.utils import current_org
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
from common.utils import get_logger
from terminal.utils import send_command_alert_mail
from terminal.serializers import InsecureCommandAlertSerializer
from ..backends import (
get_command_storage, get_multi_command_storage,
SessionCommandSerializer,
)
logger = get_logger(__name__)
__all__ = ['CommandViewSet', 'CommandExportApi']
__all__ = ['CommandViewSet', 'CommandExportApi', 'InsecureCommandAlertAPI']
class CommandQueryMixin:
@ -134,3 +137,19 @@ class CommandExportApi(CommandQueryMixin, generics.ListAPIView):
filename = 'command-report-{}.html'.format(int(time.time()))
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
return response
class InsecureCommandAlertAPI(generics.CreateAPIView):
permission_classes = [IsAppUser]
serializer_class = InsecureCommandAlertSerializer
def post(self, request, *args, **kwargs):
serializer = InsecureCommandAlertSerializer(data=request.data, many=True)
serializer.is_valid(raise_exception=True)
commands = serializer.validated_data
for command in commands:
if command['risk_level'] >= settings.SECURITY_INSECURE_COMMAND_LEVEL and \
settings.SECURITY_INSECURE_COMMAND and \
settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER:
send_command_alert_mail(command)
return Response()

View File

@ -27,6 +27,11 @@ class AbstractSessionCommand(OrgModelMixin):
class Meta:
abstract = True
@classmethod
def get_risk_level_str(cls, risk_level):
risk_mapper = dict(cls.RISK_LEVEL_CHOICES)
return risk_mapper.get(risk_level)
@classmethod
def from_dict(cls, d):
self = cls()

View File

@ -24,3 +24,11 @@ class SessionCommandSerializer(serializers.Serializer):
def get_risk_level_display(obj):
risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES)
return risk_mapper.get(obj.risk_level)
class InsecureCommandAlertSerializer(serializers.Serializer):
input = serializers.CharField()
asset = serializers.CharField()
user = serializers.CharField()
risk_level = serializers.IntegerField()
session = serializers.UUIDField()

View File

@ -12,6 +12,7 @@ from django.conf import settings
from django.core.files.storage import default_storage
from django.core.cache import cache
from assets.models import Asset
from users.models import User
from orgs.mixins.models import OrgModelMixin
from common.mixins import CommonModelMixin
@ -227,6 +228,10 @@ class Session(OrgModelMixin):
local_path = rel_path
return local_path
@property
def asset_obj(self):
return Asset.objects.get(id=self.asset_id)
@property
def _date_start_first_has_replay_rdp_session(self):
if self.__class__._DATE_START_FIRST_HAS_REPLAY_RDP_SESSION is None:

View File

@ -3,3 +3,4 @@
from .terminal import *
from .session import *
from .storage import *
from .command import *

View File

@ -0,0 +1,10 @@
# ~*~ coding: utf-8 ~*~
from rest_framework import serializers
class InsecureCommandAlertSerializer(serializers.Serializer):
input = serializers.CharField()
asset = serializers.CharField()
user = serializers.CharField()
risk_level = serializers.IntegerField()
session = serializers.UUIDField()

View File

@ -31,6 +31,7 @@ urlpatterns = [
name='terminal-access-key'),
path('terminals/config/', api.TerminalConfig.as_view(), name='terminal-config'),
path('commands/export/', api.CommandExportApi.as_view(), name="command-export"),
path('commands/insecure-command/', api.InsecureCommandAlertAPI.as_view(), name="command-alert"),
path('replay-storages/<uuid:pk>/test-connective/', api.ReplayStorageTestConnectiveApi.as_view(), name='replay-storage-test-connective'),
path('command-storages/<uuid:pk>/test-connective/', api.CommandStorageTestConnectiveApi.as_view(), name='command-storage-test-connective')
# v2: get session's replay

View File

@ -4,12 +4,15 @@ import os
from django.conf import settings
from django.core.files.storage import default_storage
from django.utils.translation import ugettext as _
import jms_storage
from common.utils import get_logger
from common.tasks import send_mail_async
from common.utils import get_logger, reverse
from settings.models import Setting
from .backends import server_replay_storage
from .models import ReplayStorage
from .models import ReplayStorage, Session, Command
logger = get_logger(__name__)
@ -63,3 +66,38 @@ def get_session_replay_url(session):
if local_path is None:
local_path, url = download_session_replay(session)
return local_path, url
def send_command_alert_mail(command):
session_obj = Session.objects.get(id=command['session'])
subject = _("Insecure Command Alert: [%(name)s->%(login_from)s@%(remote_addr)s] $%(command)s") % {
'name': command['user'],
'login_from': session_obj.get_login_from_display(),
'remote_addr': session_obj.remote_addr,
'command': command['input']
}
recipient_list = settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER.split(',')
message = _("""
Command: %(command)s
<br>
Asset: %(host_name)s (%(host_ip)s)
<br>
User: %(user)s
<br>
Level: %(risk_level)s
<br>
Session: <a href="%(session_detail_url)s">session detail</a>
<br>
""") % {
'command': command['input'],
'host_name': command['asset'],
'host_ip': session_obj.asset_obj.ip,
'user': command['user'],
'risk_level': Command.get_risk_level_str(command['risk_level']),
'session_detail_url': reverse('api-terminal:session-detail',
kwargs={'pk': command['session']},
external=True, api_to_ui=True),
}
logger.debug(message)
send_mail_async.delay(subject, message, recipient_list, html_message=message)