Alias and Virtual Domains Configuration in Postfix: Complete Guide
Introduction
Managing email aliases and virtual domains in Postfix allows you to create flexible, scalable email infrastructures. Whether you need to forward emails from multiple addresses to a single mailbox, host email for multiple domains on one server, or create catch-all addresses, Postfix's alias and virtual domain capabilities provide powerful solutions.
Email aliases redirect messages from one address to another without creating separate mailboxes. For example, you can have [email protected], [email protected], and [email protected] all deliver to a single [email protected] mailbox. This simplifies management while presenting a professional, organized email structure to the outside world.
Virtual domains take this further by allowing a single mail server to handle email for multiple independent domains. You might host email for example.com, example.net, and client-domain.com all on one server, with each domain maintaining completely separate user accounts and aliases. This is essential for hosting providers, agencies managing client email, or organizations with multiple brands.
This comprehensive guide covers everything from simple aliases to complex virtual domain setups, including virtual mailboxes, virtual aliases, catch-all addresses, address extensions, and advanced routing configurations.
Prerequisites
Before configuring aliases and virtual domains, ensure you have:
System Requirements
- Working Postfix mail server
- Ubuntu 20.04/22.04, Debian 10/11, CentOS 8/Rocky Linux 8, or similar
- Root or sudo access
- Basic Postfix configuration completed
Mail Server Requirements
- Postfix installed and sending/receiving mail
- Dovecot configured (for virtual mailboxes)
- DNS records properly configured for all domains
- Understanding of current mail setup
Knowledge Prerequisites
- Linux command-line proficiency
- Basic Postfix configuration knowledge
- Understanding of email routing
- Text editor skills (nano, vim)
Understanding Aliases vs Virtual Domains
Local Aliases
Purpose: Redirect mail within the same domain
Scope: System users and local delivery
Configuration: /etc/aliases
Use case: Small, single-domain setups
Example:
admin: root
support: admin
sales: admin, sales-team
Virtual Aliases
Purpose: Redirect mail for virtual domains
Scope: Multiple domains, virtual users
Configuration: /etc/postfix/virtual
Use case: Multi-domain hosting
Example:
[email protected] [email protected]
[email protected] [email protected]
[email protected] [email protected]
Virtual Mailboxes
Purpose: Actual mailbox storage for virtual domains
Scope: Independent mailboxes for each address
Configuration: /etc/postfix/vmailbox
Use case: Complete virtual hosting solution
Example:
[email protected] example.com/user/
[email protected] example.net/admin/
Step 1: Configure Local Aliases
Local aliases are the simplest form of email forwarding.
Edit Aliases File
sudo nano /etc/aliases
Basic Alias Syntax
# Format: alias: destination
# One destination
postmaster: root
# Multiple destinations
admin: user1, user2, user3
# Forward to external email
webmaster: [email protected]
# Chain aliases
support: admin
admin: root
root: [email protected]
# Pipe to program
devnull: /dev/null
backups: |"/usr/local/bin/backup-handler.sh"
# Include file
team: :include:/etc/postfix/team-members.txt
Common Default Aliases
Add these standard aliases:
# Required aliases
postmaster: root
hostmaster: root
webmaster: root
abuse: root
# Administrative aliases
root: [email protected]
mailer-daemon: postmaster
# Department aliases
sales: [email protected]
support: [email protected]
info: [email protected]
Apply Alias Changes
After editing /etc/aliases:
# Rebuild alias database
sudo newaliases
# Or
sudo postalias /etc/aliases
# Reload Postfix
sudo systemctl reload postfix
Test Local Aliases
# Send test email
echo "Testing alias" | mail -s "Alias Test" postmaster
# Check delivery
sudo tail -f /var/log/mail.log
View Current Aliases
# List all aliases
cat /etc/aliases | grep -v "^#" | grep -v "^$"
# Search for specific alias
grep "postmaster" /etc/aliases
# Test alias resolution
postmap -q postmaster /etc/aliases
Step 2: Configure Virtual Alias Domains
Virtual alias domains forward all mail to other addresses.
Edit Postfix Main Configuration
sudo nano /etc/postfix/main.cf
Add or modify:
# Virtual alias domains
virtual_alias_domains = example.net example.org
virtual_alias_maps = hash:/etc/postfix/virtual
Create Virtual Alias File
sudo nano /etc/postfix/virtual
Add aliases:
# Format: virtual-address real-address
# Simple forwarding
[email protected] [email protected]
[email protected] [email protected]
# Multiple destinations
[email protected] [email protected], [email protected]
# Forward entire domain
@example.org [email protected]
# User-specific aliases
[email protected] [email protected]
[email protected] [email protected]
# Department aliases
[email protected] [email protected]
[email protected] [email protected]
# External forwarding
[email protected] [email protected]
Compile and Apply
# Compile virtual alias database
sudo postmap /etc/postfix/virtual
# Reload Postfix
sudo systemctl reload postfix
Test Virtual Aliases
# Send test email
echo "Testing virtual alias" | mail -s "Test" [email protected]
# Check logs
sudo grep "example.net" /var/log/mail.log
# Test alias lookup
postmap -q [email protected] /etc/postfix/virtual
Step 3: Configure Virtual Mailbox Domains
Virtual mailbox domains provide independent mailboxes for each address.
Create Mail Storage User
# Create virtual mail user
sudo groupadd -g 5000 vmail
sudo useradd -g vmail -u 5000 vmail -d /var/mail/vmail -m -s /usr/sbin/nologin
# Create mail directory
sudo mkdir -p /var/mail/vmail
sudo chown -R vmail:vmail /var/mail/vmail
sudo chmod -R 770 /var/mail/vmail
Configure Postfix Main Settings
sudo nano /etc/postfix/main.cf
Add virtual mailbox configuration:
# Virtual mailbox settings
virtual_mailbox_domains = example.com example.net
virtual_mailbox_base = /var/mail/vmail
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/virtual
# Delivery method
virtual_transport = lmtp:unix:private/dovecot-lmtp
# Mailbox size limits
virtual_mailbox_limit = 0
message_size_limit = 52428800
Create Virtual Mailbox File
sudo nano /etc/postfix/vmailbox
Add mailboxes:
# Format: email-address mailbox-path
# Domain: example.com
[email protected] example.com/admin/
[email protected] example.com/user1/
[email protected] example.com/user2/
[email protected] example.com/sales/
# Domain: example.net
[email protected] example.net/admin/
[email protected] example.net/contact/
[email protected] example.net/info/
Mailbox paths are relative to virtual_mailbox_base.
Full path: /var/mail/vmail/example.com/admin/
Create Virtual Domains File
sudo nano /etc/postfix/vdomains
List virtual domains:
example.com OK
example.net OK
example.org OK
Update main.cf:
sudo nano /etc/postfix/main.cf
Change:
virtual_mailbox_domains = hash:/etc/postfix/vdomains
Compile Databases
# Compile mailbox database
sudo postmap /etc/postfix/vmailbox
# Compile domains database
sudo postmap /etc/postfix/vdomains
# Compile virtual aliases
sudo postmap /etc/postfix/virtual
# Reload Postfix
sudo systemctl reload postfix
Integrate with Dovecot
Dovecot must be configured for virtual users:
sudo nano /etc/dovecot/conf.d/10-mail.conf
Set:
mail_location = maildir:/var/mail/vmail/%d/%n/Maildir
mail_uid = vmail
mail_gid = vmail
first_valid_uid = 5000
last_valid_uid = 5000
Variables:
%d= domain (example.com)%n= username (admin)- Full path:
/var/mail/vmail/example.com/admin/Maildir
Create Virtual Users
For authentication, create users in Dovecot:
sudo nano /etc/dovecot/users
Add users with encrypted passwords:
[email protected]:{SHA512-CRYPT}$6$rounds=100000$...
[email protected]:{SHA512-CRYPT}$6$rounds=100000$...
[email protected]:{SHA512-CRYPT}$6$rounds=100000$...
Generate passwords:
# Generate encrypted password
doveadm pw -s SHA512-CRYPT -p 'SecurePassword123'
# Add user
echo "[email protected]:$(doveadm pw -s SHA512-CRYPT -p 'Password')" | sudo tee -a /etc/dovecot/users
# Set permissions
sudo chmod 640 /etc/dovecot/users
sudo chown root:dovecot /etc/dovecot/users
Step 4: Configure Catch-All Addresses
Catch-all addresses receive mail sent to any non-existent address in a domain.
Virtual Domain Catch-All
sudo nano /etc/postfix/virtual
Add:
# Catch-all for example.com
@example.com [email protected]
# Catch-all for example.net
@example.net [email protected]
# Catch-all forwarding to external
@example.org [email protected]
Specific User Catch-All
# Catch all mail for user
user+*@example.com [email protected]
# Catch all subaddresses
admin+*@example.com [email protected]
Compile and Apply
sudo postmap /etc/postfix/virtual
sudo systemctl reload postfix
Test Catch-All
# Send to non-existent address
echo "Test catch-all" | mail -s "Test" [email protected]
# Check delivery
sudo tail -f /var/log/mail.log
Disable Catch-All
To disable catch-all for a domain:
sudo nano /etc/postfix/virtual
Remove the @example.com line, or comment it:
# @example.com [email protected]
Compile and reload:
sudo postmap /etc/postfix/virtual
sudo systemctl reload postfix
Step 5: Configure Address Extensions
Address extensions (also called plus addressing or subaddressing) allow users to create unlimited variations of their email address.
Format: [email protected]
Enable in Postfix
sudo nano /etc/postfix/main.cf
Add:
# Enable address extensions
recipient_delimiter = +
Configure in Dovecot
sudo nano /etc/dovecot/conf.d/15-lda.conf
Add:
protocol lda {
# Enable address extensions
recipient_delimiter = +
# Deliver extensions to main mailbox
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
}
Reload Services
sudo systemctl reload postfix
sudo systemctl reload dovecot
Use Cases
Email organization:
[email protected] # Newsletter signups
[email protected] # Online shopping
[email protected] # Social media
[email protected] # Work-related
Spam tracking:
[email protected] # Track which companies leak addresses
[email protected]
Filtering: Create filters in email client to automatically sort messages:
If To contains "user+newsletter"
Move to "Newsletters" folder
Test Address Extensions
# Send to extended address
echo "Testing extension" | mail -s "Test" [email protected]
# Verify delivery to main mailbox
# Check [email protected] inbox
Step 6: Advanced Virtual Domain Configuration
Multiple Virtual Alias Maps
For better organization, split aliases across multiple files:
sudo nano /etc/postfix/main.cf
Configure:
virtual_alias_maps =
hash:/etc/postfix/virtual,
hash:/etc/postfix/virtual-aliases-example-com,
hash:/etc/postfix/virtual-aliases-example-net
Create separate files:
# Example.com aliases
sudo nano /etc/postfix/virtual-aliases-example-com
# Example.net aliases
sudo nano /etc/postfix/virtual-aliases-example-net
Compile all:
sudo postmap /etc/postfix/virtual-aliases-example-com
sudo postmap /etc/postfix/virtual-aliases-example-net
sudo systemctl reload postfix
Regex-Based Aliases
For complex matching patterns:
sudo nano /etc/postfix/main.cf
Add:
virtual_alias_maps =
hash:/etc/postfix/virtual,
regexp:/etc/postfix/virtual-regexp
Create regex file:
sudo nano /etc/postfix/virtual-regexp
Add patterns:
# Format: /pattern/ destination
# Catch all admin variants
/^admin[0-9]*@example\.com$/ [email protected]
# Catch all support variants
/^(support|help|assist)@example\.com$/ [email protected]
# Redirect old domain
/^(.+)@old-domain\.com$/ ${1}@new-domain.com
# Convert dots to plus
/^([^+]+)\.([^@]+)@example\.com$/ ${1}+${2}@example.com
No compilation needed for regexp maps. Reload:
sudo systemctl reload postfix
Per-Domain Catch-All with Exceptions
sudo nano /etc/postfix/virtual
Configure:
# Specific addresses (processed first)
[email protected] [email protected]
[email protected] [email protected]
# Catch-all (processed after specific matches)
@example.com [email protected]
Postfix processes entries in order, so specific matches take precedence.
Step 7: Managing Virtual Domains
Add New Domain
# 1. Add to virtual domains
echo "newdomain.com OK" | sudo tee -a /etc/postfix/vdomains
sudo postmap /etc/postfix/vdomains
# 2. Add mailboxes
sudo nano /etc/postfix/vmailbox
Add:
[email protected] newdomain.com/admin/
[email protected] newdomain.com/contact/
Compile:
sudo postmap /etc/postfix/vmailbox
Add users:
# 3. Add Dovecot users
echo "[email protected]:$(doveadm pw -s SHA512-CRYPT -p 'Password')" | sudo tee -a /etc/dovecot/users
Create directory:
# 4. Create mail directory
sudo mkdir -p /var/mail/vmail/newdomain.com
sudo chown -R vmail:vmail /var/mail/vmail/newdomain.com
Configure DNS:
# 5. Add DNS records
# MX record: newdomain.com -> mail.example.com
# A record: mail.newdomain.com -> your-ip
# SPF record: v=spf1 mx a ip4:your-ip ~all
Reload:
sudo systemctl reload postfix dovecot
Remove Domain
# 1. Remove from virtual domains
sudo nano /etc/postfix/vdomains
# Remove or comment out the domain
sudo postmap /etc/postfix/vdomains
# 2. Remove mailboxes
sudo nano /etc/postfix/vmailbox
# Remove domain mailboxes
sudo postmap /etc/postfix/vmailbox
# 3. Remove users
sudo nano /etc/dovecot/users
# Remove domain users
# 4. Backup and remove mail
sudo tar czf domain-backup.tar.gz /var/mail/vmail/olddomain.com/
sudo rm -rf /var/mail/vmail/olddomain.com/
# 5. Reload
sudo systemctl reload postfix dovecot
List All Domains
# List virtual mailbox domains
postconf virtual_mailbox_domains
# List from file
cat /etc/postfix/vdomains | grep -v "^#"
# Count domains
cat /etc/postfix/vdomains | grep -v "^#" | wc -l
List All Mailboxes
# List all virtual mailboxes
cat /etc/postfix/vmailbox | grep -v "^#"
# List mailboxes for specific domain
grep "@example.com" /etc/postfix/vmailbox
# Count mailboxes
cat /etc/postfix/vmailbox | grep -v "^#" | wc -l
Step 8: Testing and Verification
Test Alias Resolution
# Test local alias
postmap -q postmaster /etc/aliases
# Test virtual alias
postmap -q [email protected] /etc/postfix/virtual
# Test virtual mailbox
postmap -q [email protected] /etc/postfix/vmailbox
# Test domain
postmap -q example.com /etc/postfix/vdomains
Test Mail Delivery
# Send to alias
echo "Test alias" | mail -s "Alias Test" [email protected]
# Send to virtual mailbox
echo "Test mailbox" | mail -s "Mailbox Test" [email protected]
# Send to catch-all
echo "Test catchall" | mail -s "Catchall Test" [email protected]
# Send with extension
echo "Test extension" | mail -s "Extension Test" [email protected]
Check Logs
# Monitor mail log
sudo tail -f /var/log/mail.log
# Check specific delivery
sudo grep "[email protected]" /var/log/mail.log | tail -20
# Check bounces
sudo grep "bounced" /var/log/mail.log | tail -20
Verify Mailbox Creation
# List mail directories
sudo ls -la /var/mail/vmail/
# Check specific mailbox
sudo ls -la /var/mail/vmail/example.com/admin/Maildir/
# Check mail files
sudo find /var/mail/vmail/ -name "cur" -type d -exec ls -la {} \;
Troubleshooting Common Issues
Issue 1: Alias Not Working
Symptoms: Email not forwarded to destination
Diagnosis:
# Test alias lookup
postmap -q [email protected] /etc/postfix/virtual
# Check logs
sudo grep "[email protected]" /var/log/mail.log
Solutions:
# Recompile database
sudo postmap /etc/postfix/virtual
# Check syntax
cat /etc/postfix/virtual | grep [email protected]
# Reload Postfix
sudo systemctl reload postfix
Issue 2: Virtual Domain Not Receiving Mail
Symptoms: Mail to virtual domain bounces
Diagnosis:
# Check if domain is listed
postconf virtual_mailbox_domains
# Check domain file
grep "example.com" /etc/postfix/vdomains
# Check MX record
dig example.com MX +short
Solutions:
# Add domain
echo "example.com OK" | sudo tee -a /etc/postfix/vdomains
sudo postmap /etc/postfix/vdomains
# Verify main.cf
sudo postconf | grep virtual_mailbox_domains
# Reload
sudo systemctl reload postfix
Issue 3: Permission Denied
Symptoms: "permission denied" errors in logs
Diagnosis:
# Check ownership
sudo ls -la /var/mail/vmail/
# Check processes
ps aux | grep -E "postfix|dovecot"
Solutions:
# Fix ownership
sudo chown -R vmail:vmail /var/mail/vmail/
# Fix permissions
sudo chmod -R 770 /var/mail/vmail/
# Restart services
sudo systemctl restart postfix dovecot
Issue 4: Catch-All Not Working
Symptoms: Mail to non-existent addresses bounces instead of going to catch-all
Diagnosis:
# Check virtual aliases
grep "@example.com" /etc/postfix/virtual
# Test lookup
postmap -q [email protected] /etc/postfix/virtual
Solutions:
# Add catch-all
echo "@example.com [email protected]" | sudo tee -a /etc/postfix/virtual
# Recompile
sudo postmap /etc/postfix/virtual
# Ensure no reject_unverified_recipient
sudo postconf | grep reject_unverified_recipient
# Reload
sudo systemctl reload postfix
Issue 5: Address Extensions Not Delivered
Symptoms: mail to [email protected] bounces
Diagnosis:
# Check recipient delimiter
postconf recipient_delimiter
# Check Dovecot config
doveconf -n | grep recipient_delimiter
Solutions:
# Set delimiter in Postfix
sudo postconf -e "recipient_delimiter = +"
# Set in Dovecot
sudo nano /etc/dovecot/conf.d/15-lda.conf
Add:
recipient_delimiter = +
Reload:
sudo systemctl reload postfix dovecot
Best Practices
1. Organization
- Use descriptive alias names
- Group related aliases
- Document purpose of complex aliases
- Keep separate files for different domains
2. Security
# Restrict file permissions
sudo chmod 640 /etc/postfix/virtual
sudo chmod 640 /etc/postfix/vmailbox
sudo chmod 640 /etc/dovecot/users
# Set proper ownership
sudo chown root:postfix /etc/postfix/virtual
sudo chown root:postfix /etc/postfix/vmailbox
3. Maintenance
- Regularly review and clean up unused aliases
- Remove bouncing destinations
- Update aliases when staff changes
- Backup alias files before changes
4. Documentation
Create an alias inventory:
sudo nano /etc/postfix/README-aliases.txt
Document:
Domain: example.com
Purpose: Main company domain
Aliases:
- [email protected] -> forwards to admin-team
- [email protected] -> forwards to CRM system
- [email protected] -> forwards to ticket system
- @example.com -> catch-all to admin (temporary)
Last updated: 2026-01-11
Contact: [email protected]
5. Testing
After any changes:
# 1. Check syntax
sudo postfix check
# 2. Test lookups
postmap -q [email protected] /etc/postfix/virtual
# 3. Send test email
echo "Test" | mail -s "Test" [email protected]
# 4. Verify in logs
sudo tail -f /var/log/mail.log
Conclusion
You now have comprehensive alias and virtual domain configuration for Postfix, enabling you to manage complex email routing, host multiple domains, and create flexible addressing schemes. This setup provides the foundation for professional, scalable email infrastructure.
Key Accomplishments
- Local Aliases: Simple forwarding within primary domain
- Virtual Aliases: Cross-domain and multi-domain forwarding
- Virtual Mailboxes: Complete virtual domain hosting
- Catch-All Addresses: Flexibility in receiving mail
- Address Extensions: Enhanced organization and filtering
Next Steps
- Add more domains: Expand virtual hosting as needed
- Implement automation: Scripts for adding users/domains
- Set up quotas: Limit mailbox sizes per user/domain
- Configure webmail: Browser-based access (Roundcube/Rainloop)
- Implement backup: Automated backup of mail and configurations
Important Reminders
- Compile after changes: Always run
postmapafter editing map files - Reload services: Run
systemctl reload postfixto apply changes - Test thoroughly: Verify each alias and domain works correctly
- Document configuration: Keep records of aliases and their purposes
- Backup regularly: Protect alias configurations and mailbox data
With these alias and virtual domain configurations in place, you have a flexible, scalable email system capable of growing with your needs while maintaining organization and manageability.


