Standard SMTP Dialog

Genauere Definition und Erklärung von SMTP bei Wikipedia

RFCs

Default Ports

  • 25 TCP
  • 587 TCP (Submission Port)

Status-Codes

Das SMTP-Protokoll hält zum Status der Kommunikation zwischen Mailserver und Mailclient folgende Error-Codes bereit:

  • 1XX: Mailserver hat die Anforderung akzeptiert, ist aber selbst noch nicht tätig geworden. Eine Bestätigungsmeldung ist erforderlich.
  • 2XX: Mailserver hat die Anforderung erfolgreich ohne Fehler ausgeführt.
  • 3XX: Mailserver hat die Anforderung verstanden, benötigt aber zur Verarbeitung weitere Informationen.
  • 4XX: Mailserver hat einen temporären Fehler festgestellt. Wenn die Anforderung ohne jegliche Änderung wiederholt wird, kann die Verarbeitung möglicherweise abgeschlossen werden.
  • 5XX: Mailserver hat einen fatalen Fehler festgestellt. Ihre Anforderung kann nicht verarbeitet werden.

Quelle: Wikipedia

Standard Kommandos

Kommando Beschreibung
HELO host Eigenen Servernamen senden und Dialog beginnen
EHLO host Extended HELO; Zeigt Serverfunktionen/möglichkeiten an
MAIL FROM:xxx Absender E-Mail Adresse
RCPT TO:xxx Empfänger E-Mail Adresse
DATA Beginn der Übermittlung von Daten
Das Ende der Übermittlung wird mit <CR><LF>.<CR><LF> signalisiert.
QUIT Dialog beenden

Der SMTP Dialog

Um einen SMTP Server zu Testen kann man das Tool telnet verwenden:

# telnet mailserver.example.com 25

Wichtig ist die Portangabe 25. Protokoll ist TCP. Neuere Server verwenden unteranderem auch den Submission Port 587 TCP für Clienteinlieferungen.

>> sysadmin@vmserver01:~$ telnet mailserver.example.com 25
<< Trying 10.23.45.10...
<< Connected to mailserver.example.com.
<< Escape character is '^]'.
<< 220 mailserver.example.com ESMTP Postfix (Debian/GNU)
>> helo pc0815.example.com
<< 250 mailserver.example.com
>> mail from:absender@example.org
<< 250 2.1.0 Ok
>> rcpt to:empfaenger@example.org
<< 250 2.1.5 Ok
>> data
<< 354 End data with <CR><LF>.<CR><LF>
>> Dies ist eine Testmail.
>> .
<< 250 2.0.0 Ok: queued as 708D72C80BE
>> quit
<< 221 2.0.0 Bye
<< Connection closed by foreign host.
<< sysadmin@vmserver01:~$

SMTP Serverfunktionen abfragen mit EHLO (Extended HELO)

Der Dialog funktioniert genau so wie der andere es wird nur statt helo ehlo verwendet.

>> sysadmin@vmserver01:~$ telnet mailserver.example.com 25
<< Trying 10.23.45.10...
<< Connected to mailserver.example.com.
<< Escape character is '^]'.
<< 220 mailserver.example.com ESMTP Postfix (Debian/GNU)
>> ehlo pc0815.example.org
<< 250-mailserver.example.com
<< 250-PIPELINING
<< 250-SIZE 10240000
<< 250-VRFY
<< 250-ETRN
<< 250-STARTTLS
<< 250-ENHANCEDSTATUSCODES
<< 250-8BITMIME
<< 250 DSN
>> quit
<< 221 2.0.0 Bye
<< Connection closed by foreign host.
<< sysadmin@vmserver01:~$

Proftpd mit MySQL-Backend und Quota

Ich habe darauf Wert gelegt, dass die Passwörter verschlüsselt in der Datenbank liegen!

Wer Klartextpasswörter haben möchte soll bitte auf → howtoforge gehen.

Written by — Maximilian Thoma 2007/12/16 19:19

Anforderungen

  • Apache 2
  • PHP (mind. 4.x)
  • PHPmyAdmin
  • MySQL Server (mind. 4.x)
  • OpenSSL

Installation von proftpd und Konfiguration

Installation der Pakete

sudo apt-get install proftpd-mysql

Während der Installation taucht folgende Frage auf:

Run proftpd from inetd or standalone?

Bitte wählen Sie „standalone“ aus. (In Deutsch heisst die Auswahl „Daemon“)

User und Gruppe für proftpd Dateien anlegen

groupadd -g 2001 ftpgroup
useradd -u 2001 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser

MySQL User anlegen für proftpd

mysql -u root -p
CREATE DATABASE ftp;
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'ftp'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'ftp'@'localhost.localdomain' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

Die MySQL Shell noch nicht verlassen !!!

MySQL Tabellen für proftpd anlegen

USE ftp;
 
CREATE TABLE ftpgroup (
groupname VARCHAR(16) NOT NULL DEFAULT '',
gid SMALLINT(6) NOT NULL DEFAULT '5500',
members VARCHAR(16) NOT NULL DEFAULT '',
KEY groupname (groupname)
) TYPE=MyISAM COMMENT='ProFTP group table';
 
CREATE TABLE ftpquotalimits (
name VARCHAR(30) DEFAULT NULL,
quota_type ENUM('user','group','class','all') NOT NULL DEFAULT 'user',
per_session ENUM('false','true') NOT NULL DEFAULT 'false',
limit_type ENUM('soft','hard') NOT NULL DEFAULT 'soft',
bytes_in_avail INT(10) UNSIGNED NOT NULL DEFAULT '0',
bytes_out_avail INT(10) UNSIGNED NOT NULL DEFAULT '0',
bytes_xfer_avail INT(10) UNSIGNED NOT NULL DEFAULT '0',
files_in_avail INT(10) UNSIGNED NOT NULL DEFAULT '0',
files_out_avail INT(10) UNSIGNED NOT NULL DEFAULT '0',
files_xfer_avail INT(10) UNSIGNED NOT NULL DEFAULT '0'
) TYPE=MyISAM;
 
CREATE TABLE ftpquotatallies (
name VARCHAR(30) NOT NULL DEFAULT '',
quota_type ENUM('user','group','class','all') NOT NULL DEFAULT 'user',
bytes_in_used INT(10) UNSIGNED NOT NULL DEFAULT '0',
bytes_out_used INT(10) UNSIGNED NOT NULL DEFAULT '0',
bytes_xfer_used INT(10) UNSIGNED NOT NULL DEFAULT '0',
files_in_used INT(10) UNSIGNED NOT NULL DEFAULT '0',
files_out_used INT(10) UNSIGNED NOT NULL DEFAULT '0',
files_xfer_used INT(10) UNSIGNED NOT NULL DEFAULT '0'
) TYPE=MyISAM;
 
