fetchmail Integration in postfixadmin

Viele Benutzer haben auch Mailboxen bei anderen Anbietern, z.B. bei gmx oder web.de. Damit diese Benutzer ihre E-Mails aggregieren können, wird fetchmail eingerichtet. fetchmail ist bereits in postfixadmin integriert, somit können fetchmail-Einträge über postfixadmin verwaltet werden (derzeit leider nur von Administratoren). Über das mitgelieferte fetchmail.pl-Skript werden die Daten aus der Datenbank ausgelesen, fetchmail aufgerufen, die Mails durch amavisd-new überprüft und an die Mailboxen der Benutzer ausgeliefert. Das perl-Skript wurde etwas angepasst, damit es mit postgres interagieren kann. Des Weiteren wurden die Dateinamen etwas angepasst.

Installation:

aptitude install fetchmail
aptitude install liblockfile-simple-perl

Nötige Verzeichnisse für das Skript anlegen:

mkdir /var/run/fetchmail
touch /var/run/fetchmail/fetchmail-all.lock

Das Skript:

fetchmail.pl

#!/usr/bin/perl
 
use DBI;
use MIME::Base64;
# use Data::Dumper;
use File::Temp qw/ mkstemp /;
use Sys::Syslog;
# require liblockfile-simple-perl
use LockFile::Simple qw(lock trylock unlock);
 
openlog("fetchmail-all", "pid", "mail");
 
sub log_and_die {
        my($message) = @_;
  syslog("err", $message);
  die $message;
}
 
# read options and arguments
 
$configfile = "/etc/fetchmail/config";
 
@ARGS1 = @ARGV;
 
while ($_ = shift @ARGS1) {
    if (/^-/) {
        if (/^--config$/) {
            $configfile = shift @ARGS1
        }
    }
}
 
# postgres settings
$database="postfix";
$hostname="127.0.0.1";
$user="postfix";
$password="XXXXXX";
 
$run_dir="/var/run/fetchmail";
 
# use specified config file
if (-e $configfile) {
    do $configfile;
}
 
$dsn = "DBI:Pg:database=$database;host=$hostname";
$lock_file=$run_dir . "/fetchmail-all.lock";
 
$lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
$lockmgr->lock($lock_file) || log_and_die "can't lock ${lock_file}";
 
#postgres connect
$dbh = DBI->connect($dsn, $user, $password) || log_and_die "cannot connect the database";
 
$sql=<<SQL;
SELECT id,mailbox,src_server,src_auth,src_user,src_password,src_folder,fetchall,keep,protocol,mda,extra_options,usessl 
FROM fetchmail
WHERE date_part('epoch',now())-date_part('epoch',date) > poll_time*60
SQL
 
my (%config);
map{
        my ($id,$mailbox,$src_server,$src_auth,$src_user,$src_password,$src_folder,$fetchall,$keep,$protocol,$mda,$extra_options,$usessl)=@$_;
 
  syslog("info","fetch ${src_user}@${src_server} for ${mailbox}");
 
        $cmd="user '${src_user}' there with password '".decode_base64($src_password)."'";
        $cmd.=" folder '${src_folder}'" if ($src_folder);
        $cmd.=" mda ".$mda if ($mda);
 
#       $cmd.=" mda \"/usr/local/libexec/dovecot/deliver -m ${mailbox}\"";
        $cmd.=" is '${mailbox}' here";
 
        $cmd.=" keep" if ($keep);
        $cmd.=" fetchall" if ($fetchall);
        $cmd.=" ssl" if ($usessl);
        $cmd.=" ".$extra_options if ($extra_options);
 
        $text=<<TXT;
set postmaster "postmaster"
set nobouncemail
set no spambounce
set properties ""
set syslog
 
poll ${src_server} with proto ${protocol}
        $cmd
 
TXT
 
  ($file_handler, $filename) = mkstemp( "/tmp/fetchmail-all-XXXXX" ) or log_and_die "cannot open/create fetchmail temp file";
  print $file_handler $text;
  close $file_handler;
 
  $ret=`/usr/bin/fetchmail -f $filename -i $run_dir/fetchmail.pid`;
 
  unlink $filename;
 
  $sql="UPDATE fetchmail SET returned_text=".$dbh->quote($ret).", date=now() WHERE id=".$id;
  $dbh->do($sql);
}@{$dbh->selectall_arrayref($sql)};
 
$lockmgr->unlock($lock_file);
closelog();

Damit das Skript regelmäßig ausgeführt wird, legen wir einen Cronjob dafür an (als Benutzer root). In der hier gezeigten Konfiguration wird das Skript alle 5 Minuten ausgeführt.

crontab -e:

*/5 * * * * /PFAD/ZU/fetchmail.pl &> /dev/null

Der neue Server: Teil 6 Spambekämpfung

Nachfolgend wird erklärt, wie man policyd-weight, amavisd-new, clamav, spamassassin, dspam installiert, konfiguriert und in das bestehende Setup integriert.

