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
#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
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:
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