CREATE TABLE ftpuser (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
userid VARCHAR(32) NOT NULL DEFAULT '',
passwd VARCHAR(32) NOT NULL DEFAULT '',
uid SMALLINT(6) NOT NULL DEFAULT '5500',
gid SMALLINT(6) NOT NULL DEFAULT '5500',
homedir VARCHAR(255) NOT NULL DEFAULT '',
shell VARCHAR(16) NOT NULL DEFAULT '/sbin/nologin',
count INT(11) NOT NULL DEFAULT '0',
accessed DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
modified DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (id),
UNIQUE KEY userid (userid)
) TYPE=MyISAM COMMENT='ProFTP user table';

Jetzt können wir die MySQL Shell verlassen.

quit;

/etc/proftpd/modules.conf bearbeiten

Die Zeile LoadModule mod_sql_postgres.c muss auskommentiert sein !!!

[...]
LoadModule mod_sql_postgres.c
[...]

Auskommentiert:

[...]
# LoadModule mod_sql_postgres.c
[...]

/etc/proftpd/proftpd.conf anpassen

#
# /etc/proftpd/proftpd.conf -- This is a basic ProFTPD configuration file.
# To really apply changes reload proftpd after modifications.
#

# Includes DSO modules
Include /etc/proftpd/modules.conf

# Set off to disable IPv6 support which is annoying on IPv4 only boxes.

#################################################
### IPv6 abschalten NEU NEU NEU
#################################################
UseIPv6                         off
#################################################

ServerName                      "Debian"
ServerType                      standalone
DeferWelcome                    off

MultilineRFC2228                on
DefaultServer                   on
ShowSymlinks                    on

TimeoutNoTransfer               600
TimeoutStalled                  600
TimeoutIdle                     1200

DisplayLogin                    welcome.msg
DisplayFirstChdir               .message
ListOptions                     "-l"

DenyFilter                      \*.*/

# Port 21 is the standard FTP port.
Port                            21

# In some cases you have to specify passive ports range to by-pass
# firewall limitations. Ephemeral ports can be used for that, but
# feel free to use a more narrow range.
# PassivePorts                    49152 65534

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances                    30

# Set the user and group that the server normally runs at.
User                            proftpd
Group                           nogroup

# Umask 022 is a good standard umask to prevent new files and dirs
# (second parm) from being group and world writable.
Umask                           022  022
# Normally, we want files to be overwriteable.
AllowOverwrite                  on

# Uncomment this if you are using NIS or LDAP to retrieve passwords:
# PersistentPasswd              off

# Be warned: use of this directive impacts CPU average load!
#
# Uncomment this if you like to see progress and transfer rate with ftpwho
# in downloads. That is not needed for uploads rates.
# UseSendFile                   off

TransferLog /var/log/proftpd/xferlog
SystemLog   /var/log/proftpd/proftpd.log

<IfModule mod_tls.c>
TLSEngine off
</IfModule>

<IfModule mod_quota.c>
QuotaEngine on
</IfModule>

<IfModule mod_ratio.c>
Ratios on
</IfModule>


# Delay engine reduces impact of the so-called Timing Attack described in
# http://security.lss.hr/index.php?page=details&ID=LSS-2004-10-02
# It is on by default.
<IfModule mod_delay.c>
DelayEngine on
</IfModule>

<IfModule mod_ctrls.c>
ControlsEngine        on
ControlsMaxClients    2
ControlsLog           /var/log/proftpd/controls.log
ControlsInterval      5
ControlsSocket        /var/run/proftpd/proftpd.sock
</IfModule>

<IfModule mod_ctrls_admin.c>
AdminControlsEngine on
</IfModule>

# A basic anonymous configuration, no upload directories.

# <Anonymous ~ftp>
#   User                                ftp
#   Group                               nogroup
#   # We want clients to be able to login with "anonymous" as well as "ftp"
#   UserAlias                   anonymous ftp
#   # Cosmetic changes, all files belongs to ftp user
#   DirFakeUser on ftp
#   DirFakeGroup on ftp
#
#   RequireValidShell           off
#
#   # Limit the maximum number of anonymous logins
#   MaxClients                  10
#
#   # We want 'welcome.msg' displayed at login, and '.message' displayed
#   # in each newly chdired directory.
#   DisplayLogin                        welcome.msg
#   DisplayFirstChdir           .message
#
#   # Limit WRITE everywhere in the anonymous chroot
#   <Directory *>
#     <Limit WRITE>
#       DenyAll
#     </Limit>
#   </Directory>
#
#   # Uncomment this if you're brave.
#   # <Directory incoming>
#   #   # Umask 022 is a good standard umask to prevent new files and dirs
#   #   # (second parm) from being group and world writable.
#   #   Umask                           022  022
#   #            <Limit READ WRITE>
#   #            DenyAll
#   #            </Limit>
#   #            <Limit STOR>
#   #            AllowAll
#   #            </Limit>
#   # </Directory>
#
# </Anonymous>

##################################################################
#### NEU NEU NEU NEU NEU
##################################################################

## Nur virt. User dürfen sich anmelden !!!!

<Limit LOGIN>
AllowUser ftpuser
AllowGroup ftpgroup
DenyAll
</Limit>

DefaultRoot ~


# The passwords in MySQL are encrypted using CRYPT
SQLAuthTypes            OpenSSL
SQLAuthenticate         users groups


# used to connect to the database
# databasename@host database_user user_password
SQLConnectInfo  ftp@localhost ftp password


# Here we tell ProFTPd the names of the database columns in the "usertable"
# we want it to interact with. Match the names with those in the db
SQLUserInfo     ftpuser userid passwd uid gid homedir shell

# Here we tell ProFTPd the names of the database columns in the "grouptable"
# we want it to interact with. Again the names match with those in the db
SQLGroupInfo    ftpgroup groupname gid members

# set min UID and GID - otherwise these are 999 each
SQLMinID        2000

# create a user's home directory on demand if it doesn't exist
SQLHomedirOnDemand on

# Update count every time user logs in
SQLLog PASS updatecount
SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser

# Update modified everytime user uploads or deletes a file
SQLLog  STOR,DELE modified
SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser

# User quotas
# ===========
QuotaEngine on
QuotaDirectoryTally on
QuotaDisplayUnits Mb
QuotaShowQuotas on

SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = '%{0}' AND quota_type = '%{1}'"

SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = '%{0}' AND quota_type = '%{1}'"

SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" ftpquotatallies

SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies

QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally

RootLogin off
RequireValidShell off

Neustart von proftpd durchführen:

/etc/init.d/proftpd restart

Sollte bei Debian Etch folgender Fehler auftreten:

Starting ftp server: proftpd - Fatal: unknown configuration directive 'SQLAuthTypes' on line 42 of '/etc/proftpd/proftpd.conf'
 failed!

behebt folgende Zeile behebt das Problem.

Zeile in die proftpd.conf einfügen und restarten:

Include /etc/proftpd/modules.conf 

Test von proftpd

User / Gruppe in der Datenbank anlegen

MySQL Shell einloggen

mysql -u root -p

Datenbank wechseln

USE ftp;

Gruppe anlegen

Dies muss nur einmal gemacht werden da die gleiche Gruppe für alle User gilt!!!

INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser');

User und Quota anlegen

Das Passwort ist “password“.

 
INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('testuser', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);
INSERT INTO `ftpuser` (`id`, `userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`) VALUES (1, 'testuser', '{md5}X03MO1qnZdYdgyfeuILPmQ==', 2001, 2001, '/home/testuser', '/sbin/nologin', 0, '', '');

Ausloggen

quit;

Test

>> vmsrv01:/# ftp localhost
<< Connected to localhost.
<< 220 ProFTPD 1.3.0 Server (Debian) [127.0.0.1]
>> Name (localhost:root): testuser
<< 331 Password required for testuser.
>> Password:
<< 230 User testuser logged in.
<< Remote system type is UNIX.
<< Using binary mode to transfer files.
<< ftp>
>> ftp> quit
<< 221 Goodbye.
<< vmsrv01:/#

Das Verzeichnis für testuser sollte jetzt unter /home angelgt sein und ftpuser:ftpgroup gehören.

>> vmsrv01:/# ls -la /home
<< drwxr-xr-x  6 root     root     4096 2007-12-17 13:10 .
<< drwxr-xr-x 23 root     root     4096 2007-10-25 14:09 ..
<< drwxr-xr-x  2 ftpuser  ftpgroup 4096 2007-12-17 13:10 testuser
<< vmsrv01:/#

Verschlüsselte Passwörter für proftpd erzeugen

Welche Verschlüsselungsverfahren möglich sind können Sie mit dem Kommando

openssl list-message-digest-commands

abfragen.

Ergebnis:

vmsrv01:/# openssl list-message-digest-commands
md2
md4
md5
rmd160
sha
sha1
vmsrv01:/#

auf der Konsole

MD5

Kommando
/bin/echo "{md5}"`/bin/echo -n "password" | openssl dgst -binary -md5 | openssl enc -base64`
Ergebnis
{md5}X03MO1qnZdYdgyfeuILPmQ==

Alle möglichen Typen

Kommando
for c in `openssl list-message-digest-commands`; do
    /bin/echo "{$c}"`/bin/echo -n "password" | openssl dgst -binary -$c | openssl enc -base64`
  done
Ergebnis
{md2}8DiBqIxuORNfDsxg79YJuQ==
{md4}ip0JPxT4cB3xdzKyuxgsdA==
{md5}X03MO1qnZdYdgyfeuILPmQ==
{rmd160}LAjo9YhHUKe5n28vNC/GONsl/zE=
{sha}gAclaL6zshAjJesgP20P+S9c744=
{sha1}W6ph5Mm5Pz8GgiULbPgzG37mj9g=

mit PHP

MD5

Kommando
// $password contains the cleartext password before
$password = "{md5}".base64_encode(pack("H*", md5($password)));
// $password now contains the encrypted, encoded password
Ergebnis
{md5}X03MO1qnZdYdgyfeuILPmQ==

ClamAV mit Sanesecurity erweitern

Benötigte Tools installieren

sudo apt-get install rsync wget gunzip

Verzeichnis anlegen

mkdir -p /root/sanesecurity

Script erstellen

nano /root/sanesecurity/get_sane

Script:

cd /root/sanesecurity
wget http://www.sanesecurity.co.uk/clamav/scamsigs/scam.ndb.gz
wget http://www.sanesecurity.co.uk/clamav/phishsigs/phish.ndb.gz

rsync rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-Images.hdb /root/sanesecurity/MSRBL-Images.hdb
rsync rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-SPAM.ndb /root/sanesecurity/MSRBL-SPAM.ndb

gunzip -f scam.ndb.gz
gunzip -f phish.ndb.gz
cp -f scam.ndb /var/lib/clamav
cp -f phish.ndb /var/lib/clamav
cp -f MSRBL-Images.hdb /var/lib/clamav
cp -f MSRBL-SPAM.ndb /var/lib/clamav

/etc/init.d/clamav-daemon reload-database

Das ganze noch lauffähig machen:

chmod u+x /root/sanesecurity/get_sane

In Crontab einbinden

Updates täglich:

ln -s /root/sanesecurity/get_sane /etc/cron.daily/01get_sane

oder stündlich:

ln -s /root/sanesecurity/get_sane /etc/cron.hourly/01get_sane

Testlauf

/root/sanesecurity/get_sane

Testmail verschicken ob die Sanepatterns auch funktionieren

Mit einem Standardmailclient eine Testmail senden und folgende Testsignaturen verwenden

Einfach mit Copy & Paste einfügen und versenden. Resultat sollte folgendermaßen aussehen:

Nov 26 06:59:25 server amavis[20891]: (20891-03) Blocked INFECTED (Html.Phishing.Sanesecurity.TestSig), [10.72.30.1] [10.

Spamtrap / Blackhole Adresse unter Postfix einrichten

Eine E-Mail Adresse einrichten die Richtung “/dev/null“ geht.

main.cf

check_recipient_access hash:/etc/postfix/spam_trap sollte hinter reject_unauth_destination kommen. Die Konfig für smtpd_recipient_restrictions ist nur exemplarisch.

smtpd_recipient_restrictions =
        reject_non_fqdn_recipient
        reject_non_fqdn_sender
        reject_unknown_sender_domain
        reject_unknown_recipient_domain
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
        check_recipient_access hash:/etc/postfix/spam_trap
        reject_multi_recipient_bounce

/etc/postfix/spam_trap

Inhalt der Datei:

devnull@thoma.cc                DISCARD

Diese Datei muss noch ins Postmap Format konvertiert werden.

Hierzu folgenden Befehl ausführen:

postmap /etc/postfix/spam_trap

Postfix reloaden

Zuletzt muss noch Postfix neu gestartet werden. Ein

postfix reload

reicht.

Fertig!

Alle Mails die z.B. an devnull@thoma.cc geschickt werden verschwinden im Nirvana.

Tinyproxy – ein einfacher Proxy

Sicher der ungeschlagene „Platzhirsch“ ist und bleibt Squid aber man muss ja nicht immer mit Kanonen auf Spatzen schiessen, oder ??? Tinyproxy ist ein einfacher Proxy Daemon der einfach zu Konfigurieren ist und viele Funktionen bietet. Er ist sowohl für SOHO-Umgebungen als auch für Zuhause geeignet.

Tinyproxy Homepage http://tinyproxy.sourceforge.net/

Installation

sysadmin@vmserver01:~# sudo apt-get install tinyproxy

Konfiguration

##
## tinyproxy.conf -- tinyproxy daemon configuration file
##

#
# Name of the user the tinyproxy daemon should switch to after the port
# has been bound.
#
User nobody
Group nogroup

#
# Port to listen on.
#
Port 8080

#
# If you have multiple interfaces this allows you to bind to only one. If
# this is commented out, tinyproxy will bind to all interfaces present.
#
Listen 127.0.0.1

#
# The Bind directive allows you to bind the outgoing connections to a
# particular IP address.
#
#Bind 192.168.0.1

#
# Timeout: The number of seconds of inactivity a connection is allowed to
# have before it closed by tinyproxy.
#
Timeout 600

#
# ErrorFile: Defines the HTML file to send when a given HTTP error
# occurs.  You will probably need to customize the location to your
# particular install.  The usual locations to check are:
#   /usr/local/share/tinyproxy
#   /usr/share/tinyproxy
#   /etc/tinyproxy
#
# ErrorFile 404 "/usr/share/tinyproxy/404.html"
# ErrorFile 400 "/usr/share/tinyproxy/400.html"
# ErrorFile 503 "/usr/share/tinyproxy/503.html"
# ErrorFile 403 "/usr/share/tinyproxy/403.html"
# ErrorFile 408 "/usr/share/tinyproxy/408.html"

#
# DefaultErrorFile: The HTML file that gets sent if there is no
# HTML file defined with an ErrorFile keyword for the HTTP error
# that has occured.
#
DefaultErrorFile "/usr/share/tinyproxy/default.html"

#
# StatFile: The HTML file that gets sent when a request is made
# for the stathost.  If this file doesn't exist a basic page is
# hardcoded in tinyproxy.
#
StatFile "/usr/share/tinyproxy/stats.html"

#
# Where to log the information. Either LogFile or Syslog should be set,
# but not both.
#
Logfile "/var/log/tinyproxy.log"
# Syslog On

#
# Set the logging level. Allowed settings are:
#       Critical        (least verbose)
#       Error
#       Warning
#       Notice
#       Connect         (to log connections without Info's noise)
#       Info            (most verbose)
# The LogLevel logs from the set level and above. For example, if the LogLevel
# was set to Warning, than all log messages from Warning to Critical would be
# output, but Notice and below would be suppressed.
#
LogLevel Info

#
# PidFile: Write the PID of the main tinyproxy thread to this file so it
# can be used for signalling purposes.
#
PidFile "/var/run/tinyproxy.pid"

#
# Include the X-Tinyproxy header, which has the client's IP address when
# connecting to the sites listed.
#
#XTinyproxy mydomain.com

#
# Turns on upstream proxy support.
#
# The upstream rules allow you to selectively route upstream connections
# based on the host/domain of the site being accessed.
#
# For example:
#  # connection to test domain goes through testproxy
#  upstream testproxy:8008 ".test.domain.invalid"
#  upstream testproxy:8008 ".our_testbed.example.com"
#  upstream testproxy:8008 "192.168.128.0/255.255.254.0"
#
#  # no upstream proxy for internal websites and unqualified hosts
#  no upstream ".internal.example.com"
#  no upstream "www.example.com"
#  no upstream "10.0.0.0/8"
#  no upstream "192.168.0.0/255.255.254.0"
#  no upstream "."
#
#  # connection to these boxes go through their DMZ firewalls
#  upstream cust1_firewall:8008 "testbed_for_cust1"
#  upstream cust2_firewall:8008 "testbed_for_cust2"
#
#  # default upstream is internet firewall
#  upstream firewall.internal.example.com:80
#
# The LAST matching rule wins the route decision.  As you can see, you
# can use a host, or a domain:
#  name     matches host exactly
#  .name    matches any host in domain "name"
#  .        matches any host with no domain (in 'empty' domain)
#  IP/bits  matches network/mask
#  IP/mask  matches network/mask
#
#Upstream some.remote.proxy:port

#
# This is the absolute highest number of threads which will be created. In
# other words, only MaxClients number of clients can be connected at the
# same time.
#
MaxClients 100

#
# These settings set the upper and lower limit for the number of
# spare servers which should be available. If the number of spare servers
# falls below MinSpareServers then new ones will be created. If the number
# of servers exceeds MaxSpareServers then the extras will be killed off.
#
MinSpareServers 5
MaxSpareServers 20

#
# Number of servers to start initially.
#
StartServers 10

#
# MaxRequestsPerChild is the number of connections a thread will handle
# before it is killed. In practise this should be set to 0, which disables
# thread reaping. If you do notice problems with memory leakage, then set
# this to something like 10000
#
MaxRequestsPerChild 0

#
# The following is the authorization controls. If there are any access
# control keywords then the default action is to DENY. Otherwise, the
# default action is ALLOW.
#
# Also the order of the controls are important. The incoming connections
# are tested against the controls based on order.
#
Allow 127.0.0.1
Allow 10.23.45.0/24

#
# The "Via" header is required by the HTTP RFC, but using the real host name
# is a security concern.  If the following directive is enabled, the string
# supplied will be used as the host name in the Via header; otherwise, the
# server's host name will be used.
#
ViaProxyName "tinyproxy"

#
# The location of the filter file.
#
#Filter "/etc/tinyproxy/filter"

#
# Filter based on URLs rather than domains.
#
#FilterURLs On

#
# Use POSIX Extended regular expressions rather than basic.
#
#FilterExtended On

#
# Use case sensitive regular expressions.
#
#FilterCaseSensitive On

#
# Change the default policy of the filtering system.  If this directive is
# commented out, or is set to "No" then the default policy is to allow
# everything which is not specifically denied by the filter file.
#
# However, by setting this directive to "Yes" the default policy becomes to
# deny everything which is _not_ specifically allowed by the filter file.
#
#FilterDefaultDeny Yes

#
# If an Anonymous keyword is present, then anonymous proxying is enabled.
# The headers listed are allowed through, while all others are denied. If
# no Anonymous keyword is present, then all header are allowed through.
# You must include quotes around the headers.
#
#Anonymous "Host"
#Anonymous "Authorization"

#
# This is a list of ports allowed by tinyproxy when the CONNECT method
# is used.  To disable the CONNECT method altogether, set the value to 0.
# If no ConnectPort line is found, all ports are allowed (which is not
# very secure.)
#
# The following two ports are used by SSL.
#
ConnectPort 443
ConnectPort 563

Standard POP3 Dialog

Genauere Definition und Erklärung von POP3 bei Wikipedia

RFCs

Default Ports

  • 110 TCP
  • 995 TCP für SSL Verbindungen

Standard Kommandos

Kommando Beschreibung
USER xxx Auswahl der Benutzerkontos auf dem Server
PASS xxx Sendet das Passwort an den Server (Klartext)
STAT Liefert den Status der Mailbox, u. a. die Anzahl der neuen E-Mails.
LIST (n) Liefert die Anzahl und die Größe der (n-ten) E-Mail(s).
RETR n Holt die n-te E-Mail vom E-Mail-Server.
DELE n Löscht die n-te E-Mail am E-Mail-Server.
NOOP Keine Funktion, der Server antwortet mit +OK.
(Wird bei FTP-Servern öfters dazu verwendet die Verbindung offen zu halten.)
RSET Setzt alle DELE-Kommandos zurück.
QUIT Beendet die aktuelle POP3-Sitzung und führt alle DELE-Kommandos durch.

Der POP3 Dialog

>> sysadmin@vmserver01:~$ telnet pop3.example.net 110
<< Trying 10.23.45.10...
<< Connected to pop3.example.net.
<< Escape character is '^]'.
<< +OK POP3 Ready pop3.example.net 
>> user testuser@example.org
<<  +OK USER testuser@example.org set, mate
>> pass 123geheimKENNWORT123
<< +OK You are so in
>> list
<< +OK POP3 clients that break here, they violate STD53.
<< 1 236
>> retr 1
<< +OK 236 octets follow.
<< Date: Mon, 18 Oct 2004 04:11:45 +0200
<< From: Someone <someone@example.com>
<< To: testuser@example.org
<< Subject: Test-E-Mail
<< Content-Type: text/plain; charset=us-ascii; format=flowed
<< Content-Transfer-Encoding: 7bit
<< 
<< Dies ist eine Test-E-Mail
<< 
<< .
>> quit
<< +OK Bye-bye.
<< Connection closed by foreign host.
<< sysadmin@vmserver01:~$

Standard IMAP Dialog

Genauere Definition und Erklärung von IMAP bei Wikipedia

RFCs

Default Ports

  • 143 TCP
  • 993 TCP für SSL Verbindungen

Standard Kommandos

xx – Fortlaufende 2stellige Nummer 01, 02, 03, 04, …

Kommando Beschreibung
xx LOGIN username passwort User anmelden
xx LIST ““ * IMAP-Ordner auflisten (zwei Anführungszeichen nach List)
xx SELECT yyyy IMAP-Ordner auswählen
xx STATUS yyy (zzz) Status abfragen von einem IMAP-Ordner
Folgende Optionen für zzz sind möglich:
MESSAGES, UNSEEN, RECENT, UIDNEXT und UIDVALIDITY
xx FETCH n yyy Nachricht/Kopfzeile abrufen
n – Nachrichtenummer oder * für alle Nachrichten
yyy – Folgende Werte sind möglich:
ALL # Alle IMAP Header
FULL # Alle Headers und Body Infos
BODY # Body
ENVELOPE # Envelope
xx UID fetch n:n (UID RFC822.SIZE FLAGS BODY.PEEK[]) Nachricht komplett Empfangen
xx LOGOUT Ausloggen

Der IMAP Dialog

>> sysadmin@vmserver01:~$ telnet imap.example.org 143
<< Trying 10.23.45.10...
<< Connected to imap.example.org.
<< Escape character is '^]'.
<< * OK IMAP4 Ready imap.example.org
>> 01 LOGIN testuser@example.net 123geheimKENNWORT123
<< 01 OK You are so in
>> 02 LIST "" *
<< * LIST (\HasNoChildren) "." "INBOX.Junk"
<< * LIST (\HasNoChildren) "." "INBOX.Sent"
<< * LIST (\HasNoChildren) "." "INBOX.Drafts"
<< * LIST (\HasNoChildren) "." "INBOX.Trash"
<< * LIST (\Unmarked \HasChildren) "." "INBOX"
<< 02 OK LIST completed
>> 03 SELECT INBOX
<< * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
<< * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
<< * 1 EXISTS
<< * 0 RECENT
<< * OK [UIDVALIDITY 1196314665] Ok
<< * OK [MYRIGHTS "acdilrsw"] ACL
<< 03 OK [READ-WRITE] Ok
>> 04 STATUS INBOX (MESSAGES)
<< * STATUS "INBOX" (MESSAGES 1)
<< 04 OK STATUS Completed.
>> 05 FETCH 1 ALL
<< * 1 FETCH (FLAGS (\Seen) INTERNALDATE "28-Nov-2007 11:55:53 +0100" RFC822.SIZE 912 ENVELOPE ("Wed, 28 Nov 2007 11:24:08 +0100 (CET)" NIL ((NIL NIL "testuser" "example.net")) ((NIL NIL "testuser" "example.net")) ((NIL NIL "testuser" "example.net")) ((NIL NIL "undisclosed-recipients" NIL)(NIL NIL NIL NIL)) NIL NIL NIL "<20071128102415.7245146C215@mailserver.example.org>"))
<< 05 OK FETCH completed.
>> 06 CLOSE
<< 06 OK mailbox closed.
>> 07 LOGOUT
<< * BYE Courier-IMAP server shutting down
<< 07 OK LOGOUT completed
<< Connection closed by foreign host.
<< sysadmin@vmserver01:~$

Einfacher Captcha Code

Zufallszahl wird in der Cookie Variable „seckey“ gespeichert und kann von dort aus mit einer einfachen if-Abfrage geprüft werden.

<?php
 
if($_POST[seckey]==$_COOKIE[seckey]){
// Captchaverify okay
 
} else { 
// Captchacode falsch
 
}
?>

Beispielbild

Captcha Bild

Quelltext

<?php
 
$zufallszahl = mt_rand(10000, 99999);
setcookie("seckey", $zufallszahl); 
 
header("Content-Type: image/png");
/* das Bild und seine Eigenschaften */
$im = imagecreate(61, 21); //das bilde erstellen
$bgcolor = imagecolorallocate($im, 255, 255, 255); //Backgroundcolor setzen
$fontcolor = imagecolorallocate($im, 0, 0, 0); //Schriftfarbe setzen
$gridcolor = imagecolorallocate($im, 128, 128, 128); //Schriftfarbe setzen
 
/* die Linien auf das Bild "zeichnen" */
for($x=0; $x <= 100; $x+=10)
    imageline($im, $x, 0, $x, 50, $gridcolor);
for($y=0; $y <=50; $y+=5)
    imageline($im, 0, $y, 100, $y, $gridcolor);
 
/* den Zahlencode auf das Bild "schreiben" */
imagestring($im, 5, 8, 3, $_COOKIE['seckey'], $fontcolor);
imagepng($im);
imagedestroy($im);
?>

Postgrey installieren (Debian Etch)

Installation

sudo apt-get install postgrey

Service checken

mxadm@server:/# netstat -tulpen | grep 60000
tcp        0      0 127.0.0.1:60000         0.0.0.0:*               LISTEN     0          23135      7884/postgrey

Wenn der Service noch nicht läuft mit

/etc/init.d/postgrey start

starten.

In Postfix einbinden

main.cf:

smtpd_recipient_restrictions =
  permit_mynetworks
  permit_sasl_authenticated
  reject_unauth_destination
  ...
  check_policy_service inet:127.0.0.1:60000
  ...

Postfix reload

postfix reload

Multitail – mehre Logs live betrachten und in Farbe

Multitail ist eine Erweiterung des tail Befehls und ermöglicht mehrere Logs live gleichzeitig zu betrachten. Außerdem unterstützt multitail Syntaxhighlighting.

Bildquelle: http://www.vanheusden.com/multitail/screenshots.html

Installation

apt-get install multitail

Die Configfiles

/etc/multitail.conf : Ihr sind die Farbschemas gespeichert und allgemeine Parameter
.multitailrc : Diese Datei kann man in seinem Homepfad anlegen und eigene Defaults festlegen

Beispiel:

defaultcscheme:postfix

Mit dieser Zeile lege ich fest, das als Default Farbschema postfix ausgewählt wird.

E-Mail check abschalten

Beim Starten von multitail tritt folgender Fehler auf:

sysadmin@pc0815:~$ multitail /var/log/mail.log
Could not determine size of file '/var/mail/sysadmin' (which is supposed to be your mailfile): mail-check is disabled.
You can prevent this message by adding the line 'check_mail:0' in /etc/multitail.conf or in .multitailrc in your home-directory.

Press enter to continue...

Um diese Warnung abzuschalten folgende Zeile entweder in die /etc/multitail.conf oder in die eigene .multitailrc einfügen.

check_mail:0

Farbschema über Commandoline bestimmen

multitail -cS <farbschema>

Folgende Farbschemas sind verfügbar:

Farbschemaname Beschreibung
syslog kernel and unsorted messages
ssh for openssh logs
liniptfw Linux IPtables (2.6.x kernel)
postfix for MTA postfix logs
apache default Apache logging (webserver)
apache_error default Apache error logging
rsstail RSSTail output (RSS feed reader)
acctail (BSD-) process accounting reader
wtmptail www.vanheusden.com/wtmptail/
squid http proxy server
asterisk software PBX
sendmail MTA sendmail
mailscanner wrapper around sendmail/clamav/spamassassin
spamassassin wrapper for spamassassin
clamav clamav virus scanner
samba samba – smb for linux
audit for audit log
exim MTA exim log
httping ping for HTTP
netstat see www.vanheusden.com/multitail/examples.html
tcpdump for tcpdump logs
dhcpd DHCP server logs
bind Bind DNS server logs
smartd smartd logs
kerberos kerberos logs
oracle oracle logs
ntpd ntpd logs
nagtail www.nagios.org status viewer
websphere WebSphere error-log
nntpcache nntpcache logs
vnetbr Veritas Netbackup backup/restore logs
procmail procmail mailprocessor logs
checkpoint Checkpoint Firewall-1 logs
pppd PPP daemon logs
inn inn logs
netscapeldap Netscape Directory server (LDAP)
vmstat vmstat is part of sysstat
log4j log4j logs
lambdamoo MUD/MOO server http://www.moo.mud.org/

Farbschema über multitail.conf festlegen

Folgende Defaults sind bereits vorhanden:

scheme:postfix:/var/log/mail/
scheme:sendmail:/var/log/mail/
scheme:exim:/var/log/mail/
scheme:apache:/var/log/apache/.*access
scheme:apache_error:/var/log/apache/.*error
scheme:asterisk:/var/log/asterisk/messages
scheme:samba:/var/log/samba/
scheme:squid:/var/log/squid/
scheme:syslog,ssh:/var/log/
scheme:vnetbr:bplog.rest
scheme:procmail:procmail.log
scheme:inn:/var/log/news/

Um jetzt für ein Logfile ein Schema festzulegen einfach eine Zeile anfügen. z.B.

scheme:postfix:/var/log/mail.log

Jetzt kann man multitail /var/log/mail.log starten ohne den -cS Parameter anzugeben und ohne ein Default Schema in der .multitailrc festgelegt zu haben.

Mehrere Logs gleichzeitig

Um mehrere Logs gleichzeitig zu betrachten gehen Sie folgendermaßen vor:

Jedes Logfile mit -i dem multitail übergeben (in einer Zeile!) z.B.

multitail -i /var/log/mail.log -i /var/log/kern.log -i /var/log/apache2/access_log

Der Monitor wird dann anhand der Anzahl der Logs geteilt.

Postfix Quota Policy Daemon

Postfix Quota Policy Daemon ist ein Experiment, das ich im Halbschalf entwickelt habe :-). Ziel ist es auf einem Vmail System ohne Linuxquota auszukommen da dies eh nicht funktionieren würde. (Alle Mails haben bei einem Vmail System den selben User/Gruppe.) Ich habe den Daemon in PHP geschrieben in Perl wäre er sicher besser aber das beherrsche ich nicht sooo gut. Testen konnte ich es leider noch nicht, habe noch keine Virtualmachine installiert um das zu testen, sollte aber funktionieren. Status ist BETA.

