Set the following variables in the Python script:
<MANAGER_IP><USERNAME><PASSWORD><RULESET_FILE_PATH><RULESET_FILENAME><SENSOR_ID><SENSOR_NAME>
The script performs these operations:
Import the ruleset — Imports the ruleset file to the Manager.
Push the configuration — Performs a Suricata configuration push to the Sensor.
Monitor progress — Waits for the configuration push to complete.
Display results — Prints the results of the operations.
Script:
import requests
import json
import base64
import time
import urllib3
import logging
# --- Setup Logging ---
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Suppress insecure request warnings for production-clean logs
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def base64_encode(message):
"""Encodes string to base64 for NSM-SDK-API header."""
message_bytes = message.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
return base64_bytes.decode('ascii')
def create_session(manager_ip, username, password):
"""Authenticates and returns the session object."""
try:
url = f"https://{manager_ip}/sdkapi/session"
headers = {
'Accept': 'application/vnd.nsm.v2.0+json',
'Content-Type': 'application/json',
'NSM-SDK-API': base64_encode(f"{username}:{password}"),
}
response = requests.get(url, headers=headers, verify=False, timeout=30)
response.raise_for_status()
logger.info("Session created successfully.")
return response.json()
except Exception as e:
logger.error(f"Failed in session creation. Error: {e}")
return None
def import_ruleset(encoded_session, manager_ip, ruleset_filename, ruleset_file_path):
"""Uploads the ruleset file to the Manager."""
try:
url = f"https://{manager_ip}/sdkapi/suricata/ruleset/import"
payload = {'rulesetName': 'Test', 'publisherName': 'QA'}
headers = {
'Accept': 'application/vnd.nsm.v2.0+json',
'NSM-SDK-API': encoded_session
}
with open(ruleset_file_path, 'rb') as f:
files = [('file', (ruleset_filename, f, 'application/octet-stream'))]
response = requests.post(url, headers=headers, data=payload, files=files, verify=False, timeout=120)
response.raise_for_status()
logger.info("Ruleset file imported successfully.")
return response.json()
except Exception as e:
logger.error(f"Failed to import ruleset file. Error: {e}")
return None
def verify_suricata_config_deployment(encoded_session, manager_ip, sensor_id, request_id):
"""Polls the status until percentage is 100 and confirms success message."""
url = f"https://{manager_ip}/sdkapi/sensor/{sensor_id}/action/update_sensor_config/{request_id}"
headers = {
'Accept': 'application/vnd.nsm.v2.0+json',
'Content-Type': 'application/json',
'NSM-SDK-API': encoded_session
}
logger.info(f"Starting deployment verification for Request ID: {request_id}")
while True:
try:
response = requests.get(url, headers=headers, verify=False, timeout=30)
response.raise_for_status()
data = response.json()
percentage = data.get("sigsetConfigPercentageComplete", 0)
status_msg = data.get("sigsetConfigStatusMessage", "")
logger.info(f"Deployment Progress: {percentage}% | Status: {status_msg}")
if percentage == 100:
if status_msg == "DOWNLOAD COMPLETE":
logger.info("Verification Successful: Deployment finished with 'DOWNLOAD COMPLETE'.")
return True, data
else:
logger.error(f"Verification Failed: Reached 100% but message was '{status_msg}'.")
return False, data
time.sleep(10) # Wait before next poll
except Exception as e:
logger.error(f"Error during status verification: {e}")
return False, None
def deploy_suricata_config(encoded_session, manager_ip, sensor_id, sensor_name):
"""Triggers the configuration update on the sensor."""
try:
url = f"https://{manager_ip}/sdkapi/sensor/{sensor_id}/action/update_sensor_config"
payload = json.dumps({
"deviceName": sensor_name,
"pendingChanges": {
"isConfigurationChanged": True,
"isSignatureSetConfigurationChanged": True,
"isSuricataConfigurationChanged": True
},
"isSigsetConfigPushRequired": True,
"isSuricataUpdateRequired": True
})
headers = {
'Accept': 'application/vnd.nsm.v2.0+json',
'Content-Type': 'application/json',
'NSM-SDK-API': encoded_session
}
response = requests.put(url, headers=headers, data=payload, verify=False, timeout=30)
response.raise_for_status()
request_id = response.json().get("RequestId")
if not request_id:
logger.error("Deployment triggered but no Request ID received.")
return None
# Verify the deployment status
success, final_data = verify_suricata_config_deployment(encoded_session, manager_ip, sensor_id, request_id)
if success:
logger.info("FINAL RESULT: Deployment Succeeded.")
else:
logger.error("FINAL RESULT: Deployment Failed.")
return final_data
except Exception as e:
logger.error(f"Failure in triggering suricata config deployment: {e}")
return None
if __name__ == "__main__":
# Constants
MANAGER_IP = "10.213.172.35"
USERNAME = "admin"
PASSWORD = "admin123"
RULESET_FILE_PATH = r"C:\Users\Administrator\Desktop\All\1. PROJECTS\TROS_Deployment\suricata_ruleset_new.rules"
RULESET_FILENAME = "suricata_ruleset_new.rules"
SENSOR_ID = "1068"
SENSOR_NAME = "suricata_stack_41_42"
# Step 1: Session
session_res = create_session(MANAGER_IP, USERNAME, PASSWORD)
if session_res:
auth_header = base64_encode(f"{session_res['session']}:{session_res['userId']}")
# Step 2: Import
import_res = import_ruleset(auth_header, MANAGER_IP, RULESET_FILENAME, RULESET_FILE_PATH)
# Step 3: Deploy & Verify
if import_res:
deploy_suricata_config(auth_header, MANAGER_IP, SENSOR_ID, SENSOR_NAME)
else:
logger.error("Skipping deployment because ruleset import failed.")
else:
logger.error("Exiting script: Authentication failed.")Sample output:
python suricata_automation_prod.py 2026-03-18 09:04:00,614 - INFO - Session created successfully. 2026-03-18 09:04:02,177 - INFO - Ruleset file imported successfully. 2026-03-18 09:04:11,755 - INFO - Starting deployment verification for Request ID: 1773870863956 2026-03-18 09:04:11,786 - INFO - Deployment Progress: 0% | Status: IN PROGRESS:Queued: Generation of Signature file Segment for Sensor: suricata_stack_41_42 2026-03-18 09:04:21,833 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:04:31,880 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:04:41,927 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:04:51,958 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:05:02,005 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:05:12,052 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:05:22,099 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:05:32,146 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:05:42,193 - INFO - Deployment Progress: 1% | Status: IN PROGRESS:Generating Signature Segments for Stack: suricata_stack_41_42. Sig Version: 11.10.33.7 ,sensorSoftwareVersion: 11.1.5.167 2026-03-18 09:05:52,239 - INFO - Deployment Progress: 30% | Status: IN PROGRESS:Generating Response Segments for Stack: suricata_stack_41_42 2026-03-18 09:06:02,286 - INFO - Deployment Progress: 50% | Status: IN PROGRESS:Transferring files in progress for... ...node :suricata_stack_41_42-2 ...node :suricata_stack_41_42-1 2026-03-18 09:06:12,318 - INFO - Deployment Progress: 50% | Status: IN PROGRESS:Transferring files in progress for... ...node :suricata_stack_41_42-2 ...node :suricata_stack_41_42-1 2026-03-18 09:06:22,365 - INFO - Deployment Progress: 100% | Status: DOWNLOAD COMPLETE 2026-03-18 09:06:22,365 - INFO - Verification Successful: Deployment finished with 'DOWNLOAD COMPLETE'. 2026-03-18 09:06:22,365 - INFO - FINAL RESULT: Deployment Succeeded.