policyd-weight

policyd-weight ist ein effektives Tool zur Spambekämpfung schon vor der Annahme einer E-Mail. Es überprüft das “Envelope” und gleicht die Absenderadresse gegen mehrere DNS-Blacklists ab.

aptitude install policyd-weight

Danach erstellen wir noch eine Standardkonfiguration für policyd-weight:

policyd-weight defaults > /etc/policyd-weight.conf

Folgende Zeile in “/etc/postfix/main.cf” ändern:

###  check_policy_service inet:127.0.0.1:12525,

… zu:

check_policy_service inet:127.0.0.1:12525,

Jetzt muss die postfix-Konfiguration neu geladen werden und policyd-weight neu gestartet werden:

/etc/init.d/policyd-weight restart
postfix reload

amavisd-new

Amavisd-new ist ein Content-Filter, der sich in fast jeden MTA integrieren lässt. Über amavisd-new lassen sich viele verschiedene Tools, wie z.B. ClamAV zur Virenprüfung, Spamassassin zur Spamfilterung oder dspam – ebenfalls zu Spamfilterung – integrieren.
Wenn eine E-Mail in postfix ankommt, wird diese an amavis weitergeleitet, überprüft und wieder – mit zusätzlichen Headern – an postfix zur Auslieferung zurückgesendet. Natürlich kann man amavis auch so konfigurieren, dass bestimmte Nachrichtentypen, z.B. Virusmails oder Spammails, sofort geblockt werden. Sobald die Nachricht von amavis an postfix zurückgegeben wurde, kann eine automatische Einsortierung in Ordner über sieve folgen (z.B. Spam-Mails nach Junk).

Installation:
Zu “/etc/apt/sources.list” hinzufügen:

# volatile repository (e.g. for clamav)
deb http://volatile.debian.org/debian-volatile lenny/volatile main contrib non-free
aptitude install amavisd-new spamassassin clamav clamav-daemon clamav-freshclam pax lha arj bzip2 unrar zoo nomarch cpio lzop cabextract apt-listchanges libauthen-sasl-perl libdbi-perl dspam libmail-dkim-perl razor pyzor dcc-client libdbd-pg-perl

Nun folgt die Konfiguration von amavis (Konfigurationsdateien sind unter “/etc/amavis/conf.d/” zu finden). Ich führe jeweils nur geänderte Zeilen auf:

01-debian:

$unrar      = ['rar', 'unrar']; #disabled (non-free, no security support)
#$unrar         = undef;
$lha    = 'lha'; #disabled (non-free, no security support)
#$lha   = undef;

05-domain_id:

@local_domains_acl = ( "." );

05-node_id:

$myhostname = "mail.domain.tld";

15-content_filter_mode:

@bypass_virus_checks_maps = ( 
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

20-debian_defaults:

$final_virus_destiny      = D_DISCARD;  # (data not lost, see virus quarantine)
$final_banned_destiny     = D_PASS;   # D_REJECT when front-end MTA
$final_spam_destiny       = D_PASS;
$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)
 
# $sa_spam_subject_tag = '***SPAM*** ';
$sa_tag_level_deflt  = undef;

50-user:

$max_servers = 2;
 
$policy_bank{'MYNETS'} = {   # mail originating from @mynetworks
  originating => 1,  # is true in MYNETS by default, but let's make it explicit
  os_fingerprint_method => undef,  # don't query p0f for internal clients
};
 
$recipient_delimiter = '+';
 
$warnvirusrecip = 1;
 
$mailfrom_notify_admin = "postmaster\@$mydomain";
$mailfrom_notify_recip = "postmaster\@$mydomain";
$mailfrom_notify_spamadmin = "postmaster\@$mydomain";

Jetzt fügen wir noch den clamav-Nutzer der amavis-Gruppe hinzu:

adduser clamav amavis

Danach müssen wir Änderungen an der postfix-Konfiguration vornehmen:

Zu main.cf hinzufügen:

content_filter = amavis:[127.0.0.1]:10024
receive_override_options = no_address_mappings

Zu master.cf hinzufügen:

amavis       unix  -       -       n       -       2       lmtp 
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20
127.0.0.1:10025 inet n  -       n       -       -       smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_delay_reject=no
    -o smtpd_restriction_classes=
    -o smtpd_client_restrictions=
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o mynetworks=127.0.0.0/8    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

Zuletzt werden postfix, amavis und clamav neu gestartet:

/etc/init.d/postfix restart
/etc/init.d/amavis restart
/etc/init.d/clamav-daemon restart

Testen der Konfiguration

Zum Testen genügt es eine Mail an den Mailserver zu schicken und sich danach die Header-Informationen anzuschauen. Finden sich ähnliche Header wie die folgenden in der Mail wieder, so wird amavis aufgerufen.

X-virus-scanned: Debian amavisd-new at domain.tld
X-spam-flag: NO
X-spam-score: 2.898
X-spam-level: **
X-spam-status: No, score=2.898 required=6.31 tests=[SPF_PASS=-0.001, TVD_SPACE_RATIO=2.899]

