Postfix konfigurace

1. Požadavky

    Poznámka: Pokud nebude instalovat Postfixadmin, pak musíte vytvořit databázi a tabulky ručně! (viz. Příloha 2)

2. Odkazy

3. Instalace Postfix

Vytvořte nový jail (s názvem např. mail) a připojte k němu ZFS svazek, na který se budou ukládat příchozí e-maily. V návodu připojujeme svazek jako '/mnt/mail' uvnitř jail.

Připojte se pomocí SSH k FreeBSD serveru, připojte se k vytvořenému jail (jexec mail tcsh) a nainstalujte postfix pomocí portsnap. Je to z důvodu nutnosti konfigurace podpory PostgreSQL, která není nastavena v rámci pkg balíčku. Až bude postfix sestaven a nainstalován, odpovězte 'yes' na otázku 'Would you like to activate Postfix in /etc/mail/mailer.conf [n]?'

pkg install perl5 pcre postgresql94-client
portsnap fetch
portsnap extract
cd /usr/ports/mail/postfix/
make config
# při konfiguraci postfix nastavte:
# set PGSQL=on: PostgreSQL maps (uses DEFAULT_PGSQL_VER)
# set TLS=on: SSL and TLS support
# set DOVECOT2=on: Dovecot 2.x SASL authentication method
# set VDA=on: VDA (Virtual Delivery Agent 32Bit)
#
# při konfiguraci dovecot2 nastavte:
# set PGSQL=on: PostgreSQL maps (uses DEFAULT_PGSQL_VER)
# set SSL=on: SSL protocol support
make install clean
pkg install dovecot-pigeonhole

Automatické spuštění postfix serveru a vypnutí sendmail serveru se provede aktualizací souboru '/etc/rc.conf' s těmito parametry.

postfix_enable="YES"

sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

Vypnutí automatické denní údržby nastavené pro sendmail se provede úpravou souboru '/etc/periodic.conf'. Pokud soubor neexistuje, tak jej vytvořte a vložte následující hodnoty.

cat << EOF >> /etc/periodic.conf
daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"
EOF

4. Konfigurace Postfix

Vytvořte a zabezpečte SMTP SSL certifikáty pro postfix (nebo použijte existující).

