Skip to content

Commit

Permalink
Allow updater to fetch new rules from the database even if the source…
Browse files Browse the repository at this point in the history
…s have no new files
  • Loading branch information
cccs-sgaron committed May 22, 2020
1 parent 6383fdf commit 665caa3
Showing 1 changed file with 34 additions and 26 deletions.
60 changes: 34 additions & 26 deletions suricata_/suricata_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,29 @@ def suricata_update() -> None:

# Exit if no update sources given
if 'sources' not in update_config.keys() or not update_config['sources']:
LOGGER.error(f"Update configuration does not contain any source to update from")
exit()

# Initialise al_client
server = update_config['ui_server']
user = update_config['api_user']
api_key = update_config['api_key']
LOGGER.info(f"Connecting to Assemblyline API: {server}...")
al_client = get_client(server, apikey=(user, api_key), verify=False)
LOGGER.info(f"Connected!")

# Parse updater configuration
previous_update = update_config.get('previous_update', None)
previous_hash = update_config.get('previous_hash', None) or {}
if previous_hash:
previous_hash = json.loads(previous_hash)
previous_hash = json.loads(update_config.get('previous_hash', None) or "{}")
sources = {source['name']: source for source in update_config['sources']}
files_sha256 = {}
source_default_classification = {}

# Go through each source and download file
for source_name, source in sources.items():
uri: str = source['uri']
source_default_classification[source_name] = source.get('default_classification', classification.UNRESTRICTED)
source_default_classification[source_name] = source.get('default_classification',
classification.UNRESTRICTED)

if uri.endswith('.git'):
files = git_clone_repo(source, previous_update=previous_update)
Expand All @@ -204,45 +212,45 @@ def suricata_update() -> None:
if previous_hash.get(source_name, {}).get(file, None) != sha256:
files_sha256[source_name][file] = sha256

if not files_sha256:
LOGGER.info('No Suricata rule file(s) downloaded')
shutil.rmtree(UPDATE_OUTPUT_PATH, ignore_errors=True)
exit()

LOGGER.info("Suricata rule(s) file(s) successfully downloaded")
if files_sha256:
LOGGER.info("Found new Suricata rule files to process!")

server = update_config['ui_server']
user = update_config['api_user']
api_key = update_config['api_key']
al_client = get_client(server, apikey=(user, api_key), verify=False)
suricata_importer = SuricataImporter(al_client, logger=LOGGER)

suricata_importer = SuricataImporter(al_client, logger=LOGGER)
for source, source_val in files_sha256.items():
total_imported = 0
default_classification = source_default_classification[source]
for file in source_val.keys():
total_imported += suricata_importer.import_file(file, source,
default_classification=default_classification)
LOGGER.info(f"{total_imported} signatures were imported for source {source}")

for source, source_val in files_sha256.items():
total_imported = 0
default_classification = source_default_classification[source]
for file in source_val.keys():
total_imported += suricata_importer.import_file(file, source, default_classification=default_classification)
LOGGER.info(f"{total_imported} signatures were imported for source {source}")
else:
LOGGER.info('No new Suricata rule files to process')

if al_client.signature.update_available(since=previous_update or '', sig_type='suricata')['update_available']:
LOGGER.info("AN UPDATE IS AVAILABLE TO DOWNLOAD")
LOGGER.info("An update is available for download from the datastore")

if not os.path.exists(UPDATE_OUTPUT_PATH):
os.makedirs(UPDATE_OUTPUT_PATH)

temp_zip_file = os.path.join(UPDATE_OUTPUT_PATH, 'temp.zip')
al_client.signature.download(output=temp_zip_file, query="type:suricata AND (status:NOISY OR status:DEPLOYED)")
al_client.signature.download(output=temp_zip_file,
query="type:suricata AND (status:NOISY OR status:DEPLOYED)")

if os.path.exists(temp_zip_file):
with ZipFile(temp_zip_file, 'r') as zip_f:
zip_f.extractall(UPDATE_OUTPUT_PATH)

os.remove(temp_zip_file)

# Create the response yaml
with open(os.path.join(UPDATE_OUTPUT_PATH, 'response.yaml'), 'w') as yml_fh:
yaml.safe_dump(dict(hash=json.dumps(files_sha256)), yml_fh)
# Create the response yaml
with open(os.path.join(UPDATE_OUTPUT_PATH, 'response.yaml'), 'w') as yml_fh:
yaml.safe_dump(dict(hash=json.dumps(files_sha256)), yml_fh)

LOGGER.info(f"New ruleset successfully downloaded and ready to use")

LOGGER.info(f"Suricata updater completed successfully")
except Exception:
LOGGER.exception("Updater ended with an exception!")

Expand Down

0 comments on commit 665caa3

Please sign in to comment.