From 3ddb5a13a57d0202206c5f66411ac4b1fcd5835e Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Tue, 7 Mar 2023 13:19:24 +0100 Subject: [PATCH] fix(ulimit): handle low ulimit OSError (#2042) Co-authored-by: Toni de la Fuente --- prowler/lib/check/check.py | 12 ++++++++++-- prowler/lib/utils/utils.py | 5 +++++ prowler/providers/aws/aws_provider.py | 8 ++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/prowler/lib/check/check.py b/prowler/lib/check/check.py index 367a6ecd..d2c2a0d4 100644 --- a/prowler/lib/check/check.py +++ b/prowler/lib/check/check.py @@ -4,6 +4,7 @@ import os import sys import traceback from pkgutil import walk_packages +from resource import RLIMIT_NOFILE, getrlimit from types import ModuleType from typing import Any @@ -108,8 +109,8 @@ def exclude_services_to_run( # Load checks from checklist.json def parse_checks_from_file(input_file: str, provider: str) -> set: checks_to_execute = set() - f = open_file(input_file) - json_file = parse_json_file(f) + with open_file(input_file) as f: + json_file = parse_json_file(f) for check_name in json_file[provider]: checks_to_execute.add(check_name) @@ -356,6 +357,13 @@ def execute_checks( audit_progress=0, ) + # Check ulimit for the maximum system open files + soft, _ = getrlimit(RLIMIT_NOFILE) + if soft < 4096: + logger.warning( + f"Your session file descriptors limit ({soft} open files) is below 4096. We recommend to increase it to avoid errors. Solve it running this command `ulimit -n 4096`. For more info visit https://docs.prowler.cloud/en/latest/troubleshooting/" + ) + # Execution with the --only-logs flag if audit_output_options.only_logs: for check_name in checks_to_execute: diff --git a/prowler/lib/utils/utils.py b/prowler/lib/utils/utils.py index 3d9137fa..8a1f5484 100644 --- a/prowler/lib/utils/utils.py +++ b/prowler/lib/utils/utils.py @@ -16,6 +16,11 @@ from prowler.lib.logger import logger def open_file(input_file: str, mode: str = "r") -> TextIOWrapper: try: f = open(input_file, mode) + except OSError: + logger.critical( + "Ooops! You reached your user session maximum open files. To solve this issue, increase the shell session limit by running this command `ulimit -n 4096`. For more info visit https://docs.prowler.cloud/en/latest/troubleshooting/" + ) + sys.exit(1) except Exception as e: logger.critical( f"{input_file}: {e.__class__.__name__}[{e.__traceback__.tb_lineno}]" diff --git a/prowler/providers/aws/aws_provider.py b/prowler/providers/aws/aws_provider.py index 11126a98..6f4ca198 100644 --- a/prowler/providers/aws/aws_provider.py +++ b/prowler/providers/aws/aws_provider.py @@ -110,8 +110,8 @@ def generate_regional_clients( regional_clients = {} # Get json locally actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__))) - f = open_file(f"{actual_directory}/{aws_services_json_file}") - data = parse_json_file(f) + with open_file(f"{actual_directory}/{aws_services_json_file}") as f: + data = parse_json_file(f) # Check if it is a subservice json_regions = data["services"][service]["regions"][ audit_info.audited_partition @@ -144,8 +144,8 @@ def generate_regional_clients( def get_aws_available_regions(): try: actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__))) - f = open_file(f"{actual_directory}/{aws_services_json_file}") - data = parse_json_file(f) + with open_file(f"{actual_directory}/{aws_services_json_file}") as f: + data = parse_json_file(f) regions = set() for service in data["services"].values():