> ## Documentation Index
> Fetch the complete documentation index at: https://jetemail.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Postfix

> Configure Postfix mail server to use JetEmail as a smarthost

This guide will walk you through configuring Postfix to use JetEmail as your smarthost for improved email deliverability and authentication.

## Prerequisites

* Root access to your server
* Postfix mail server installed and running
* JetEmail SMTP credentials from your [dashboard](/outbound/getting-started)

## Configuration Steps

<Steps>
  <Step title="Create an SMTP user">
    In your JetEmail [dashboard](/outbound/getting-started), go to **Outbound** → **SMTP** and create an SMTP user (or use an existing one). Keep its username and password handy for the next step.
  </Step>

  <Step title="Configure SMTP Authentication">
    Create or edit `/etc/postfix/sasl_passwd` to include your JetEmail credentials:

    ```plaintext theme={null}
    relay.jetsmtp.net:587    your_username:your_password
    ```

    Replace `your_username` and `your_password` with your actual JetEmail SMTP credentials.

    Secure the file. With `texthash` there is no separate database to build, so there is no `postmap` step:

    ```bash theme={null}
    chmod 600 /etc/postfix/sasl_passwd
    ```

    <Note>
      This guide uses the `texthash` map type throughout. It reads the plaintext file directly, needs no `postmap`, and is built into every Postfix, so the same commands work on Debian / Ubuntu and on AlmaLinux / Rocky / RHEL. The indexed types are distro-specific (`hash` on Debian / Ubuntu, `lmdb` on RHEL 9+); if you prefer one for a large map, switch the type, run the matching `postmap`, and check `postconf -m` to confirm your build supports it.
    </Note>
  </Step>

  <Step title="Update Postfix Main Configuration">
    Apply the relay settings with `postconf -e`. It updates each key in place, so it never leaves a duplicate entry in `/etc/postfix/main.cf`:

    ```bash theme={null}
    postconf -e 'relayhost=relay.jetsmtp.net:587'
    postconf -e 'smtp_sasl_auth_enable=yes'
    postconf -e 'smtp_sasl_password_maps=texthash:/etc/postfix/sasl_passwd'
    postconf -e 'smtp_sasl_security_options=noanonymous'
    postconf -e 'smtp_tls_security_level=encrypt'
    postconf -e 'smtp_tls_note_starttls_offer=yes'
    ```

    `smtp_tls_security_level=encrypt` makes TLS mandatory. On Debian and Ubuntu the default `main.cf` ships `smtp_tls_security_level = may` (opportunistic); because `postconf -e` overwrites that line in place rather than adding a second one, you won't see an `overriding earlier entry` warning from `postfix check`.

    <Note>
      Authentication happens over SASL using the username and password from the previous step. JetEmail does not use any custom authentication headers, so do not add an `smtp_header_checks` step for that purpose.
    </Note>

    <Note>
      `smtp_tls_CAfile` is intentionally omitted: at the `encrypt` level Postfix requires TLS but does not verify the relay's certificate, so a CA bundle is never consulted. Only if you raise the level to `verify` do you need `smtp_tls_CAfile`, pointing at your distro's CA bundle (`/etc/ssl/certs/ca-certificates.crt` on Debian / Ubuntu, `/etc/pki/tls/certs/ca-bundle.crt` on AlmaLinux / Rocky / RHEL).
    </Note>
  </Step>

  <Step title="Optional: Configure Sender Canonical Maps">
    If you need to rewrite sender addresses, create `/etc/postfix/sender_canonical`:

    ```plaintext theme={null}
    # Rewrite local users to use your domain
    root@localhost.localdomain    noreply@yourdomain.com
    www-data@localhost.localdomain noreply@yourdomain.com
    ```

    Enable the map. `texthash` reads the file directly, so no `postmap` is needed:

    ```bash theme={null}
    postconf -e 'sender_canonical_maps=texthash:/etc/postfix/sender_canonical'
    ```
  </Step>

  <Step title="Test Configuration and Restart Postfix">
    Test your configuration and restart Postfix:

    ```bash theme={null}
    postfix check  # Test configuration syntax
    systemctl restart postfix
    ```
  </Step>
</Steps>

## Alternative Ports

The relay listens on **587, 25, and 2525** for STARTTLS, and **465** for implicit TLS (SSL). Port 587, used above, is the recommended default. Port 25 outbound is blocked by most cloud providers and ISPs, so avoid it unless you know it is open.

Ports 25 and 2525 use the same STARTTLS settings as 587; only the port number in `relayhost` (and `/etc/postfix/sasl_passwd`) changes.

To use implicit TLS on port 465 instead, set:

```bash theme={null}
postconf -e 'relayhost=relay.jetsmtp.net:465'
postconf -e 'smtp_tls_wrappermode=yes'
postconf -e 'smtp_tls_security_level=encrypt'
```

Remember to use the matching `relay.jetsmtp.net:465` key in `/etc/postfix/sasl_passwd` as well.

## Additional Configuration

### SPF Records

Don't forget to update your SPF records to include JetEmail's servers:

```
v=spf1 include:spf.jetsmtp.net ~all
```

