Webserver install - Part 4 - Hardening III. - Debian Lenny

This tutorial is part of The LAB project.

 

PSAD (Port Scan Active Detector)

This part will show you how to replace Debians built-in rsyslog to Syslog-ng and how to install and configure PSAD.


Replace rsyslog with Syslog-ng

The reason why I do this is because PSAD currently does not support rsyslog in the official Debian package. Of course there is the opportunity to compile PSAD from source with rsyslog support but I do not like to compile when there is an official almost up-to-date version of the same software which could be automatically patched via apt-get. There is a workaround for this also but I like Syslog-ng pretty much (hungarian development).

The replacement is pretty easy, you just have to install syslog-ng with aptitude or apt-get and it will remove rsyslog (at least it says that...).

aptitude install syslog-ng

Some other packages will be installed with syslog-ng:

 libevtlog0 libglib2.0-0 libglib2.0-data syslog-ng

The last step of the replacement is to remove the old rsyslog because itt will not be completely removed.

aptitude purge rsyslog

Configure syslog-ng because we removed some users previously

 

Remove the deleted users config from "/etc/syslog-ng/syslog-ng.conf" if it was automatically added to it at install time:

Edit the config file:

nano /etc/syslog-ng/syslog-ng.conf

Comment out or delete every line which contains the string "news". You can search with CTRL+W.

I have commented out the following lines:

#destination df_news_dot_notice { file("/var/log/news/news.notice" owner("news")); };
#destination df_news_dot_err { file("/var/log/news/news.err" owner("news")); };
#destination df_news_dot_crit { file("/var/log/news/news.crit" owner("news")); };
 
#filter f_news { facility(news); };

I removed the word "news" from some lines and the resulting lines are:

filter f_debug { level(debug) and not facility(auth, authpriv, mail); };
 
filter f_messages {
        level(info,notice,warn)
            and not facility(auth,authpriv,cron,daemon,mail);
};
 
filter f_xconsole {
    facility(daemon,mail)
        or level(debug,info,notice,warn);
};

I have commented out the following lines at the end:

# news.crit                       /var/log/news/news.crit
#log {
#        source(s_all);
#        filter(f_news);
#        filter(f_at_least_crit);
#        destination(df_news_dot_crit);
#};
 
# news.err                        /var/log/news/news.err
#log {
#        source(s_all);
#        filter(f_news);
#        filter(f_at_least_err);
#        destination(df_news_dot_err);
#};
 
# news.notice                     /var/log/news/news.notice
#log {
#        source(s_all);
#        filter(f_news);
#        filter(f_at_least_notice);
#        destination(df_news_dot_notice);
#};

After you are done simply restart syslog-ng:

/etc/init.d/syslog-ng restart

Securing log files

The /var/log directory contains a lot of log files. They should not be readable by anyone. Debian does not set the "faillog" and "lastlog" according to this best practice so we have to change it manually:

chmod 660 /var/log/lastlog
chmod 660 /var/log/faillog

You can check which log files are readable by anyone:

find /var/log -perm +004

Install PSAD

As I mentioned psad can be installed via apt or aptitude. Simply run the command:

aptitude install psad

Some other packages will be installed with psad:

bastille libbit-vector-perl libcarp-clan-perl libcurses-perl libdate-calc-perl libiptables-chainmgr-perl libiptables-parse-perl   libnetwork-ipv4addr-perl libunix-syslog-perl psad psmisc

Bastille is a very useful hardening tool and I will configure it later.

During the install you will se an error message:

ERR: Syslog has not been configured to send messages to
/var/lib/psad/psadfifo. Please configure it as described in psad(8).
To correct the settings you have to edit syslog-ng.conf:

nano /etc/syslog-ng/syslog-ng.conf

Find the appropriate places and insert the following lines (note: you can simply add al the stuff to the end of the syslog-ng.conf).

#The source section is commented out, because syslog-ng does not like to read twice from the same source (it will die with duplication errors) and this is identical to s_all. 
 
#PSAD 
#source psadsrc { 
#        unix-stream("/dev/log"); 
#        internal(); 
#        pipe("/proc/kmsg"); 
#};  
 
#PSAD 
destination psadpipe {
         pipe("/var/lib/psad/psadfifo");
};  
 
#PSAD 
filter f_psad {
         facility(kern) and match("IN=") and match("OUT=");
};  
 
#PSAD 
log {
         source(s_all);
         filter(f_psad);
         destination(psadpipe);
}; 

Perhaps you noticed that psadsrc is the same as the default s_all source. Since syslog-ng does not like to read from the same source you should just ignore these lines. If is is completely missing from your config, you should add the commented source parts also. Than you can use it by replacing the s_all with psadsrc for the PSAD config.

 

After these you have to restart syslog-ng:

/etc/init.d/syslog-ng restart

You will notice that the iptables logs are not received yet because psad is not configured correctly by default for syslog-ng.

Configure PSAD

To configure PSAD edit the psad.conf file:

nano /etc/psad/psad.conf

Check all parameters to customize the settings for yourself. I will show you an example setting for a typical webserver with my minimum requirements.

I leave the email address on the default until I configure a general mail server.

EMAIL_ADDRESSES    root@localhost; 
HOSTNAME    debsrv.localdomain;

I set the host name to NOT_USED because this will be a hosted www server with "only enemies" outside.

HOME_NET    NOT_USED;

I changed the syslog daemon to syslog-ng:

SYSLOG_DAEMON    syslog-ng;

The followings are defaults:

CHECK_INTERVAL    5; 
PORT_RANGE_SCAN_THRESHOLD    1; 
ENABLE_PERSISTENCE    Y; 
ALERTING_METHODS    ALL;

