Perfect RootServer

Aus crazylinux.de
Wechseln zu: Navigation, Suche

der Server soll hauptsächlich als Web- und Mailserver dienen.

Inhaltsverzeichnis

1 Grundkonfiguration

RootServer_EX4

1.1 User anlegen

useradd -m -G root,staff -c "Adminuser" -s /bin/bash adminuser
useradd -m -G staff -c "User XYZ" -s /bin/bash user


1.2 Alias root to admin

#/etc/aliases
root: admin

1.3 Hardening

1.3.1 Default umask

/etc/login.defs

# UMASK is the default umask value for pam_umask and is used by
# useradd and newusers to set the mode of the new home directories.
# 022 is the "historical" value in Debian for UMASK
# 027, or even 077, could be considered better for privacy
# There is no One True Answer here : each sysadmin must make up his/her
# mind.

UMASK           077

http://www.cyberciti.biz/tips/understanding-linux-unix-umask-value-usage.html

1.3.2 Secure shared memory/Partition Security

/etc/fstab

tmpfs     /dev/shm     tmpfs     defaults,noexec,nosuid     0     0
/dev/vg0/tmp  /tmp  ext4  defaults,nodev,nosuid,noexec 0 0
/dev/vg0/var  /var  ext4  defaults,nodev 0 0
/dev/vg0/mysql  /xxx/mysql  ext4  defaults,nodev,nosuid,noexec 0 0
/dev/vg0/mail  /xxx/mail  ext4  defaults,nodev,nosuid,noexec 0 0
/dev/vg0/home  /home  ext4  defaults,nosuid,nodev 0 0
/dev/vg0/www  /xxx/www  ext4  defaults,nodev,nosuid,noexec 0 0


add /etc/apt/apt.conf.d/00tempdir

APT::ExtractTemplates::TempDir "/var/tmp";

1.3.3 SSH Hardening - disable root login and change port.

#/etc/ssh/sshd_config
Port 563
AllowGroups staff
PermitRootLogin no


1.3.4 Harden network with sysctl settings

#/etc/sysctl.conf
# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0 
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0

# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Block SYN attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5

# Log Martians
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0 
net.ipv6.conf.default.accept_redirects = 0


1.4 Security

1.4.1 Chkrootkit

1.4.2 Checksecurity

1.4.3 Logcheck

1.4.4 Shorewall

-> Ziel, alles von aussen sperren, nach innen nur 'named' port, wie z.b. 22(ssh),25(smtp),80(http),443(https),993(imaps),995(pop3s) als Firewall wird shorewall (mit iptables/netfilter) verwendet.

1.4.4.1 Konfiguration

nach der Installation wird entsprechend konfiguriert. Folgendes geändert, der Rest default.

/etc/default/shorewall

# prevent startup with default configuration
# set the below varible to 1 in order to allow shorewall to start
startup=1

/etc/shorewall/shorewall.conf

#IP_FORWARDING=off
#DISABLE_IPV6=yes

/etc/shorewall/interfaces

##############################################################################
#ZONE    INTERFACE      BROADCAST       OPTIONS
net     eth0            detect          tcpflags,logmartians,nosmurfs

/etc/shorewall/policy (für das 'Normalverhalten')

###############################################################################
#SOURCE         DEST            POLICY          LOG             LIMIT:BURST
$FW             net             ACCEPT
net             all             DROP            #info
# The FOLLOWING POLICY MUST BE LAST
all             all             REJECT          #info

/etc/shorewall/zones

#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
net     ipv4

/etc/shorewall/rules (was wir explizit erlauben wollen)

####################################################################################################
#ACTION  SOURCE         DEST            PROTO   DEST    SOURCE     ORIGINAL     RATE            USER/
#                                               PORT    PORT(S)    DEST         LIMIT           GROUP
SECTION NEW

ACCEPT          all             fw              tcp     563
#ACCEPT          all             fw              tcp     22
ACCEPT          all             fw              tcp     443
ACCEPT          all             fw              tcp     80
ACCEPT          all             fw              tcp     25
ACCEPT          all             fw              tcp     993
ACCEPT          all             fw              tcp     995
Ping(ACCEPT)    all       fw

# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
#Ping(DROP)     net             $FW

# Permit all ICMP traffic FROM the firewall TO the net zone
ACCEPT          $FW             net             icmp

/etc/shorewall/accounting

#####################################################################################
#ACTION CHAIN   SOURCE          DESTINATION     PROTO   DEST            SOURCE  USER/
#                                                       PORT(S)         PORT(S) GROUP
mail             -       eth0    -               tcp             25,993,995
mail             -       -       eth0            tcp             -               25,993,995
mail             -       -       eth0            tcp             25,993,995
COUNT           mail     eth0
COUNT           mail     -       eth0

