From 67d084fc4321be02b52665e5e8c32b89aa48b39d Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Thu, 18 Nov 2021 22:20:35 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20ip=20list=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/acls/serializers/rules/rules.py | 15 +-- apps/jumpserver/conf.py | 14 ++- apps/jumpserver/settings/custom.py | 16 +-- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 162 ++++++++++++-------------- apps/settings/serializers/security.py | 37 ++---- apps/users/utils.py | 26 ++--- 7 files changed, 125 insertions(+), 149 deletions(-) diff --git a/apps/acls/serializers/rules/rules.py b/apps/acls/serializers/rules/rules.py index bfac5f65f..80316147e 100644 --- a/apps/acls/serializers/rules/rules.py +++ b/apps/acls/serializers/rules/rules.py @@ -8,7 +8,7 @@ from common.utils.ip import is_ip_address, is_ip_network, is_ip_segment logger = get_logger(__file__) -__all__ = ['RuleSerializer'] +__all__ = ['RuleSerializer', 'ip_group_child_validator', 'ip_group_help_text'] def ip_group_child_validator(ip_group_child): @@ -21,13 +21,14 @@ def ip_group_child_validator(ip_group_child): raise serializers.ValidationError(error) -class RuleSerializer(serializers.Serializer): - ip_group_help_text = _( - 'Format for comma-delimited string, with * indicating a match all. ' - 'Such as: ' - '192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 ' - ) +ip_group_help_text = _( + 'Format for comma-delimited string, with * indicating a match all. ' + 'Such as: ' + '192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 ' +) + +class RuleSerializer(serializers.Serializer): ip_group = serializers.ListField( default=['*'], label=_('IP'), help_text=ip_group_help_text, child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator])) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index a0f535414..b41cb64b5 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -291,12 +291,6 @@ class Config(dict): 'SECURITY_COMMAND_EXECUTION': True, 'SECURITY_SERVICE_ACCOUNT_REGISTRATION': True, 'SECURITY_VIEW_AUTH_NEED_MFA': True, - 'SECURITY_LOGIN_IP_BLACK_LIST': [], - 'SECURITY_LOGIN_IP_WHITE_LIST': [], - 'SECURITY_LOGIN_LIMIT_COUNT': 7, - 'SECURITY_LOGIN_IP_LIMIT_COUNT': 99999, - 'SECURITY_LOGIN_IP_LIMIT_TIME': 30, - 'SECURITY_LOGIN_LIMIT_TIME': 30, 'SECURITY_MAX_IDLE_TIME': 30, 'SECURITY_PASSWORD_EXPIRATION_TIME': 9999, 'SECURITY_PASSWORD_MIN_LENGTH': 6, @@ -321,6 +315,14 @@ class Config(dict): 'USER_LOGIN_SINGLE_MACHINE_ENABLED': False, 'ONLY_ALLOW_EXIST_USER_AUTH': False, 'ONLY_ALLOW_AUTH_FROM_SOURCE': False, + # 用户登录限制的规则 + 'SECURITY_LOGIN_LIMIT_COUNT': 7, + 'SECURITY_LOGIN_LIMIT_TIME': 30, + # 登录IP限制的规则 + 'SECURITY_LOGIN_IP_BLACK_LIST': [], + 'SECURITY_LOGIN_IP_WHITE_LIST': [], + 'SECURITY_LOGIN_IP_LIMIT_COUNT': 99999, + 'SECURITY_LOGIN_IP_LIMIT_TIME': 30, # 启动前 'HTTP_BIND_HOST': '0.0.0.0', diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 04e5905e4..a95571194 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -32,14 +32,8 @@ TERMINAL_REPLAY_STORAGE = CONFIG.TERMINAL_REPLAY_STORAGE # Security settings SECURITY_MFA_AUTH = CONFIG.SECURITY_MFA_AUTH -SECURITY_COMMAND_EXECUTION = CONFIG.SECURITY_COMMAND_EXECUTION -SECURITY_LOGIN_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_LIMIT_COUNT -SECURITY_LOGIN_IP_BLACK_LIST = CONFIG.SECURITY_LOGIN_IP_BLACK_LIST -SECURITY_LOGIN_IP_WHITE_LIST = CONFIG.SECURITY_LOGIN_IP_WHITE_LIST -SECURITY_LOGIN_IP_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_IP_LIMIT_COUNT -SECURITY_LOGIN_IP_LIMIT_TIME = CONFIG.SECURITY_LOGIN_IP_LIMIT_TIME -SECURITY_LOGIN_LIMIT_TIME = CONFIG.SECURITY_LOGIN_LIMIT_TIME # Unit: minute SECURITY_MAX_IDLE_TIME = CONFIG.SECURITY_MAX_IDLE_TIME # Unit: minute +SECURITY_COMMAND_EXECUTION = CONFIG.SECURITY_COMMAND_EXECUTION SECURITY_PASSWORD_EXPIRATION_TIME = CONFIG.SECURITY_PASSWORD_EXPIRATION_TIME # Unit: day SECURITY_PASSWORD_MIN_LENGTH = CONFIG.SECURITY_PASSWORD_MIN_LENGTH # Unit: bit SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH = CONFIG.SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH # Unit: bit @@ -66,6 +60,14 @@ SECURITY_INSECURE_COMMAND = CONFIG.SECURITY_INSECURE_COMMAND SECURITY_INSECURE_COMMAND_LEVEL = CONFIG.SECURITY_INSECURE_COMMAND_LEVEL SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = CONFIG.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER SECURITY_CHECK_DIFFERENT_CITY_LOGIN = CONFIG.SECURITY_CHECK_DIFFERENT_CITY_LOGIN +# 用户登录限制的规则 +SECURITY_LOGIN_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_LIMIT_COUNT +SECURITY_LOGIN_LIMIT_TIME = CONFIG.SECURITY_LOGIN_LIMIT_TIME # Unit: minute +# 登录IP限制的规则 +SECURITY_LOGIN_IP_BLACK_LIST = CONFIG.SECURITY_LOGIN_IP_BLACK_LIST +SECURITY_LOGIN_IP_WHITE_LIST = CONFIG.SECURITY_LOGIN_IP_WHITE_LIST +SECURITY_LOGIN_IP_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_IP_LIMIT_COUNT +SECURITY_LOGIN_IP_LIMIT_TIME = CONFIG.SECURITY_LOGIN_IP_LIMIT_TIME # Unit: minute # Terminal other setting TERMINAL_PASSWORD_AUTH = CONFIG.TERMINAL_PASSWORD_AUTH diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 7164484fa..d718427e5 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9172f06d374831f6c332158b163c4044b6abf76fa7047b29a9bb9091cca5cf3 -size 93453 +oid sha256:c9823f96465943a304034daf10ad6a98f2e02d8fe80a145f6e0196693a933387 +size 93547 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index a4239f2bd..c97495937 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-19 10:40+0800\n" +"POT-Creation-Date: 2021-11-19 15:28+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -180,7 +180,7 @@ msgstr "" "格式为逗号分隔的字符串, * 表示匹配所有。例如: 192.168.10.1, 192.168.1.0/24, " "10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)" -#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:32 +#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:33 #: applications/serializers/attrs/application_type/mysql_workbench.py:18 #: assets/models/asset.py:211 assets/models/domain.py:61 #: assets/serializers/account.py:12 @@ -225,12 +225,12 @@ msgstr "组织 `{}` 不存在" msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" -#: acls/serializers/rules/rules.py:20 settings/serializers/security.py:35 +#: acls/serializers/rules/rules.py:20 #: xpack/plugins/cloud/serializers/task.py:23 msgid "IP address invalid: `{}`" msgstr "IP 地址无效: `{}`" -#: acls/serializers/rules/rules.py:26 +#: acls/serializers/rules/rules.py:25 msgid "" "Format for comma-delimited string, with * indicating a match all. Such as: " "192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:" @@ -239,7 +239,7 @@ msgstr "" "格式为逗号分隔的字符串, * 表示匹配所有。例如: 192.168.10.1, 192.168.1.0/24, " "10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64" -#: acls/serializers/rules/rules.py:34 +#: acls/serializers/rules/rules.py:35 msgid "Time Period" msgstr "时段" @@ -1623,13 +1623,13 @@ msgstr "" msgid "" "The account has been locked (please contact admin to unlock it or try again " "after {} minutes)" -msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)" +msgstr "账号已被锁定(请联系管理员解锁或{}分钟后重试)" #: authentication/errors.py:59 msgid "" "The ip has been locked (please contact admin to unlock it or try again after " "{} minutes)" -msgstr "IP已被锁定(请联系管理员解锁 或 {}分钟后重试)" +msgstr "IP 已被锁定(请联系管理员解锁或{}分钟后重试)" #: authentication/errors.py:67 #, python-brace-format @@ -1824,7 +1824,7 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:42 users/models/user.py:458 +#: settings/serializers/security.py:39 users/models/user.py:458 #: users/serializers/profile.py:99 users/templates/users/mfa_setting.html:60 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" @@ -3332,67 +3332,53 @@ msgstr "必须包含数字" msgid "Must contain special" msgstr "必须包含特殊字符" -#: settings/serializers/security.py:43 -msgid "All users" -msgstr "所有用户" - -#: settings/serializers/security.py:44 -msgid "Only admin users" -msgstr "仅管理员" - -#: settings/serializers/security.py:46 -msgid "Global MFA auth" -msgstr "全局启用 MFA 认证" - -#: settings/serializers/security.py:50 -msgid "Limit the number of user login failures" -msgstr "限制用户登录失败次数" - -#: settings/serializers/security.py:54 -msgid "Block user login interval" -msgstr "禁止用户登录时间间隔" - -#: settings/serializers/security.py:56 +#: settings/serializers/security.py:31 msgid "" "Unit: minute, If the user has failed to log in for a limited number of " "times, no login is allowed during this time interval." msgstr "单位:分, 当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录" -#: settings/serializers/security.py:62 +#: settings/serializers/security.py:40 +msgid "All users" +msgstr "所有用户" + +#: settings/serializers/security.py:41 +msgid "Only admin users" +msgstr "仅管理员" + +#: settings/serializers/security.py:43 +msgid "Global MFA auth" +msgstr "全局启用 MFA 认证" + +#: settings/serializers/security.py:47 +msgid "Limit the number of user login failures" +msgstr "限制用户登录失败次数" + +#: settings/serializers/security.py:51 +msgid "Block user login interval" +msgstr "禁止用户登录时间间隔" + +#: settings/serializers/security.py:56 msgid "Limit the number of IP login failures" -msgstr "限制IP登录失败次数" +msgstr "限制 IP 登录失败次数" -#: settings/serializers/security.py:66 +#: settings/serializers/security.py:60 msgid "Block IP login interval" -msgstr "禁止IP登录时间间隔" +msgstr "禁止 IP 登录时间间隔" -#: settings/serializers/security.py:68 -msgid "" -"Unit: minute, If the IP has failed to log in for a limited number of times, " -"no login is allowed during this time interval." -msgstr "单位:分, 当IP登录失败次数达到限制后,那么在此时间间隔内禁止登录" - -#: settings/serializers/security.py:73 +#: settings/serializers/security.py:64 msgid "Login IP White List" -msgstr "IP登录白名单" +msgstr "IP 登录白名单" -#: settings/serializers/security.py:76 settings/serializers/security.py:84 -msgid "" -"Format for comma-delimited string. Such as: 192.168.10.1, 192.168.1.0/24, " -"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64" -msgstr "" -"格式为逗号分隔的字符串。例如: 192.168.10.1, 192.168.1.0/24, " -"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)" - -#: settings/serializers/security.py:81 +#: settings/serializers/security.py:69 msgid "Login IP Black List" -msgstr "IP登录黑名单" +msgstr "IP 登录黑名单" -#: settings/serializers/security.py:90 +#: settings/serializers/security.py:75 msgid "User password expiration" msgstr "用户密码过期时间" -#: settings/serializers/security.py:92 +#: settings/serializers/security.py:77 msgid "" "Unit: day, If the user does not update the password during the time, the " "user password will expire failure;The password expiration reminder mail will " @@ -3402,55 +3388,55 @@ msgstr "" "单位:天, 如果用户在此期间没有更新密码,用户密码将过期失效; 密码过期提醒邮件" "将在密码过期前5天内由系统(每天)自动发送给用户" -#: settings/serializers/security.py:99 +#: settings/serializers/security.py:84 msgid "Number of repeated historical passwords" msgstr "不能设置近几次密码" -#: settings/serializers/security.py:101 +#: settings/serializers/security.py:86 msgid "" "Tip: When the user resets the password, it cannot be the previous n " "historical passwords of the user" msgstr "提示:用户重置密码时,不能为该用户前几次使用过的密码" -#: settings/serializers/security.py:106 +#: settings/serializers/security.py:91 msgid "Only single device login" msgstr "仅一台设备登录" -#: settings/serializers/security.py:107 +#: settings/serializers/security.py:92 msgid "Next device login, pre login will be logout" msgstr "下个设备登录,上次登录会被顶掉" -#: settings/serializers/security.py:110 +#: settings/serializers/security.py:95 msgid "Only exist user login" msgstr "仅已存在用户登录" -#: settings/serializers/security.py:111 +#: settings/serializers/security.py:96 msgid "If enable, CAS、OIDC auth will be failed, if user not exist yet" msgstr "开启后,如果系统中不存在该用户,CAS、OIDC 登录将会失败" -#: settings/serializers/security.py:114 +#: settings/serializers/security.py:99 msgid "Only from source login" msgstr "仅从用户来源登录" -#: settings/serializers/security.py:115 +#: settings/serializers/security.py:100 msgid "Only log in from the user source property" msgstr "开启后,如果用户来源为本地,CAS、OIDC 登录将会失败" -#: settings/serializers/security.py:119 +#: settings/serializers/security.py:104 msgid "MFA verify TTL" msgstr "MFA 校验有效期" -#: settings/serializers/security.py:121 +#: settings/serializers/security.py:106 msgid "" "Unit: second, The verification MFA takes effect only when you view the " "account password" msgstr "单位: 秒, 目前仅在查看账号密码校验 MFA 时生效" -#: settings/serializers/security.py:126 +#: settings/serializers/security.py:111 msgid "Enable Login dynamic code" msgstr "启用登录附加码" -#: settings/serializers/security.py:127 +#: settings/serializers/security.py:112 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -3458,96 +3444,96 @@ msgstr "" "密码和附加码一并发送给第三方认证系统进行校验, 如:有的第三方认证系统,需要 密" "码+6位数字 完成认证" -#: settings/serializers/security.py:132 +#: settings/serializers/security.py:117 msgid "MFA in login page" msgstr "MFA 在登录页面输入" -#: settings/serializers/security.py:133 +#: settings/serializers/security.py:118 msgid "Eu security regulations(GDPR) require MFA to be on the login page" msgstr "欧盟数据安全法规(GDPR) 要求 MFA 在登录页面,来确保系统登录安全" -#: settings/serializers/security.py:136 +#: settings/serializers/security.py:121 msgid "Enable Login captcha" msgstr "启用登录验证码" -#: settings/serializers/security.py:137 +#: settings/serializers/security.py:122 msgid "Enable captcha to prevent robot authentication" msgstr "开启验证码,防止机器人登录" -#: settings/serializers/security.py:157 +#: settings/serializers/security.py:142 msgid "Enable terminal register" msgstr "终端注册" -#: settings/serializers/security.py:159 +#: settings/serializers/security.py:144 msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" msgstr "是否允许终端注册,当所有终端启动后,为了安全应该关闭" -#: settings/serializers/security.py:163 +#: settings/serializers/security.py:148 msgid "Enable watermark" msgstr "开启水印" -#: settings/serializers/security.py:164 +#: settings/serializers/security.py:149 msgid "Enabled, the web session and replay contains watermark information" msgstr "启用后,Web 会话和录像将包含水印信息" -#: settings/serializers/security.py:168 +#: settings/serializers/security.py:153 msgid "Connection max idle time" msgstr "连接最大空闲时间" -#: settings/serializers/security.py:169 +#: settings/serializers/security.py:154 msgid "If idle time more than it, disconnect connection Unit: minute" msgstr "提示:如果超过该配置没有操作,连接会被断开 (单位:分)" -#: settings/serializers/security.py:172 +#: settings/serializers/security.py:157 msgid "Remember manual auth" msgstr "保存手动输入密码" -#: settings/serializers/security.py:175 +#: settings/serializers/security.py:160 msgid "Enable change auth secure mode" msgstr "启用改密安全模式" -#: settings/serializers/security.py:178 +#: settings/serializers/security.py:163 msgid "Insecure command alert" msgstr "危险命令告警" -#: settings/serializers/security.py:181 +#: settings/serializers/security.py:166 msgid "Email recipient" msgstr "邮件收件人" -#: settings/serializers/security.py:182 +#: settings/serializers/security.py:167 msgid "Multiple user using , split" msgstr "多个用户,使用 , 分割" -#: settings/serializers/security.py:185 +#: settings/serializers/security.py:170 msgid "Batch command execution" msgstr "批量命令执行" -#: settings/serializers/security.py:186 +#: settings/serializers/security.py:171 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/security.py:189 +#: settings/serializers/security.py:174 msgid "Session share" msgstr "会话分享" -#: settings/serializers/security.py:190 +#: settings/serializers/security.py:175 msgid "Enabled, Allows user active session to be shared with other users" msgstr "开启后允许用户分享已连接的资产会话给它人,协同工作" -#: settings/serializers/security.py:193 +#: settings/serializers/security.py:178 msgid "Remote Login Protection" msgstr "异地登录保护" -#: settings/serializers/security.py:195 +#: settings/serializers/security.py:180 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " "a remote login reminder" msgstr "" -"根据登录IP是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地登" -"录提醒" +"根据登录 IP 是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地" +"登录提醒" #: settings/serializers/sms.py:7 msgid "Label" diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index aad205616..6463cdff2 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -1,7 +1,7 @@ from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers -from common.utils.ip import is_ip_address, is_ip_network, is_ip_segment +from acls.serializers.rules import ip_group_help_text, ip_group_child_validator class SecurityPasswordRuleSerializer(serializers.Serializer): @@ -27,13 +27,10 @@ class SecurityPasswordRuleSerializer(serializers.Serializer): ) -def ip_child_validator(ip_child): - is_valid = is_ip_address(ip_child) \ - or is_ip_network(ip_child) \ - or is_ip_segment(ip_child) - if not is_valid: - error = _('IP address invalid: `{}`').format(ip_child) - raise serializers.ValidationError(error) +login_ip_limit_time_help_text = _( + 'Unit: minute, If the user has failed to log in for a limited number of times, ' + 'no login is allowed during this time interval.' +) class SecurityAuthSerializer(serializers.Serializer): @@ -52,10 +49,7 @@ class SecurityAuthSerializer(serializers.Serializer): SECURITY_LOGIN_LIMIT_TIME = serializers.IntegerField( min_value=5, max_value=99999, required=True, label=_('Block user login interval'), - help_text=_( - 'Unit: minute, If the user has failed to log in for a limited number of times, ' - 'no login is allowed during this time interval.' - ) + help_text=login_ip_limit_time_help_text ) SECURITY_LOGIN_IP_LIMIT_COUNT = serializers.IntegerField( min_value=3, max_value=99999, @@ -64,26 +58,17 @@ class SecurityAuthSerializer(serializers.Serializer): SECURITY_LOGIN_IP_LIMIT_TIME = serializers.IntegerField( min_value=5, max_value=99999, required=True, label=_('Block IP login interval'), - help_text=_( - 'Unit: minute, If the IP has failed to log in for a limited number of times, ' - 'no login is allowed during this time interval.' - ) + help_text=login_ip_limit_time_help_text ) SECURITY_LOGIN_IP_WHITE_LIST = serializers.ListField( default=[], label=_('Login IP White List'), allow_empty=True, - child=serializers.CharField(max_length=1024, validators=[ip_child_validator]), - help_text=_( - 'Format for comma-delimited string. Such as: ' - '192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64' - ) + child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]), + help_text=ip_group_help_text ) SECURITY_LOGIN_IP_BLACK_LIST = serializers.ListField( default=[], label=_('Login IP Black List'), allow_empty=True, - child=serializers.CharField(max_length=1024, validators=[ip_child_validator]), - help_text=_( - 'Format for comma-delimited string. Such as: ' - '192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64' - ) + child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]), + help_text=ip_group_help_text ) SECURITY_PASSWORD_EXPIRATION_TIME = serializers.IntegerField( min_value=1, max_value=99999, required=True, diff --git a/apps/users/utils.py b/apps/users/utils.py index 807c7cc0f..6f311c74f 100644 --- a/apps/users/utils.py +++ b/apps/users/utils.py @@ -11,7 +11,7 @@ from django.conf import settings from django.core.cache import cache from common.tasks import send_mail_async -from common.utils import reverse, get_object_or_none +from common.utils import reverse, get_object_or_none, ip from .models import User logger = logging.getLogger('jumpserver') @@ -184,22 +184,23 @@ class BlockGlobalIpUtilBase: @property def ip_in_black_list(self): - return self.ip in settings.SECURITY_LOGIN_IP_BLACK_LIST + return ip.contains_ip(self.ip, settings.SECURITY_LOGIN_IP_BLACK_LIST) @property def ip_in_white_list(self): - return self.ip in settings.SECURITY_LOGIN_IP_WHITE_LIST + return ip.contains_ip(self.ip, settings.SECURITY_LOGIN_IP_WHITE_LIST) def set_block_if_need(self): - if not self.ip_in_white_list and not self.ip_in_black_list: - count = cache.get(self.limit_key, 0) - count += 1 - cache.set(self.limit_key, count, self.key_ttl) + if self.ip_in_white_list or self.ip_in_black_list: + return + count = cache.get(self.limit_key, 0) + count += 1 + cache.set(self.limit_key, count, self.key_ttl) - limit_count = settings.SECURITY_LOGIN_IP_LIMIT_COUNT - if count < limit_count: - return - cache.set(self.block_key, True, self.key_ttl) + limit_count = settings.SECURITY_LOGIN_IP_LIMIT_COUNT + if count < limit_count: + return + cache.set(self.block_key, True, self.key_ttl) def clean_block_if_need(self): cache.delete(self.limit_key) @@ -210,8 +211,7 @@ class BlockGlobalIpUtilBase: return False if self.ip_in_black_list: return True - if not self.ip_in_white_list and not self.ip_in_black_list: - return bool(cache.get(self.block_key)) + return bool(cache.get(self.block_key)) class LoginBlockUtil(BlockUtilBase):