Postfix + postgresql + SMTP auth + postfix.admin + reszta ...



o czym jest ten dokument.

Niniejszy dokument opisuje instalację MTA Postfix (zamiast sendmaila) z takimi dodatkami jak:
- dane userów w bazie danych (postgresql, ale są też opisy pod mysqla)
- SMTP AUTH (poprzez cyrus-sasl)
- zarządzanie postfixem poprzez www (Postfix.Admin)
- odbiór poczty przez POP3 (courier-imap)
- ochrona antywirusowa (clamav) i antyspamowa (spamassasin)

Wszystko to było testowane na Slackware 10.1, postfix-2.2.5, cyrus-sasl-2.1.21, postfixadmin-2.1.0 . Sądzę jednak że może artykuł może być pomocny również przy innych dystrybucjach i wersjach oprogramowania.

po co?

Podstawowe pytanie: w czym postfix jest lepszy od innych MTA ? Wg. mnie sendmail odpada z powodu braku obsługi wirtualnych userów w SQL (userzy w bazie to porządek na serwerze + łatwa obsługa poprzez www). Qmail jest świetny ale chora licencja powoduje że zmuszeni jesteśmy do instalowania mnóstwa pathy i dodatków. Co do Exima się nie wypowiadam bo nie znam.

Podsumowując: na bazie postfixa można stworzyć wydajny i łatwo zarządzalny system pocztowy. I o tym właśnie poniżej.

postgresql

Postgres musi być zainstalowany a ścieżka /usr/local/pgsql/lib dodana do pliku /etc/ld.so.conf. Jeśli nie ma to:

echo "/usr/local/pgsql/lib" >> /etc/ld.so.conf
ldconfig

następnie tworzymy użytkownika bazy i tabele:

su postgres
/usr/local/pgsql/bin/createuser -ADP postfix
/usr/local/pgsql/bin/createdb -O postfix -E LATIN2 postfix
/usr/local/pgsql/bin/psql -U postfix -d postfix -f postfix_pgsql.sql

zawartość pliku postfix_pgsql.sql:

  -- tworzy bazy dla postfixa i Postfix.Admina
  -- sam postfix potrzebuje jedynie tabel alias, domain i mailbox
  --
  --
  -- Table structure for table admin
  --
  CREATE TABLE "admin" (
   "username" character varying(255) NOT NULL default '',
   "password" character varying(255) NOT NULL default '',
   "created" timestamp with time zone default now(),
   "modified" timestamp with time zone default now(),
   "active" boolean NOT NULL default true,
   Constraint "admin_key" Primary Key ("username")
  );
  COMMENT ON TABLE admin IS 'Postfix.Admin';
  --
  -- Table structure for table alias
  --
  CREATE TABLE alias (
   address character varying(255) NOT NULL default '',
   goto text NOT NULL,
   domain character varying(255) NOT NULL default '',
   created timestamp with time zone default now(),
   modified timestamp with time zone default now(),
   active boolean NOT NULL default true,
   -- PRIMARY KEY ("address"),
   -- KEY address ("address"),
   Constraint "alias_key" Primary Key ("address")
  );
  COMMENT ON TABLE alias IS 'Postfix.Admin';
  --
  -- Table structure for table domain
  --
  CREATE TABLE domain (
   domain character varying(255) NOT NULL default '',
   description character varying(255) NOT NULL default '',
   aliases integer NOT NULL default 0,
   mailboxes integer NOT NULL default 0,
   maxquota integer NOT NULL default 0,
   transport character varying(255) default NULL,
   backupmx smallint NOT NULL default 0,
   created timestamp with time zone default now(),
   modified timestamp with time zone default now(),
   active boolean NOT NULL default true,
   -- PRIMARY KEY ("domain"),
   -- KEY domain ("domain"),
   Constraint "domain_key" Primary Key ("domain")
  );
  COMMENT ON TABLE domain IS 'Postfix.Admin';
  --
  -- Table structure for table domain_admins
  --
  CREATE TABLE domain_admins (
   username character varying(255) NOT NULL default '',
   domain character varying(255) NOT NULL default '',
   created timestamp with time zone default now(),
   active smallint NOT NULL default 1
   -- KEY username ("username")
  );
  COMMENT ON TABLE domain_admins IS 'Postfix.Admin';
  --
  -- Table structure for table log
  --
  CREATE TABLE log (
   timestamp timestamp with time zone default now(),
   username character varying(255) NOT NULL default '',
   domain character varying(255) NOT NULL default '',
   action character varying(255) NOT NULL default '',
   data character varying(255) NOT NULL default ''
   -- KEY timestamp ("timestamp")
  );
  COMMENT ON TABLE log IS 'Postfix.Admin';
  --
  -- Table structure for table mailbox
  --
  CREATE TABLE mailbox (
   username character varying(255) NOT NULL default '',
   password character varying(255) NOT NULL default '',
   name character varying(255) NOT NULL default '',
   maildir character varying(255) NOT NULL default '',
   quota integer NOT NULL default 0,
   domain character varying(255) NOT NULL default '',
   created timestamp with time zone default now(),
   modified timestamp with time zone default now(),
   active smallint NOT NULL default 1,
   transport character varying(9) NOT NULL DEFAULT 'virtual' ,
   -- PRIMARY KEY ("username"),
   -- KEY username ("username"),
   Constraint "mailbox_key" Primary Key ("username")
  );
  COMMENT ON TABLE mailbox IS 'Postfix.Admin + pole transport';
  --
  -- Table structure for table vacation
  --
  CREATE TABLE vacation (
   email character varying(255) NOT NULL default '',
   subject character varying(255) NOT NULL default '',
   body text NOT NULL,
   cache text NOT NULL,
   domain character varying(255) NOT NULL default '',
   created timestamp with time zone default now(),
   active smallint NOT NULL default 1,
   -- PRIMARY KEY ("email"),
   -- KEY email ("email")
   Constraint "vacation_key" Primary Key ("email")
  );
  COMMENT ON TABLE vacation IS 'Postfix.Admin';
  

