Mengganti user sistem dengan virtual mailboxes berbasis database: konsep multi-domain, struktur tabel virtual_domains, virtual_users, dan virtual_aliases di MariaDB, konfigurasi virtual_mailbox_domains dan virtual_mailbox_maps di Postfix, serta passdb dan userdb SQL di Dovecot.

Sampai episode 6, mailbox kita terikat pada user sistem Linux — untuk tiap akun email harus ada akun OS. Itu tidak praktis untuk multi-domain: kalian tidak ingin membuat user OS untuk setiap akun email, kan?
Solusinya adalah virtual mailboxes: akun email yang hidup hanya di database, tidak punya user sistem. Postfix dan Dovecot sama-sama membaca database untuk mengetahui domain, user, dan alias mana yang valid. Episode ini membangun fondasi itu dengan MariaDB.
Kita akan membedah konsep virtual users, merancang struktur tabel, mengonfigurasi Postfix untuk domain virtual, lalu menghubungkan Dovecot ke SQL untuk autentikasi.
Perbedaan mendasar:
/var/mail/vhosts/<domain>/<user>/.Postfix mengenali domain virtual lewat virtual_mailbox_domains. User virtual tidak pernah login ke shell — mereka hanya "ada" sebagai entri database, dan itu justru lebih aman karena tidak menambah permukaan serangan OS.
Pasang dan amankan database server:
sudo apt install -y mariadb-server
sudo mysql_secure_installationSetelah itu buat database dan user khusus untuk mail, dengan password kuat yang disimpan di file konfigurasi:
sudo mysql -e "CREATE DATABASE maildb;"
sudo mysql -e "CREATE USER 'mail'@'localhost' IDENTIFIED BY 'ganti-password';"
sudo mysql -e "GRANT ALL ON maildb.* TO 'mail'@'localhost';"mysql -e adalah cara menjalankan SQL langsung dari baris perintah — berguna untuk otomasi tanpa membuka klien interaktif.
Tiga tabel inti yang hampir semua tutorial mail server pakai:
CREATE TABLE virtual_domains (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE virtual_users (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id)
);
CREATE TABLE virtual_aliases (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
source VARCHAR(255) NOT NULL,
destination VARCHAR(255) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id)
);Perhatikan: password disimpan sebagai hash, bukan teks biasa. Episode 13 akan membahas cara menghasilkan hash yang cocok dengan mekanisme autentikasi Dovecot.
Beritahu Postfix bahwa domain dan user bersifat virtual. Postfix tidak membaca database langsung — ia memakai lookup table yang dihasilkan dari query SQL. Untuk itu dibutuhkan parameter tambahan virtual_mailbox_domains, virtual_mailbox_maps, dan virtual_mailbox_base:
sudo postconf -e 'virtual_mailbox_domains = example.com'
sudo postconf -e 'virtual_mailbox_base = /var/mail/vhosts'
sudo postconf -e 'virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf'
sudo postconf -e 'virtual_transport = virtual'
sudo postfix check
sudo postfix reloadFile mysql-virtual-mailbox-maps.cf berisi koneksi dan query, misalnya:
user = mail
password = ganti-password
hosts = localhost
dbname = maildb
query = SELECT email FROM virtual_users WHERE email='%s'Uji lookup-nya langsung:
postmap -q user@example.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cfJika query mengembalikan alamat yang sama, Postfix menemukan mailbox yang benar.
Dovecot memakai passdb (verifikasi password) dan userdb (lokasi mailbox & uid/gid). Keduanya dikonfigurasi di conf.d/auth-sql.conf.ext:
sudo sed -i 's/#!include auth-sql.conf.ext/!include auth-sql.conf.ext/' /etc/dovecot/conf.d/10-auth.confBuat /etc/dovecot/dovecot-sql.conf.ext:
driver = mysql
connect = host=localhost dbname=maildb user=mail password=ganti-password
password_query = SELECT email AS user, password FROM virtual_users WHERE email='%u'
user_query = SELECT 5000 AS uid, 5000 AS gid, '/var/mail/vhosts/%d/%n' AS home, \
'maildir:/var/mail/vhosts/%d/%n' AS mailDi sini %u adalah email penuh, %d adalah domain, dan %n adalah bagian nama sebelum @. Uid/gid 5000 menunjuk ke user virtual yang kita buat di sistem — satu user OS menaungi semua mailbox.
Warning
Jangan lupa membuat user OS penampung mailbox: sudo useradd -r -u 5000 -m -d /var/mail/vhosts -s /usr/sbin/nologin vmail. Semua mailbox virtual "hidup" sebagai user vmail ini — tidak ada login shell, tidak ada home yang mencurigakan.
Menambah akun kini cukup insert SQL. Hash password bisa dihasilkan dengan doveadm pw:
doveadm pw -s SHA512-CRYPTHasil hash lalu dimasukkan ke tabel:
INSERT INTO virtual_domains (name) VALUES ('example.com');
INSERT INTO virtual_users (domain_id, email, password)
VALUES (1, 'admin@example.com', '$6$rounds=656000$abc...');Setiap perubahan database langsung berlaku tanpa reload — inilah keunggulan backend SQL dibanding map statis.
Saatnya memastikan Postfix dan Dovecot "berbicara" user yang sama:
postmap -q admin@example.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
doveadm auth test admin@example.com 'password-rahasia'doveadm auth test menguji passdb persis seperti server IMAP saat login. Jika output auth succeeded, kalian siap mengirim email ke mailbox virtual — dan mailbox akan muncul di /var/mail/vhosts/example.com/admin/.
Episode 7 selesai. Inti yang harus dibawa pulang:
vmail menampung semua.virtual_domains, virtual_users, dan virtual_aliases adalah pola baku.virtual_mailbox_maps dan virtual_transport = virtual.%u, %d, %n adalah placeholder penting.doveadm auth test dan postmap -q adalah alat verifikasi tercepat.Backend pengguna sudah hidup. Di episode 8 kita memasang wajah depan: Roundcube — instalasi dan konfigurasi webmail, dari persiapan PHP dan web server sampai instalasi lewat /installer dan pengaturan config.inc.php. Sampai jumpa di episode 8!