I ignore the port 53 to be on the safe side. It can be turned off later.

IGNORE_PORTS    udp/53, tcp/53;

The following parameters should be set according to your needs. I suggest to test it starting with the defaults:

MIN_DANGER_LEVEL    1; 
EMAIL_ALERT_DANGER_LEVEL    3;

More defaults:

ENABLE_MAC_ADDR_REPORTING    Y; 
EMAIL_LIMIT    0;

To reserve previous values after restarting the service you should enable the following feature:

IMPORT_OLD_SCANS    Y;

The following setting should only be enabled after you are sure that all the settings are correct because you can lock yourself out with these. This is the IPS mode. TCPWrappers should be disabled because we will block with iptables. Only deamons which support this function could be protected with it and only local system deamons could be protected.

ENABLE_AUTO_IDS    Y; 
AUTO_IDS_DANGER_LEVEL    2; 
AUTO_BLOCK_TIMEOUT    3600; 
ENABLE_AUTO_IDS_REGEX       N;
TCPWRAPPERS_BLOCK_METHOD    N;

I like to change this to a lower value.

WHOIS_TIMEOUT    10; ### seconds

I want to check the disk usage in every 6 hours and want to be alerted at 70% usage.

DISK_CHECK_INTERVAL    21600; ### seconds 
DISK_MAX_PERCENTAGE    70;

Auto-blocked IPs can be checked in the following dirs.

AUTO_BLOCK_IPT_FILE    $PSAD_DIR/auto_blocked_iptables; 
AUTO_BLOCK_TCPWR_FILE    $PSAD_DIR/auto_blocked_tcpwr;

Save and exit.

To add some IP addresses to the whitelist edit /etc/psad/auto_dl. This ensures that these IPs will not be blocked by psad.

nano /etc/psad/auto_dl

Add your desktops IP and the localhost to it. My desktop IP is: 20.0.0.11.

20.0.0.11   0; 
127.0.0.1   0; 

Restart the psad service.

/etc/init.d/psad restart

The status of PSAD can be checked with the following command:

psad -S

Logs will be saved here: /var/log/psad/

PSAD signatures can be found here: /etc/psad/signatures

UPDATE: PSAD signatures can be updated like this:

psad --sig-update

FORENSICS: PSAD can be run in forensics mode and it reads logs from a specified directory. The default is /var/log/messages:

psad -A -m /archive/log/

Other useful arguments:

  • --Status :status
  • -D :dump config to STDOUT
  • --fw-dump :dump iptables rules
  • --fw-list :list active blocking rules
  • --fw-block-ip :add an IP to the blocked list
  • --fw-rm-block-ip :remove IP from blocked list
  • --Flush :flush psad rules
  • --debug :run in debug mode

If you want to block something with a simple script based on a string match you can do that with the following script. It is from one of my favorite linux network security book. It uses a unix domain socket to communicate with psad.

The following Perl script (sshauth.pl) monitors the /var/log/auth.log
file for 20 successive authentication failures from the same IP address. If
this threshold is met or exceeded, the script sends the command add IP
over the socket to the running psad daemon for subsequent addition into
the custom psad blocking chains. (This script can be downloaded from
http://www.cipherdyne.org/LinuxFirewalls/ch08/). Just run it or schedule it in cron. Later I will use a more effective method to block by stringmatch but this method is very good for fast response.

#!/usr/bin/perl -w
#
#############################################################################
#
# File: sshauth.pl
#
# Purpose: To interface with psad to block IP addresses that commit failed
#          login attempts against SSHD.  This script was written for the
#          book "Linux Firewalls: Attack Detection and Response with
#          iptables, psad, and fwsnort".
#
# Copyright (C) 2006-2007 Michael Rash (mbr@cipherdyne.org)
#
# License (GNU Public License):
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
#   USA
#
#
#############################################################################
#
# $Id: index.html 2980 2011-01-09 15:27:41Z mbr $
#
 
use IO::Socket;
use IO::Handle;
use strict;
 
#============== config ===============
my $auth_failed_threshold = 2;
my $auth_failed_regex =
    'sshd.*Authentication\s*failure.*?((?:[0-2]?\d{1,2}\.){3}[0-2]?\d{1,2})';
#IP address should be the regexp variable value above
my $sockfile = '/var/run/psad/auto_ipt.sock';
my $sleep_interval = 5;  ### seconds
#============ end config =============
 
### cache previously seen IP addresses and associated failed login
### counts
my %ip_cache = ();
 
### open the psad domain socket for writing
my $psad_sock = IO::Socket::UNIX->new($sockfile)
    or die "[*] Could not acquire psad domain ",
        "socket $sockfile: $!";
 
my $file = $ARGV[0] or die "$0 <file>";
 
### open the log file
open F, $file or die "[*] Could not open $file: $!";
my $skip_first_loop = 0;
for (;;) {
    unless ($skip_first_loop) {
        seek F,0,2; ### seek to the end of the file
            $skip_first_loop = 1;
    }
    my @messages = <F>;
    for my $msg (@messages) {
        if ($msg =~ m|$auth_failed_regex|) {
            $ip_cache{$1}++;
        }
    }
    for my $src (keys %ip_cache) {
        ### block the IP if the threshold is exceeded
        if ($ip_cache{$src} % $auth_failed_threshold == 0) {
            print $psad_sock "add $src\n";
        }
    }
    F->clearerr();  ### be ready for new data
    sleep $sleep_interval;
}
close F;
close $psad_sock;
exit 0;

 

Link: http://www.cipherdyne.org/LinuxFirewalls/

The BOOK: http://www.nostarch.com/firewalls_mr.htm

 

The next tutorial is: Webserver install - Part 5 - Hardening IV. - Debian Lenny