[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cobalt-security] How to stop FTP-scans (proposal for hotfix)



Hi all,

with the recent discussion about FTP-scans I decided to do something about 
the matter. Here is a little script which puts an idea into practice which I 
have been mulling over for a while. Finally I got around to give it a try:

Requirements: 

1) RaQ3 or RaQ4 with POP-before-SMTP patch from Cobalt installed

2) POP-before-SMTP must be active (i.e.: poprelayd must be running) 

3) IPchains is installed (knowledge of IPchains required)

4) Basic Linux skills required. 

5) Proper attitude in regards to "screw the warranty" required ;o)


General purpose of this undertaking:
=============================

If a user wants to access your server by FTP, then he has to check his email 
account first. We will use the same authentication mechanism for FTP that we 
use for SMTP through the POP-before-SMTP package.

Anyone trying to connect to the FTP server without having checked his email 
first will not be able to connect to FTP at all.


How to:
======

Create the following script in /usr/local/sbin and name it something you can 
remember. Like ftprelay.pl

--------------- Begin of File: /usr/local/sbin/ftprelay.pl ---------------
#!/usr/bin/perl

#
#  Configuration settings from poprelayd. No need to change them!
#

$logfile = "/var/log/maillog";          # POP3 daemon log.
$pidfile = "/var/run/poprelayd.pid";    # Where we put our PID.
$dbfile = "/etc/mail/popip.db";         # Sendmail map to update.
$dbtype = "DB_HASH";

#
#  Modules
#

use Getopt::Std;
use Fcntl;
use DB_File;
use POSIX;

# You may need to uncomment this if your fcntl.ph doesn't export it.
sub O_EXLOCK { 0x20 };

#
#  Variables
#

undef $pid;                             # Process ID.
undef %db;                              # Hash into database file.
undef $lffd;                            # $logfile file descriptor.
undef $lfino;                           # Inode of $logfile when we opened it.
undef $lfbuf;                           # Buffer for data from $lffd.
undef @addrs;                           # List of IP addresses to add.
undef $lasttimeout;                     # Last time we did a timeout.

# Print address list.
$countopts++;
tie(%db, "DB_File", $dbfile, O_RDONLY, 0, $$dbtype) ||\
        die "Can't open $dbfile";
foreach $key (sort(keys(%db))) {
system "/sbin/ipchains -A input -i eth0 -s $key -d 0/0 21 -p tcp -j ACCEPT";
}
system "/sbin/ipchains -A input -i eth0 -s 0/0 -d 0/0 21 -p tcp -j DENY";
untie %db;
closedb;

--------------- End of File: /usr/local/sbin/ftprelay.pl ---------------


Put a "chmod 700" on the script and then put a chown "root:root" on it.

Next create a small shell script which contains your firewall rules. That is, 
if you do not already have a firewall ruleset.

If you already have a firewall script running, then you can simply call the 
perlscript from within your firewall script by using the example below as 
guideline:


A very, very rudimentary firewall ruleset could look like this:

--------------- Begin of File: /usr/local/sbin/firewall.sh ---------------
#!/bin/sh

# Flush existing ruleset:
/sbin/ipchains -F

# Suppress IP Spoofing
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] ; then
    for i in /proc/sys/net/ipv4/conf/*/rp_filter; do
        echo 1 > $i
  done
fi

# Syn Flood protection
if [ -e /proc/sys/net/ipv4/tcp_syncookies ] ; then
    echo 1 > /proc/sys/net/ipv4/tcp_syncookies
fi

# Disable Source Routed Packets
for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do
    echo 0 > $i
done

# Execute Perlscript ftprelay.pl
perl /usr/local/sbin/ftprelay.pl

--------------- End of File: /usr/local/sbin/firewall.sh ---------------

Also put a "chmod 700" on the script and then put a chown "root:root" on it 
for good measure.


Now create the a cronjob for user root which will run this script every 15 
minutes:

Type (as user "root") "crontab -e" and add the following line:

0,15,30,45 * * * * /usr/local/sbin/firewall.sh >/dev/null

Exit the editor by pressing ":wq!"


What the PERL-Script will do:
=======================

The Perl-Script opens the POPrelayD database and fetches all IP addresses 
from that database. It will then create IPchain rules for those listed IP 
addresses so that they can access the FTP port.

At the end it will put an ipchains DENY rule to block port 21 for all other 
IP addresses.


What the Firewall-Shellscript will do:
============================

If executed it will remove all existing firewall rules. It'll then add a 
little more protection to your TCP/IP stack and will finally call the 
Perl-script, which generates our FTP rules.

To call this a comprehensive Firewall is not true, as it is just a 
rudimentary (working) example of the FTP protection. You will need further 
ipchains rules customized to your specific needs to protect other services. 
However, it might give you ideas of how to do so.


Comments welcome.


P.S.: Yeah, you guessed it: The perlscript is in fact a trimmed down and 
adapted copy of the original poprelayd script which is part of the 
POP-before-SMPT patch from Cobalt.


-- 

Mit freundlichen Grüßen / With best regards

Michael Stauber

 Stauber Multimedia Design ____ Phone:  +49-6081-946240
 Eppsteiner Weg 9 ___  D-61267 Neu-Anspach ___ Germany
 SMD.NET ___ SOLARSPEED.NET ___ FORUMWORLD.COM