Ihr findet mein Experiment auch unter → Downloads

Quelltext

<?php

/**
 * Postfix Quota Policy Daemon
 * based on PHP
 *
 * @version 1.0 beta
 * @copyright 2007 Maximilian Thoma nospam@thoma.cc
 *
 * Anleitung:
 * master.cf:
 * 127.0.0.1:9990  inet  n       n       n       -       0       spawn  user=root argv=/opt/bin/php -f /etc/postfix/deamon/pqpd.php
 *
 * main.cf:
 * smtpd_recipient_restrictions = ... , check_policy_service inet:127.0.0.1:9990, ...
 * smtpd_end_of_data_restrictions = ..., check_policy_service inet:127.0.0.1:9990, ...
 *
 */

////////////////////////////////////////////////////////////////////////////////
/// CONFIG
////////////////////////////////////////////////////////////////////////////////
$db_host="localhost"; // DB Host
$db_user="mailadmin"; // DB User
$db_pass="123test123"; // DB Passwort
$db_db="mailserver"; // Database
$db_tab_box="mailbox"; // Tabelle mit den Mailboxen
$db_box_user_col="username"; // Spalte mit dem Usernamen
$db_tab_alias="aliases"; // Tabelle mit den Aliases
$db_alias_alias_col="address"; // Spalte mit dem Alias
$db_alias_goto_col="goto"; // Spalte mit dem Ziel des Alias
$db_quota_col="quota"; // Spalte mit Quota
$db_maildir_col="maildir"; // Spalte mit dem Maildir