ssh             -       eth0    -               tcp             22,563
ssh             -       -       eth0            tcp             -               22,563
COUNT           ssh     eth0
COUNT           ssh     -       eth0

ftp             -       eth0    -               tcp             21,20,33000:33100
ftp             -       -       eth0            tcp             -               21,20,33000:33100
COUNT           ftp     eth0
COUNT           ftp     -       eth0

stream             -       eth0    -               tcp             8000,8001
stream             -       -       eth0            tcp             -               8000,8001
COUNT           stream     eth0
COUNT           stream     -       eth0

web             -       eth0    -               tcp             80,443
web             -       -       eth0            tcp             -               80,443
COUNT           web     eth0
COUNT           web     -       eth0

dns             -       eth0    -               udp             -       53
dns             -       -       eth0            udp             53
COUNT           dns     eth0
COUNT           dns     -       eth0

countall                -       eth0
countall                -       -       eth0
COUNT           countall        eth0
COUNT           countall        -       eth0

backup:COUNT             -       eth0   188.xx.xx.xx               tcp  -       -
backup:COUNT             -       188.xx.xx.xx       eth0            tcp -       -
DONE    backup

1.4.4.2 Betrieb

ein

shorewall check

prüft die Konfig, ein

shorewall start

startet das ganze.


1.4.4.3 IP-Adressen blocken

Sind mal wieder böse Leute im Netz unterwegs, kann man diese einfach sperren, bzw. droppen:

shorewall drop 61.129.57.x

1.5 HDDTemp

1.6 NTP-Date

1.7 smartmontools

aktuelle Festplatten unterstützen smart, damit kann man den 'Gesundheitsstatus' abfragen:

/etc/smartd.conf

...
#DEVICESCAN
# First two SCSI disks.  This will monitor everything that smartd can
# monitor.  Do extended self-tests Wednesdays at 6pm and Sundays at 1 am
/dev/sda -d ata -a -s L/../../3/18
/dev/sdb -d ata -a -s L/../../7/01
...

1.8 cron-apt

Per Cron werde die Paketlisten aktualisiert und es gibt ein syslog-Eintrag, falls es neue Updates gibt.

2 Dienste

2.1 Cron

root-crontabs:

54 08 * * * /bin/sh /srv/www/_server/bin/make_all_stats.sh
4 06 * * * /srv/backup/bin/packagelist.sh

2.2 Webserver

als Webserver verwenden wir Apache2 mit PHP, mod_security, mod_auth_pam, mod_deflate. Desweiteren lassen wir die Logfiles nach einem Tag rotieren.

2.2.1 conf.d/myconfig

LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vcombined
LogFormat "%{Host}i %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined

# global access log
CustomLog "|| /usr/sbin/vlogger -s access.log -t access.log.%Y.%m -u ${APACHE_RUN_USER} -g ${APACHE_RUN_GROUP} ${APACHE_LOG_DIR}/vlogger" vcombined

UseCanonicalName Off


2.2.2 conf.d/z_security

<Directory />
        AllowOverride None
      <IfVersion >= 2.4>
    Require all denied
    </IfVersion>
    <IfVersion < 2.4>
        Order Deny,Allow
        Deny from all
    </IfVersion>
</Directory>


ServerTokens Prod
ServerSignature Off
TraceEnable Off

#SSL

#against BEAST
SSLHonorCipherOrder On

SSLCipherSuite          "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS:!LOW:!MEDIUM"
SSLCipherSuite AES256+EECDH:AES256+EDH:AES128+EECDH:AES128+EDH:!DES:!NULL:!RC2:!RC4:!3DES:!MD5:!ADH:!AECDH:!EXP:!SHA1

# enable only secure protocols: TLSv1.2, but not SSLv2
SSLProtocol -ALL -TLSv1 -TLSv1.1 +TLSv1.2

2.2.3 conf-avaiable/joomla-admin-block.conf

Blocks access to /administrator, eg. from joomla and to sample files

But if you have a special cookie you are allowd to access

Just type /admin-mega-hidden

#this is global
RewriteEngine On

#the rules from the current scope are applied before rules specified in any child's scope
#works only if child has 'RewriteEngine On'
RewriteOptions InheritDownBefore

RewriteCond %{REQUEST_URI} ^/administrator
RewriteCond %{REQUEST_URI} ^/wp-login.php [or]
RewriteCond %{REQUEST_URI} ^/README.txt [OR]
RewriteCond %{REQUEST_URI} ^/LICENSE.txt [OR]
RewriteCond %{REQUEST_URI} ^/htaccess.txt [OR]
RewriteCond %{REQUEST_URI} ^/robots.txt.dist [OR]
RewriteCond %{REQUEST_URI} ^/web.config.txt
RewriteCond %{HTTP_COOKIE} !JoomlaAdminSession=19283ddfgdfgdfgdfgdgdgdg65