Des Weiteren kann man mit folgendem Befehl testen, ob Spam erkannt wird:

sendmail john@example.com < /usr/share/doc/spamassassin/examples/sample-spam.txt

… oder Viren:

telnet localhost 25
HELO localhost
MAIL FROM: <user@change_to_my_domain.tld>
RCPT TO: <user@change_to_my_domain.tld>
DATA
From: virus-tester
To: undisclosed-recipients:;
Subject: amavisd test - simple - spam test pattern
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
.
 
quit

Spamassassin Konfiguration

Ans Ende der Datei “/etc/spamassassin/local.cf” anfügen:

use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
bayes_auto_expire 0
 
# pyzor
use_pyzor 1
pyzor_path /usr/bin/pyzor
 
# razor
use_razor2 1
razor_config /etc/razor/razor-agent.conf

/etc/spamassassin/v312.pre:

loadplugin Mail::SpamAssassin::Plugin::DKIM

/etc/spamassassin/v320.pre:

loadplugin Mail::SpamAssassin::Plugin::Shortcircuit
loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody

Razor konfigurieren:

su - amavis
razor-admin -create

Spamassassin-Regeln neu laden:

sa-update

Automatische Updates

Um spamassassin voll auszureizen, richten wir einen cronjob ein über welchen jede Nacht die Regeln auf den neuesten Stand gebracht werden (als root ausführen!):

/usr/local/sbin/updateSpamassassin:

#!/bin/bash
 
sa-update &> /dev/null
sa-compile &> /dev/null
 
exit 0
crontab -e
42 3 * * * /usr/local/sbin/updateSpamassassin &> /dev/null

Ham/Spam aus /var/vmail lernen

Nun erstellen wir noch ein Skript, welches Spam, bzw. Ham aus den Mailboxen der Benutzer lernt (aus den Ordnern “INBOX” und “Junk”). Dieses Skript rufen wir wöchentlich über einen Cronjob auf.

/usr/local/sbin/trainSpamassassin:

#!/bin/bash
 
VMAILDIR="/var/vmail"
SADIR="/var/lib/amavis/.spamassassin"
DBPATH="/var/lib/amavis/.spamassassin/bayes"
 
cd $VMAILDIR
for domain in $(find ./ -maxdepth 1 -not -name "." -type d); do
        domaindir="$VMAILDIR/$domain"
        cd $domaindir
        for user in $(find ./ -maxdepth 1 -not -name "." -type d); do
                maildir="$domaindir/$user/maildir"
                inbox="$maildir/cur"
                junk="$maildir/.Junk/cur"
 
                echo "Learning ham from $inbox"
                sa-learn --ham --showdots --dbpath $DBPATH $inbox
                echo "Learning junk from $junk"
                sa-learn --spam --showdots --dbpath $DBPATH $junk
        done
done
 
chown -R amavis:amavis $SADIR

Nun noch das Skript in die crontab aufnehmen (als root ausführen!):

crontab -e
33 4 * * 0 /usr/local/sbin/trainSpamassassin &> /dev/null

Globale sieve-Regeln

Um dem Benutzer das Erstellen von sieve-Regeln für Spam zu ersparen, fügen wir in die Datei “/var/vmail/default.sieve” folgende Zeile ein, um Spam-Mails automatisch in den Ordner “Junk” zu verschieben (sieve wurde schon in Teil 5 dieser Serie konfiguriert):

require ["fileinto"];
# Move spam to spam folder
if header :contains "X-Spam-Flag" ["YES"] {
  fileinto "Junk";
  stop;
}

dspam

Die Konfiguration von dspam wird nachgereicht.

Quellen:

http://workaround.org/articles/ispmail-etch/#step-5-deliver-emails-through-the-dovecot-lda

http://www200.pair.com/mecham/spam/spamfilter20090215.html#amavisconfig

http://wiki.rootforum.de/mailserver/postfix/clamav_amavisd

http://www.howtoforge.com/virtual-users-domains-postfix-courier-mysql-squirrelmail-debian-lenny-p3

http://www.tuxj0b.de/HOWTO_Mailserver_mit_Postfix_Dovecot_Antispam_und_PostgreSQL_Backend

Der neue Server: Teil 2 System härten

Wenn man einen Server betreibt, dann legt man normalerweise auch Wert auf Sicherheit (wenn nicht, dann diesen Abschnitt einfach überspringen). Hier zeige ich einige Mittel und Wege auf einen Server sicherer zu machen. Die Liste ist sicherlich nicht komplett und wird es wohl auch nie werden und selbst wenn ihr alles unternehmt, was ich hier aufführe, kann euer System immer noch gehackt werden – totale Sicherheit gibt es nicht – also schiebt die Schuld nicht auf mich, wenn euer System gehackt wurde. Und vor allem: installiert euer System komplett neu, wenn ihr gehackt wurdet!

Verzeichnisse härten