$q_ulimited="0"; // Quota Unlimited
$path_base="/srv/mail"; // Maildir
$path_box=$path_base."/".$user_maildir; // Maildir Struktur

////////////////////////////////////////////////////////////////////////////////
/// AB HIER NICHTS MEHR ÄNDERN !!!!
////////////////////////////////////////////////////////////////////////////////

//MySQL connect
$verbindung=mysql_connect($db_host,$db_user,$db_pass);
mysql_select_db($db_db);

// STDIN
if ($fp=fopen("php://stdin","r")) {

while($stop!=1){
        $line = fgets($fp,512);
        $teile = explode("=", $line);
        $stdin[$teile[0]]=$teile[1];
        // Entfernen von Leerzeilen und Zeilenumbrüchen
        $stdin[$teile[0]] = preg_replace("/\r|\n/s", "", $stdin[$teile[0]]);
        if($line=="\n"){$stop=1;}
     }
fclose($fp);
}

////////////////////////////////////////////////////////////////////////////////

// User Zerlegen
$recipient_expl=explode('@',$stdin[recipient]);
$user=$recipient_expl[0];
$domain=$recipient_expl[1];
// User Mail setzen
$email=$stdin[recipient];

// Check ob das eine Mailbox ist oder ein alias
$sql="SELECT * FROM ".$db_tab_box." WHERE ".$db_box_user_col."='".$email."'";
$ergebnis=mysql_num_rows(mysql_query($sql));

