Multidomain levelező szerver

Jan. 02

Üzemeljünk be egy full-extrás levelezőszervert: több domainnel, adatbázisban tárolt felhasználókkal, spamszűréssel, szerveroldali levél-szétválogatással, hitelesítéssel, webmail rendszerrel.

Tartalomjegyzék

Tanúsítvány elkészítése

A biztonságos adatkapcsolathoz először csináljunk nagy egyedi Diffie-Hellmann paramétert! Ennek az elk;szítése akár 10 percig is eltarthat.

openssl dhparam -out /etc/ssl/dhparams.pem 4096

Majd telepítsük a certbot csomagot, és készítsük el a vele a tanúsítványunkat:

apt install certbot
certbot certonly ...

Adatbázis elkészítése

A domaineket, felhasználókat és aliasokat mind egy SQL adatbázisban tároljuk. Ehhez telepítsük fel a MariaDB-t.

apt install mariadb-server

Hozzuk létre az adatbázist, készítsünk egy felhasználót akinek ebben csak keresni van jogosultsága, majd hozzuk létre a három táblát:

CREATE DATABASE mailserver;
GRANT SELECT ON mailserver.* TO 'mailuser'@'127.0.0.1' IDENTIFIED BY 'mailpassword';
FLUSH PRIVILEGES;

USE mailserver;

