view xml/syslog2iptables.in @ 63:60f59936fabb

good authentication prevents ip blocking for awhile
author Carl Byington <carl@five-ten-sg.com>
date Sat, 19 Dec 2015 10:12:24 -0800
parents b45dddebe8fc
children 45e53c44c46c
line wrap: on
line source

<reference>
    <title>@PACKAGE@ - Version @VERSION@</title>
    <partintro>
        <title>Packages</title>

        <para>The various source and binary packages are available at <ulink
        url="http://www.five-ten-sg.com/@PACKAGE@/packages/">http://www.five-ten-sg.com/@PACKAGE@/packages/</ulink>
        The most recent documentation is available at <ulink
        url="http://www.five-ten-sg.com/@PACKAGE@/">http://www.five-ten-sg.com/@PACKAGE@/</ulink>
        </para>

        <para>A <ulink
        url="http://www.selenic.com/mercurial/wiki/">Mercurial</ulink> source
        code repository for this project is available at <ulink
        url="http://hg.five-ten-sg.com/@PACKAGE@/">http://hg.five-ten-sg.com/@PACKAGE@/</ulink>.
        </para>

    </partintro>

    <refentry id="@PACKAGE@.1">
        <refentryinfo>
            <date>2015-12-18</date>
            <author>
                <firstname>Carl</firstname>
                <surname>Byington</surname>
                <affiliation>
                     <orgname>510 Software Group</orgname>
                </affiliation>
            </author>
        </refentryinfo>

        <refmeta>
            <refentrytitle>@PACKAGE@</refentrytitle>
            <manvolnum>1</manvolnum>
            <refmiscinfo>@PACKAGE@ @VERSION@</refmiscinfo>
        </refmeta>

        <refnamediv id='name.1'>
            <refname>@PACKAGE@</refname>
            <refpurpose>a simple adaptive firewall</refpurpose>
        </refnamediv>

        <refsynopsisdiv id='synopsis.1'>
            <title>Synopsis</title>
            <cmdsynopsis>
                <command>@PACKAGE@</command>
                <arg><option>-c</option></arg>
                <arg><option>-d <replaceable class="parameter">n</replaceable></option></arg>
            </cmdsynopsis>
        </refsynopsisdiv>

        <refsect1 id='description.1'>
            <title>Description</title>

            <para><command>@PACKAGE@</command> is a simple adaptive firewall.  It
            maintains the INPUT chain of the <citerefentry>
            <refentrytitle>iptables</refentrytitle> <manvolnum>1</manvolnum>
            </citerefentry> firewall set based on syslog entries.  These syslog
            entries are typically generated by your hardware firewall, but they
            could come from any source.  Any syslog entry that contains a host name
            or ip address can be used as input to this package.</para>

            <para>The <citerefentry> <refentrytitle>@PACKAGE@.conf</refentrytitle>
            <manvolnum>5</manvolnum> </citerefentry> file specifies the syslog
            files to be monitored, and the regular expressions (<citerefentry>
            <refentrytitle>regex</refentrytitle> <manvolnum>7</manvolnum>
            </citerefentry>) to be applied to new lines in those files.  Each
            regular expression needs an INDEX to specify the matching substring
            that contains either an ip address or host name, and a DELTA which is
            used to modify the leaky bucket count for that ip address when a
            matching line is read from that syslog file. </para>

            <para>If the DELTA is negative, the leaky bucket count is set to that
            DELTA value, any existing blocking for that ip address is removed, and
            new blocking is prevented until that bucket leaks upward to zero.
            </para>

            <para>If the DELTA is positive and the current leaky bucket count is
            not negative, that DELTA value is added to the leaky bucket count for
            that ip address. Once the bucket contains more than a configurable
            THRESHOLD number of tokens, that ip address is added to the INPUT
            chain with a DROP target.</para>

            <para>Each ip address has an associated leaky bucket, which leaks one
            token per second so the count moves toward zero.  When the bucket is
            drained to zero, that ip address is removed from the INPUT
            chain.</para>

            <para>The discussion has focused on syslog files, but any ascii text
            file can be used, so long as some other process appends lines to that
            file, and those lines containing hostname or ip addresses can be matched
            with some regular expression.</para>

            <para>Considering syslog files in particular, these are normally rotated
            via logrotate.  <command>@PACKAGE@</command> properly detects and
            handles this case by closing the old file, and reopening the newly
            created file.</para>

            <para>With the default config file, you can manually unblock an ip
            address with <command>logger -p authpriv.info "manual unblock
            1.2.3.4"</command> </para>

        </refsect1>

        <refsect1 id='options.1'>
            <title>Options</title>
            <variablelist>
                <varlistentry>
                    <term>-c</term>
                    <listitem>
                        <para>
                            Load the configuration file, print a cannonical form
                            of the configuration on stdout, and exit.
                       </para>
                   </listitem>
                </varlistentry>
                <varlistentry>
                    <term>-d <replaceable class="parameter">n</replaceable></term>
                    <listitem>
                        <para>
                            Set the debug level to <replaceable class="parameter">n</replaceable>.
                        </para>
                    </listitem>
                </varlistentry>
            </variablelist>
        </refsect1>

        <refsect1 id='usage.1'>
            <title>Usage</title>
            <para><command>@PACKAGE@</command> -d 2</para>
        </refsect1>

        <refsect1 id='configuration.1'>
            <title>Configuration</title>
            <para>
                The configuration file is documented in <citerefentry>
                <refentrytitle>@PACKAGE@.conf</refentrytitle> <manvolnum>5</manvolnum>
                </citerefentry>.  Any change to the config file will cause it to be
                reloaded within three minutes.
            </para>
        </refsect1>

        <refsect1 id='todo.1'>
            <title>TODO</title>
            <para>
                The following ideas are under consideration.
            </para>
            <para>
                Add a configuration option for the iptables table name in the
                pattern statement. This implies handling multiple tables, so each
                table needs its own map of ip addresses and bucket values.
            </para>
        </refsect1>

        <refsect1 id='copyright.1'>
            <title>Copyright</title>
            <para>
                Copyright (C) 2007 by 510 Software Group &lt;carl@five-ten-sg.com&gt;
            </para>
            <para>
                This program is free software; you can redistribute it and/or modify it
                under the terms of the GNU General Public License as published by the
                Free Software Foundation; either version 3, or (at your option) any
                later version.
            </para>
            <para>
                You should have received a copy of the GNU General Public License along
                with this program; see the file COPYING.  If not, please write to the
                Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
            </para>
        </refsect1>

        <refsect1 id='version.1'>
            <title>Version</title>
            <para>
                @VERSION@
            </para>
        </refsect1>
    </refentry>


    <refentry id="@PACKAGE@.conf.5">
        <refentryinfo>
            <date>2015-12-18</date>
        </refentryinfo>

        <refmeta>
            <refentrytitle>@PACKAGE@.conf</refentrytitle>
            <manvolnum>5</manvolnum>
            <refmiscinfo>@PACKAGE@ @VERSION@</refmiscinfo>
        </refmeta>

        <refnamediv id='name.5'>
            <refname>@PACKAGE@.conf</refname>
            <refpurpose>configuration file for @PACKAGE@</refpurpose>
        </refnamediv>

        <refsynopsisdiv id='synopsis.5'>
            <title>Synopsis</title>
            <cmdsynopsis>
                <command>@PACKAGE@.conf</command>
            </cmdsynopsis>
        </refsynopsisdiv>

        <refsect1 id='description.5'>
            <title>Description</title>
            <para>The <command>@PACKAGE@.conf</command> configuration file is
            specified by this partial bnf description. The entire config file
            is case sensitive. All the keywords are lower case.
            </para>

            <literallayout class="monospaced"><![CDATA[
CONFIG     = {CONTEXT ";"}+
CONTEXT    = "context" NAME "{" {STATEMENT}+ "}"
STATEMENT := (THRESHOLD | ADD-CMD | REM-CMD | IGNORE | FILE) ";"
THRESHOLD := "threshold" THRESHOLD-INTEGER-VALUE
ADD-CMD   := "add_command" IPT-CMD
REM-CMD   := "remove_command" IPT-CMD
IGNORE    := "ignore" "{" IG-SINGLE+ "}"
IG-SINGLE := IP-ADDRESS "/" CIDR-BITS
FILE      := "file" FILENAME "{" PATTERN+ "}"
PATTERN   := "pattern" REGULAR-EXPRESSION "{" {INDEX | BUCKET | MESSAGE}+ "};"
INDEX     := "index" REGEX-INTEGER ";"
DELTA     := "bucket" BUCKET-DELTA-INTEGER ";"
MESSAGE   := "message" REASON ";"
REASON    := string to appear in syslog messages
IPT-CMD   := string containing exactly one %s replacement token for
             the ip address]]></literallayout>
        </refsect1>

        <refsect1 id='sample.5'>
            <title>Sample</title>
            <literallayout class="monospaced"><![CDATA[
context general {
    threshold 550;

    add_command    "/sbin/iptables -I INPUT --src %s --jump DROP";
    remove_command "/sbin/iptables -D INPUT --src %s --jump DROP";

    ignore {
        127.0.0.0/8;        // localhost
    };

    file "/var/log/secure" {
        pattern "manual unblock (.*)" {
            index 1;    // zero based
            bucket -5000;
            message "manual unblock";
        };
        pattern "sshd.*Failed password .* from ::ffff:(.*) port" {
            index 1;    // zero based
            bucket 400;
            message "ssh failed password";
        };
        pattern "sshd.*Failed password .* from (.*) port" {
            index 1;    // zero based
            bucket 400;
            message "ssh failed password";
        };
        pattern "sshd.*authentication failure; .* rhost=(.*) " {
            index 1;    // zero based
            bucket 400;
            message "ssh failed password";
        };
        pattern "sshd.*Did not receive identification string from (.*)" {
            index 1;    // zero based
            bucket 400;
            message "ssh failed password";
        };
        pattern "proftpd.*no such user found from (.*) \[" {
            index 1;    // zero based
            bucket 400;
            message "ftp failed password";
        };
        pattern "proftpd.* authentication failure; .* rhost=(.*) " {
            index 1;    // zero based
            bucket 400;
            message "ftp failed password";
        };
        pattern "vsftpd.* authentication failure; .* rhost=(.*) " {
            index 1;    // zero based
            bucket 400;
            message "ftp failed password";
        };
        pattern "dovecot.* authentication failure; .* rhost=::ffff:(.*) " {
            index 1;    // zero based
            bucket 100;
            message "dovecot failed password";
        };
        pattern "dovecot.* authentication failure; .* rhost=(.*) " {
            index 1;    // zero based
            bucket 100;
            message "dovecot failed password";
        };
    };

    file "/var/log/messages" {
        pattern "dovecot.* authentication failure; .* rhost=(.*) " {
            index 1;    // zero based
            bucket 100;
            message "dovecot failed password";
        };
        pattern "kernel.*local-net-to.*SRC=(.*) DST=.*DPT=" {
            index 1;    // zero based
            bucket 400;
            message "kernel firewall blocked packet";
        };
        pattern "kernel.*outside-net-from.*SRC=(.*) DST=.*DPT=" {
            index 1;    // zero based
            bucket 400;
            message "kernel firewall blocked packet";
        };
    };

    file "/var/log/maillog" {
        pattern "lost input channel from.* \[(.*)\] .* after (mail|rcpt|auth)" {
            index 1;    // zero based
            bucket 100;
            message "sendmail spammer dropping connection";
        };
        pattern " \[(.*)\].* possible SMTP attack" {
            index 1;    // zero based
            bucket 100;
            message "sendmail authentication attack";
        };
        pattern "rejecting commands from.* \[(.*)\] due to pre-greeting traffic" {
            index 1;    // zero based
            bucket 1800;
            message "sendmail pre-greeting";
        };
        pattern "authentication failure: checkpass failed, .*\[(.*)\]" {
            index 1;    // zero based
            bucket 100;
            message "sendmail authentication failed";
        };
        pattern "dovecot.*Aborted login .* rip=(.*)," {
            index 1;    // zero based
            bucket 100;
            message "dovecot failed password";
        };
        pattern "dovecot.*Login: .* rip=(.*)," {
            index 1;    // zero based
            bucket -5000;
            message "dovecot good authentication";
        };
        pattern "sendmail.*AUTH=server, .*\[(.*)\]," {
            index 1;    // zero based
            bucket -5000;
            message "sendmail good authentication";
        };
    };
};]]></literallayout>
        </refsect1>

        <refsect1 id='version.5'>
            <title>Version</title>
            <para>
                @VERSION@
            </para>
        </refsect1>

    </refentry>
</reference>