// Wenn Ergebnis gleich null dann soll er mal kucken ob das evtl. ein alias ist
// wenn nicht folgt noch der catchall check
if($ergebnis==0){
$sql2="SELECT * FROM ".$db_tab_alias." LEFT JOIN ".$db_tab_box." ON ".$db_tab_alias.".".$db_alias_goto_col."=".$db_tab_box.".".$db_box_user_col." WHERE ".$db_alias_alias_col."='".$email."'";
$ergebnis2=mysql_num_rows(mysql_query($sql2));

	// Check ob Catchall
	if($ergebnis2==0){
	$sql3="SELECT * FROM ".$db_tab_alias." LEFT JOIN ".$db_tab_box." ON ".$db_tab_alias.".".$db_alias_goto_col."=".$db_tab_box.".".$db_box_user_col." WHERE ".$db_alias_alias_col."='@".$domain."'";
	$ergebnis3=mysql_num_rows(mysql_query($sql3));

		if($ergebnis3==0){
		// User existiert nicht lokal, wir lassen die Mail passieren
		$entscheidung="pass";

		} else {
		// Emailadresse gehört zu einem Catchall
			$query_catchall=mysql_query($sql3);
			while($row_catchall=mysql_fetch_object($query_catchall)){
				$user_quota=$row_catchall->$db_quota_col;
				$user_maildir=$row_catchall->$db_maildir_col;
			}
		}

	} else {
	// Ja es ist ein Alias mit Postfach
	$query_alias=mysql_query($sql2);
			while($row_alias=mysql_fetch_object($query_alias)){
				$user_quota=$row_alias->$db_quota_col;
				$user_maildir=$row_alias->$db_maildir_col;
			}
	}
} else {
// Ja es ist ein Postfach
$query_box=mysql_query($sql);
			while($row_box=mysql_fetch_object($query_box)){
				$user_quota=$row_box->$db_quota_col;
				$user_maildir=$row_box->$db_maildir_col;
			}
}

////////////////////////////////////////////////////////////////////////////////

if($entscheidung!="pass"){

// Get Disc Quota
$disk_quota_string=exec("du -s $path_box");
$disk_quota_expl=explode(" ",$disk_quota_string);
$disk_quota_sum=$disk_quota_expl[0];

// Der ultimative Quota check !!!
	if($user_quota>=$disk_quota_sum OR $q_ulimited==$user_quota){
	// Der User hat entweder Quota unlimited oder noch genügend Platz also immer rein damit
	$action="DUNNO";
	} else {
		// Der User hat keinen Platz mehr und darf nichts mehr speichern
		$action="defer_if_permit User Quotalimit exceeded. Please try again later.";
		}
	} else {
	// Der User scheint kein Postfach oder Alias oder Catchall zu haben und ist wahrscheinlich extern deshalb pass
	$action="DUNNO";
	}

////////////////////////////////////////////////////////////////////////////////
//STD OUT
////////////////////////////////////////////////////////////////////////////////
if(isset($action)){
$stdout = fopen('php://stdout', 'w');
fwrite($stdout,"action=$action\n\n");
fclose($stdout);
}

mysql_close($verbindung);

?>

Policyd-weight installieren (Debian Etch)

Installation

sudo apt-get install policyd-weight

Service checken

mxadm@server:/# netstat -tulpen | grep policyd-weight
tcp        0      0 127.0.0.1:12525         0.0.0.0:*               LISTEN     0          23134      7883/policyd-weight

Wenn der Service noch nicht laufen sollte dann mit

/etc/init.d/policyd-weight start

starten.

Einbinden in Postfix für bestimmte User / Domains

main.cf:

smtpd_restriction_classes = check_policyd_weight
 check_policyd_weight =
   check_policy_service inet:127.0.0.1:12525

smtpd_recipient_restrictions =
...
check_recipient_access hash:/etc/postfix/policyd_weight_users
...

/etc/postfix/policyd_weight_users:

für Domain:

example-domain.de check_policyd_weight

für User:

user@example-domain.de check_policyd_weight

postmap /etc/postfix/policyd_weight_users nicht vergessen !!!

Einbinden in Postfix für alle Domains

main.cf:

smtpd_recipient_restrictions =
...
check_policy_service inet:127.0.0.1:12525      # required
...

POP3/IMAP Proxy Perdition mit MySQL backend

Perdition ist ein POP3/IMAP Proxy (SSL fähig) der zu mehreren Backend Servern (POP3 und IMAP) sich Verbinden kann. Die Entscheidung zu welchem Server er weiterverbinden soll erfolgt durch eine Tabelle. Perdition unterstützt mehrere Tabellenformate. Ich verwende MySQL.

Installation

apt-get install perdition perdition-mysql

Konfiguration

/etc/default/perdition:

######################################################################
# /etc/sysconfig/perdition (RPM based systems)
# /etc/default/perdition   (Debian)
#
# Run time configuration parameters for perdition
######################################################################

# Run perdition
# Set to "yes" to run perdition
# Set to any other value to not run perdition
RUN_PERDITION=yes

# Command line parameters to pass to perdition when run in any mode.
# This is in addition to any mode specific flags.
# That is, it is in addtion to any command line options supplied
# by POP3_FLAGS, POP3S_FLAGS, IMAP4_FLAGS or IMAP4S_FLAGS
FLAGS=

# Run an instance of perdition in POP3 mode
# Set to "yes" to run this instance of perdition
# Set to any other valye to not run this instance of perdition
POP3=yes

#Command line parameters to pass to perdition when run in POP3 mode
POP3_FLAGS="--ssl_mode tls_listen"

# Run an instance of perdition in POP3S mode
# Set to "yes" to run this instance of perdition
# Set to any other valye to not run this instance of perdition
POP3S=yes

#Command line parameters to pass to perdition when run in POP3S mode
POP3S_FLAGS="--ssl_mode ssl_listen -p 110"

# Run an instance of perdition in IMAP4 mode
# Set to "yes" to run this instance of perdition
# Set to any other valye to not run this instance of perdition
IMAP4=yes

#Command line parameters to pass to perdition when run in IMAP4 mode
IMAP4_FLAGS="--ssl_mode tls_listen"

# Run an instance of perdition in IMAP4S mode
# Set to "yes" to run this instance of perdition
# Set to any other valye to not run this instance of perdition
IMAP4S=yes

#Command line parameters to pass to perdition when run in IMAP4S mode
IMAP4S_FLAGS="--ssl_mode ssl_listen -p 143"

/etc/perdition/perdition.conf:

connection_logging
connection_limit 1000
map_library /usr/lib/libperditiondb_mysql.so.0
map_library_opt "localhost:3306:db:table:user:password"
username_from_database
# Interner IMAP an den weitergeleitet werden soll wenn keine Weiterleitung in der DB ist
outgoing_server  127.0.0.1
# Hier das SSL Cert wenn gewünscht.
ssl_cert_file /etc/perdition/ssl_perdition.cert
ssl_key_file /etc/perdition/ssl_perdition.key
# Perdition an ein Interface binden da er sonst 0.0.0.0 versucht und auf 127.0.0.1 lauscht ja schon unser lokaler
bind_address 10.4.4.1