Learn more about [email authentication](/outbound/email-authentication).

### Domain Authentication

For enhanced security and deliverability:

* Configure [Domain Lockdown](/outbound/domain-lockdown) to prevent domain spoofing
* Set up [DMARC](/outbound/dmarc) for email authentication
* Ensure proper DKIM signing is configured

## Testing Your Configuration

After configuration, test your setup:

1. Send a test message. Postfix provides its own `sendmail`, so no extra mail client is needed (the `mail` command is not installed by default):
   ```bash theme={null}
   printf 'From: sender@example.com\nSubject: JetEmail relay test\n\nTest message body\n' \
     | sendmail -f sender@example.com test@example.com
   ```
   Use a `From` / `-f` address on a domain you have verified in JetEmail, and a recipient mailbox you can check.

2. Check the mail queue:
   ```bash theme={null}
   postqueue -p
   ```

3. Monitor Postfix logs:
   ```bash theme={null}
   tail -f /var/log/mail.log
   # OR
   tail -f /var/log/maillog
   ```

4. Verify authentication in email headers

5. Monitor delivery in your JetEmail dashboard

## Troubleshooting

### Authentication Failures

* Verify your SMTP credentials in `/etc/postfix/sasl_passwd`
* With `texthash` there is no separate database to build; confirm Postfix can read `/etc/postfix/sasl_passwd` (owned by root, mode 600) and that you reloaded Postfix after editing it
* Check that your JetEmail account is active and in good standing

### Connection Issues

* Verify the relay port is reachable from your server (587 by default):
  ```bash theme={null}
  telnet relay.jetsmtp.net 587
  # OR, if you switched ports
  telnet relay.jetsmtp.net 465
  ```
* Check TLS configuration and certificate paths
* Ensure SASL authentication modules are installed:
  ```bash theme={null}
  # Debian/Ubuntu
  apt-get install libsasl2-modules

  # CentOS/RHEL
  yum install cyrus-sasl-plain
  ```

### Configuration Errors

* Check Postfix logs for detailed error messages:
  ```bash theme={null}
  grep postfix /var/log/mail.log
  ```
* Test configuration syntax: `postfix check`
* Verify file permissions on configuration files

### Common Error Messages

**"SASL authentication failed"**

* Check username/password in `/etc/postfix/sasl_passwd`
* Verify the password database exists and is readable

**"TLS is required"**

* Ensure `smtp_tls_security_level = encrypt` is set (`postconf smtp_tls_security_level` to check the active value)
* Confirm your firewall and provider allow outbound on the relay port (587 by default)

**"Connection refused"**

* Verify network connectivity to JetEmail servers
* Check firewall settings

**"unsupported dictionary type: hash" or "...: lmdb"**

* Indexed map types are compiled in at build time and differ by distro: `hash` (Berkeley DB) exists on Debian / Ubuntu but not RHEL 9+, while `lmdb` is built in on RHEL 9+ but needs the `postfix-lmdb` plugin on Debian / Ubuntu (and is absent on some releases). Run `postconf -m` to list what your build supports.
* This guide uses `texthash`, which is built into every Postfix and avoids the split. If you copied a `hash:` or `lmdb:` map from elsewhere and hit this error, change it to `texthash:` and drop the matching `postmap` command, since `texthash` needs none.
* If you specifically want an indexed map, use `hash` on Debian / Ubuntu or `lmdb` on RHEL 9+, run the matching `postmap`, then `systemctl reload postfix`.

## Advanced Configuration

### Multiple Domains with Different Credentials

If you need different SMTP credentials for different domains:

1. Create `/etc/postfix/sender_dependent_relayhost_maps`:
   ```plaintext theme={null}
   @domain1.com    relay.jetsmtp.net:587
   @domain2.com    relay.jetsmtp.net:587
   ```

2. Create `/etc/postfix/sender_dependent_sasl_passwd_maps`:
   ```plaintext theme={null}
   @domain1.com    username1:password1
   @domain2.com    username2:password2
   ```

3. Apply the settings. `texthash` reads each file directly, so no `postmap` step is needed. This also repoints `smtp_sasl_password_maps` at the per-sender map, replacing the value from the main configuration step in place:

   ```bash theme={null}
   postconf -e 'sender_dependent_relayhost_maps=texthash:/etc/postfix/sender_dependent_relayhost_maps'
   postconf -e 'smtp_sender_dependent_authentication=yes'
   postconf -e 'smtp_sasl_password_maps=texthash:/etc/postfix/sender_dependent_sasl_passwd_maps'
   systemctl reload postfix
   ```

   <Note>
     For a large number of per-sender entries, an indexed map performs better: switch these to `hash` (Debian / Ubuntu) or `lmdb` (RHEL 9+) and run the matching `postmap` on each file.
   </Note>

## Security Considerations

* Keep your SMTP credentials secure with proper file permissions
* Regularly rotate your JetEmail SMTP passwords
* Monitor your email logs for suspicious activity
* Consider implementing rate limiting if needed

For additional support, contact our team or visit our [Discord community](https://jetemail.com/discord).