CREATE TABLE `virtual_domains` (
`id`  INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `virtual_aliases` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `source` (`source`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Alapvető parancsfájlok

Ha nem akarunk minden egyes alkalommal újra belemélyedni az adatbázisunkba, akkor az alapvető feladatokra érdemes létrehoznunk néhány egyszerű scriptet. Ha a leveleket sdbox vagy mdbox formátumban tárolja a dovecot, akkor a felhasználó törlésnél arra is figyelnünk kell, hogy a felhasználóhoz tartozó csatolmányok is törlődjenek.

add_domain.sh

#!/bin/bash
echo "INSERT INTO virtual_domains (name) VALUES ('$1');" | mysql mailserver

add_user.sh

#!/bin/bash
if [ $# -eq 2 ]; then
  PW="$2"
elif [ $# -eq 1 ]; then
  PW="x";PWS="xx"
  while [ "$PW" != "$PWS" ] ; do
    read -s -p "Password: " PW ; echo
    read -s -p "Verifying - Password: " PWS  ; echo
    [ "$PW" != "$PWS" ] && echo "Verify failure" >&2
  done
else
  echo "Wrong number of arguments" >&2
  exit 1
fi
DOMAIN=${1##*@}
PWENC=$(echo "$PW" | openssl passwd -6 -stdin)

echo "INSERT INTO virtual_users (domain_id,password,email) \
             SELECT id,'$PWENC','$1' FROM virtual_domains \
             WHERE name='$DOMAIN';" | mysql mailserver

add_alias.sh

#!/bin/bash
if [ $# -ne 2 ]; then
        echo "Wrong number of arguments" >&2
        exit 1
fi

DOMAIN=${1##*@}
echo "INSERT INTO virtual_aliases (domain_id,source,destination) \
        SELECT id,'$1',"$2" FROM virtual_domains \
        WHERE name='$DOMAIN';" | mysql mailserver

ch_passwd.sh

#!/bin/bash
if [ $# -eq 2 ]; then
  PW="$2"
elif [ $# -eq 1 ]; then
  PW="x";PWS="xx"
  while [ "$PW" != "$PWS" ] ; do
          read -s -p "Password: " PW ; echo
          read -s -p "Verifying - Password: " PWS  ; echo
          [ "$PW" != "$PWS" ] && echo "Verify failure" >&2
  done
else
  echo "Wrong number of arguments" >&2
  exit 1
fi
DOMAIN=${1##*@}
PWENC=$(echo "$PW" | openssl passwd -6 -stdin)

echo "UPDATE virtual_users SET password='$PWENC' \
        WHERE email='$1';" | mysql mailserver

del_user.sh

#!/bin/bash
doveadm mailbox list -u "$1" |sort -r|  while read a; do
  doveadm mailbox delete -u "$1" -s -r "$a"
done

echo "DELETE FROM virtual_users WHERE email='$1';" | mysql mailserver

U="${1%@*}"
D="${1#*@}"

rm -rf "/var/mail/vhosts/${D}/${U}"

Dovecot szerver

A dovecot sok csomagból áll össze, amiből csak a szükségeseket telepítjük fel. Mivel az install után automatikusan elindul konfigurálatlanul, ezért állítsuk is le rögtön!

apt install dovecot-imapd dovecot-mysql dovecot-lmtpd dovecot-sieve dovecot-managesieved
systemctl stop dovecot

Hozzunk létre egy speciális felhasználót, akihez a levelek tartozni fognak, és állítsuk be a neki kellő jogosultságokat:

addgroup vmail
adduser --ingroup vmail --home /var/mail --no-create-home --disabled-password --shell /usr/sbin/nologin --gecos "Virtual Mail User" vmail
chown -R vmail:vmail /var/mail

Mondjuk meg, hogy az adatbázist szeretnénk authentikációra használni: (/etc/dovecot/conf.d/10-auth.conf)

#!incude auth-system.conf.ext
!include auth-sql.conf.ext

Konfiguráljuk az adatbázis használatát: (/etc/dovecot/dovecot-sql.conf.ext)

driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailpasswd
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

Mivel a operációs rendszerben csak egy felhasználót használunk a összes email fiókhoz, ezért az uid,gid és home értékeket nem az adatbázisból vesszük, hanem fixen megadjuk: (/etc/dovecot/conf.d/auth-sql.conf.ext)

# userdb {
#   driver = sql
#   args = /etc/dovecot/dovecot-sql.conf.ext
# }
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

Állítsuk be a levelek tárolási módját! Az sdbox formátumú tárolásnál minden egyes levél külön fájlba kerül, és a csatolmányokat is külön tárolhatóak. Ebben az esetben ha pl egy cicás videót 100 felhasználónak elküldtek, akkor is csak egy példányban tároljuk le. (/etc/dovecot/conf.d/10-mail.conf)

mail_location = sdbox:~/sdbox:UTF-8
mail_attachment_dir = /var/mail/attachments
mail_attachment_fs = sis posix
mail_attachment_hash = %{sha1}

Addjuk meg a tanúsítványokra vonatkozó beállításokat: (/etc/dovecot/conf.d/10-ssl.conf)

ssl = required
ssl_cert = < /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem
ssl_key = < /etc/letsencrypt/live/mail.mydomain.com/privkey.pem
ssl_dh = </etc/ssl/dhparams.pem
ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = yes

SPF, DKIM, DMARC, rDNS

Postfix server

Spamszűrés

Webmail

nginx

roundcube

autoconfig

Kényelmes dolog, ha a felhasználóknak nem kell a szerver adatait kézzel megadniuk a levelezőprogramjukban. Ha szolgáltatunk erről információt, akkor az email-cím alapján a programok ki tudják deríteni a szükséges beállításokat.

Ehhez a DNS-szolgáltatónknál jegyezzük be az autoconfig.mydomain.com, autoconfig.mydomain2.com és autoconfig.mydomain3.com címeket, és irányítsuk ezt is a szerverünkre.

Az nginx-ben állítsuk be ezeknek a címeknek a kiszolgálását:

server {
        server_name autoconfig.mydomain.com;
        root /var/www/autoconfig/mydomain;
        index index.html;
        location / {
                try_files $uri $uri/ =404;
        }
}
server {
        server_name autoconfig.mydomain2.com;
        root /var/www/autoconfig/mydomain2;
        index index.html;
        location / {
                try_files $uri $uri/ =404;
        }
}
server {
        server_name autoconfig.mydomain3.com;
        root /var/www/autoconfig/mydomain3;
        index index.html;
        location / {
                try_files $uri $uri/ =404;
        }
}

/var/www/autoconfig/mydomain/mail/config-v1.1.xml

<?xml version="1.0"?>
<clientConfig version="1.1">
        <emailProvider id="mydomain.com">
                <domain>mydomain.com</domain>
                <displayName>My Own Company</displayName>
                <displayShortName>My Own Company</displayShortName>
                <incomingServer type="imap">
                        <hostname>mail.mydomain.com</hostname>
                        <port>993</port>
                        <socketType>SSL</socketType>
                        <username>%EMAILADDRESS%</username>
                        <authentication>password-cleartext</authentication>
                </incomingServer>
                <outgoingServer type="smtp">
                        <hostname>mail.mydomain.com</hostname>
                        <port>587</port>
                        <socketType>STARTTLS</socketType>
                        <username>%EMAILADDRESS%</username>
                        <authentication>password-cleartext</authentication>
                        <addThisServer>true</addThisServer>
                        <useGlobalPreferredServer>true</useGlobalPreferredServer>
                </outgoingServer>
        </emailProvider>
        <webMail>
                <LoginPage url="https://mail.mydomain.com/" />
                <LoginPageInfo url="https://mail.mydomain.com/">
                        <username>%EMAILADDRESS%</username>
                        <usernameField id="rcmloginuser" name="_user" />
                        <passwordField id="rcmloginpwd" name="_pass" />
                        <loginButton id="rcmloginsubmit" />
                </LoginPageInfo>
        </webMail>
</clientConfig>

Előző bejegyzés