Build a Complete Mail Server: Postfix + Dovecot on Ubuntu 22.04

Postfix Dovecot Mail Server Ubuntu Production
공개: Email Wiki의 일부 링크는 VPS 제공업체(예: Vultr)의 제휴 링크입니다. 이 링크를 통해 구매하면 추가 비용 없이 수수료를 받을 수 있습니다. 이는 사이트를 무료로 유지하는 데 도움이 됩니다. 모든 튜토리얼은 독립적으로 작성되었으며, 셀프호스팅 이메일에 적합한 신뢰할 수 있는 서비스만 추천합니다.

This guide builds a complete, production-ready self-hosted mail server from scratch. When you’re done, you’ll have:

  • Postfix for SMTP (sending and receiving)
  • Dovecot for IMAP/POP3 (mail retrieval)
  • TLS encryption everywhere (Let’s Encrypt)
  • SPF, DKIM, and DMARC configured
  • Virtual mailboxes supporting multiple domains and users

Architecture Overview

Internet


Postfix (port 25 — inbound SMTP)
Postfix (port 587 — submission, authenticated)


Dovecot (delivers to Maildir)


Mail clients (IMAP port 993 / POP3 port 995)

Prerequisites

  • Fresh Ubuntu 22.04 VPS with at least 1 GB RAM
  • A domain name: example.com
  • Mail subdomain: mail.example.com with A record pointing to your server IP
  • Ports 25, 587, 993, 995 open in your firewall

Phase 1: System Preparation

sudo apt update && sudo apt upgrade -y
sudo hostnamectl set-hostname mail.example.com

Edit /etc/hosts:

YOUR_IP  mail.example.com  mail

Install prerequisites:

sudo apt install -y postfix postfix-mysql dovecot-core dovecot-imapd \
  dovecot-pop3d dovecot-lmtpd dovecot-mysql opendkim opendkim-tools \
  certbot mailutils

Select No Configuration when the Postfix dialog appears — we’ll configure manually.

Phase 2: TLS Certificate

sudo certbot certonly --standalone -d mail.example.com

Certificates are at /etc/letsencrypt/live/mail.example.com/.

Set up auto-renewal hook to reload services after cert renewal:

cat > /etc/letsencrypt/renewal-hooks/post/mail.sh << 'EOF'
#!/bin/bash
systemctl reload postfix dovecot
EOF
chmod +x /etc/letsencrypt/renewal-hooks/post/mail.sh

Phase 3: Postfix Configuration

main.cf

sudo nano /etc/postfix/main.cf
# Basic settings
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all

# TLS inbound (smtpd)
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file  = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes

# TLS outbound (smtp)
smtp_tls_security_level = may
smtp_tls_loglevel = 1

# SASL authentication via Dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

# Virtual mailboxes
virtual_mailbox_domains = example.com
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

# Relay restrictions
smtpd_relay_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination

# DKIM milter
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Virtual Mailbox Map

Create /etc/postfix/vmailbox:

user@example.com    example.com/user/
admin@example.com   example.com/admin/

Index it:

sudo postmap /etc/postfix/vmailbox

master.cf — Enable Submission (Port 587)

Edit /etc/postfix/master.cf and uncomment/add the submission service:

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

Create Virtual Mail Directory

sudo groupadd -g 5000 vmail
sudo useradd -g vmail -u 5000 vmail -d /var/mail/vhosts
sudo mkdir -p /var/mail/vhosts/example.com
sudo chown -R vmail:vmail /var/mail/vhosts

Phase 4: Dovecot Configuration

10-mail.conf

mail_location = maildir:/var/mail/vhosts/%d/%n
mail_uid = vmail
mail_gid = vmail

10-auth.conf

disable_plaintext_auth = yes
auth_mechanisms = plain login

!include auth-static.conf.ext

Create /etc/dovecot/conf.d/auth-static.conf.ext:

passdb {
  driver = static
  args = password=changeme
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

Note: For production, use a database-backed auth. This static config is for initial testing.

10-ssl.conf

ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key  = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2

10-master.conf — LMTP and Auth Socket

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Phase 5: DKIM Setup

sudo mkdir -p /etc/opendkim/keys/example.com
sudo opendkim-genkey -b 2048 -d example.com -s mail \
  -D /etc/opendkim/keys/example.com/
sudo chown -R opendkim:opendkim /etc/opendkim/keys/

# Get the DNS record to publish
cat /etc/opendkim/keys/example.com/mail.txt

Edit /etc/opendkim.conf:

Mode            sv
Domain          example.com
Selector        mail
KeyFile         /etc/opendkim/keys/example.com/mail.private
Socket          inet:8891@localhost
TrustAnchorFile /usr/share/dns/root.key

Phase 6: DNS Records

Add these records to your domain’s DNS:

TypeNameValue
MXexample.commail.example.com (priority 10)
Amail.example.comYOUR_SERVER_IP
TXTexample.comv=spf1 ip4:YOUR_SERVER_IP ~all
TXTmail._domainkey.example.com(from mail.txt above)
TXT_dmarc.example.comv=DMARC1; p=none; rua=mailto:admin@example.com

Also configure reverse DNS (PTR record) through your VPS provider panel.

Phase 7: Start Services and Test

sudo systemctl restart opendkim postfix dovecot
sudo systemctl enable opendkim postfix dovecot

Send a test email:

echo "Test email body" | mail -s "Test" someone@gmail.com

Check logs:

sudo tail -f /var/log/mail.log

Test authentication by connecting with a mail client using:

  • IMAP: mail.example.com:993 (SSL/TLS), user user@example.com
  • SMTP: mail.example.com:587 (STARTTLS), same credentials

Maintenance Checklist

  • TLS cert renewal: sudo certbot renew --dry-run
  • Log rotation: /var/log/mail.log rotated automatically
  • IP blacklist checks: check weekly with MXToolbox
  • Dovecot password changes: update auth-static.conf.ext and reload
  • Software updates: sudo apt upgrade monthly

What’s Next

  • Set DMARC policy from p=none to p=quarantine after reviewing reports
  • Add SpamAssassin for inbound spam filtering
  • Consider Rspamd as a more modern alternative
  • Set up Roundcube for webmail access

메일 서버를 배포할 준비가 되셨나요?

깨끗한 IP 평판을 가진 안정적인 VPS가 필요합니다. Vultr로 시작하세요 — 전용 IP, NVMe SSD, 글로벌 데이터센터, 월 $6부터.