#send error 404, so it will not be logged in audit.log
RewriteRule .* - [L,F,R=404]



#this php file creates a cookie to access /administrator
Alias /admin-mega-hidden /srv/www/_webrootauth/joomla-admin-12345
<Directory "/srv/www/_webrootauth/joomla-admin-12345/">
        Require all granted
</Directory>


#/srv/www/_webrootauth/joomla-admin-12345/index.php
<?php
$admin_cookie_code="19283ddfgdfgdfgdfgdgdgdg65";
setcookie("JoomlaAdminSession",$admin_cookie_code,0,"/");
header("Location: /administrator/index.php");
?>


#enable module
a2enconf joomla-admin-block

2.3 Module

2.3.1 Verzeichnisschutz

2.3.1.1 authnz_external (pwauth)

replaces mod_auth_pam

apt-get install libapache2-mod-authnz-external pwauth


#/etc/apache2/conf-available/auth_external.conf
AddExternalAuth pwauth /usr/sbin/pwauth
SetExternalAuthMethod pwauth pipe


AuthBasicProvider external
AuthExternal pwauth
Require user user

see http://icephoenix.us/linuxunix/apache-and-http-authentication-with-pam/

2.3.1.2 authnz_external (imap)

replaces mod_auth_imap Download

#/etc/checkpasswd-imap.ini
[localhost]
host = localhost
port = 1143
cache-dir = /srv/www/_tmp
allow-everybody = .*


#/etc/apache2/conf-available/auth_external.conf
AddExternalAuth imapauth /usr/bin/checkpasswd-imap-pipe.py
SetExternalAuthMethod imapauth pipe


#virtual host
AuthType Basic
    AuthName "Authentication Required"
    AuthBasicProvider external
    AuthExternal imapauth
require valid-user

2.3.1.3 mod_auth_pam

Für den Verzeichnisschutz verwenden wir mod_auth_pam, d.h. wir können die gleichen Logindaten wie am System nutzen. Damit man eine Gruppe nutzen kann, wird libapache2-mod-auth-sys-group benötigt!

eine bsp. .htaccess:

AuthPAM_Enabled on
AuthType Basic
AuthName "secure area"
require group staff

Falls es nicht geht, vom error.log:

[error] [client 217.229.133.31] PAM: user 'xyz' - not authenticated: Authentication failure

Der User www-data muß Mitglied der Gruppe shadow sein!

2.3.1.4 mod-auth-imap

Source: http://ben.brillat.net/projects/mod_auth_imap/
kleines Howto: https://hw.cs.southern.edu/prot/mod_auth_imap.htm

Patch for dovecot:  http://srteam.skyrock.com/2121064465-mod-auth-imap2-et-dovecot-le-patch.html or you get
mod_auth_imap: Premature server disconnect for user xxx
mod_auth_imap: Server said: * CAPABILITY ...


--- mod_auth_imap.c.orig        2006-05-08 01:22:43.000000000 +0200
+++ mod_auth_imap.c     2012-09-24 19:56:27.000000000 +0200
@@ -44,8 +44,6 @@
  
 #define _OK 1
 