Datenbank

CREATE TABLE `pop3_imap_proxy` (
`user` varchar(128) NOT NULL,
`servername` varchar(255) NOT NULL,
`port` varchar(8) default NULL,
PRIMARY KEY  (`user`),
KEY `idxtblPerdition_user` (`user`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Noch ein restart …

/etc/init.d/perdition restart

Perdition log

tail -f /var/log/syslog | grep perdition

Courier POP3 / IMAP per User aktivieren / deaktivieren

Anleitung für Courier POP3/IMAP mit MySQL backend.

/etc/courier/authmysqlrc

MYSQL_PASSWORD          password1
MYSQL_CRYPT_PWFIELD     password
MYSQL_DATABASE          courier
MYSQL_GID_FIELD         '5001'
MYSQL_HOME_FIELD        '/var/mail'
MYSQL_LOGIN_FIELD       username
MYSQL_MAILDIR_FIELD     maildir
MYSQL_NAME_FIELD        name
MYSQL_OPT               0
#MYSQL_PASSWORD          postfix
MYSQL_QUOTA_FIELD      quota
MYSQL_SERVER            localhost
MYSQL_SOCKET           /var/run/mysqld/mysqld.sock
MYSQL_UID_FIELD         '5001'
MYSQL_USERNAME          dbuser
MYSQL_USER_TABLE        mailbox
MYSQL_AUXOPTIONS_FIELD  CONCAT("disableimap=",disableimap,",disablepop3=",disablepop3)

Die entscheidende Zeile:

MYSQL_AUXOPTIONS_FIELD  CONCAT("disableimap=",disableimap,",disablepop3=",disablepop3)

Datenbank anpassen

CREATE TABLE `mailbox` (
  `username` varchar(255) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  `name` varchar(255) NOT NULL default '',
  `maildir` varchar(255) NOT NULL default '',
  `quota` int(10) NOT NULL default '0',
  `domain` varchar(255) NOT NULL default '',
  `created` datetime NOT NULL default '0000-00-00 00:00:00',
  `modified` datetime NOT NULL default '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL default '1',
  `disableimap` int(1) NOT NULL default '0',
  `disablepop3` int(1) NOT NULL default '0',
  PRIMARY KEY  (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Mailboxes';

Folgende Zeilen kommen hinzu:

  `disableimap` int(1) NOT NULL default '0',
  `disablepop3` int(1) NOT NULL default '0',

Mit Feldwert 1 wird der jeweilige Dienst deaktiviert.

Spamassassin Test mit GTUBE

GTUBE bedeutet

  • Generic
  • Test for
  • Unsolicited
  • Bulk
  • Email

GTUBE ist ein String der bei Spamassassin mit ca. 1000 Punkten bewertet wird. Hiermit kann man Testen ob Spamassassin überhaupt Spam erkennt und die gewünschten Aktionen ausführt.

Um Spamassassin zu Testen müssen Sie einfach den String per Mail (von einem externen Konto) an den Zielserver/adresse schicken.

GTUBE String

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Auszug aus /var/log/mail.log:

Jul 25 14:20:23 mailserver amavis[31947]: (31947-07) Blocked SPAM, [xx.xx.xx.xx] [xx.xx.xx.xx] <test@example.com> -> <ziel@example.com>, Message-ID: <2016475223@example.com>, Hits: 1000.568, 386 ms

Weitere Informationen auf Wikipedia

Amavisd-new/Clamav Test mit EICAR

Die EICAR-Testdatei (auch „Eicar test file“ genannt) ist ein am European Institute for Computer Antivirus Research entwickeltes Testmuster, mit dessen Hilfe die Funktionen von Antivirenprogrammen getestet werden können. Dabei handelt es sich um eine reine Textdatei mit 68 ASCII-Zeichen und einer daraus resultierenden Dateigröße von 68 Byte (bzw. 70 Byte), welche somit in jeden beliebigen Texteditor eingegeben werden kann. Die Datei ist gutartig und richtet keinerlei Schaden an, sollte aber dennoch von allen Virenscannern als Virus erkannt und angezeigt werden. Damit lässt sich beispielsweise auch testen, ob ein Virenscanner ein Archiv korrekt lesen kann.

Es gibt verschiedene Anbieter die diesen Testvirus und andere per Mail zuschicken.

Quelle: Wikipedia EICAR-Testdatei

SSH mit Private/Public Key Authentifizierung

Einfache und effektive Methode um SSH sicherer zu machen. Anleitung für alle Linux Distributionen

SSH ermöglicht es, sich von einem entfernten Computer aus an einer Shell auf dem Zielcomputer anzumelden und daran so zu arbeiten, als sitze man direkt vor dem Zielsystem. Dabei werden im Gegensatz zu anderen ähnlichen Diensten wie Telnet alle Daten verschlüsselt übertragen.

Schritt 1: Erstellen eines Schlüsselpaars

  blade:/root # ssh-keygen -t rsa
  Generating public/private rsa key pair.
  Enter file in which to save the key (/root/.ssh/id_rsa):

Das Programm fragt nach einem Speicherort für den Public- und den Privatekey. Dieser wird default im Homeverzeichnis unter .ssh/id_rsa gespeichert. Das ist okay. Jetzt wird nach einem Passwort für den privaten Schlüssel gefragt. Hier ein sicheres Passwort eingeben und wiederholen.

Schritt 2: Verteilen des Publickeys

  blade:/root # ssh-copy-id -i ./.ssh/id_rsa.pub root@192.168.4.204
  17
  Password:

Nach dem Parameter i wird der Speicherort des Publickeys angegeben. Danach folgt der User und das Zielsystem auf dem der Publickey installiert werden soll. Dabei wird der Publickey in der Datei authorized_keys im .ssh Verzeichnis des angegebenen Users gespeichert.

    Now try logging into the machine, with "ssh ' root@192.168.4.204 '", and check in:

      .ssh/authorized_keys

    to make sure we haven't added extra keys that you weren't expecting.

    blade:/root #

Schritt 3: Testen des Public/Privatekeys

  ssh root@192.168.4.204

Es wird nach dem Passwort des privaten Schlüssels gefragt. Sollte der Login erfolgreich sein kann man die Authentifizierung des SSH Servers mit Passwörtern abschalten, d. h. das nur noch Private/Public Key Anmeldungen funktionieren. Dies erhöht die Sicherheit gegen BruteForce Angriffe auf SSH.

Schritt 4: Abschalten der Passwortauthentifizierung

  nano /etc/ssh/sshd_config

Folgenden Parameter / Zeile ergänzen:

  ChallengeResponseAuthentication no

ACHTUNG !!!

Durch abschalten der ChallengeResponseAuthentication ist eine Anmeldung mit Username/Passwort nicht mehr möglich. Es wird dringend empfohlen die Private/Public Key Authentifizierung mehrmals zu testen.