mkdir -p /etc/ssl/postfix
cd /etc/ssl/postfix
openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 3650
chmod 640 /etc/ssl/postfix/*
chgrp -R postfix /etc/ssl/postfix

Následně upravte soubor '/usr/local/etc/postfix/main.cf' s parametry uvedenými níže:

...
# SOFT BOUNCE
#
# The soft_bounce parameter provides a limited safety net for
# testing.  When soft_bounce is enabled, mail will remain queued that
# would otherwise bounce. This parameter disables locally-generated
# bounces, and prevents the SMTP server from rejecting mail permanently
# (by changing 5xx replies into 4xx replies). However, soft_bounce
# is no cure for address rewriting mistakes or mail routing mistakes.

smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_hostname,
  reject_non_fqdn_sender,
  reject_non_fqdn_recipient,
  reject_unauth_destination,
  reject_unauth_pipelining,
  reject_invalid_hostname,
  reject_rbl_client bl.spamcop.net

smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks

virtual_mailbox_base = /mnt/mail
virtual_mailbox_maps = pgsql:/usr/local/etc/postfix/pgsql_virtual_mailbox_maps.cf
virtual_mailbox_domains = pgsql:/usr/local/etc/postfix/pgsql_virtual_mailbox_domains.cf
virtual_alias_maps = pgsql:/usr/local/etc/postfix/pgsql_virtual_alias_maps.cf
local_recipient_maps = $virtual_mailbox_maps $virtual_alias_maps
relay_domains = pgsql:/usr/local/etc/postfix/pgsql_relay_domains.cf

# use static uid:gid, dynamic can caused permission related problems
virtual_uid_maps = static:26
virtual_gid_maps = static:6

smtpd_delay_reject = yes
smtpd_helo_required = yes

mailbox_command = /usr/lib/dovecot/deliver-lda -f "$SENDER" -a "$RECIPIENT"
virtual_transport = dovecot
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes

smtp_use_tls = yes
smtp_tls_note_starttls_offer = yes

smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/ssl/postfix/smtpd.pem
smtpd_tls_cert_file = /etc/ssl/postfix/smtpd.pem
smtpd_tls_CAfile = /etc/ssl/postfix/smtpd.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s

tls_random_source = dev:/dev/urandom

...
myhostname = mail.example.com
...
mydomain = example.com
...
myorign = $mydomain
...

V souboru '/usr/local/etc/postfix/master.cf' zrušte označení 'komentář' u následujících řádků. 'Message_size_limit' změní maximální velikost e-malové zprávy z 10M (výchoyí) na 25M.

smtps     inet  n       -       n       -       -       smtpd
    -o smtpd_tls_wrappermode=yes
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_client_restrictions=permit_sasl_authenticated,reject
    -o message_size_limit=26214400

dovecot    unix -        n       n       -       -       pipe
  flags=DRhu user=mailnull:mail argv=/usr/local/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -m ${extension}

Nyní vytvořte soubory s SQL dotazy do databáze uživatelů a MX domén. V proměnné hosts použijte IP adresu, FQDN nebo cestu k PostgreSQL soketu.

cat << EOF > /usr/local/etc/postfix/pgsql_relay_domains.cf
user = postfix
password = postfix_password
hosts = /tmp
dbname = mail
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = true
EOF
cat << EOF > /usr/local/etc/postfix/pgsql_virtual_alias_maps.cf
user = postfix
password = postfix_password
hosts = /tmp
dbname = mail
query = SELECT goto FROM alias WHERE address='%s' AND active = true
EOF
cat << EOF > /usr/local/etc/postfix/pgsql_virtual_mailbox_domains.cf
user = postfix
password = postfix_password
hosts = /tmp
dbname = mail
#query = SELECT domain FROM mailbox WHERE domain = '%s' AND active = true
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = false and active = true
EOF
cat << EOF > /usr/local/etc/postfix/pgsql_virtual_mailbox_limit_maps.cf
user = postfix
password = postfix_password
hosts = /tmp
dbname = mail
query = SELECT quota FROM mailbox WHERE username = '%u' AND domain = '%d' AND active = true
EOF
cat << EOF > /usr/local/etc/postfix/pgsql_virtual_mailbox_maps.cf
user = postfix
password = postfix_password
hosts = /tmp
dbname = mail
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true
EOF

Nakonec zabezpečte nově vytvořené sobory.

chmod 640 /usr/local/etc/postfix/pgsql_*
chgrp postfix /usr/local/etc/postfix/pgsql_*

Pokud nepřipojíte ZFS svazek (zmíněný v bodu 3), vytvořte adresář pro ukládání e-malových zpráv. Název adresáře je definován v souboru '/usr/local/etc/postfix/main.cf' v proměnné 'virtual_mailbox_base = /mnt/mail'.

mkdir -p /mnt/mail
chown mailnull:mail /mnt/mail

5. Spuštění a kotrola postfix serveru

Spuštění postfix serveru

service postfix start

Nyní můžete vyzkoušet SSL spojení pomocí příkazu:

openssl s_client -connect smtp.example.com:smtps

SMTP spojení se může otestovat pomocí příkazu:

echo test | mail postmaster@example.com

Appendix 1. Konfigurace MX DNS záznamů

Pro korektní odesílání a příjem e-malových zpráv je potřeba správně nastavit DNS záznamy vašeho poštovního serveru. Správně nastavené DNS záznamy (především PTR záznam) jsou nutné pro doménu a doménové jméno vašeho poštovního serveru.

DNS záznamy pro doménu a doménové jméno vašeho poštovního serveru ('myhostname = mail.example.com') mohou být v následujícím tvaru:

MX  10 mail.example.com.
mail.example.com. IN A 012.345.678.9

DNS PTR záznam (in-addr.arpa) může být:

9.678.345.012 IN PTR mail.example.com.
  • Poznámka: Bez správného DNS PTR záznamu nebudete moci odesílat e-mailové zprávy na většinu poštovních serverů (např. Gmail)!

Pro test nastavení vašich DNS záznamů použijte tyto příkazy:

dig example.com MX
dig mail.example.com ANY
dig -x ip_adresa_mail.example.com

Příloha 2. PostgreSQL databáze a tabulky

Přihlaste k PostgreSQL serveru a pro vytoření postfix uživatele, databáze a tabulek použijte následující příkazy:

su pgsql
createuser --pwprompt --encrypted --no-createrole --no-createdb postfix
createdb --encoding=UTF8 --owner=postfix mail
psql mail
  • Poznámka: Nezapomeňte nastavit autentizační soubor '/mnt/sql/pgsql/data/pg_hba.conf' pro uživatele 'postfix' a znovu načíst konfiguraci PostgreSQL.

Po připojení k databázi 'mail' povolte šifrovací modul:

-- enable crypto module for crypted passwords
CREATE EXTENSION pgcrypto;

Vytvořte tabulku alias:

-- Table: alias
-- DROP TABLE alias;
CREATE TABLE alias
(
  address character varying(255) NOT NULL,
  goto text NOT NULL,
  domain character varying(255) NOT NULL,
  created timestamp with time zone DEFAULT now(),
  modified timestamp with time zone DEFAULT now(),
  active boolean NOT NULL DEFAULT true,
  CONSTRAINT alias_key PRIMARY KEY (address),
  CONSTRAINT alias_domain_fkey FOREIGN KEY (domain)
      REFERENCES domain (domain) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);

ALTER TABLE alias OWNER TO postfix;
GRANT ALL ON TABLE alias TO postfix;

-- Index: alias_address_active
-- DROP INDEX alias_address_active;
CREATE INDEX alias_address_active
  ON alias
  USING btree
  (address COLLATE pg_catalog."default", active);

-- Index: alias_domain_idx
-- DROP INDEX alias_domain_idx;
CREATE INDEX alias_domain_idx
  ON alias
  USING btree
  (domain COLLATE pg_catalog."default");

Vytvořte tabulku domain:

-- Table: domain
-- DROP TABLE domain;
CREATE TABLE domain
(
  domain character varying(255) NOT NULL,
  description character varying(255) NOT NULL DEFAULT ''::character varying,
  aliases integer NOT NULL DEFAULT 0,
  mailboxes integer NOT NULL DEFAULT 0,
  maxquota bigint NOT NULL DEFAULT 0,
  quota bigint NOT NULL DEFAULT 0,
  transport character varying(255) DEFAULT NULL::character varying,
  backupmx boolean NOT NULL DEFAULT false,
  created timestamp with time zone DEFAULT now(),
  modified timestamp with time zone DEFAULT now(),
  active boolean NOT NULL DEFAULT true,
  CONSTRAINT domain_key PRIMARY KEY (domain)
)
WITH (
  OIDS=FALSE
);

ALTER TABLE domain OWNER TO postfix;

-- Index: domain_domain_active
-- DROP INDEX domain_domain_active;
CREATE INDEX domain_domain_active
  ON domain
  USING btree
  (domain COLLATE pg_catalog."default", active);

A nakonec vytvořte tabulku mailbox:

-- Table: mailbox
-- DROP TABLE mailbox;
CREATE TABLE mailbox
(
  username character varying(255) NOT NULL,
  password character varying(255) NOT NULL DEFAULT ''::character varying,
  name character varying(255) NOT NULL DEFAULT ''::character varying,
  maildir character varying(255) NOT NULL DEFAULT ''::character varying,
  quota bigint NOT NULL DEFAULT 0,
  created timestamp with time zone DEFAULT now(),
  modified timestamp with time zone DEFAULT now(),
  active boolean NOT NULL DEFAULT true,
  domain character varying(255),
  local_part character varying(255) NOT NULL,
  CONSTRAINT mailbox_key PRIMARY KEY (username),
  CONSTRAINT mailbox_domain_fkey1 FOREIGN KEY (domain)
      REFERENCES domain (domain) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);

ALTER TABLE mailbox OWNER TO postfix;
GRANT ALL ON TABLE mailbox TO postfix;

-- Index: mailbox_domain_idx
-- DROP INDEX mailbox_domain_idx;
CREATE INDEX mailbox_domain_idx
  ON mailbox
  USING btree
  (domain COLLATE pg_catalog."default");

-- Index: mailbox_username_active
-- DROP INDEX mailbox_username_active;
CREATE INDEX mailbox_username_active
  ON mailbox
  USING btree
  (username COLLATE pg_catalog."default", active);

Když jsou všechny tabulky vytvořeny, můžete vložit doménu, uživatele a jeho aliasy:

-- create virtual domain
INSERT INTO domains VALUES ('example.com');

-- create e-mail user
# MD5-CRYPT
#INSERT INTO mailbox VALUES ('root@example.com', crypt('password', gen_salt('md5')), '', '', 0, now(), now(), true, 'example.com', 'root');
# BLF-CRYPT
INSERT INTO mailbox VALUES ('rootexample.com', crypt('password', gen_salt('bf',5)), '', '', 0, now(), now(), true, 'example.com', 'root');
# PLAIN-MD5
#INSERT INTO mailbox VALUES ('root@example.com', md5('password'), '', '', 0, now(), now(), true, 'example.com', 'root');

-- create virtual aliases
INSERT INTO alias VALUES ('postmaster@example.com', 'root@example.com', 'example.com');
INSERT INTO alias VALUES ('abuse@example.com', 'root@example.com', 'example.com');
INSERT INTO alias VALUES ('example@example.com', 'root@example.com', 'example.com');

Komentáře