cyrus-sasl

Cyrus-sasl odpowiada za sprawdzanie hasła przy wysyłaniu poczty - chyba najskuteczniejsza metoda by nie stać się open relayem. Hasła przechowywane są jawnie w bazie. Mi to zdecydowanie nie odpowiada, więc oprócz źródeł ściągam patcha szyfrującego hasła w md5 (wtedy pasują te z /etc/shadow - wystarczy je tylko przekopiować).

wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-sasl-2.1.21.tar.gz
wget http://frost.ath.cx/software/cyrus-sasl-patches/dist/2.1.19/cyrus-sasl-2.1.19-checkpw.c.patch

następnie rozpakowujemy źródła, kopiujemy do nich patcha i aplikujemy go komendą

patch -p0 < cyrus-sasl-2.1.19-checkpw.c.patch

kompilujemy i instalujemy:

./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-login --enable-plain --enable-sql --with-gnu-ld --with-saslauthd --with-pgsql=/usr/local/pgsql --with-openssl=/usr
make
make install

tworzymy plik /usr/lib/sasl2/smtpd.conf, wpisujemy tam:

  pwcheck_method: auxprop
  auxprop_plugin: sql
  allowanonymouslogin: no
  allowplaintext: yes
  mech_list: PLAIN LOGIN
  srp_mda: md5

  srvtab: /dev/null
  opiekeys: /dev/null

  password_format: crypt

  sql_user: postfix
  sql_passwd: haslodobazy
  sql_hostnames: 127.0.0.1
  sql_database: postfix
  sql_statement:select password from mailbox where username='%u@%r'
  

ustawiamy odpowiednie prawa dost. do pliku i tworzymy katalog tymczasowy:

chown root.root /usr/lib/sasl2/smtpd.conf
chmod 640 /usr/lib/sasl2/smtpd.conf
mkdir -p /var/state/saslauthd

uruchamiać demona poniższą komendą. Nie zapomnij dodać tego do skryptów startowych systemu.

/usr/sbin/saslauthd -a shadow

postfix

tworzenie usera - zapamiętaj UID i GID

groupadd -g 800 postfix
useradd -g 800 -u 800 postfix
groupadd postdrop

ściągamy żródła postfixa - linki są na http://postfix.org

wget ftp://ftp.cvut.cz/postfix/official/postfix-2.2.5.tar.gz

ściągamy z http://web.onda.com.br/nadal patcha do quoty, potem kopiujemy go do katalogu ze źródłami postfixa, rozgzipowujemy i aplikujemy

patch -p1 < postfix-2.2.5-vda.patch

kompilujemy i instalujemy postfixa

make makefiles AUXLIBS="-lssl -lcrypto -L/usr/lib -lsasl2 -L/usr/local/pgsql/lib -lpq" \
CCARGS="-DUSE_TLS -DUSE_SASL_AUTH -I/usr/include/sasl -DHAS_PGSQL -I/usr/local/pgsql/include" \
OPT="-O2" DEBUG=""
make
make install

