Skip to content

Instantly share code, notes, and snippets.

@netson
Last active November 6, 2022 23:24
Show Gist options
  • Save netson/cc6ffa751aa4610c13c0 to your computer and use it in GitHub Desktop.
Save netson/cc6ffa751aa4610c13c0 to your computer and use it in GitHub Desktop.

Revisions

  1. netson revised this gist Jan 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion psad-and-logstash.md
    Original file line number Diff line number Diff line change
    @@ -286,4 +286,4 @@ Useful links with information about PSAD:
    * [Official PSAD website](http://www.cipherdyne.org/psad/index.html)
    * [Official Logstash website](http://logstash.net/)
    * Puppet module for PSAD: [Puppetforge](https://forge.puppetlabs.com/tedivm/psad) / [Github](https://github.com/tedivm/puppet-psad)
    * [Using PSAD and UFW gist](https://gist.github.com/netson/c45b2dc4e835761fbccc)
    * [Gist: Using PSAD and UFW](https://gist.github.com/netson/c45b2dc4e835761fbccc)
  2. netson revised this gist Jan 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion psad-and-logstash.md
    Original file line number Diff line number Diff line change
    @@ -286,4 +286,4 @@ Useful links with information about PSAD:
    * [Official PSAD website](http://www.cipherdyne.org/psad/index.html)
    * [Official Logstash website](http://logstash.net/)
    * Puppet module for PSAD: [Puppetforge](https://forge.puppetlabs.com/tedivm/psad) / [Github](https://github.com/tedivm/puppet-psad)
    * [Using PSAD and UFW gist](https://gist.github.com/netson/c45b2dc4e835761fbccc)
  3. netson created this gist Jan 17, 2015.
    289 changes: 289 additions & 0 deletions psad-and-logstash.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,289 @@
    # PSAD and Logstash

    ### Table of Contents

    - [What are we doing here?](#whatarewedoinghere)
    - [What is PSAD?](#whatispsad)
    - [What is Logstash?](#whatislogstash)
    - [Using PSAD and Logstash](#usingpsadandlogstash)
    - [First, configure rsyslog](#firstconfigurersyslog)
    - [Then, configure logstash patterns](#thenconcifgurelogstashpatterns)
    - [Available log parameters](#availablelogparameters)
    - [Next up: logstash input](#nextuplogstashinput)
    - [Are you using logstash-forwarder?](#areyouusinglogstashforwarder)
    - [On to: logstash filter](#ontologstashfilter)
    - [Roundup](#roundup)
    - [Links](#links)

    <a name="whatarewedoinghere"></a>
    ## What are we doing here?

    <a name="whatispsad"></a>
    ### What is PSAD?

    psad is a collection of three lightweight system daemons (two main daemons and one helper daemon) that run on Linux machines and analyze iptables log messages to detect port scans and other suspicious traffic. A typical deployment is to run psad on the iptables firewall where it has the fastest access to log data.

    [PSAD website](http://cipherdyne.org/psad/ "PSAD website")

    <a name="whatislogstash"></a>
    ### What is Logstash?

    logstash is a tool for managing events and logs. You can use it to collect logs, parse them, and store them for later use (like, for searching). Speaking of searching, logstash comes with a web interface for searching and drilling into all of your logs.

    [Logstash website](http://logstash.net/ "Logstash website")

    <a name="usingpsadandlogstash"></a>
    ### Using PSAD and Logstash

    Using Logstash, you can process and tag PSAD events (logs) based on their significance. Also, as an alternative to using the PSAD email alerts, you could use one of Logstash' many output filters to send notifications of important events. For example, you could use Nagios to notify you of any port scans PSAD has detected. As the number of servers you install PSAD on grows, receiving email alerts from all of them can become cumbersome and could become a 'boy who cried wolf' situation. Logstash in combination with Kibana will let you chart all port scans and attempted attacks that PSAD can discover in a unified way.

    This gist will explain how to configure both PSAD and Logstash to play nice together. This gist is focused on PSAD 2.2.4, Logstash 1.4.2 and Ubuntu Server 14.04; if you're using a different OS or different versions of Logstash/PSAD you may have to tweak the instructions a bit.

    This gist assumes you have PSAD and Logstash up and running individually.

    <a name="firstconfigurersyslog"></a>
    ## First, configure rsyslog

    The first thing we need to do is configure rsyslog on Ubuntu to write any PSAD events to a separate logfile. Although it is perfectly possible to parse the `/var/log/syslog` directly for any PSAD messages, I prefer to write PSAD events to its own logfile; it makes it easier to determine its actions and makes our logstash configuration simpler as well, as we don't have to filter out any other kernel messages.

    To do this, we need to tell rsyslog to send all messages that originate from PSAD to a different logfile. Create a file called `/etc/rsyslog.d/30-psad.conf`. The 30 is added to make sure the settings in this configuration file are parsed before the default settings, which start with `50-`.

    Add the following contents to the file:
    ```sh
    if $programname == 'psad' then /var/log/psad.log # redirect psad log line to separate file
    & stop # prevent log lines from application psad to be prcessed by any other filters
    ```
    The first line ensures that any log lines from the application `psad` are sent to the file `/var/log/psad.log`. The second line ensures that any lines matching the previous criteria will not be processed by any other filters. This second line is needed to prevent the log lines from also showing up in your `/var/log/messages` or `/var/log/kern.log` file.
    **Note:** *with older versions of rsyslog, you may have to replace the word `stop` on the second line with the `~` character; on newer version of Ubuntu the `~` character as a stop indicator has been deprecated and will cause warning messages when (re)starting the rsyslog service.*
    Then, restart the rsyslog service to enable the changes:
    ```sh
    sudo service rsyslog restart
    ```
    <a name="thenconcifgurelogstashpatterns"></a>
    ## Then, configure logstash patterns
    To make processing PSAD messages easier, I have created a set of GROK patterns which should allow you to detect and act upon the various PSAD messages without too much effort.
    First, you need to create a logstash patterns file. Depending on your logstash configuration, the location of these pattern files may vary but I store mine in `/etc/logstash/patterns/`. Here are the patterns:
    ```grok
    # psad grok patterns
    PSAD_PORT_RANGE (?:(%{DATA:[psad][start_port]}\-%{DATA:[psad][end_port]})|%{DATA:[psad][scan_port]})
    PSAD_SCAN_DETECTED %{SYSLOGBASE} scan detected(:? \(%{DATA:[psad][scan_type]}\))?: %{IPORHOST:src_ip} -> %{IPORHOST:dst_ip} %{WORD:[psad][proto]}: \[%{PSAD_PORT_RANGE}\](:? flags: %{DATA:[psad][flags]})? %{WORD} pkts: %{NUMBER:[psad][proto_num_pkts]} DL: %{NUMBER:[psad][danger_level]}%{GREEDYDATA:message}
    PSAD_SIGNATURE_MATCH %{SYSLOGBASE} src: %{IPORHOST:src_ip} signature match: \"%{DATA:[psad][signature]}\" \(sid: %{NUMBER:[psad][signature_id]}\) %{WORD:[psad][proto]} port: %{NUMBER:[psad][scan_port]}
    PSAD_AUTO_BLOCK %{SYSLOGBASE} added iptables auto\-block against ${IPORHOST:src_ip} for %{NUMBER:[psad][block_time]} seconds
    PSAD_AUTO_UNBLOCK %{SYSLOGBASE} removed iptables auto\-block against ${IPORHOST:src_ip}
    PSAD_NOTICE %{SYSLOGBASE} (?=%{GREEDYDATA:message})(?:flushing|imported|received|domain)
    PSAD_WARNING %{SYSLOGBASE} %{LOGLEVEL:[psad][log_level]}: (?=%{GREEDYDATA:message})
    ```
    Let me briefly explain what each pattern does:
    #### `PSAD_PORT_RANGE`
    This pattern is only used by other patterns to prevent having to duplicate the port range part of the pattern
    *Fields: start_port, end_port, scan_port*
    #### `PSAD_SCAN_DETECTED`
    Used for port scan detections
    *Fields: scan_type, src_ip, dst_ip, proto, flags, proto_num_pkts, danger_level, message*
    #### `PSAD_SIGNATURE_MATCH`
    Used for psad/fwsnort signature matches
    *Fields: src_ip, signature, signature_id, proto, scan_port*
    #### `PSAD_AUTO_BLOCK`
    Used to detect auto-block actions
    *Fields: src_ip, block_time*
    #### `PSAD_AUTO_UNBLOCK`
    Used to detect auto-unblock actions
    *Fields: src_ip*
    #### `PSAD_NOTICE`
    Used to detect PSAD notice messages; usually generated by PSAD upon starting the service or updating the signatures
    *Fields: message*
    #### `PSAD_WARNING`
    Used to detect PSAD warning messages
    *Fields: log_level, message*
    <a name="availablelogparameters"></a>
    ### Available log parameters
    Here's a list of all paramters which are available for use in Logstash (or elasticsearch, if that's what you're using to store your logs; these are also the fields you can use to create your dashboards in Kibana).
    #### `[psad][start_port]` / `[psad][end_port]`
    Start and end port of a port scan range
    #### `[psad][scan_port]`
    Port scanned or found in signature match
    #### `[psad][scan_type]`
    Indicates the type of scan, if any
    #### `[psad][proto]`
    Protocol used in scan (TCP/UDP)
    #### `[psad][flags]`
    Any attack flags found (SYN, etc)
    #### `[psad][proto_num_pkts]`
    The number of packets received in the attack/scan
    #### `[psad][danger_level]`
    The PSAD danger lever assigned to the attack/scan
    #### `[psad][signature]`
    The psad/fwsnort signature detected
    #### `[psad][signature_id]`
    The psad/fwsnort signature ID detected
    #### `[psad][block_time]`
    The time an IP address was auto-blocked
    #### `[psad][log_level]`
    The log level of a PSAD warning message
    #### `message`
    A generic message for the logline; varies per type of log line
    #### `src_ip`
    The source IP of the attack/scan
    #### `dst_ip`
    The destination IP of the attack/scan
    **Note:** *Why not place the src_ip and dst_ip in the [psad] array as well? Since I use logstash to process almost all my logfiles, I prefer to keep things consistent. This way I can create a separate GEOIP filter to process all fields called src_ip and dst_ip and I don't have to create a separate filter for each logfile.*
    <a name="nextuplogstashinput"></a>
    ## Next up: logstash input
    The logstash input filter will assure that our psad log is parsed by logstash. Here's what it looks like:
    ```yaml
    input {
    file {
    path => '/var/log/psad.log' # the location of our psad logfile
    type => 'psad' # assign a type so we can easily process this in the filters
    }
    }
    ```
    <a name="areyouusinglogstashforwarder"></a>
    ### Are you using logstash-forwarder?
    No problem, use this instead in your `config.json` file:
    ```json
    {
    "files": [
    {
    "paths": [ "/var/log/psad.log" ],
    "fields": { "type": "psad" }
    }
    ]
    }
    ```
    <a name="ontologstashfilter"></a>
    ## On to: logstash filter
    Now that we've made sure logstash has access to our PSAD logfile, we need to tell it what to do with each line. I've placed comments in the code to guide you through each part.
    ```yaml
    filter {
    # only process lines which are of type 'psad'; this is set in the input section
    if [type] == "psad" {
    # parse for detected scans
    grok {
    patterns_dir => "/etc/logstash/patterns/" # specify the folder where logstash can find your patterns file
    match => [ "message", "%{PSAD_SCAN_DETECTED}" ]
    add_tag => [ "psad", "scan-detected" ] # add tags so we can determine what to do with each type of line
    tag_on_failure => [] # do not add tags on failure just yet, first check the other line types
    }
    # parse for signature match
    if "psad" not in [tags] {
    grok {
    patterns_dir => "/etc/logstash/patterns/"
    match => [ "message", "%{PSAD_SIGNATURE_MATCH}" ]
    add_tag => [ "psad", "signature-match" ]
    tag_on_failure => []
    }
    }
    # parse for auto block
    if "psad" not in [tags] {
    grok {
    patterns_dir => "/etc/logstash/patterns/"
    match => [ "message", "%{PSAD_AUTO_BLOCK}" ]
    add_tag => [ "psad", "iptables-auto-block" ]
    tag_on_failure => []
    }
    }
    # parse for auto unblock
    if "psad" not in [tags] {
    grok {
    patterns_dir => "/etc/logstash/patterns/"
    match => [ "message", "%{PSAD_AUTO_UNBLOCK}" ]
    add_tag => [ "psad", "iptables-auto-unblock" ]
    tag_on_failure => []
    }
    }
    # parse for psad warning
    if "psad" not in [tags] {
    grok {
    patterns_dir => "/etc/logstash/patterns/"
    match => [ "message", "%{PSAD_WARNING}" ]
    add_tag => [ "psad", "warning" ]
    tag_on_failure => []
    }
    }
    # parse for psad notice
    if "psad" not in [tags] {
    grok {
    patterns_dir => "/etc/logstash/patterns/"
    match => [ "message", "%{PSAD_NOTICE}" ]
    add_tag => [ "psad", "service-notice" ]
    tag_on_failure => []
    }
    }
    # check for unmatched loglines
    # if you find these often, I may have missed a line type and we will need to add a
    # pattern for it; please send me any such lines so I can create the grok pattern
    if "psad" not in [tags] {
    mutate {
    add_tag => [ "psad", "unmatched-logline" ]
    }
    }
    }
    }
    ```
    <a name="roundup"></a>
    ## Roundup
    Now you've configured rsyslog to write your psad messages to a separate file, told logstash where to find this file and what to do with each type of log line. Use your creativity to send your logstash filtered logs to any of the available outputs; I personally use elasticsearch to store my logs and kibana to visualize them. In a next gist I will likely publish my Kibana PSAD dashboard, but I still need to do some finetuning there first.
    If you have any questions, please feel free to contact me: [https://www.github.com/netson](https://www.github.com/netson)
    ## Links
    Useful links with information about PSAD:
    * [Official PSAD website](http://www.cipherdyne.org/psad/index.html)
    * [Official Logstash website](http://logstash.net/)
    * Puppet module for PSAD: [Puppetforge](https://forge.puppetlabs.com/tedivm/psad) / [Github](https://github.com/tedivm/puppet-psad)