mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-03-18 02:52:08 +00:00
feat: support enable trusted ip verify
This commit is contained in:
@@ -157,29 +157,57 @@ def is_uuid(seq):
|
||||
return False
|
||||
|
||||
|
||||
def verify_ip_if_need(request, ip):
|
||||
if not settings.X_FORWARDED_FOR_VERIFY_ENABLED:
|
||||
return ip
|
||||
|
||||
received = request.META.get(settings.X_FORWARDED_FOR_VERIFY_VALUE_HEADER, '')
|
||||
if not received:
|
||||
# 内部请求
|
||||
return ip
|
||||
|
||||
verify_key_path = settings.X_FORWARDED_FOR_VERIFY_KEY_PATH
|
||||
if verify_key_path and os.path.exists(verify_key_path):
|
||||
with open(verify_key_path) as f:
|
||||
key = f.read().strip()
|
||||
expected = hmac.new(key.encode(), ip.encode(), hashlib.sha256).hexdigest()
|
||||
if hmac.compare_digest(expected.lower(), received.lower()):
|
||||
# ip 不可信
|
||||
ip = '0.0.0.0'
|
||||
return ip
|
||||
|
||||
|
||||
def get_request_ip(request):
|
||||
x_forwarded_for_header = settings.X_FORWARDED_FOR_HEADER
|
||||
x_forwarded_for = request.META.get(x_forwarded_for_header, '').split(',')
|
||||
if settings.TRUSTED_IP_VERIFY_ENABLED:
|
||||
login_ip = get_trusted_request_ip(request)
|
||||
else:
|
||||
login_ip = get_common_request_ip(request)
|
||||
return login_ip
|
||||
|
||||
|
||||
def get_trusted_request_ip(request):
|
||||
trusted_ip = request.META.get(settings.TRUSTED_IP_SOURCE_HEADER, '')
|
||||
if not trusted_ip:
|
||||
logger.warning(
|
||||
f"Trusted IP verification enabled but no source header '{settings.TRUSTED_IP_SOURCE_HEADER}' "
|
||||
f"found in request."
|
||||
)
|
||||
return '0.0.0.0'
|
||||
|
||||
signature_header_name = settings.TRUSTED_IP_VERIFY_SIGNATURE_HEADER
|
||||
received_signature = request.META.get(signature_header_name, '')
|
||||
if not received_signature:
|
||||
logger.warning(
|
||||
f"Trusted IP verification enabled but no signature header '{signature_header_name}' "
|
||||
f"found in request."
|
||||
)
|
||||
return '0.0.0.0'
|
||||
|
||||
verification_key_path = settings.TRUSTED_IP_VERIFY_KEY_PATH
|
||||
if not verification_key_path or not os.path.exists(verification_key_path):
|
||||
logger.warning(
|
||||
f"Trusted IP verification enabled but no valid verification key found at "
|
||||
f"'{verification_key_path}'."
|
||||
)
|
||||
return '0.0.0.0'
|
||||
|
||||
with open(verification_key_path) as f:
|
||||
verification_key = f.read().strip()
|
||||
expected_signature = hmac.new(
|
||||
verification_key.encode(), trusted_ip.encode(), hashlib.sha256
|
||||
).hexdigest()
|
||||
if not hmac.compare_digest(expected_signature.lower(), received_signature.lower()):
|
||||
logger.warning(
|
||||
f"Trusted IP verification failed. Expected signature: {expected_signature}, "
|
||||
f"Received signature: {received_signature}."
|
||||
)
|
||||
return '0.0.0.0'
|
||||
|
||||
return trusted_ip
|
||||
|
||||
|
||||
def get_common_request_ip(request):
|
||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '').split(',')
|
||||
if x_forwarded_for and x_forwarded_for[0]:
|
||||
login_ip = x_forwarded_for[0]
|
||||
if login_ip.count(':') == 1:
|
||||
@@ -187,9 +215,7 @@ def get_request_ip(request):
|
||||
login_ip = login_ip.split(":")[0]
|
||||
else:
|
||||
login_ip = request.META.get('REMOTE_ADDR', '')
|
||||
|
||||
ip = verify_ip_if_need(request, login_ip)
|
||||
return ip
|
||||
return login_ip
|
||||
|
||||
|
||||
def get_request_ip_or_data(request):
|
||||
|
||||
@@ -745,10 +745,10 @@ class Config(dict):
|
||||
'VENDOR': 'jumpserver',
|
||||
|
||||
# x-forwarded-for 相关
|
||||
'X_FORWARDED_FOR_HEADER': 'HTTP_X_FORWARDED_FOR',
|
||||
'X_FORWARDED_FOR_VERIFY_ENABLED': False,
|
||||
'X_FORWARDED_FOR_VERIFY_VALUE_HEADER': '',
|
||||
'X_FORWARDED_FOR_VERIFY_KEY_PATH': '',
|
||||
'TRUSTED_IP_VERIFY_ENABLED': False,
|
||||
'TRUSTED_IP_SOURCE_HEADER': '',
|
||||
'TRUSTED_IP_VERIFY_SIGNATURE_HEADER': '',
|
||||
'TRUSTED_IP_VERIFY_KEY_PATH': '',
|
||||
}
|
||||
|
||||
old_config_map = {
|
||||
|
||||
@@ -277,8 +277,7 @@ VENDOR_TEMPLATES_DIR = Path(STATIC_DIR) / VENDOR
|
||||
if Path(VENDOR_TEMPLATES_DIR).is_dir():
|
||||
TEMPLATES[0]['DIRS'].insert(0, VENDOR_TEMPLATES_DIR)
|
||||
|
||||
|
||||
X_FORWARDED_FOR_HEADER = CONFIG.X_FORWARDED_FOR_HEADER
|
||||
X_FORWARDED_FOR_VERIFY_ENABLED = CONFIG.X_FORWARDED_FOR_VERIFY_ENABLED
|
||||
X_FORWARDED_FOR_VERIFY_VALUE_HEADER = CONFIG.X_FORWARDED_FOR_VERIFY_VALUE_HEADER
|
||||
X_FORWARDED_FOR_VERIFY_KEY_PATH = CONFIG.X_FORWARDED_FOR_VERIFY_KEY_PATH
|
||||
TRUSTED_IP_VERIFY_ENABLED = CONFIG.TRUSTED_IP_VERIFY_ENABLED
|
||||
TRUSTED_IP_SOURCE_HEADER = CONFIG.TRUSTED_IP_SOURCE_HEADER
|
||||
TRUSTED_IP_VERIFY_SIGNATURE_HEADER = CONFIG.TRUSTED_IP_VERIFY_SIGNATURE_HEADER
|
||||
TRUSTED_IP_VERIFY_KEY_PATH = CONFIG.TRUSTED_IP_VERIFY_KEY_PATH
|
||||
|
||||
Reference in New Issue
Block a user