postfix konfiguracja

w pliku /etc/postfix/main.cf ustawiam

  myhostname = host.mojadomena.pl
  mydomain = mojadomena.pl

  home_mailbox = Maildir/

  virtual_uid_maps = static:800
  virtual_gid_maps = static:800
  virtual_minimum_uid = 800
  virtual_mailbox_base = /var/spool/mail/virtual
  virtual_alias_maps = pgsql:/etc/postfix/pgsql_virtual_alias_maps.cf
  virtual_alias_domains = $virtual_alias_maps
  virtual_mailbox_domains = pgsql:/etc/postfix/pgsql_virtual_domains_maps.cf
  virtual_mailbox_maps = pgsql:/etc/postfix/pgsql_virtual_mailbox_maps.cf
  virtual_mailbox_limit = 512000000
  virtual_mailbox_limit_maps = pgsql:/etc/postfix/pgsql_virtual_limit_maps.cf
  virtual_mailbox_limit_inbox = yes
  virtual_mailbox_limit_override = yes
  #opcja odpowiadająca za zwroty przy pełnej skrzynce:
  virtual_overquota_bounce = yes
  virtual_create_maildirsize = yes
  transport_maps = pgsql:/etc/postfix/pgsql_transport.cf
  

tworzę następujące pliki:

  #/etc/postfix/pgsql_virtual_alias_maps.cf
  user = postfix
  password = haslodobazy
  hosts = localhost
  dbname = postfix
  table = alias
  select_field = goto
  where_field = address
  
  # /etc/postfix/pgsql_virtual_domains_maps.cf
  user = postfix
  password = haslodobazy
  hosts = localhost
  dbname = postfix
  table = domain
  select_field = description
  where_field = domain
  
  # /etc/postfix/pgsql_virtual_mailbox_maps.cf
  user = postfix
  password = haslodobazy
  hosts = localhost
  dbname = postfix
  table = mailbox
  select_field = maildir
  where_field = username
  
  # /etc/postfix/pgsql_virtual_limit_maps.cf
  user = postfix
  password = haslodobazy
  hosts = localhost
  dbname = postfix
  table = mailbox
  select_field = quota
  where_field = username
  
  # /etc/postfix/pgsql_transport.cf
  user = postfix
  password = haslodobazy
  hosts = localhost
  dbname = postfix
  table = mailbox
  select_field = transport
  where_field = username
  

ustawiamy odpowiednie uprawnienia

