Syslog Sender
Use the Syslog Sender integration to send messages and mirror incident War Room entries to Syslog.
Analytics & SIEM · Syslog
Details
| ID | Syslog Sender |
|---|---|
| Provider | Open Source |
| Category | Analytics & SIEM |
| From Version | 5.5.0 |
| Docker Image | demisto/syslog:1.0.0.10133006 |
| Supported Modules | Agentix XSIAM |
README
Overview
Use the Syslog Sender integration to send messages in RFC 5424 message format and mirror incident War Room entries to Syslog.
Use Cases
- Send messages to Syslog via TCP or UDP or TLS.
- Mirror incident war room entries to Syslog.
- Track any activity from the Playground and War Room to your SIEM for improved visibility. This activity should be logged and attributed to the specific analyst.
Configure Syslog Sender on Cortex XSOAR
Usage example for rsyslog
To allow sending messages to rsyslog via Cortex XSOAR, the following lines have to be in the rsyslog configuration:
For TCP:
module(load="imtcp")
input(type="imtcp" port="<port>")
For UDP:
module(load="imudp")
input(type="imudp" port="<port>")
Usage example for sending War Room/Playground actions to Syslog
- From the Incidents page, click an incident.
- Run the !mirror-investigation type=”all” command.
If you receive an Investication mirrored to Syslog successfully response, any action in the War Room will be sent to Syslog.
For example:
Run the command !Print value=”test msg”
<14>1 2023-09-19T13:49:38.140870+00:00 a1427a8493b5 SysLogLogger 1 - - 29, 105@29, admin: !Print value=" incident owner is ${incident.owner}"
<14>1 2023-09-19T13:49:38.162145+00:00 a4140f2eb707 SysLogLogger 1 - - 29, 106@29, DBot: incident owner is admin
Syslog already contains the analyst name - admin (the user who performed the action).
The action is: !Print value=”test msg”
The action result appears on the second line.
If you run the same command with a different user on the same Cortex XSOAR instance, the output will be:
<14>1 2023-09-19T13:56:02.152486+00:00 a1427a8493b5 SysLogLogger 1 - - 8069, 86@8069, jsmith: !Print value=" incident owner is ${incident.owner}"
<14>1 2023-09-19T13:56:02.180858+00:00 a4140f2eb707 SysLogLogger 1 - - 8069, 87@8069, DBot: incident owner is admin
Username (analyst) is present and located before each command. In this case, jsmith.
The timestamp is present and loacated at the beginning of each string.
To determine the execution time (duration), calculate the difference between the second timestamp and the first.
Integration configuration
- Navigate to Settings > Integrations > Servers & Services.
- Search for Syslog Sender.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- IP Address (e.g. 127.0.0.1)
- Port
- Protocol (TCP / UDP)
- Minimum severity of incidents to send messages on
- Log level to send
- Facility
- Long running instance. Required for investigation mirroring.
- Incident type
- Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
- mirror-investigation
- send-notification
1. mirror-investigation
Mirrors the investigation’s War Room to syslog.
Base Command
mirror-investigation
Input
| Argument Name | Description | Required |
|---|---|---|
| type | The mirroring type. Can be “all”, which mirrors everything, “chat”, which mirrors only chats (not commands), or “none”, which stops all mirroring. | Optional |
Context Output
There is no context output for this command.
Command Example
!mirror-investigation
Human Readable Output
Investigation mirrored successfully.
2. send-notification
Sends a message to syslog.
Base Command
send-notification
Input
| Argument Name | Description | Required |
|---|---|---|
| message | The message content. | Optional |
| entry | An entry ID to send as a link. | Optional |
| ignoreAddURL | Whether to include a URL to the relevant component in Cortex XSOAR. Can be “true” or “false”. The default value is “false’. | Optional |
| level | Log level to send. Can be “DEBUG”, “INFO”, “WARNING”, “ERROR”, or “CRITICAL”. | Optional |
Context Output
There is no context output for this command.
Command Example
!send-notification message=Test ignoreAddURL=true
Human Readable Output
Message sent to Syslog successfully.
3. syslog-send
Send a message to Syslog
Base Command
syslog-send
Input
| Argument Name | Description | Required |
|---|---|---|
| message | The message content. | Optional |
| level | The log level to send. Can be “DEBUG”, “INFO”, “WARNING”, “ERROR”, or “CRITICAL”. | Optional |
| address | The Syslog server address. | Optional |
| protocol | The protocol to use | Optional |
| port | The Syslog server port (required for TCP or UDP protocols). | Optional |
| facility | The Syslog facility. | Optional |
Context Output
There is no context output for this command.
Command Example
!syslog-send address=127.0.0.1 port=514 protocol=TCP message=yo level=ERROR
Human Readable Output
Message sent to Syslog successfully.
Troubleshooting
Make sure you can access the Syslog server on the provided IP address and the port is open.
Demo Video
Sorry, your browser doesn't support embedded videos. You can download the video at: https://github.com/demisto/content-assets/blob/7982404664dc68c2035b7c701d093ec026628802/Assets/Syslog/syslog-sender-demo.mp4
Configuration parameters
address— IP Address (e.g., 127.0.0.1)port— Portprotocol— Protocolcertificate—self_signed_certificate— Self Signed Certificatefacility— Facilitypriority— Log level to sendseverity— Minimum severity of incidents to send messages on
Commands (3)
-
mirror-investigationMirrors the investigation's War Room to Syslog.
-
send-notificationSends a message to Syslog. Used by the mirroring functionality.
-
syslog-sendSends a message to Syslog.
from CommonServerPython import * import pytest from contextlib import contextmanager import logging class Logger: def debug(self, message): return "debug" + message def info(self, message): return "info" + message def warning(self, message): return "warning" + message def error(self, message): return "error" + message def critical(self, message): return "critical" + message class Manager: @contextmanager def get_logger(self): try: yield Logger() finally: pass def test_init_manager(): from SyslogSender import init_manager # Set params = {"address": "127.0.0.1", "port": "514", "protocol": "tcp", "priority": "LOG_DEBUG", "facility": "LOG_SYSLOG"} # Arrange manager = init_manager(params) # Assert assert manager.address == "127.0.0.1" assert manager.port == 514 assert manager.protocol == "tcp" assert manager.logging_level == 10 assert manager.facility == 5 @pytest.mark.parametrize("investigation_id", ["999", "909"]) def test_mirror_investigation_new_and_existing(mocker, investigation_id): from SyslogSender import mirror_investigation # Set mocker.patch.object(demisto, "args", return_value={}) mocker.patch.object(demisto, "investigation", return_value={"id": investigation_id}) mocker.patch.object(demisto, "results") mocker.patch.object(demisto, "mirrorInvestigation") # Arrange mirror_investigation() success_results = demisto.results.call_args_list[0][0] mirror_id = demisto.mirrorInvestigation.call_args[0][0] mirror_type = demisto.mirrorInvestigation.call_args[0][1] auto_close = demisto.mirrorInvestigation.call_args[0][2] # Assert assert success_results[0] == "Investigation mirrored to Syslog successfully." assert mirror_id == investigation_id assert mirror_type == "all:FromDemisto" assert auto_close is False def test_send_with_severity(mocker): from SyslogSender import syslog_send_notification # Set mocker.patch.object(demisto, "args", return_value={"severity": "4", "message": "!!!", "messageType": "incidentOpened"}) link = "https://www.eizelulz.com:8443/#/WarRoom/727" mocker.patch.object(demisto, "investigation", return_value={"type": 1, "id": 1}) mocker.patch.object(demisto, "demistoUrls", return_value={"warRoom": link}) mocker.patch.object(demisto, "results") mocker.patch.object(Logger, "info") # Arrange syslog_send_notification(Manager(), 1) send_args = Logger.info.call_args[0] results = demisto.results.call_args[0][0] # Assert assert send_args[0] == "1, !!! https://www.eizelulz.com:8443/#/WarRoom/727" assert results == "Message sent to Syslog successfully." def test_send_with_severity_zero(mocker): from SyslogSender import syslog_send_notification # Set mocker.patch.object(demisto, "args", return_value={"severity": "0", "message": "!!!", "messageType": "incidentOpened"}) link = "https://www.eizelulz.com:8443/#/WarRoom/727" mocker.patch.object(demisto, "investigation", return_value={"type": 1, "id": 1}) mocker.patch.object(demisto, "demistoUrls", return_value={"warRoom": link}) mocker.patch.object(demisto, "results") mocker.patch.object(Logger, "critical") # Arrange syslog_send_notification(Manager(), 1) send_count = Logger.critical.call_count results_count = demisto.results.call_count # Assert assert send_count == 0 assert results_count == 0 def test_send(mocker): from SyslogSender import syslog_send_notification # Set mocker.patch.object(demisto, "args", return_value={"message": "eyy"}) link = "https://www.eizelulz.com:8443/#/WarRoom/727" mocker.patch.object(demisto, "investigation", return_value={"type": 1, "id": 1}) mocker.patch.object(demisto, "demistoUrls", return_value={"warRoom": link}) mocker.patch.object(demisto, "results") mocker.patch.object(Logger, "info") # Arrange syslog_send_notification(Manager(), 1) send_args = Logger.info.call_args[0] results = demisto.results.call_args[0][0] # Assert assert send_args[0] == "1, eyy https://www.eizelulz.com:8443/#/WarRoom/727" assert results == "Message sent to Syslog successfully." def test_send_with_non_default_log_level(mocker): from SyslogSender import syslog_send_notification # Set mocker.patch.object(demisto, "args", return_value={"message": "eyy", "level": "DEBUG"}) link = "https://www.eizelulz.com:8443/#/WarRoom/727" mocker.patch.object(demisto, "investigation", return_value={"type": 1, "id": 1}) mocker.patch.object(demisto, "demistoUrls", return_value={"warRoom": link}) mocker.patch.object(demisto, "results") mocker.patch.object(Logger, "debug") mocker.patch.object(Logger, "info") # This is the default log level # Arrange syslog_send_notification(Manager(), 1) debug_send_args = Logger.debug.call_args[0] info_send_args = Logger.info.call_args # make sure nothing was sent in the info log level results = demisto.results.call_args[0][0] # Assert assert debug_send_args[0] == "1, eyy https://www.eizelulz.com:8443/#/WarRoom/727" assert not info_send_args assert results == "Message sent to Syslog successfully." def test_prepare_certificate_file(): """ Given: - certificate: Certificate. When: - Preparing global variables and creating the StreamServer. Then: - Ensure globals are set as expected and server is returned with expected attributes. """ from SyslogSender import prepare_certificate_file result = prepare_certificate_file("example") assert len(result) def test_SyslogHandlerTLS_init(mocker): """ Given: - address - port - facility - log_level - certificate: Certificate. When: - Preparing global variables and creating the SyslogHandlerTLS handler. Then: - Ensure globals are set as expected and the handler was created. """ from SyslogSender import SyslogHandlerTLS address = "127.0.0.1" port = 6514 log_level = logging.DEBUG facility = 0 cert_path = "cert.pem" mocker.patch("ssl.SSLContext.load_verify_locations", return_value=None) mocker.patch.object(ssl.SSLContext, "wrap_socket") mocker.patch.object(socket.socket, "connect") handler = SyslogHandlerTLS(address, port, log_level, facility, cert_path, False) assert handler.address == address assert handler.port == port assert handler.certfile == cert_path assert handler.facility == facility assert handler.level == log_level def test_SyslogManager(): """ Given: - address - port - facility - log_level - certificate: Certificate. When: - Preparing global variables and creating the SyslogHandlerTLS handler. Then: - Ensure globals are set as expected and the handler was created. """ from SyslogSender import SyslogManager address = "127.0.0.1" port = 6514 log_level = logging.DEBUG facility = 0 cert_path = "cert.pem" protocol = "udp" self_signed = True handler = SyslogManager(address, port, protocol, log_level, facility, cert_path, self_signed) assert handler.address == address assert handler.port == port assert handler.syslog_cert_path == cert_path assert handler.facility == facility assert handler.logging_level == log_level def test_syslog_send(mocker): """ Given: - address - port - facility - log_level - certificate: Certificate. When: - calling syslog_send. Then: - Ensure the message was sent. """ import SyslogSender mocker.patch.object(demisto, "args", return_value={}) mocker.patch.object(SyslogSender, "send_log") demisto_results_mocker = mocker.patch.object(demisto, "results") SyslogSender.syslog_send(None) assert demisto_results_mocker.called assert demisto.results.call_args[0][0] == "Message sent to Syslog successfully." def test_SyslogManager_tcp(mocker): """ Given: - address - port - facility - log_level - certificate: Certificate. When: - calling creating a logger using tcp protocol. Then: - Ensure manger, handler and logger are being created. """ from SyslogSender import SyslogManager, init_manager params = { "address": "127.0.0.1", "port": "514", "protocol": "tcp", "priority": "LOG_DEBUG", "facility": "LOG_SYSLOG", "cert_path": "", } handler = { "SysLogLogger": { "level": "INFO", "class": "rfc5424logging.handler.Rfc5424SysLogHandler", "address": ("127.0.0.1", 514), "enterprise_id": 32473, } } # Arrange manager = init_manager(params) mocker.patch.object(SyslogManager, "_get_handler", return_value=handler) handler = SyslogManager._get_handler(manager) # mocker.patch.object(Logger, 'setLevel') logger = SyslogManager._init_logger(manager, handler) assert logger.level == 10 def test_SyslogManager_tls(mocker): """ Given: - address - port - facility - log_level - certificate: Certificate. When: - calling creating a logger using tls protocol. Then: - Ensure manger, handler and logger are being created. """ import SyslogSender from SyslogSender import SyslogManager, init_manager params = { "address": "127.0.0.1", "port": "6514", "protocol": "tls", "priority": "LOG_DEBUG", "facility": "LOG_SYSLOG", "certificate": {"certificate": "cert.pem"}, } handler = { "syslog": { "level": "INFO", "class": "tlssyslog.handlers.TLSSysLogHandler", "formatter": "simple", "address": ("127.0.0.1", 6514), "ssl_kwargs": { "cert_reqs": ssl.CERT_REQUIRED, "ssl_version": ssl.PROTOCOL_TLS_CLIENT, "ca_certs": "cert.pem", }, } } # Arrange mocker.patch.object(SyslogSender, "prepare_certificate_file", return_value="cert.pem") manager = init_manager(params) mocker.patch.object(SyslogManager, "init_handler_tls", return_value=handler) handler = SyslogManager.init_handler_tls(manager, "cert.pem") logger = SyslogManager._init_logger(manager, handler) assert logger.level == 10 def test_main(mocker): import SyslogSender from SyslogSender import main params = { "address": "127.0.0.1", "port": "6514", "protocol": "tls", "priority": "LOG_DEBUG", "facility": "LOG_SYSLOG", "certificate": {"password": "-----BEGIN SSH CERTIFICATE----- MIIF7z gdwZcx IENpdH -----END SSH CERTIFICATE-----"}, } mocker.patch.object(demisto, "params", return_value=params) mocker.patch.object(demisto, "command", return_value="syslog-send") mocker.patch.object(demisto, "args", return_value={}) mocker.patch.object(SyslogSender, "send_log") demisto_results_mocker = mocker.patch.object(demisto, "results") main() assert demisto_results_mocker.called assert demisto.results.call_args[0][0] == "Message sent to Syslog successfully."