mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-06-26 06:52:53 +00:00
perf: 提升服务注册安全性
This commit is contained in:
parent
9ed822bb3e
commit
b55000663e
30
apps/authentication/backends/test/test_drf.py
Normal file
30
apps/authentication/backends/test/test_drf.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from httpsig.requests_auth import HTTPSignatureAuth
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def test_drf_ak():
|
||||||
|
KEY_ID = os.environ.get('KEY_ID') or ''
|
||||||
|
SECRET = os.environ.get('KEY_SECRET') or ''
|
||||||
|
|
||||||
|
signature_headers = ['(request-target)', 'date']
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
headers = {
|
||||||
|
'Host': 'localhost:8000',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Date': now.strftime('%a, %d %b %Y %H:%M:%S GMT'),
|
||||||
|
}
|
||||||
|
|
||||||
|
# url = 'http://localhost:8080/api/v1/assets/assets/?limit=100'
|
||||||
|
url = 'http://localhost:8080/api/v1/users/users/?limit=100'
|
||||||
|
|
||||||
|
auth = HTTPSignatureAuth(key_id=KEY_ID, secret=SECRET,
|
||||||
|
algorithm='hmac-sha256',
|
||||||
|
headers=signature_headers)
|
||||||
|
req = requests.get(url, auth=auth, headers=headers)
|
||||||
|
print(req.content)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_drf_ak()
|
@ -27,10 +27,23 @@ class IsServiceAccount(IsValidUser):
|
|||||||
|
|
||||||
|
|
||||||
class WithBootstrapToken(permissions.BasePermission):
|
class WithBootstrapToken(permissions.BasePermission):
|
||||||
|
def check_can_register(self):
|
||||||
|
enabled = settings.SECURITY_SERVICE_ACCOUNT_REGISTRATION
|
||||||
|
if enabled == 'auto':
|
||||||
|
return time.time() - settings.JUMPSERVER_UPTIME < 300
|
||||||
|
elif enabled:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
authorization = request.META.get('HTTP_AUTHORIZATION', '')
|
authorization = request.META.get('HTTP_AUTHORIZATION', '')
|
||||||
if not authorization:
|
if not authorization:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if not self.check_can_register():
|
||||||
|
return False
|
||||||
|
|
||||||
request_bootstrap_token = authorization.split()[-1]
|
request_bootstrap_token = authorization.split()[-1]
|
||||||
return settings.BOOTSTRAP_TOKEN == request_bootstrap_token
|
return settings.BOOTSTRAP_TOKEN == request_bootstrap_token
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ class Config(dict):
|
|||||||
'SECURITY_COMMAND_BLACKLIST': [
|
'SECURITY_COMMAND_BLACKLIST': [
|
||||||
'reboot', 'shutdown', 'poweroff', 'halt', 'dd', 'half', 'top'
|
'reboot', 'shutdown', 'poweroff', 'halt', 'dd', 'half', 'top'
|
||||||
],
|
],
|
||||||
'SECURITY_SERVICE_ACCOUNT_REGISTRATION': True,
|
'SECURITY_SERVICE_ACCOUNT_REGISTRATION': 'auto',
|
||||||
'SECURITY_VIEW_AUTH_NEED_MFA': True,
|
'SECURITY_VIEW_AUTH_NEED_MFA': True,
|
||||||
'SECURITY_MAX_IDLE_TIME': 30,
|
'SECURITY_MAX_IDLE_TIME': 30,
|
||||||
'SECURITY_MAX_SESSION_TIME': 24,
|
'SECURITY_MAX_SESSION_TIME': 24,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
from .base import (
|
from .base import (
|
||||||
REDIS_SSL_CA, REDIS_SSL_CERT, REDIS_SSL_KEY, REDIS_SSL_REQUIRED, REDIS_USE_SSL,
|
REDIS_SSL_CA, REDIS_SSL_CERT, REDIS_SSL_KEY, REDIS_SSL_REQUIRED, REDIS_USE_SSL,
|
||||||
REDIS_PROTOCOL, REDIS_SENTINEL_SERVICE_NAME, REDIS_SENTINELS, REDIS_SENTINEL_PASSWORD,
|
REDIS_PROTOCOL, REDIS_SENTINEL_SERVICE_NAME, REDIS_SENTINELS, REDIS_SENTINEL_PASSWORD,
|
||||||
@ -197,3 +197,5 @@ PIICO_DEVICE_ENABLE = CONFIG.PIICO_DEVICE_ENABLE
|
|||||||
PIICO_DRIVER_PATH = CONFIG.PIICO_DRIVER_PATH
|
PIICO_DRIVER_PATH = CONFIG.PIICO_DRIVER_PATH
|
||||||
|
|
||||||
LEAK_PASSWORD_DB_PATH = CONFIG.LEAK_PASSWORD_DB_PATH
|
LEAK_PASSWORD_DB_PATH = CONFIG.LEAK_PASSWORD_DB_PATH
|
||||||
|
|
||||||
|
JUMPSERVER_UPTIME = int(time.time())
|
||||||
|
@ -18,7 +18,11 @@ class TerminalSettingSerializer(serializers.Serializer):
|
|||||||
('25', '25'),
|
('25', '25'),
|
||||||
('50', '50'),
|
('50', '50'),
|
||||||
)
|
)
|
||||||
SECURITY_SERVICE_ACCOUNT_REGISTRATION = serializers.BooleanField(
|
SECURITY_SERVICE_ACCOUNT_REGISTRATION = serializers.ChoiceField(
|
||||||
|
choices=[
|
||||||
|
('auto', _('Auto(Enabled for the first 5 minutes after startup, then disabled.)')),
|
||||||
|
(True, _('Enable')), (False, _('Disable'))
|
||||||
|
],
|
||||||
required=True, label=_('Registration'),
|
required=True, label=_('Registration'),
|
||||||
help_text=_(
|
help_text=_(
|
||||||
"Allow component register, after all component setup, you should disable this for security"
|
"Allow component register, after all component setup, you should disable this for security"
|
||||||
|
@ -85,12 +85,6 @@ class TerminalRegistrationApi(generics.CreateAPIView):
|
|||||||
permission_classes = [WithBootstrapToken]
|
permission_classes = [WithBootstrapToken]
|
||||||
http_method_names = ['post']
|
http_method_names = ['post']
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
|
||||||
if not settings.SECURITY_SERVICE_ACCOUNT_REGISTRATION:
|
|
||||||
data = {"error": "service account registration disabled"}
|
|
||||||
return Response(data=data, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
return super().create(request, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class EncryptedTerminalConfig(generics.CreateAPIView):
|
class EncryptedTerminalConfig(generics.CreateAPIView):
|
||||||
serializer_class = serializers.EncryptedConfigSerializer
|
serializer_class = serializers.EncryptedConfigSerializer
|
||||||
|
Loading…
Reference in New Issue
Block a user