Das /tmp-Verzeichnis ist oft ein Einfalltor für Angreifer, deshalb werden wir dieses nun absichern. Zusätzlich wollen wir auch die Verzeichnisse /var und /home besser schützen, … sowie / bei Fehlern read-only mounten:

/etc/fstab:

proc /proc proc defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
/dev/md0 /boot ext2 defaults 0 0
# /dev/md1 belongs to LVM volume group 'vg0'
/dev/vg0/root  /  ext3  defaults,errors=remount-ro 0 1
/dev/vg0/swap  swap  swap  defaults 0 0
/dev/vg0/tmp  /tmp  ext3  rw,noexec,nosuid,nodev 0 0
/dev/vg0/home  /home  ext3  rw,nosuid,nodev 0 2
/dev/vg0/var  /var  ext3  rw,nosuid,nodev 0 2

Quelle: http://www.cromwell-intl.com/security/linux-hardening.html

sshd absichern

Voraussetzung dafür diesen Abschnitt zu implementieren ist, dass es neben root noch mindestens einen anderen Benutzer gibt, denn im folgenden wird root das direkte Anmelden über ssh verboten. Dies erschwert es einem Angreifer root-Rechte zu erlangen, da er erst das Passwort eines Benutzers knacken muss und dann zusätzlich noch das root-Passwort (oder aber er macht es sich einfach und benutzt einfach einen Exploit um sich root-Rechte zu verschaffen). Zudem kann man so immer über “/var/log/auth.log” herausfinden, wer sich als root angemeldet hat.

Als erstes erstellen wir eine Gruppe “sshusers”. Nur Benutzer, die dieser Gruppe angehören, dürfen sich auch am ssh-Server anmelden:

addgroup --system sshusers

Danach fügen wir unseren nicht-root Benutzer dieser Gruppe hinzu:

adduser <Benutzername> sshusers

Nun meine sshd_config:

# Package generated configuration file
# See the sshd(8) manpage for details
 
# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
ListenAddress 78.46.92.6
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
 
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768
 
# Logging
SyslogFacility AUTH
LogLevel VERBOSE
 
# Authentication:
LoginGraceTime 30
AllowGroups sshusers
PermitRootLogin no
StrictModes yes
 
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys
 
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
 
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
 
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
 
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
 
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
 
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
 
X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
 
#MaxStartups 10:30:60
Banner /etc/issue.net
 
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
 
Subsystem sftp /usr/lib/openssh/sftp-server
 
UsePAM yes

Wer auf “security by obscurity” steht, kann auch noch den ssh-Port auf einen nicht Standardport verlegen. Im Grunde genommen bringt es nichts – außer vielleicht Verstimmungen bei den Benutzern, da die Benutzerfreundlichkeit stark leidet und die Tipparbeit steigt – da jeder Portscan, z.b. mit nmap, den ssh-Port preisgibt. Natürlich kann man auf der anderen Seite auch argumentieren, dass primitive DoS-Skripts nur den Standardport ausprobieren und das Umlegen des ssh-Ports doch einen gewissen Schutz bietet.
Zusätzlich kann man noch fail2ban installieren, um sich vor DoS-Attacken über ssh (und auch über viele andere Dienste) zu schützen. Dies wird in einem späteren Abschnitt behandelt und stellt meiner Meinung nach die bessere Alternative zu einem nicht-Standardport dar.

Quellen:

http://root-support.com/blog/?p=183
http://aymanh.com/tips-to-secure-linux-workstation
http://www.pro-linux.de/work/rootserver/teil2.html

forkbombs

Eine forkbomb ist ein DoS-Angriff, bei dem sehr viele Prozesse gestartet werden. So viele, dass der komplette Arbeitsspeicher vollgeschrieben wird und das System somit unbenutzbar wird. Ein Beispiel für eine forkbomb wäre (ACHTUNG: Nicht auf einem Produktivsystem ausführen!):

 :(){ :|:& };:

Um diese Art eines Angriffs (zumindest teilweise) zu verhindern, ändern wir die Datei “/etc/security/limits.conf” dahingehend ab, dass jeder Nutzer der Gruppe “users” (in denen all unsere Konsolennutzer Mitglied sind) maximal 150 Prozesse starten darf:

/etc/security/limits.conf:

@users          soft    nproc  100
@users          hard    nproc  150

Quelle:
http://wiki.craz1.homelinux.com/index.php/Linux:Security:Forkbomb
http://aymanh.com/tips-to-secure-linux-workstation

rkhunter

Dieses Tool dient dem Aufspüren von rootkits. Es hat eine Datenbank mit Signaturen, welche wöchentlich aktualisiert wird und überprüfen täglich über einen cronjob, ob das System potentiell infiziert ist. Wird eine Infizierung/Gefahr festgestellt, verschickt rkhunter eine E-Mail.
Neben rkhunter gibts es auch noch chkrootkit, falls jemand will kann er zusätzlich auch noch dieses Tool installieren.

aptitude install rkhunter chkrootkit