-int Sock;
-
 
 /*******************************************************************************
  * tcp_gets
@@ -141,6 +139,7 @@
     char result[512],buf[512];
     int ret=0;
     int port;
+    int Sock; // Don't know why it used to be global, but having it local solved *all* my problems
 
     port=atoi(cport);
 
@@ -164,15 +163,17 @@
     tcp_puts(Sock,buf);
 
     //get the capability line...
-    tcp_gets(Sock,result,500);
+    //tcp_gets(Sock,result,500);
 
     //get the "A001 OK CAPABILITY completed" line..
-    tcp_gets(Sock,result,500);
+    //tcp_gets(Sock,result,500);
 
     //skip lines that start with "*"
-    if (strncmp(result,"* ",2 == 0)) {
+    //if (strncmp(result,"* ",2 == 0)) {
+    do {
        tcp_gets(Sock,result,500);
-    }
+    //}
+    } while (strncmp(result,"* ",2) == 0);
 
     //Verify that it supports the CAPABILITY command
     if (strncmp(result,"A001 OK", 7) != 0) {
@@ -186,7 +187,11 @@
     memset(buf,0,500);
     sprintf(buf,"A002 LOGIN %s \"%s\"\r\n", username, pass);
     tcp_puts(Sock,buf);
-    tcp_gets(Sock,result,500);
+
+    //skip lines that start with "*" (sometimes needed with dovecot)
+    do {
+       tcp_gets(Sock,result,500);
+    } while (strncmp(result,"* ",2) == 0);
 
     if (strncmp(result,"A002 OK",7) == 0) {
         if (logflag) {
@@ -197,7 +202,6 @@
     } else if (strncmp(result,"A002 NO",7) == 0) {
         if (logflag) {
             ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,0,r,"mod_auth_imap: Login failed for user %s.", user
name);
-            ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,0,r,"mod_auth_imap: Server said: %s", result);
         }
 
         ret=!_OK;
@@ -205,7 +209,6 @@
         //it must have told us BYE and disconnected
         if (logflag) {
             ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,0,r,"mod_auth_imap: Premature server disconnect for 
user %s.", username);
-            ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,0,r,"mod_auth_imap: Server said: %s", result);
         }
 
         ret=!_OK;
@@ -218,11 +221,11 @@
     sprintf(buf,"A003 LOGOUT\r\n");
     tcp_puts(Sock,buf);
 
-    //read the BYE line
-    tcp_gets(Sock,result,500);
+    //read the BYE line, skip lines that start with "*"
+    do {
+        tcp_gets(Sock,result,500);
+    } while (strncmp(result,"* ",2) == 0);
 
-    //read the OK LOGOUT
-    tcp_gets(Sock,result,500);
 
     if (strncmp(result,"A003 OK",7) == 0) {
         if (logflag) {
@@ -233,7 +236,6 @@
     } else {
         if (logflag) {
             ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,0,r,"mod_auth_imap: Error in logout for %s.", userna
me);
-            ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,0,r,"mod_auth_imap: Server said: %s", result);
         }
 
         ret=!_OK;



.htaccess

#Turn on IMAP Authentication
Auth_IMAP_Enabled on

#Give a name to the authentication domain, whatever you want:
AuthName "SAU Email username and password"

#Only basic authentication is supported for now:
AuthType Basic

#If you feel like it, restrict the users or allow all valid users:
Require valid-user
#Make IMAP Authentication authoritative for this .htaccess file:
Auth_IMAP_Authoritative on

#Set the IMAP Server to which you want to connect (default=localhost):
Auth_IMAP_Server imap.southern.edu

#Set the port on which the imap server is running (default=143):
Auth_IMAP_Port 143

#Turn on some extra logging (login attempts, etc.) in Apache's Error Log
Auth_IMAP_Log on

2.3.2 mod_security

ModSecurity is an open source, free web application firewall (WAF) Apache module. With over 70% of all attacks now carried out over the web application level, organizations need all the help they can get in making their systems secure. WAFs are deployed to establish an external security layer that increases security, detects and prevents attacks before they reach web applications. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and real-time analysis with little or no changes to existing infrastructure.

Installation http://www.thefanclub.co.za/how-to/how-install-apache2-modsecurity-and-modevasive-ubuntu-1204-lts-server

2.3.2.1 Links

2.3.2.2 Install

#/etc/modsecurity/modsecurity.conf
SecRuleEngine On

SecRequestBodyLimit 16384000
SecRequestBodyInMemoryLimit 16384000

SecTmpDir /var/cache/modsecurity/
SecDataDir /var/cache/modsecurity/
SecUploadDir /var/cache/modsecurity/upload/


cd /etc/modsecurity
mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
mkdir activated_rules activated_optional_rules
ln -s /usr/share/modsecurity-crs/base_rules base_rules
ln -s /usr/share/modsecurity-crs/optional_rules/ optional_rules
cd base_rules
for f in `ls *` ; do ln -s /etc/modsecurity/base_rules/$f /etc/modsecurity/activated_rules/$f ; done
cd ..

cd optional_rules
for f in `ls *` ; do ln -s /etc/modsecurity/optional_rules/$f /etc/modsecurity/activated_optional_rules/$f ; done
cd ..

ln -s /usr/share/modsecurity-crs/modsecurity_crs_10_config.conf


2.3.2.3 Enable module in apache

#/etc/apache2/mods-available/mod-security.conf
...
Include "/etc/modsecurity/*.conf"
Include "/etc/modsecurity/activated_rules/*.conf"
Include "/etc/modsecurity/activated_optional_rules/*.conf"
...

2.3.2.4 optional disable filter

Für bestimmte Verzeichnisse kann man den Filter auch ausstellen:
<LocationMatch "/ajaxplorer/">
SecRuleRemoveById 200003 960024 960915
</LocationMatch>

OR

<Location /upload.php>
    # Do not inherit filters from the parent folder
    SecFilterInheritance Off
</Location>


2.3.2.5 Virus-Scanner for uploaded files

#in modsecurity_crs_46_av_scanning.conf
#
# Modify the operator to use the correct AV scanning script/tool
# Example tools are in the util directory.
#

SecRule FILES_TMPNAMES "@inspectFile /usr/bin/runAV.pl" \
        "phase:2,t:none,block,msg:'Virus found in uploaded file',id:'950115',tag:'MALICIOUS_SOFTWARE/VIRUS',tag:'PCI/5.1',severity:'2',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-MALICIOUS_SOFTWARE/VIRUS-%{matched_var_name}=%{tx.0}"

2.3.2.6 Global Blacklist

#/etc/apache2/conf.d/modsecurity-blacklist 
#disable rule for all domains

#missing_request_header
SecRuleRemoveById 960015

#Request Missing a User Agent Header
SecRuleRemoveById 960009


2.3.2.7 bad robot data

/etc/modsecurity/activated_rules/modsecurity_35_bad_robots.data e.g. to remove surveybot

2.3.2.8 Links

2.3.3 mod_php

see PHP

2.3.4 mod_dav

WEBDAV-Modul für Apache. Damit ist es möglich Dateien über https zu manipulieren (ändern, löschen, erstellen usw.). installieren: a2enmod dav

#httpd.conf 
 Alias /phparea /home/gstein/php_files
 Alias /php-source /home/gstein/php_files
 DavLockDB /tmp/DavLock.myvhost
 <Location /php-source>
  Dav On
  AuthType Basic
  AuthName DAV
  AuthPAM_Enabled on
  require group staff
  php_flag engine off # oder  ForceType text/plain
 </Location>

2.3.5 mod_evasive

mod_evasive is an evasive maneuvers module for Apache to provide evasive action in the event of an HTTP DoS or DDoS attack or brute force attack. It is also designed to be a detection and network management tool, and can be easily configured to talk to ipchains, firewalls, routers, and etcetera. mod_evasive presently reports abuses via email and syslog facilities.

Detection is performed by creating an internal dynamic hash table of IP Addresses and URIs, and denying any single IP address from any of the following:

  • Requesting the same page more than a few times per second
  • Making more than 50 concurrent requests on the same child per second
  • Making any requests while temporarily blacklisted (on a blocking list)
<IfModule mod_evasive.c>
  #DOSHashTableSize gibt die Größe der Hashtabelle in Bytes an
  DOSHashTableSize 3097

  #DOSPageCount gibt die Anzahl der Seitenaufrufe eines Clients pro DOSPageInterval-Zeitintervall
  DOSPageCount 2

  #DOSSiteCount gibt die Anzahl der Seitenaufrufe auf einen Child-Prozess pro DOSSiteInterval-Zeitintervall
  DOSSiteCount 50

  #DOSPageInterval und DOSSiteInterval werden in Sekunden angegeben
  DOSPageInterval 1
  DOSSiteInterval 1

  #DOSBlockingPeriod gibt die Sperrzeit in Seknunden an
  DOSBlockingPeriod 60

  #DOSEmailNotify gibts die eMail Adresse an, an welche eine Warnmail geschickt wird
  DOSEmailNotify admin@mydomain.net

  #DOSSystemCommand führt bei einem Angriff weitere Programme/Scripte aus wenn gewünscht
  #DOSSystemCommand "su - someuser -c '/sbin/... %s ...'"

  #DOSLogDir gibt das Verzeichnis an in dem das Modul seine Logfiles schreibt
  DOSLogDir /srv/www/vlogger/_mod_evasive

  #DOSWhitelist beinhaltet eine Aufzählung aller IP-Adressen für die mod_evasive NICHT gilt
  DOSWhitelist 127.0.0.1
</IfModule>

2.3.6 mod_cband

Bandbreiten-Beschränkung http://nodomain.cc/archives/2007/01/05/684-Apache2-Zugriffskontrolle-mit-mod_cband.html

2.3.7 mod_ssl

config see above (z_security)

SSL-Test: https://www.ssllabs.com/ssltest/ or https://observatory.mozilla.org/

2.4 Logging POST requests with Apache

found on https://www.technovelty.org/web/logging-post-requests-with-apache.html

SecRuleEngine On
SecAuditEngine on
SecAuditLog /var/log/apache2/website-audit.log
SecRequestBodyAccess on
SecAuditLogParts ABIFHZ

SecDefaultAction "nolog,noauditlog,allow,phase:2"

SecRule REQUEST_METHOD "^POST$" "chain,allow,phase:2"
SecRule REQUEST_URI ".*" "auditlog"


2.5 Links

2.6 Mailserver

2.6.1 Webmail

2.6.1.1 Horde

2.6.2 Virusscanner

2.6.2.1 ClamAV

2.6.3 Spamschutz

2.6.3.1 Spamassissin

2.6.3.2 DCC-Distributed Checksum Clearinghouse

2.6.3.3 Blacklists

2.6.3.4 Pyzor

2.6.3.5 Razor

2.6.4 Statistiken

2.7 Mysql-Server

2.7.1 PHPMyAdmin

2.7.2 mysqldumper

2.8 File-Zugriff

2.8.1 PureFTP

2.8.1.1 Config

in /etc/pure-ftpd/conf

#in /etc/pure-ftpd/conf # more *
::::::::::::::
AllowDotFiles
::::::::::::::
yes
::::::::::::::
AltLog
::::::::::::::
clf:/var/log/pure-ftpd/transfer.log
::::::::::::::
Bind
::::::::::::::
x.x.x.x,21
::::::::::::::
BrokenClientsCompatibility
::::::::::::::
yes
::::::::::::::
ChrootEveryone
::::::::::::::
yes
::::::::::::::
CustomerProof
::::::::::::::
yes
::::::::::::::
DisplayDotFiles
::::::::::::::
yes
::::::::::::::
DontResolve
::::::::::::::
1
::::::::::::::
MaxClientsPerIP
::::::::::::::
3
::::::::::::::
MinUID
::::::::::::::
32
::::::::::::::
MySQLConfigFile
::::::::::::::
/etc/pure-ftpd/db/mysql.conf
::::::::::::::
NoAnonymous
::::::::::::::
yes
::::::::::::::
PAMAuthentication
::::::::::::::
no
::::::::::::::
PassivePortRange
::::::::::::::
33000 33100
::::::::::::::
PerUserLimits
::::::::::::::
2 0
::::::::::::::
PureDB
::::::::::::::
/etc/pure-ftpd/pureftpd.pdb
::::::::::::::
SyslogFacility
::::::::::::::
none
::::::::::::::
TLS
::::::::::::::
2
::::::::::::::
VerboseLog_off
::::::::::::::
yes

2.8.1.2 vboxadm als Auth-Backend (MySQL)

User must be an Domainadmin to login

#/etc/pure-ftpd/db/mysql.conf
# Optional : MySQL server name or IP. Don't define this for unix sockets.
# MYSQLServer     127.0.0.1

# Optional : MySQL port. Don't define this if a local unix socket is used.
# MYSQLPort       3306

# Optional : define the location of mysql.sock if the server runs on this host.
MYSQLSocket      /var/run/mysqld/mysqld.sock

# Mandatory : user to bind the server as.
MYSQLUser       dovecot

# Mandatory : user password. You must have a password.
MYSQLPassword   xxxx

# Mandatory : database to open.
MYSQLDatabase   vboxadm

# Mandatory : how passwords are stored
# Valid values are : "cleartext", "crypt", "sha1", "md5" and "password"
# ("password" = MySQL password() function)
# You can also use "any" to try "crypt", "sha1", "md5" *and* "password"
MYSQLCrypt      crypt

# In the following directives, parts of the strings are replaced at
# run-time before performing queries :
#
# \L is replaced by the login of the user trying to authenticate.
# \I is replaced by the IP address the user connected to.
# \P is replaced by the port number the user connected to.
# \R is replaced by the IP address the user connected from.
# \D is replaced by the remote IP address, as a long decimal number.
#
# Very complex queries can be performed using these substitution strings,
# especially for virtual hosting.

# Query to execute in order to fetch the password
#MYSQLGetPW      SELECT Password FROM users WHERE User='\L'
MYSQLGetPW      SELECT passwd_crypt FROM mailboxes AS m LEFT JOIN domains AS d ON m.domain_id = d.id WHERE m.local_part = CONCAT(SUBSTRING_INDEX('\L', '@', 1)) AND d.name = CONCAT(SUBSTRING_INDEX('\L', '@', -1)) AND m.is_active AND d.is_active AND m.is_domainadmin = 1

# Query to execute in order to fetch the system user name or uid
MYSQLGetUID     SELECT 33 as Uid FROM mailboxes AS m LEFT JOIN domains AS d ON m.domain_id = d.id WHERE m.local_part = CONCAT(SUBSTRING_INDEX('\L', '@', 1)) AND d.name = CONCAT(SUBSTRING_INDEX('\L', '@', -1)) AND m.is_active AND d.is_active

# Optional : default UID - if set this overrides MYSQLGetUID
#MYSQLDefaultUID 1000

# Query to execute in order to fetch the system user group or gid
MYSQLGetGID     SELECT 33 as Gid FROM mailboxes AS m LEFT JOIN domains AS d ON m.domain_id = d.id WHERE m.local_part = CONCAT(SUBSTRING_INDEX('\L', '@', 1)) AND d.name = CONCAT(SUBSTRING_INDEX('\L', '@', -1)) AND m.is_active AND d.is_active

# Optional : default GID - if set this overrides MYSQLGetGID
#MYSQLDefaultGID 1000

# Query to execute in order to fetch the home directory
MYSQLGetDir     SELECT CONCAT('/srv/www/',SUBSTRING_INDEX('\L', '@', -1)) as Dir FROM mailboxes AS m LEFT JOIN domains AS d ON m.domain_id = d.id WHERE m.local_part = CONCAT(SUBSTRING_INDEX('\L', '@', 1)) AND d.name = CONCAT(SUBSTRING_INDEX('\L', '@', -1)) AND m.is_active AND d.is_active

2.8.1.3 vpopmail als Auth-Backend (alt)

from http://www.qmailinfo.org/index.php/Horde-Procmail-Filters

das ganze wird benötigt, um von Horde aus z.b. den Mailfilter (maildrop) zu ändern.


/etc/init.d/pure-ftpd_vpopmail
#! /bin/sh
# Starts a pure-ftp-auth-process with vpopmail as backend and pure-ftpd on Port 2121
#
# Author:       Jonathan Tietz <http://crazylinux.de>
#
# Version:      1.0  03-Dec-2006
#

set -e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Pure-Ftpd-vpopmail"
NAME=pure-authd
NAME2=pure-ftpd
DAEMON=/usr/sbin/pure-authd
PIDFILE=/var/run/pure-ftpd_auth_vpop.pid
PIDFILE2=/var/run/pure-ftpd_vpop.pid
SCRIPTNAME=/etc/init.d/pure-ftpd_vpop

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

# Read config file if it is present.
#if [ -r /etc/default/$NAME ]
#then
#       . /etc/default/$NAME
#fi

#
#       Function that starts the daemon/service.
#
d_start() {
        #start-stop-daemon --start --quiet --pidfile $PIDFILE \
        #       --exec $DAEMON
                /usr/sbin/pure-authd -p /var/run/pure-ftpd_auth_vpop.pid -s /var/run/pure-ftpd_auth_vpop.sock -r /usr/sbin/pure-authd_vpopmail &
                /usr/sbin/pure-ftpd -0 -B -A -E -H -g /var/run/pure-ftpd_vpop.pid -S 127.0.0.1,2121 -lextauth:/var/run/pure-ftpd_auth_vpop.sock

}

#
#       Function that stops the daemon/service.
#
d_stop() {
        start-stop-daemon --stop --quiet --pidfile $PIDFILE \
                --name $NAME
        start-stop-daemon --stop --quiet --pidfile $PIDFILE2 \
                --name $NAME2
}

#
#       Function that sends a SIGHUP to the daemon/service.
#
d_reload() {
        start-stop-daemon --stop --quiet --pidfile $PIDFILE \
                --name $NAME --signal 1
        start-stop-daemon --stop --quiet --pidfile $PIDFILE2 \
                --name $NAME2 --signal 1
}

case "$1" in
  start)
        echo -n "Starting $DESC: $NAME"
        d_start
        echo "."
        ;;
  stop)
        echo -n "Stopping $DESC: $NAME"
        d_stop
        echo "."
        ;;
  #reload)
        #
        #       If the daemon can reload its configuration without
        #       restarting (for example, when it is sent a SIGHUP),
        #       then implement that here.
        #
        #       If the daemon responds to changes in its config file
        #       directly anyway, make this an "exit 0".
        #
        # echo -n "Reloading $DESC configuration..."
        # d_reload
        # echo "done."
  #;;
  restart|force-reload)
        #
        #       If the "reload" option is implemented, move the "force-reload"
        #       option to the "reload" entry above. If not, "force-reload" is
        #       just the same as "restart".
        #
        echo -n "Restarting $DESC: $NAME"
        d_stop
        sleep 1
        d_start
        echo "."
        ;;
  *)
        # echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 1
        ;;
esac

exit 0

Activate init-script:

update-rc.d pure-ftpd_vpop defaults


/usr/sbin/pure-authd_vpopmail
#!/bin/bash

#  ftpauth: This program is called by pure-authd to check if the email l/p are correct
#  Copyright (C) 2005 Roman Volf

#  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 2
#  of the License, or (at your option) any later version.

#  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

VPOPHOME=/var/vpopmail


## Do not change anything below here

PATH=$PATH:$VPOPHOME/bin


VPOPMAIL_UID=`printf "%s\0%s\0%s\0" $AUTHD_ACCOUNT $AUTHD_PASSWORD Y123457 | vchkpw id -u vpopmail 3<&0`
VPOPMAIL_GID=`id -g vpopmail`
DOMAIN_DIR=`vdominfo -d $DOMAIN`
USER_DIR=`vuserinfo -d $AUTHD_ACCOUNT`

if [ $VPOPMAIL_UID ]; then
        DOMAIN=`echo $AUTHD_ACCOUNT|cut -d "@" -f 2`
        USER=`echo $AUTHD_ACCOUNT|cut -d "@" -f 1`
        DOMAIN_DIR=`vdominfo -d $DOMAIN`
        #not used
        #if [ !  -f $DOMAIN_DIR/.qmail-$USER ]; then
        #        echo "| /var/qmail/bin/preline /usr/local/bin/preprocmail" > $DOMAIN_DIR/.qmail-$USER
        #        echo "| $VPOPHOME/bin/vdelivermail '' $USER_DIR/Maildir/" >> $DOMAIN_DIR/.qmail-$USER
        #        chown vpopmail $DOMAIN_DIR/.qmail-$USER
        #        chmod 600 $DOMAIN_DIR/.qmail-$USER
        #fi
        echo "auth_ok:1"
        echo "uid:$VPOPMAIL_UID"
        echo "gid:$VPOPMAIL_GID"
        echo "dir:$USER_DIR"
        echo "end"
        exit
fi

echo "auth_ok:0"
echo "end"

3 Monitoring

3.1 Cacti

3.2 Munin

3.3 SNMP

/etc/snmp/snmpd.conf

...
smuxsocket 127.0.0.1

# Check the / partition and make sure it contains at least 10 megs.
disk / 10000

# Check for loads:
load 12 14 14
...

Integration von Qmail-Stats gibt's bei Cacti

3.4 IP-Accounting

4 Backup

Backup ist natürlich auch notwendig. Auch wenn das System sich auf einem gespiegelten Raid befindet, so hilft das nicht gegen Datenverlust, sondern nur vor Hardwareausfall. Deshalb müssen die folgenden Sachen gesichert werden. Backup-Dir ist /srv/backup. Unter /srv/backup/bin/ liegen die (Cron)Scripte.

4.1 Serverkonfiguration

4.1.1 Dateien mit rsnapshot

Config ist /etc/rsnapshot.conf, alles default-werte, sonst diese Änderungen. Im root-Dir liegen dann die Backups der letzten Woche.

 # All snapshots will be stored under this root directory.
 snapshot_root   /srv/backup/rsnapshot/
 #retain         hourly  6
 retain          daily   7
 #retain         weekly  4

 logfile /var/log/rsnapshot.log

 backup  /home/          localhost/
 backup  /etc/           localhost/
 backup  /srv/vmail/     localhost/
 backup  /srv/www/       localhost/

und das dazugehörige cronscript /etc/cron.d/rsnapshot:

 30 3    * * *           root    /usr/bin/rsnapshot daily

4.1.2 Partitionstabelle

liegen unter /srv/backup/server (manuell erstellt, parted)

parted -l|tee /srv/backup/server/partitions

4.1.3 Liste der installierten Packeten

/srv/backup/server/package.list (cron, /srv/backup/bin/packagelist.sh):

 #!/bin/sh
 /usr/bin/dpkg -l>/srv/backup/server/package.list

4.2 SQL-Export

der Export wird via MySQLDumper (im AdminBereich unter Verwaltung) täglich per cron dürchgeführt. Jede DB hat ein eigene Datei. Die Files liegen unter .../msd/work/backup/ und werden jeweils 10 Tage aufgehoben.


4.3 Dateisystem extern via Duply

Backups auf nicht vertrauenswürdige (FTP-)Server

Wer seine Daten auf einem unbekannten Server sichert, muss sie verschlüsseln und signieren, um sie zuverlässig vor neugierigen Blicken und Manipulationen zu schützen. Dafür ist duplicity das richtige Werkzeug, und das c't-Skript ftplicity (jetzt duply) macht die Arbeit damit zu einem Kinderspiel.

/etc/duply/<profile>/exclude

/dev
/proc
/sys
/tmp
/home
/srv/mysql
/var/cache
/var/tmp
/var/spool/postfix/private
/run
/build
/mnt
/srv/backup
/srv/backupserver
/root/.cache/


4.3.1 Restore

Einzelne Dateien aus dem Backup restauriert man mit duply fetch. Der Befehl benötigt drei Optionen: Datei- beziehungsweise Verzeichnisname, Ziel und Alter:

duply <profile> fetch etc/passwd /root/pw 4D

beispielsweise restauriert /etc/passwd im Stand von vor 4 Tagen nach /root/pw, "now" liefert den aktuellen Stand. Details zu dem verwendeten Zeitformat finden sie in der Manpage von duplicity im Abschnitt TIME FORMATS.

4.3.2 Cronjobs

27 7 1 * * /usr/bin/duply <profile> backup_verify_purge --force
23 6 * * * /usr/bin/duply <profile> bkp 2>/dev/null
0 7 * * 5 /usr/bin/duply <profile> status 2>/dev/null


4.3.3 Links

4.4 Tools