chmod 640 /etc/postfix/*.cf
chown root /etc/postfix/*.cf
chgrp postfix /etc/postfix/*.cf

i uruchamiamy postfixa

postfix start

trzeba oczywiście dodać skrypt startowy, choćby taki:

  #!/bin/sh
  #
  # Start the Postfix server
  #
  case "$1" in
    'start')
      /usr/sbin/postfix start ;;
    'stop')
      /usr/sbin/postfix stop ;;
    'restart')
      /usr/sbin/postfix reload ;;
    *)
      echo "usage $0 start|stop|restart" ;;
  esac
  

postfix.admin

Postfix.Admin to zestaw skryptów oferujący pracę na trzech poziomach:
- dla admina: dodawanie domen, kont, wyznaczanie adminów domen itp.
- dla adminów domen zarządzanie: kontami w domenie (dodawanie, kasowanie, itp.)
- dla userów: zmiana hasła, ustawianie przekierowań

pobieramy postfix.admina ze strony http://high5.net/postfixadmin
rozpakowujemy, udostępniamy poprzez apacza i edytujemy plik config.ini.php.
ja ustawiam w nim opcje:

  $CONF['domain_path'] = 'YES';
  $CONF['domain_in_mailbox'] = 'NO';
  $CONF['quota'] = 'YES';
  

następnie uruchamiamy go poprzez www i jeśli setup pokazał OK to usuwamy pliczek setup.php
teraz pod adresami:
http://mojadomenka.pl/katalog-postfixadmina/admin - jest panel admina
http://mojadomenka.pl/katalog-postfixadmina/ - jest panel adminów domen
http://mojadomenka.pl/katalog-postfixadmina/users - jest panel userów

courier-authlib

Courier-authlib to biblioteki odpowiadające za autoryzację pop3.
Ściągamy źródłą ze strony http://www.courier-mta.org/authlib, rozpakowujemy i NIE JAKO ROOT wykonujemy:

./configure --with-authpgsql --with-pgsql-libs=/usr/local/pgsql/lib --with-pgsql-includes=/usr/local/pgsql/include/
make

i już jako root:

make install

teraz czas na konfigurację

cd /usr/local/etc/authlib
mv authdaemonrc.dist authdaemonrc
mv authpgsqlrc.dist authpgsqlrc

authdaemonrc jest w porządku, natomiast w authpgsqlrc ustawiamy:

  PGSQL_HOST              localhost
  PGSQL_PORT              5432
  PGSQL_USERNAME          postfix
  PGSQL_PASSWORD          haslodobazy

  PGSQL_DATABASE          postfix
  PGSQL_USER_TABLE        mailbox
  PGSQL_CRYPT_PWFIELD     password
  # PGSQL_CLEAR_PWFIELD   password
  # DEFAULT_DOMAIN        example.com

  PGSQL_UID_FIELD         800
  PGSQL_GID_FIELD         800
  PGSQL_LOGIN_FIELD       username
  PGSQL_HOME_FIELD        '/var/spool/mail/virtual/'
  PGSQL_NAME_FIELD        name
  PGSQL_MAILDIR_FIELD     maildir
  

courier-imap

Curier-imapa ściągamy z http://www.courier-mta.org/imap. Rozpakowujemy i też NIE JAKO ROOT kompilujemy:

./configure --without-ipv6 --enable-unicode=iso-8859-1,utf-8,iso-8859-2 --disable-sieve
make

i już jako root:

make install
cd /usr/lib/courier-imap/etc
mv pop3d.dist pop3d

tworzymy jeszcze skrypt startowy, np. taki jak poniżej:

  #!/bin/sh
  #
  # Start the courier-imap
  #

  case "$1" in
    'start')
      /usr/local/libexec/courier-authlib/authdaemond &
      /usr/lib/courier-imap/libexec/pop3d.rc start
      ;;
    'stop')
      killall authdaemond
      /usr/lib/courier-imap/libexec/pop3d.rc stop
      ;;
    *)
      echo "usage $0 start|stop|restart" ;;
  esac
  

clamav

Skaner antywirusowy ClamAV pobieramy z http://download.sourceforge.net/clamav. Dodajemy użytkownika i grupę, następnie kompilujemy i instalujemy:

groupadd clamav
useradd -g clamav -s /bin/false -c "clamav user" clamav
./configure
make
make install

edytujemy plik konfiguracyjny /usr/local/etc/clamav.conf ustawiając takie opcje jak poniżej (reszta bez zmian)

#Example
LogFile /var/log/clamd.log
LogVerbose
PidFile /var/amavis/clamd.pid
LocalSocket /var/amavis/clamd.sock
User amavis    #(User amavis a nie clamav żeby uniknąć problemów na styku amavis-clamd.)
  

można już uruchomić demona i ustawić prawa do pliku z logami

/usr/local/sbin/clamd
chown amavis /var/log/clamd.log

Jeszcze skrypt startowy:

#!/bin/sh
# Start/stop/restart clamd.

clamd_start() {
  if [ -x /usr/local/sbin/clamd ]; then
    echo "Starting clamav Daemon"
    /usr/local/sbin/clamd
  fi
}

clamd_stop() {
  killall clamd
}

clamd_restart() {
  clamd_stop
  sleep 1
  clamd_start
}

case "$1" in
  'start')
  clamd_start
  ;;
'stop')
  clamd_stop
  ;;
'restart')
  clamd_restart
  ;;
*)
  echo "usage $0 start|stop|restart"
esac

amavis-new

Amavis-new jest interfejsem pośredniczącym pomiędzy MTA (u nas postfixem) a programami do filtrowania treści (skanery antywirusowe i antyspamowe). Pobrać go można z http://www.ijs.si/software/amavisd/#download. Następnie rozpakowujemy go, wchodzimy do środka i instalujemy w nasp. sposób:

groupadd amavis
useradd -g amavis -s /bin/bash -c "amavis user" amavis
mkdir -p /var/amavis/tmp
mkdir -p /var/amavis/db
chown -R amavis.amavis /var/amavis
chmod 750 /var/amavis
cp amavisd /usr/local/sbin/
chown root /usr/local/sbin/amavisd
chmod 755 /usr/local/sbin/amavisd
cp amavisd.conf /etc/
chown root /etc/amavisd.conf
chmod 644 /etc/amavisd.conf
mkdir /var/virusmails
chown amavis.amavis /var/virusmails
chmod 750 /var/virusmail

Amavis jest programem perlowym, który do poprawnego działania potrzebuje szeregu modułów (szczegóły w INSTALL). Najprostszym sposobem ich instalacji jest skorzystanei z modułu CPAN, który pobierze i zainstaluje moduły bezpośrednio z archiwum CPAN. Spokojnie - mimo pokaźnej listy nie zaśmieci to nam systemu, wszystko instaluje się w drzewku perla. Wystarczy wykonać poniższe komendy i potem klikać na domyślne odpowiedzi.

perl -MCPAN -e shell

wszystkie opcje domyślnie (enter) dopóki ne spyta o kraj z mirrorem. Wybieramy Europę i Polskę a potem wg. uznania (ja wybieram sunsite.icm.edu.pl) potem znowu entery dopóki nie dostaniemy linni poleceń cpan (cpan> ), wtedy dajemy komendy:

install Archive::Tar
install Archive::Zip
install Compress::Zlib
install Convert::TNEF
install install Convert::UUlib
install MIME::Base64
install MIME::Decoder
install Net::Server
install Unix::Syslog
install BerkeleyDB
install Digest::MD5
install Time::HiRes
install Mail::SpamAssassin
quit

kolejny krok to edycja /etc/amavisd.conf . Ja ustawnaim w nim:

  $mydomain = 'moja.domena.pl';
  $daemon_user  = 'amavis';
  $daemon_group = 'amavis';
  #$DO_SYSLOG = 1;
  $LOGFILE = "/var/log/amavis.log";
  $virus_admin            = undef;
  $virus_quarantine_to    = undef;
  $spam_quarantine_to     = '/var/virusmails';
  

oraz odhashowuję opcje dla "Clam Antivirus-clamd" i "Clam Antivirus - clamscan" (w pliku jest to jasno zaznaczone), a dla clamd poprawiam

#\&ask_daemon, ["CONTSCAN {}\n", '/var/amavis/clamd'],
\&ask_daemon, ["CONTSCAN {}\n", '/var/amavis/clamd.sock'],
  

teraz można uruchomić amavisa (/usr/local/sbin/amavisd), sprawdzić co mamy w logach i utworzyć skrypty startowe

#!/bin/sh
# Start the Amavis
#

amavis_start() {
  # Start daemons.
  rm -fr /var/amavis/amavis*.sock
  echo "Starting amavis daemon "
  /usr/local/sbin/amavisd
}

amavis_stop() {
  # Stop daemons.
  echo "Shutting down amavis daemon "
  killall amavisd
  rm -fr /var/amavis/amavis*.sock
}

amavis_restart() {
  amavis_stop
  sleep 2
  amavis_start
}

case "$1" in
  start)
    amavis_start
    ;;
  stop)
    amavis_stop
    ;;
  restart|reload)
    amavis_restart
    ;;
  *)
    echo "Usage: amavis {start|stop|restart}"
esac
  

Przystosowujemy postfixa do współpracy z amavisem.
Do /etc/postfix/main.cf dodajemy:

# AMaViS
content_filter=smtp-amavis:127.0.0.1:10024
  

zaś do /etc/postfix/master.cf:

smtp-amavis     unix    -       -       y       -       2       smtp
  -o smtp_data_done_timeout=1200
  -o disable_dns_lookups=yes
127.0.0.1:10025 inet    n       -       n       -       -       smtpd
  -o content_filter=
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_client_restrictions=
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks=127.0.0.0/8
  -o strict_rfc821_envelopes=yes
  -o smtpd_error_sleep_time=0
  -o smtpd_soft_error_limit=1001
  -o smtpd_hard_error_limit=1000
  

restartujemy postfixa i to powinno być wszystko

postfix - zarządzanie

przede wszystkim postfix.admin

postsuper - zarządzanie kolejką

migracja mailbox - maildir

FIX ME

podsumowanie

Mam nadzieję że powyższe dziełko komuś się przyda. Przedstawione konfiguracje u mnie działają, ale nie daję gwarancji że będą u Ciebie. W razie problemów sprawdź logi, a potem google. Jeśli to nic nie da to możesz do mnie napisać, ale raczej nie licz na odpowiedź.

Autor: Grzegorz Jemielity     ©2005     ver: 2005-12-12     lastmod: 2007-01-04

Prawa autorskie jak w GNU GPL: możesz powyższy dokument rozpowszechniać, kopiować i modyfikować, ale podaj link do oryginału (http://hip.ipadmin.info/index.php?d=1&co=postfix).

email
nazwa.pl