Tools: How To Install and Configure Postfix on Ubuntu (2026)
Source: DigitalOcean
By Hanif Jetha, Mark Drake and Manikandan Kurup Postfix is a popular open-source Mail Transfer Agent (MTA) that can be used to route and deliver email on a Linux system. In this guide, you’ll learn how to install and configure Postfix on an Ubuntu server. Then, you’ll test that Postfix is able to correctly route mail by installing s-nail, a Mail User Agent (MUA), also known as an email client. Note that the goal of this tutorial is to help you get Postfix up and running quickly with only some bare-bones email functionality. You won’t have a full-featured email server by the end of this guide, but you will have some of the foundational components of such a setup to help you get started. Setting up and maintaining your own mail server is complicated and time-consuming. For most users, it’s more practical to instead rely on a paid mail service. If you’re considering running your own mail server, we encourage you to review this article on why you may not want to run your own mail server. If you’re sure you want to follow this guide to install and configure Postfix, then you must first have the following: Note that this tutorial assumes that you are configuring a host that has the FQDN of mail.example.com. Wherever necessary, be sure to change example.com or mail.example.com to reflect your own FQDN. Note: This guide has been tested on Ubuntu 22.04 and 24.04. While the steps remain largely the same, newer versions may include updated package versions and systemd-based logging behavior. Postfix is an open-source Mail Transfer Agent (MTA) that routes and delivers email on Linux systems. As an MTA, Postfix’s job is to accept email messages and deliver them to their destinations, whether those destinations are on the same server or on remote mail servers across the internet. All of this communication happens using the Simple Mail Transfer Protocol (SMTP), which is the standard protocol mail servers use to exchange messages. When you send an email, it doesn’t go directly from your computer to the recipient. Instead, it passes through several mail servers along the way. Postfix acts as one of these servers, accepting mail from senders, determining where it needs to go, and either delivering it locally or forwarding it to the next server in the chain. This process happens behind the scenes every time you send or receive email. Postfix was developed in the late 1990s at IBM Research by Wietse Venema as a more secure and easier-to-configure alternative to Sendmail, which was the dominant MTA at the time. Venema designed Postfix with security as a priority, implementing features like privilege separation (where different components run with minimal system permissions) and a modular architecture that isolates functions from each other. This design philosophy has made Postfix the default MTA on many Linux distributions, including Ubuntu. Today, Postfix is estimated to power around 25% of public mail servers on the internet, handling everything from small personal servers to large enterprise deployments. Understanding Postfix requires knowing how it fits into the email ecosystem. A complete email system has three main components that work together: Mail Transfer Agent (MTA): This is Postfix’s role. The MTA is responsible for the “server-to-server” part of email delivery. When you send an email, the MTA accepts it from your email client, looks up where it needs to go (using DNS MX records), and transfers it to the destination mail server. It also receives incoming mail from other MTAs and either delivers it to local mailboxes or forwards it if the recipient is elsewhere. The MTA manages message queues, handles temporary delivery failures by retrying later, and can implement security measures like spam filtering and sender authentication. Think of it as the “post office” that moves mail between locations. Mail User Agent (MUA): This is the email client users interact with, like s-nail (which you’ll use in this tutorial), Thunderbird, Outlook, or web-based interfaces. The MUA lets you compose, send, read, and organize your email. When you click “send” in your email client, the MUA hands the message to an MTA for delivery. When you check for new mail, the MUA retrieves messages that have been delivered to your mailbox. Mail Delivery Agent (MDA): Tools like Dovecot or Courier handle the final step of storing received messages in user mailboxes and providing access to those mailboxes through protocols like IMAP (Internet Message Access Protocol) or POP3 (Post Office Protocol version 3). While Postfix can deliver mail directly to local mailboxes on the same server, MDAs add important features like remote mailbox access (so you can check email from anywhere), server-side filtering rules, and quota management. In this tutorial, you’ll set up Postfix as the MTA and use s-nail as a simple MUA to test your configuration. This gives you a basic but functional mail system. Postfix offers several advantages that make it popular among system administrators: Strong security through isolation: Postfix runs different components as separate processes, each with minimal system privileges. For example, the process that receives mail from the internet runs with very limited permissions and can’t access most of the system. If an attacker compromises this process, the damage is contained—they can’t easily take over the entire mail server or gain root access. This compartmentalized design significantly reduces security risks compared to monolithic mail servers. Reliable performance: Postfix is designed to handle mail efficiently, whether you’re running a personal mail server that processes a few messages per day or a busy server handling thousands of messages per hour. It uses smart queue management to process multiple messages simultaneously and can defer messages that can’t be delivered immediately, retrying them at appropriate intervals. This efficiency means Postfix runs well even on modest hardware. Straightforward configuration: Unlike Sendmail, which uses a complex macro-based configuration language, Postfix uses simple configuration files with readable parameters. Most settings are in /etc/postfix/main.cf and use a straightforward parameter = value format. This makes it much easier to understand what each setting does and to make changes without extensive training. You can query and modify settings using the postconf command, which you’ll use in this tutorial. Flexible integration: Postfix works well with other tools to build a complete mail system. It supports TLS encryption for secure connections, can integrate with spam filtering software like SpamAssassin, implements various authentication mechanisms to prevent unauthorized relay, and can interface with databases for managing virtual users and domains. This modularity means you can start with a basic setup and add features as your needs grow. Postfix is included in Ubuntu’s default repositories, so you can install it with APT. This step installs Postfix and performs the initial configuration required to send and receive email using SMTP. To begin, update your local package cache: Then install the postfix package with the following command. The DEBIAN_PRIORITY=low environment variable ensures that you are prompted to configure additional options during installation: During installation, an interactive configuration screen will appear in your terminal. For the purposes of this tutorial, use the following information to answer the prompts: General type of mail configuration?: For this, choose Internet Site since this matches our infrastructure needs. System mail name: This is the base domain used to construct a valid email address when only the account portion of the address is given. For example, if your server’s hostname is mail.example.com, you should set this to example.com. Postfix will then generate addresses like [email protected]. Root and postmaster mail recipient: This is the Linux account that will receive mail addressed to root@ and postmaster@. Use your primary user account. Other destinations to accept mail for: This defines the domains that this Postfix instance will accept mail for. In most cases, the default value will be sufficient. Force synchronous updates on mail queue?: Since most modern systems use journaled filesystems, select No for better performance. Local networks: This specifies the networks that are allowed to relay mail through your server. The default value works for most setups. If you modify this, ensure it is restricted to trusted networks only. Mailbox size limit: This sets a limit on message size. Setting it to 0 disables any size restriction. Local address extension character: This character (default +) allows you to create dynamic email aliases (for example, [email protected]). Internet protocols to use: Choose all to enable both IPv4 and IPv6. Note: If you need to change these settings later, you can run: Once the installation is complete, verify that Postfix is running: You should see output indicating that the service is active (running). You can also confirm the installed version: At this stage, Postfix is installed but not fully configured for secure or production use. Now you can adjust some settings that the package installation process didn’t prompt you for. Many of Postfix’s configuration settings are defined in the /etc/postfix/main.cf file. Instead of editing this file directly, you can use the postconf command to query or set configuration settings. The postconf -e option safely updates configuration values in main.cf without requiring manual file edits. To begin, set the location for your non-root Ubuntu user’s mailbox. In this guide, we’ll use the Maildir format, which separates messages into individual files that are then moved between directories based on user action. Maildir stores each message as a separate file, improving reliability and avoiding file locking issues. The alternative option that isn’t covered in this guide is the mbox format, which stores all messages within a single file. Set the home_mailbox variable to Maildir/. Later, you will create a directory structure under that name within your user’s home directory. Configure home_mailbox by typing: Next, set the location of the virtual_alias_maps table, which maps arbitrary email accounts to Linux system accounts. This allows you to receive email for multiple addresses and route them to a single user account. Run the following command, which maps the table location to a hash database file named /etc/postfix/virtual: Now that you’ve defined the location of the virtual maps file in your main.cf file, you can create the file itself and begin mapping email accounts to user accounts on your Linux system. Create the file with your preferred text editor; in this example, we’ll use nano: List any addresses that you wish to accept email for, followed by a space and the Linux user you’d like that mail delivered to. For example, if you would like to accept email at [email protected] and [email protected] and would like to have those emails delivered to the sammy Linux user, you could set up your file like this: After you’ve mapped all of the addresses to the appropriate server accounts, save and close the file. If you used nano, do this by pressing CTRL + X, Y, then ENTER. Apply the mapping by typing: This command generates a hashed database file (/etc/postfix/virtual.db) from the text file. Postfix uses this database for efficient lookups. Restart the Postfix process to be sure that all of your changes have been applied: Verify that Postfix is running: You should see output indicating that the service is active (running). If you are using UFW, ensure that SMTP traffic is allowed: This allows incoming SMTP connections (typically on port 25). With that, Postfix is configured and ready to accept external connections. However, it is not yet configured for secure or production use (for example, TLS encryption and spam protection are not enabled). In the next step, you’ll install a mail client to test the setup. In order to interact with the mail being delivered, this step will walk you through the process of installing the s-nail package. This is a feature-rich variant of the BSD mailx client that supports the Maildir format. Before installing the client, it is useful to ensure your MAIL environment variable is set correctly. s-nail uses this variable to determine where to find mail for your user. To set this variable for your current session, run: Note: Setting the MAIL variable system-wide (for example, in /etc/bash.bashrc or /etc/profile.d) is optional and not required for this tutorial. With that complete, install the s-nail email client with APT: Before running the client, there are a few settings you need to adjust. Open the /etc/s-nail.rc file in your editor: At the bottom of the file, add the following options: Here’s what these lines do: Save and close the file when you are finished. You’re now ready to initialize your system’s Maildir structure. A quick way to create the Maildir structure within your home directory is to send yourself an email with the s-nail command. Because the sent folder is only created after Maildir exists, you should disable recording for this initial message using the -Snorecord option. Send the email by piping a string to the s-nail command. Replace sammy with your Linux username: Note: You may see the following message: This is expected during the first run and can be ignored. You can check to make sure the directory was created by listing your Maildir: You should see a structure similar to: At this point, the Maildir structure has been created. In the next step, you will use s-nail to read and send email messages. To open the client, run the s-nail command: In your console, you’ll see a rudimentary inbox with the init message waiting: Press ENTER to display the message: You can get back to the message list by typing h, and then ENTER: Notice that the message now has a state of R, indicating that it’s been read. Since this message isn’t very useful, you can delete it by pressing d, and then ENTER: To get back to the terminal, type q and then ENTER: As a final test, check whether s-nail is able to correctly send email messages. To do this, you can pipe the contents of a text file into the s-nail process, like you did with the init message you sent in the previous step. Begin by writing a test message in a text editor: Inside, enter some text you’d like to send: Save and close the file after writing your message. Then, use the cat command to pipe the message to the s-nail process. You can do so with the following example, which uses these options: Be sure to replace [email protected] and [email protected] with valid addresses: Then, check the inbox of the destination email address. The message should arrive within a few seconds. Note: If the message does not appear in the inbox, check the spam or junk folder. Also note that without proper DNS records (such as SPF, DKIM, and reverse DNS), messages may be marked as spam or rejected by some mail providers. You can view your sent messages within your s-nail client. Start the interactive client again: From the email client, view your sent messages by typing: You’ll see output like this: You can manage sent mail using the same commands you use for incoming mail. At this stage, you have verified that Postfix can send and receive email locally and externally. In many deployments, you only need Postfix to send outbound email rather than operate as a full mail server. This send-only configuration is ideal for web applications, monitoring systems, and other services that need to send notifications or alerts but don’t need to receive or store incoming mail. This approach simplifies management, reduces security risks, and is one of the most common Postfix use cases in modern infrastructure. In a standard mail server setup, Postfix listens on all network interfaces for incoming connections and accepts mail for specific domains. In a send-only configuration, Postfix only accepts mail from local processes on the same server and doesn’t listen on external interfaces. This means applications, scripts, and cron jobs can submit mail, which Postfix then forwards either directly to recipient servers or through an SMTP relay. This configuration reduces your server’s attack surface because Postfix doesn’t accept connections from the internet. It also eliminates the need to manage mailbox storage, spam filtering, or user authentication for incoming mail. When combined with an SMTP relay service, it provides reliable delivery even on cloud platforms where port 25 traffic may be restricted. The inet_interfaces parameter controls which network interfaces Postfix listens on. To restrict it to localhost only, run: This tells Postfix to bind only to 127.0.0.1 (IPv4 localhost) and ::1 (IPv6 localhost). External systems will not be able to connect to your Postfix service, preventing unauthorized relay attempts and reducing security risks. The mydestination parameter defines which domains Postfix accepts mail for. For a send-only server, clear this parameter: This prevents Postfix from accepting incoming mail for any domains. Local applications can still submit mail to external addresses, and Postfix will forward those messages appropriately. This setting works with the localhost restriction to ensure Postfix only sends mail on behalf of local applications. Apply the configuration changes by restarting Postfix: Verify that the service restarted successfully: If you see errors, check the Postfix logs using the troubleshooting techniques covered later in this tutorial. Confirm that Postfix is only listening on localhost: You should see output showing that Postfix is bound to 127.0.0.1:25 (and possibly [::1]:25 for IPv6). You should not see 0.0.0.0:25 or your server’s public IP address. If you do, the configuration wasn’t applied correctly. Example of correct output: While the above steps create a functional send-only server, production deployments should typically use an SMTP relay service. Many cloud providers block outbound SMTP traffic on port 25, and mail sent directly from cloud servers often faces deliverability challenges due to poor IP reputation scores and missing DNS authentication. SMTP relay services like SendGrid or Mailgun maintain high-reputation IP addresses, handle DNS authentication (SPF, DKIM, DMARC), and manage relationships with major email providers to ensure good deliverability. Your Postfix server simply forwards mail to the relay service, which handles final delivery. To configure a relay, set the relayhost parameter: Replace smtp.example.com with your relay provider’s SMTP server hostname. The square brackets tell Postfix to connect directly without looking up MX records. Port 587 is the standard submission port for authenticated SMTP and is less likely to be blocked than port 25. Restart Postfix after setting the relay host: Most SMTP relay services require authentication via SASL (Simple Authentication and Security Layer) and TLS encryption. The detailed configuration steps are beyond this basic tutorial, but the process generally involves creating a password file with your relay credentials, configuring Postfix to use that file, and enabling TLS. Your relay provider will supply specific configuration instructions and credentials. Without proper authentication, your relay provider will reject connection attempts and mail will not be delivered. TLS encryption is essential to protect your credentials during transmission. This send-only configuration provides several security advantages. By restricting Postfix to localhost, you’ve eliminated external attack vectors—malicious actors cannot probe for vulnerabilities or attempt to relay spam through your server. Clearing mydestination means you don’t need to manage mail storage or user accounts, reducing configuration complexity and potential errors. Your server cannot be used as an open relay because Postfix only accepts mail from local processes and only forwards it to external recipients. Using a relay service is strongly recommended if your hosting provider blocks or restricts port 25 (common on AWS, Google Cloud, and Azure), if you need reliable delivery to major email providers like Gmail and Outlook, or if you want to avoid managing sender reputation and DNS authentication yourself. Most relay services offer free tiers for low-volume sending, and the cost is typically lower than the time required to maintain good deliverability when sending directly. Most modern mail servers expect encrypted communication using STARTTLS. Major providers including Gmail, Outlook, and Yahoo will reject, defer, or flag as spam any messages arriving over unencrypted connections. Enabling TLS protects message content from interception and dramatically improves deliverability because receiving servers view encrypted connections as a sign of a properly configured mail server. Email TLS works differently than HTTPS. The connection begins unencrypted on the standard SMTP port and then upgrades to encryption if both servers support it. Postfix uses smtpd_tls_* settings for incoming connections (when acting as a server) and smtp_tls_* settings for outgoing connections (when acting as a client). Most production deployments enable TLS opportunistically, meaning encryption is used when available but connections aren’t rejected if the remote server doesn’t support it. To enable TLS, you need a valid SSL/TLS certificate for your mail server’s hostname (for example, mail.example.com). Use Let’s Encrypt: Before requesting the certificate, ensure your hostname has a DNS A record and port 80 is accessible: The certificate files are created in /etc/letsencrypt/live/mail.example.com/, including fullchain.pem (complete certificate chain) and privkey.pem (private key). Configure Postfix to use the certificate for encrypting SMTP connections. Point Postfix to your certificate and private key: The smtpd_tls_cert_file points to the full certificate chain (your certificate plus intermediate certificates), and smtpd_tls_key_file points to the private key. Enable opportunistic TLS for incoming connections: This setting offers STARTTLS to clients; if they support it, the connection is encrypted. If not, Postfix still accepts the unencrypted connection. This is recommended because requiring encryption would reject mail from servers that don’t support TLS. Configure TLS for outgoing mail: The smtp_tls_security_level=may setting (note smtp_ not smtpd_) enables opportunistic TLS for outgoing connections. Postfix will use STARTTLS if the remote server supports it, or fall back to unencrypted delivery if not. This maximizes both security and deliverability. Specify the trusted certificate authority bundle for validating remote server certificates: This allows Postfix to verify remote servers’ certificates, protecting against man-in-the-middle attacks. For the TLS configuration changes to take effect, restart the Postfix service: Verify it started successfully: If Postfix failed to start, check the logs: Common errors include certificate file not found, permission denied, or private key mismatch. Correct any errors and restart Postfix again. Verify that TLS is being used by sending a test email and examining the logs. Monitor logs in real time: Send a test email and watch for log entries showing TLS negotiation: Key indicators: “TLS connection established”, TLS version (1.2 or 1.3), cipher information, and whether the connection is “Trusted” or “Untrusted”. You can also verify STARTTLS is offered by connecting manually: This shows certificate details and confirms the TLS handshake completed. Type QUIT to exit. The opportunistic configuration (security_level=may) balances security and compatibility. To require encryption for all connections instead, set: This rejects any connection that doesn’t negotiate STARTTLS, guaranteeing no unencrypted email is received. However, it will also reject mail from servers that don’t support TLS. For outgoing deliveries: This refuses to deliver mail to servers that don’t support STARTTLS, which may cause legitimate delivery failures. Note: Requiring encryption improves security but may reject legitimate mail. This is generally not recommended for general-purpose mail servers. If you enable mandatory TLS, monitor your mail queue and logs carefully for rejected deliveries. Let’s Encrypt certificates are valid for only 90 days. This short lifetime limits the damage if a private key is compromised and encourages renewal automation. Certbot includes a systemd timer (or cron job) that periodically checks for certificates nearing expiration and renews them automatically. Verify automatic renewal is configured: You can test renewal without actually renewing: When Certbot renews a certificate, it updates the files in /etc/letsencrypt/live/mail.example.com/. Your Postfix configuration points to these files, but Postfix won’t use the new certificate until restarted. To ensure Postfix automatically picks up renewed certificates, add a deploy hook: Now Certbot will restart Postfix automatically after certificate renewal. TLS alone doesn’t guarantee deliverability. You also need proper DNS authentication records (SPF, DKIM, and DMARC). TLS encrypts the connection, but SPF/DKIM/DMARC prove you’re authorized to send mail for your domain. Both are necessary for good deliverability to major providers. The may security level is recommended. It uses TLS when available but falls back to unencrypted delivery when necessary, maximizing both security and reliability. Monitor certificate expiration. Although automatic renewal should work reliably, failures can occur due to network issues or configuration changes. Check periodically with sudo certbot certificates. TLS configuration is dual-sided. The smtpd_tls_* parameters control incoming connections while smtp_tls_* parameters control outgoing connections. Both need proper configuration. Enable TLS logging for troubleshooting. Increase logging verbosity with sudo postconf -e 'smtpd_tls_loglevel=1' and sudo postconf -e 'smtp_tls_loglevel=1'. Set back to 0 after troubleshooting to reduce log volume. Even after Postfix is installed and running, email delivery may still fail due to various factors including DNS misconfigurations, network restrictions imposed by hosting providers, or errors in your Postfix configuration. Understanding how to diagnose these issues is essential for maintaining a reliable mail server. Postfix provides several diagnostic tools and maintains detailed logs that help you identify and resolve delivery problems. This section walks through the most important troubleshooting commands, explains how to interpret their output, and covers common issues you’re likely to encounter. Postfix writes detailed information about every email transaction to its system logs. The log records each stage of message processing, from initial receipt to final delivery or failure, making it your primary resource for diagnosing mail problems. On Ubuntu systems, Postfix logs may be stored in different locations depending on your logging configuration: First, check if the dedicated mail log file exists: If this file exists, view recent log entries with: To monitor activity in real time: If /var/log/mail.log doesn’t exist, Postfix logs are likely being written to /var/log/syslog or managed by systemd. Use one of these methods instead: To monitor in real time: View recent Postfix logs: To follow logs in real time: To view logs since a specific time: The journalctl method is particularly useful on modern Ubuntu systems and provides additional filtering options. You can combine flags like -u postfix (filter by service) with time ranges and search patterns. Every email processed by Postfix generates multiple log entries as it moves through different stages. A typical successful delivery produces entries showing the message being received, queued, and finally delivered. Each log line includes: The status field in Postfix logs indicates what happened to a message. Understanding these statuses helps you quickly identify the nature of delivery problems: status=sent: The message was successfully delivered to the destination mail server. This means Postfix completed its job and handed the message off to the recipient’s server. Note that this doesn’t guarantee the message reached the user’s inbox; the recipient’s server might still apply spam filtering or other policies. status=deferred: Delivery was temporarily unsuccessful, but Postfix will automatically retry. This is common and not necessarily a problem; temporary failures happen regularly in email delivery. Postfix will retry deferred messages at increasing intervals, starting at 5 minutes (minimal_backoff_time) and increasing up to approximately 67 minutes (maximal_backoff_time). Common causes of deferred status include: status=bounced: Delivery failed permanently and Postfix will not retry. The message is returned to the sender as undeliverable. This indicates a fundamental problem that won’t resolve itself with time. Common causes of bounced messages include: status=reject: Postfix refused to accept or relay the message during the SMTP transaction. This happens before the message enters Postfix’s queue and is usually due to configuration or policy violations. Common causes include: When diagnosing delivery problems, pay attention to these key pieces of information: The recipient domain: Verify that Postfix is attempting delivery to the correct server. The relay= field shows which server Postfix connected to. SMTP response codes: The three-digit codes (like 250, 550, 421) indicate what the remote server said. Codes starting with 2 mean success, 4 means temporary failure, and 5 means permanent failure. Delay information: The delays= field shows time spent in different stages: before queue/in queue/connection setup/message transmission. Long delays in connection setup might indicate network issues. DSN (Delivery Status Notification) codes: These provide standardized information about delivery status. For example, dsn=2.0.0 indicates successful delivery. If you’re troubleshooting a specific delivery problem, search the logs for the recipient’s email address: When Postfix cannot immediately deliver a message, it stores the message in its mail queue and schedules retry attempts. Messages remain in the queue until they’re successfully delivered, bounced, or reach the maximum queue lifetime (default is 5 days). You can view all messages currently in the queue with: If the queue is empty (the ideal state), you’ll see: If there are queued messages, the output shows each message with: Here’s an example of queue output: This tells you that message A1B2C3D4E5 has been queued since 15:35 because Postfix cannot connect to the recipient’s mail server—the connection is timing out. Messages in the queue aren’t necessarily a problem. It’s normal for some messages to be temporarily queued, especially if you just sent them or if remote servers are temporarily unreachable. However, messages that remain queued for hours or days indicate a persistent delivery problem that needs investigation. If you want to examine the contents and headers of a queued message to diagnose why it’s not being delivered, use the postcat command with the queue ID: Replace A1B2C3D4E5 with the actual queue ID from your mailq output. This command displays: This is particularly useful for diagnosing: For example, if a message is repeatedly deferred, examining its headers might reveal that your server is identifying itself with an incorrect hostname, causing remote servers to reject it. Postfix automatically retries queued messages at scheduled intervals. However, if you’ve just fixed a configuration problem or network issue and want to immediately retry all queued messages, you can force Postfix to attempt delivery now: This tells Postfix to attempt immediate delivery of all queued messages instead of waiting for the next scheduled retry. This is useful after: Note that flushing the queue doesn’t guarantee delivery—it just triggers immediate retry attempts. Messages will be requeued if delivery still fails. If mailq shows messages with errors like “Connection timed out” or “Connection refused,” this typically indicates network-level problems preventing your server from reaching destination mail servers. DNS misconfiguration: Postfix cannot resolve the recipient domain’s mail server. Check if DNS lookups work from your server: This should return one or more MX records. If it doesn’t, the domain may not be configured to receive email. Firewall blocking outbound SMTP: Your server’s firewall or network firewall may be blocking connections to port 25. Verify with: If the connection times out or is refused, outbound SMTP traffic is likely blocked. Destination server offline: The recipient’s mail server may actually be down. This should resolve itself when their server comes back online. Many cloud providers and VPS hosts block outbound connections to port 25 by default to prevent spam. This is one of the most common causes of mail delivery failures on new servers. Request port 25 access from your provider: Many hosts will unblock it after verifying your intentions are legitimate. This often requires filling out a form explaining your use case. Use an SMTP relay service: Configure Postfix to send mail through a third-party service like: To configure a relay, set the relayhost parameter in Postfix: Most relay services also require SASL authentication credentials. Use a different port: Some relay services accept submissions on ports 465 (SMTPS) or 587 (submission), which are less commonly blocked. If your messages are successfully delivered (shown as status=sent in logs) but recipients find them in their spam folders, this indicates reputation or authentication problems rather than delivery failures. Missing SPF record: SPF (Sender Policy Framework) is a DNS record that specifies which mail servers are authorized to send email for your domain. Without it, receiving servers may suspect your messages are forged. Check your SPF record: You should see a record like: v=spf1 mx ~all No DKIM signing: DKIM (DomainKeys Identified Mail) cryptographically signs your messages to prove they actually came from your domain. Major providers like Gmail and Outlook increasingly require DKIM. Missing or incorrect reverse DNS: Your server’s IP address should have a PTR (reverse DNS) record pointing to your mail server’s hostname. Many spam filters check this. Verify your PTR record: Poor sender reputation: If your server IP has been used for spam previously, it may be on blocklists. Check with services like MXToolbox. Missing DMARC policy: DMARC builds on SPF and DKIM to tell recipients what to do with messages that fail authentication. Note that configuring these authentication mechanisms is beyond the scope of this basic tutorial but is essential for a production mail server. Postfix identifies itself to other mail servers using your server’s hostname. If this hostname doesn’t match your DNS records or mail domain, some servers may reject your messages as potentially fraudulent. Check your server’s hostname: This should return your server’s fully qualified domain name (FQDN), like mail.example.com. Verify it matches your Postfix configuration: If these don’t match, update Postfix: Also ensure that your myhostname has a corresponding DNS A record and that your server’s IP has a PTR record pointing back to this hostname. If Postfix logs show “Relay access denied” errors, this means Postfix refused to accept a message for delivery because the sender is not authorized to relay mail through your server. Postfix has security settings that prevent unauthorized users from using your server to send mail. By default, Postfix only accepts: If someone tries to send mail through your server to a remote domain and they’re not in mynetworks, Postfix rejects it to prevent your server from being used as an open relay for spam. Check your relay settings: The mynetworks parameter should only include trusted networks. The default value (which varies by installation but is commonly 127.0.0.0/8 on single-interface servers) restricts relaying to trusted networks. Proper DNS configuration is critical for email delivery. Other mail servers use DNS to find your server, verify your identity, and determine whether to trust your messages. Essential DNS records for mail: A record: Maps your mail domain to your server’s IP address Should return your server’s IP address. MX record: Tells other mail servers where to deliver mail for your domain Should return your mail server hostname (e.g., mail.example.com) and its priority number (lower numbers = higher priority). PTR record (reverse DNS): Maps your IP address back to your hostname Should return your mail server’s hostname. Note that PTR records are typically configured by your hosting provider, not through your DNS control panel. Additional authentication records: SPF record: Specifies which servers can send mail for your domain: Look for a record starting with v=spf1 DKIM record: Contains the public key for verifying mail signatures: DMARC record: Specifies what recipients should do with messages that fail authentication: If any of these records are missing or incorrect, email delivery will be unreliable. Work with your DNS provider to add or correct these records as needed. Yes. Postfix remains highly relevant and continues to be the default mail transfer agent on Ubuntu and most Debian-based distributions, with active development and regular security updates. It powers an estimated 25% of public mail servers on the internet, from small personal servers to large enterprise deployments handling millions of messages daily. Postfix configuration is primarily managed through /etc/postfix/main.cf, which uses a simple parameter = value format that’s human-readable and well-documented. After making changes, apply them with sudo postfix reload for configuration updates or sudo systemctl restart postfix for changes requiring a full restart (like TLS certificate updates). Before applying changes, use sudo postfix check to validate syntax and catch configuration errors. The postconf command provides powerful configuration management: For more complex configurations, you may also work with /etc/postfix/master.cf for service definitions and various lookup tables like /etc/postfix/virtual for address mappings. Always back up your configuration files before making changes. Follow these steps to set up a basic SMTP server with Postfix: Install Postfix: Run sudo apt install postfix to begin the installation. This will launch an interactive configuration wizard. Complete the installation wizard: Configure main parameters: Edit /etc/postfix/main.cf and set these critical parameters: Set up email aliases: Configure /etc/aliases to route system mail (root, postmaster) to real user accounts, then run sudo newaliases to rebuild the alias database. Test and verify your configuration: Install mail utilities: Run sudo apt install mailutils to get the mail command for testing. Send test messages to verify your configuration works correctly. For production use, you’ll also need to configure TLS encryption, set up proper DNS records (MX, SPF, DKIM), and implement authentication mechanisms. Postfix is significantly more approachable than its predecessor Sendmail, thanks to its modular architecture and human-readable configuration files. For basic use cases like send-only SMTP servers or simple mail routing, you can achieve a working configuration by editing fewer than ten directives in main.cf, making it accessible even to users with limited mail server experience. The configuration syntax is straightforward—simple key-value pairs rather than complex macro languages—and the official documentation is comprehensive with clear examples. However, the learning curve steepens for advanced configurations involving TLS/SSL, SASL authentication, virtual domains, spam filtering integration, and complex routing rules. These scenarios require understanding how multiple components interact and careful attention to security implications. The postconf command helps by providing detailed descriptions of each parameter with postconf -d parameter, and the error messages are generally informative. Community resources, including extensive tutorials and active forums, provide strong support for troubleshooting common issues. Postfix was created in the late 1990s by Wietse Venema at IBM Research specifically to address Sendmail’s security and usability shortcomings while maintaining compatibility. The most significant difference is security architecture: Postfix uses privilege separation with multiple small processes running with minimal permissions, while Sendmail historically ran as a single large process with root privileges. Configuration approaches differ dramatically. Sendmail uses sendmail.cf, a notoriously complex file generated from m4 macros that’s difficult to read and error-prone to edit manually. Postfix uses intuitive parameter = value syntax in main.cf that administrators can modify directly. Postfix’s modular design separates concerns across multiple configuration files and daemon processes (smtp, qmgr, local, cleanup), making it easier to understand and debug. Performance-wise, Postfix generally handles high-volume mail more efficiently with better queue management. Both MTAs can achieve similar functionality in production, but Postfix requires less specialized knowledge to configure correctly and maintain securely, which is why it has become the default choice on most Linux distributions. Use sudo systemctl status postfix to check service status and look for active (running) in green. For configuration validation, run sudo postfix check to catch syntax errors before they cause runtime problems. Set inet_interfaces = loopback-only in /etc/postfix/main.cf to restrict Postfix to accepting connections only from 127.0.0.1 and ::1 (localhost). This prevents external systems from connecting to your SMTP port while allowing local applications, scripts, and cron jobs to submit mail. Additionally, clear the mydestination parameter with mydestination = to prevent Postfix from accepting mail for any domains, ensuring it only forwards outbound messages. After making these changes, restart with sudo systemctl restart postfix and verify with sudo ss -tulnp | grep :25—you should see only 127.0.0.1:25, not 0.0.0.0:25. This send-only configuration is ideal for web applications, monitoring systems, and servers that generate notification emails but don’t need to receive incoming mail. For cloud deployments where port 25 is often blocked, combine this with relayhost = [smtp.relay.com]:587 to route outbound mail through a third-party SMTP relay service that uses the less-restricted port 587. Postfix typically writes to /var/log/mail.log on Ubuntu systems using traditional syslog, though on newer systemd-based installations logs may go to /var/log/syslog or be managed entirely by journald. Check which applies with ls -l /var/log/mail.log. For traditional logs, use sudo tail -f /var/log/mail.log to monitor activity in real time, or sudo grep postfix /var/log/mail.log | tail -50 to view recent entries. On systemd systems, use sudo journalctl -u postfix -f for live monitoring or sudo journalctl -u postfix -n 100 for recent entries. To troubleshoot specific addresses, search with sudo grep "[email protected]" /var/log/mail.log. Log entries include queue IDs (unique message identifiers), status codes (sent, deferred, bounced, rejected), SMTP response codes from remote servers, and delay information. Monitor the queue with mailq or postqueue -p to see messages waiting for delivery. For debugging, temporarily increase logging verbosity with postconf -e 'debug_peer_list=problem-domain.com' and postconf -e 'debug_peer_level=2', then restore normal logging after troubleshooting. You now have Postfix installed and configured on your Ubuntu server with TLS encryption, send-only SMTP configuration options, and troubleshooting techniques for diagnosing delivery issues. You’ve learned how to work with the mail queue, interpret Postfix logs, and diagnose common problems like port 25 restrictions and DNS misconfigurations. For production use, you’ll need to add SPF, DKIM, and DMARC DNS records for sender authentication, configure SASL authentication for relay access control, and potentially integrate spam filtering. Managing a mail server requires ongoing maintenance including sender reputation monitoring and security updates. For many use cases, especially application notifications, using an SMTP relay service like SendGrid or Mailgun provides better deliverability with less operational overhead. With this foundation, you can deploy Postfix as a send-only SMTP server for applications, expand it into a full mail server with components like Dovecot for IMAP/POP3 access, or use it as a smart host forwarding through a relay service. For more related tutorials, check out these articles: Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about our products DevOps Engineer, Former Technical Writer and Editor at DigitalOcean. Expertise in topics including Ubuntu, Kubernetes, Docker, CentOS. Former Technical Writer at DigitalOcean. Focused on SysAdmin topics including Debian 11, Ubuntu 22.04, Ubuntu 20.04, Databases, SQL and PostgreSQL. With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers. This textbox defaults to using Markdown to format your answer. You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link! Great article for getting started! What kind of steps mail admins would usually take beyond this article? As a developer who wonders whether to invest time to setup my own mail server or go with a third-party solution, I would love to have some grasp on how deep the rabbit hole goes. Some overall view of possible steps to take next would be very helpful. For example, maybe setting up an auto-response would be one of the possible steps? As many have angrily noted in the comment section of the older 18.04 article, I too failed to send email to my default Gmail address after following this tutorial. Here is an excerpt from my /var/log/mail.log, domains and email addresses replaced. The error “Our system has detected an unusual rate of unsolicited mail originating from your IP address” is rather weird because this is the first mail ever sent from my Droplet. Maybe the IP has been previously been a source of spam but I think insufficient configuration is the most probable cause. No one in the older article seemed to be able to provide a sounding fix to this issue. I hope DO can. It’s nice to have a tutorial for half of a mail server, but now a tutorial on dovecot is needed, other tutorials I have tried for 20.04 don’t work. stuck at step 3 when I type echo ‘init’ | s-nail -s ‘init’ -Snorecord relaxslow and enter it shows nothing and next I type ls -R ~/Maildir it gives error msg ls: cannot access ‘/home/relaxslow/Maildir’: No such file or directory can you please tell me the reason I’ve done up to this stage: $echo ‘init’ | s-nail -s ‘init’ -Snorecord sammy But I get the following: ls: cannot access ‘/home/sammy/Maildir’: No such file or directory Please note that when I created a new user I literally used the same name “Sammy” (as in the tutorial) Getting s-nail working Like a lot of other posters, I think the tutorial needs to be amended. This tutorial doesn’t create the Maildir or its subfolders or files or whatever is supposed to be there and other tutorials are similarly unclear. For me, I ended up finding this post: https://support.nagios.com/forum/viewtopic.php?f=7&t=50454 and modified the instructions from ssax to the following: Where USERNAME is replaced with the user you want on the system and in the main tutorial for this page is referred to as ‘sammy’ As others mentioned, cant get test mails to work and nothing appears. Also it was noted that SMTP could be disabled for new accounts. Step I’m stuck at: ls -R ~/Maildir mailq shows this connection timed-out error: -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient------- 811D513BD4C 373 Mon Jan 4 17:04:12 [email protected] (connect to alt2.gmail-smtp-in.l.google.com[74.125.137.26]:25: Connection timed out) So it seems that VPS providers block smtp by default? I just spent all evening trying to get postfix to send, before seeing a comment here that made me contact Interserver… steaming right now, they should be required to tell you… I am on Ubuntu 20.01.1, just booted up a new droplet this morning. Followed the instructions up until this command: echo ‘init’ | s-nail -s ‘init’ -Snorecord USERNAME It does not create the Maildir structure. After creating the Maildir structure manually, as other have suggested, I am still unable to send mail to myself. It appears in the “sent” directory but does not show up in the “new” mail. Strangely, I can send mail to an external email address, but I still cannot send mail internally to my own user. As others have noted in the comments the mail is not being delivered properly locally and the Maildir is never created. This is because an important step is missing in the configuration of Postfix in Step 1. There is a possibly new configuration option in the setup which asks “Use procmail for local delivery?”. This should be changed from the default value of “Yes” to “No”. If procmail is used for local delivery the mail will be routed to /var/mail instead of the specified Maildir directory. Please complete your information! Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation. Full documentation for every DigitalOcean product. The Wave has everything you need to know about building a business, from raising funding to marketing your product. Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter. New accounts only. By submitting your email you agree to our Privacy Policy Scale up as you grow — whether you're running one virtual machine or ten thousand. From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.