Editieren der Datei “/etc/rkhunter.conf” (hier werden nur die Zeilen angezeigt, die geändert wurden):

DISABLE_TESTS="suspscan deleted_files packet_cap_apps"
ALLOWHIDDENDIR=/etc/.java

/etc/default/rkhunter: (auch nur geänderte Zeilen):

DB_UPDATE_EMAIL="yes"

Diese Einstellungen nehmen einen erweiterten Test für versteckte Prozesse zu den Standardtests auf und nehmen das Verzeichnis “/etc/.java” auf die Whitelist mit auf, damit rkhunter sich nicht bei jedem Scan beschwert, dass er eine verdächtige Datei gefunden hat, nur weil Java installiert ist. Darüber hinaus bekommt man wöchentlich eine E-Mail über die Ergebnisse des Datenbank-Updates.

bastille

Bastille ist ein Tool, welches das Härten eines Systems drastisch vereinfacht. Bastille führt den Nutzer über eine Textberfläche durch verschiedene Fragen und anhand der Antworten des Benutzers wird das System am Schluss verändert. Das Besondere dabei ist, dass bastille alle Aktionen genau und ausführlich erklärt und man die Aktionen auch selbst ausführen kann, anstatt bastille die Ausführung zu überlassen. Bastille wird aktiv von vielen großen Firmen entwickelt und sollte eigentlich zu den Standardwerkzeugen eines jeden verantwortungsbewussten Linux-Administrators gehören, da es viel Arbeit abnimmt und auf Dinge aufmerksam macht, die man sonst evtl. übersieht.

aptitude install bastille

Da das bastille Paket in lenny von Haus aus nicht kompatibel mit lenny ist, muss die Konfigurationsdateien von bastille ändern werden, um bastille vorzugaukeln, dass es kompatibel mit lenny wäre (siehe hier und hier):

/usr/lib/Bastille/API.pm:

sub get_supported_OS_list () {
  my @list = ( "DB2.2", "DB3.0", "DB3.1", "DB4.0", "DB5.0",

/usr/lib/Bastille/IOLoader.pm:

 my $supported_versions = 'DB2.2 DB3.0 DB3.1      DB4.0 DB5.0';

Die Fragen von bastille nach bestem Wissen und Gewissen beantworten und das System so seinen Wünschen nach anpassen.
Bastille legt ein ausführliches Log über die Änderungen an und bietet die Möglichkeit die vorgenommenen Änderungen später wieder rückgängig zu machen.

Quelle:
http://linux.com/feature/118353

/etc/passwd

In diesem Abschnitt geht es darum, die Shells von Systembenutzern auf “/bin/false” bzw. “/bin/nologin” umzustellen, denn die meisten Serverdienste brauchen keinen Konsolenzugriff und stellen in der Standardeinstellung eine gewisse Sicherheitsgefahr dar. Welche Diensten ohne Konsole zurechtkommen, muss man recherchieren oder ausprobieren. Nachdem man einen neuen Serverdienst installiert hat, bietet es sich an diese Datei erneut zu überprüfen und die Konsole der Benutzer ggf. zu ändern.

Beispielhaft zwei Zeilen, wie soetwas aussehen könnte:

man:x:6:12:man:/var/cache/man:/bin/false
mail:x:8:8:mail:/var/mail:/bin/false

fail2ban

Fail2ban ist eine effektive Waffe gegen DoS-Angriffe jedweder Art – und nicht nur das: man kann auch gescheiterte Authentifizierungsversuche über PAM oder Overflow-Angriffe auf Apache eindämmen. Es bringt schon viele vordefinierte Filter (jails), z.B. für ssh und apache, mit und lässt sich zusätzlich über selbstgeschriebene jails erweitern. Es ist über die Datei “/etc/fail2ban/jail.local” anpassbar. Man sollte die Datei “/etc/fail2ban/jail.conf” nicht selbst verändern. Das stellt sicher, dass bei einem Update auch immer die neuesten Regeln und Anpassungen verwendet werden. Über jail.local lässt sich jede Einstellung in jail.conf überschreiben. Bitte genau abwägen, welche jails man aktiviert und welche nicht (falls postfix nicht auf dem Server nicht installiert ist, ist es unsinnig den jail dafür zu aktivieren).

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

/etc/fail2ban/jail.local:

# Fail2Ban jail.local file
[DEFAULT]
 
ignoreip = 127.0.0.1
bantime  = 600
maxretry = 3
 
backend = polling
destemail = root
 
#
# ACTIONS
#
 
banaction = iptables-multiport
mta = sendmail
protocol = tcp
action = %(action_mwl)s
 
#
# JAILS
#
 
[ssh]
enabled = true
port    = ssh
filter  = sshd
logpath  = /var/log/auth.log
 
[ssh-ddos]
enabled = true
port    = ssh
filter  = sshd-ddos
logpath  = /var/log/auth.log
 
[pam-generic]
enabled = true
filter  = pam-generic
port = all
banaction = iptables-allports
port     = anyport
logpath  = /var/log/auth.log
 
[xinetd-fail]
enabled   = false
filter    = xinetd-fail
port      = all
banaction = iptables-multiport-log
logpath   = /var/log/daemon.log
maxretry  = 2
 
#
# HTTP servers
#
 
[apache]
enabled = true
port    = http,https
filter  = apache-auth
logpath = /var/log/apache*/*error.log
 
[apache-noscript]
enabled = true
port    = http,https
filter  = apache-noscript
logpath = /var/log/apache*/*error.log
 
[apache-overflows]
enabled = true
port    = http,https
filter  = apache-overflows
logpath = /var/log/apache*/*error.log
maxretry = 2
 
#
# Mail servers
#
 
[postfix]
enabled  = true
port     = smtp,ssmtp
filter   = postfix
logpath  = /var/log/mail.log
 
[sasl]
enabled  = true
port     = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
filter   = sasl
logpath  = /var/log/mail.log

Quellen:
http://debianclusters.cs.uni.edu/index.php/Fail2Ban:_Preventing_Brute_Force_SSH
http://debaday.debian.net/2007/04/29/fail2ban-an-enemy-of-script-kiddies/

Intrusion Detection System

IDS-Systeme wie tripwire, aide oder fcheck helfen Manipulationen an Dateien festzustellen. Um das bewerkstelligen zu können, wird anfänglich eine Datenbank erstellt mit Hash-Werten der zu überwachenden Ordner und dann werden die Werte regelmäßig überprüft. Stimmen die Hash-Werte nicht mehr überein, wird man per E-Mail benachrichtigt. Der große Nachteil ist natürlich, dass man die Datenbank immer aktuell halten muss und z.B. nach jeden “aptitude update/install/purge/…” ist dies der Fall. Die große Frage ist: Zu welchem Zeitpunkt es interessant ist ein IDS aufzusetzen. Wenn man einen Server ganz neu hat, ändern sich fast täglich Konfigurationsdateien oder es werden neue Pakete installiert, zu einem späteren Zeitpunkt läuft man Gefahr, dass ein Angreifer schon Programme/Konfigurationsdateien ausgetauscht hat und dann ist das IDS bereits nutzlos.
Dieser Abschnitt wird zu einem späteren Zeitpunkt mit Inhalt gefüllt.

iptables

Früher oder später sollte man sich darüber Gedanken machen, ob man eine Firewall/Paketfilter einsetzen will oder nicht, bzw. ob es überhaupt Sinn macht.
Diese Sektion wird zu einem späteren Zeitpunk um Vorschläge für eine kleine Firewall-Konfiguration, bzw. über den Aufbau von iptables-Regeln erweitert.

Netzwerkscanner

Um von außen zu überprüfen, ob der Server sicher ist, kann man Tools wie nmap oder nessus einsetzen. nmap dient dabei dazu offene Ports aufzuspüren, damit man diese ggf. schließen kann. nessus hingegen überprüft, ob der Server anfällig für bestimmte Exploits ist, z.B. anhand der Versionsnummer eines Dienstes. Um es allgemeiner auszudrücken: nessus ist ein Vulnerability (Schwachstellen)-Scanner.

nmap -A -T4 <Serveradresse>

Die Bedienung von nessus ist etwas umfangreicher und an dieser Stelle sei deshalb auf google verwiesen und es wird zum Ausprobieren ermuntert.
Des Weiteren sollte man einen Blick auf netstat werfen. Mit diesem Tool kann man lokal auf dem Server herausfinden, welche Ports geöffnet sind und welcher Dienst sich hinter welchem Port versteckt.
Beispielhafter Aufruf:

netstat -tulpen

Weitere Möglichkeiten sich zu schützen

Dies sind nur einige grundlegende Schritte, die man unternehmen kann, um einen Server abzusichern. Die Liste ist keineswegs vollständig und erhebt auch nicht den Anspruch darauf. Falls jemand weitere Wege kennt, einen Server abzusichern, dann bitte ich um einen Kommentar, bzw. um eine E-Mail und ich werde dieses Howto erweitern.
Empfehlenswert ist natürlich auch das Eintragen in Mailinglisten zum Thema Sicherheit und sich allgemein über sicherheitsrelevante Themen auf dem Laufenden zu halten. Ein weiterer Schritt, um Schwachstellen zu vermeiden ist es, das System immer aktuell zu halten. Das Paketmanagement macht es einem unter Linux sehr einfach und deshalb empfehle ich es aktiv zu nutzen, anstatt Programme selbst zu kompilieren. Normalerweise ist jedes Programm, das man auf einem Server brauchen könnte in den Debian-Repositories enthalten (dass man auf einem Server nur mit den stable-Repositories arbeiten sollte und von testing tunlichst die Finger lassen sollte, brauche ich hier wohl kaum zu erwähnen).
Abschließend bleibt nur noch einmal zu wiederholen, dass es keine absolute Sicherheit gibt und dass man einen guten Kompromiss zwischen Sicherheit und Freiheit (der Nutzer) finden sollte (Hallo, Herr Innenminister).

Der neue Server: Teil 1 Installation und Basiskonfiguration

Seit ca. November letzten Jahres war klar, dass ein neuer Server her muss – nicht zuletzt, weil einige Leute bei ibutho ausgestiegen sind und ibutho doch etwas zu schwach ist für unsere Ansprüche. Die Planungen liefen auch schon seit Ende letzten Jahres und nun haben sie alle Gestalt angenommen. Die Domains werden alle zentral über inwx.de verwaltet. Dies hat den Vorteil, dass wir unabhängig vom Provider des Root-Servers sind und später ohne Probleme wechseln können. Beim Server haben wir uns für einen DS3000 von Hetzner entschieden. Dieser sagte uns sowohl von den Hardware-Daten als auch vom Preis-/Leistungsverhältnis zu (AMD Athlon 64 X2 5600+, 2GB RAM, 2 x 400GB Festplatte, 100MBit Anbindung ans Internet, 7 IP-Adressen, unbegrenzter Traffic).

Im Weiteren will ich auf die Grundinstallation eingehen und in den folgenden Teilen auf die beispielhafte Installation und Konfiguration verschiedenster Server-Dienste. Ich hoffe, dass diese Beiträge für den ein oder anderen nützlich sind, wenn sie ihren eigenen Server konfigurieren und absichern wollen. Ich bitte um rege Diskussionen, damit die Beiträge sinnvoll erweitert und Fehler beseitigt werden können.

Installation des Systems

Hetzner vereinfacht dem Administrator die Installation eines eigenen Betriebssystems über das Rescue-System sehr. Es wir ein Skript installimage angeboten, über welches man z.B. die Festplatte partitionieren kann, ein LVM einrichten kann oder einen Software-RAID konfigurieren kann.

Bei meiner Installation entschied ich mich für ein RAID1-System mit LVM. Für RAID1 entschied ich mich aufgrund der gesteigerten Ausfallsicherheit und der gesteigerten Lese-Performance. Für LVM entschied ich mich, da dies mehr Flexibilität mit sich bringt als ein starres Partitionsschema. Sollte man später bemerken, dass eine Volume zu groß oder zu klein ist, kann man es einfach verkleinern/vergrößern. Versierte Leser mögen sich hier fragen, warum ich nicht komplett auf ein LVM-Setup setze und dem LVM auch das Mirroring überlasse. Der Grund ist einfach: über ein Software-RAID erhalte ich höhere Leseraten (siehe auch: http://www.joshbryan.com/blog/2008/01/02/lvm2-mirrors-vs-md-raid-1/, insbesondere auch die Kommentare). Beim Dateisystem setze ich auf ext3 bzw. ext2 für “/boot”, da sich ext3 im LVM problemlos im laufenden Betrieb vergrößern bzw. verkleinern lässt.

Hier mein Partitionslayout:

Mountpunkt Dateisystem Größe
/boot ext2 256M
vg0 lvm all
swap swap 2G
/ ext3 5G
/home ext3 15G
/tmp ext3 4G
/var ext3 50G

Sowohl “/boot”, als auch “vg0″ sind jeweils eine RAID1-Partition. Die ganze Arbeit das RAID einzurichten und danach das LVM hat mir das hetzner-Skript abgenommen.

Erste Schritte

aptitude-Mirror konfigurieren

Hetzner stellt einen eigenen aptitude-/apt-Mirror und diesen werden wir als allererstes ändern. Die Vorteile liegen auf der Hand: hohe Übertragungsraten und es handelt sich um internen Traffic, wird als nicht berechnet.

/etc/apt/sources.list:

# Packages and Security Updates from the Hetzner Debian Mirror
deb ftp://mirror.hetzner.de/debian/packages  lenny          main contrib non-free
deb ftp://mirror.hetzner.de/debian/security  lenny/updates  main contrib non-free

Und nun ein erstes Update&Upgrade:

aptitude update &amp;&amp; aptitude dist-upgrade

postfix Installation

Da postfix der Mailserver meiner Wahl ist und ich nicht will, dass irgend ein Programm exim oder ähnliches installiert, werden wir jetzt gleich postfix installieren, jedoch noch nicht konfigurieren. Die Konfiguration folgt ausführlich in einem weiteren Teil.

aptitude install postfix

Systemtools

apticron

apticron ist ein Tool, welches einen per Mail informiert, wenn es Updates gibt. Dies ist besonders hilfreich, da das Tool die Paketquellen im Hintergrund updated, aber die Updates nicht einspielt; so bleibt es dem Administrator immer selbst überlassen, welche Pakete er einspielt und welche nicht, bzw. welche er erst ausführlicher testen will, da die Funktionalität des Systems evtl. erheblich beeinträchtigt werden könnte.

aptitude install apticron

mdadm

Mit mdadm wurde bereits das Software-RAID erstellt. Doch mdadm kann mehr: es kann den Benutzer auch per E-Mail informieren, wenn es Probleme mit dem RAID gibt. Dies wollen wir hier einstellen:

dpkg-reconfigure mdadm

smartmontools

Mit den smartmontools kann man den Status des Festplatten abfragen und bekommt E-Mails, wenn die Festplatte kurz vor ihrem Lebensende ist.

aptitude install smartmontools

/etc/default/smartmontools:

# uncomment to start smartd on system startup
start_smartd=yes
 
# uncomment to pass additional options to smartd on startup
smartd_opts="--interval=1800"

/etc/smartd.conf:

DEVICESCAN -m root -M exec /usr/share/smartmontools/smartd-runner

htop

htop ist eine erweiterte Version von top und bietet eine ncurses-Oberfläche, sowie Farben und “grafische” Anzeigen.

aptitude install htop

lsof

lsof kann anzeigen, wer gerade auf einen Ordner/Gerät zugreift. Das Tool kann nützlich sein, wenn man einen Ordner unmounten will, aber noch jemand/etwas darauf zugreift.

aptitude install lsof

mc

Wer DOS noch kennt, kennt auch den Norton Commander. mc (ausgeschrieben: midnight commander) ist ein Norton Commander-Klon und vereinfacht einem das Leben in vielen Situationen. Einfach mal ausprobieren:

aptitude install mc

locate

Mit locate kann man schnell nach Dateien suchen. Es baut einen Index über Dateien und Ordner des Dateisystems auf und aktualisiert diesen mittels eines Cronjobs regelmäßig. Sucht man eine Datei, so gibt man einfach folgendes ein:

locate <Dateiname>

Das Paket kann mit folgendem Befehl installiert werden:

aptitude install locate

Nach der Installation sollte als Erstes der Index aufgebaut werden (dies wird später automatisch gemacht):

updatedb

Benutzer anlegen

Meine Anforderung an die Home-Laufwerke der einzelnen Benutzer ist, dass sie nicht von jedem gelesen werden können, aber dass man trotzdem Ordner/Dateien unterhalb des eigenen Home-Laufwerks für andere zugänglich machen kann, um z.B. einen “Briefkasten” zu implementieren, wo andere Benutzer Dateien für einen ablegen können, aber nicht sehen können, was sich sonst noch darin befindet. Deshalb wird mit folgenden Befehl die Sichtbarkeit der Home-Verzeichnisse geändert:

dpkg-reconfigure adduser

Außerdem hätte ich gerne, dass jeder Benutzer standardmäßig in der Gruppe “users” ist (man weiß ja nie, wozu das noch gut sein könnte). Dazu fügen wir an die Datei “/etc/default/useradd” am Ende folgendes an – bzw. an die Datei “/etc/adduser.conf” (je nachdem, ob man adduser oder useradd zum Hinzufügen von Benutzern verwendet):
/etc/default/useradd:

GROUPS=users

/etc/adduser.conf:

EXTRA_GROUPS="users"
ADD_EXTRA_GROUPS=1

Die “Briefkasten”-Erweiterung:

cd /etc/skel/
mkdir public
chmod 755 public/
mkdir public/dropbox
chmod 753 public/dropbox/
chown root: public/ -R

Nun legen wir noch eigene Versionen der Dateien .vimrc, .bashrc, .bash_aliases in “/etc/skel/“:
.vimrc:

sy on
se nu
set incsearch
set hlsearch
colorscheme slate

.bashrc:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
 
export PS1='\h:\w\$ '
umask 022
 
# If not running interactively, don't do anything
[ -z "$PS1" ] &amp;&amp; return
 
# don't put duplicate lines in the history. See bash(1) for more options
# don't overwrite GNU Midnight Commander's setting of `ignorespace'.
export HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoredups
# ... or force ignoredups and ignorespace
export HISTCONTROL=ignoreboth
 
# append to the history file, don't overwrite it
shopt -s histappend
 
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
 
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
 
# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] &amp;&amp; eval "$(SHELL=/bin/sh lesspipe)"
 
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "$debian_chroot" ] &amp;&amp; [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi
 
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color) color_prompt=yes;;
esac
 
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
 
if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] &amp;&amp; tput setaf 1 &gt;&amp;/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi
 
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
 
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac
 
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
 
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
 
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    eval "`dircolors -b`"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'
 
    #alias grep='grep --color=auto'
    #alias fgrep='fgrep --color=auto'
    #alias egrep='egrep --color=auto'
fi
 
# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'
 
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

.bash_aliases:

alias l='ls -lA'
alias ll='ls -l'
alias la='ls -a'
alias lla='ls -la'
alias lal='ls -la'

Zusätzlich installieren wir noch das Paket “bash-completion”, um eine komplexere Code- und Befehlsvervollständigung zu bekommen (wird erst nach erneutem Anmelden an der Konsole aktiv):

aptitude install bash-completion

Nun können wir mittels adduser einen Benutzer anlegen:

adduser <Benutzername>