550 Relay Access Denied — Cannot Send Through SMTP Server
Symptômes
- Sending email to external domains fails: `550 5.7.1 Relaying denied`
- SMTP client log: `Server response: 550 5.7.0 Relay access denied`
- Email clients (Thunderbird, Outlook) show "The server responded: 550 relay not permitted"
- Only email sent to the server's own domain succeeds; all external delivery fails
- Postfix log: `NOQUEUE: reject: RCPT from unknown[x.x.x.x]: 554 5.7.1 <[email protected]>: Relay access denied`
- SMTP client log: `Server response: 550 5.7.0 Relay access denied`
- Email clients (Thunderbird, Outlook) show "The server responded: 550 relay not permitted"
- Only email sent to the server's own domain succeeds; all external delivery fails
- Postfix log: `NOQUEUE: reject: RCPT from unknown[x.x.x.x]: 554 5.7.1 <[email protected]>: Relay access denied`
Causes profondes
- SMTP AUTH (SASL) not configured — server requires authentication to relay but client is not authenticating
- Client IP not listed in mynetworks (Postfix) or relay_from_hosts (Exim)
- Missing TLS/STARTTLS requirement — server rejects AUTH over plain text connections
- Application uses wrong SMTP port (25 vs 587 submission port which requires auth)
- SASL library (Cyrus SASL, Dovecot SASL) not installed or misconfigured on the server
Diagnostic
**Step 1 — Attempt SMTP AUTH manually**
```bash
# Connect to submission port with STARTTLS
openssl s_client -connect mail.yourdomain.com:587 -starttls smtp
# After TLS handshake:
EHLO test.com
# Look for: 250-AUTH PLAIN LOGIN
# If AUTH is not listed, SASL is not configured
```
**Step 2 — Test authenticated send**
```bash
# Encode credentials: \x00username\x00password in base64
python3 -c "import base64; print(base64.b64encode(b'\[email protected]\x00password').decode())"
# In the SMTP session:
AUTH PLAIN <base64string>
# 235 2.7.0 Authentication successful
RCPT TO:<[email protected]>
# Should now succeed
```
**Step 3 — Check Postfix relay settings**
```bash
postconf mynetworks
postconf smtpd_relay_restrictions
postconf smtpd_recipient_restrictions
# Look for: permit_sasl_authenticated in the restriction list
```
**Step 4 — Verify SASL is running**
```bash
# Dovecot SASL
sudo systemctl status dovecot
ls -la /var/spool/postfix/private/auth # socket must exist
# Cyrus SASL
sudo systemctl status saslauthd
testsaslauthd -u username -p password -s smtp
```
**Step 5 — Inspect mail logs for rejection detail**
```bash
grep 'Relay access denied' /var/log/mail.log | tail -20
# Note the client IP — if it is an application server, add it to mynetworks
```
```bash
# Connect to submission port with STARTTLS
openssl s_client -connect mail.yourdomain.com:587 -starttls smtp
# After TLS handshake:
EHLO test.com
# Look for: 250-AUTH PLAIN LOGIN
# If AUTH is not listed, SASL is not configured
```
**Step 2 — Test authenticated send**
```bash
# Encode credentials: \x00username\x00password in base64
python3 -c "import base64; print(base64.b64encode(b'\[email protected]\x00password').decode())"
# In the SMTP session:
AUTH PLAIN <base64string>
# 235 2.7.0 Authentication successful
RCPT TO:<[email protected]>
# Should now succeed
```
**Step 3 — Check Postfix relay settings**
```bash
postconf mynetworks
postconf smtpd_relay_restrictions
postconf smtpd_recipient_restrictions
# Look for: permit_sasl_authenticated in the restriction list
```
**Step 4 — Verify SASL is running**
```bash
# Dovecot SASL
sudo systemctl status dovecot
ls -la /var/spool/postfix/private/auth # socket must exist
# Cyrus SASL
sudo systemctl status saslauthd
testsaslauthd -u username -p password -s smtp
```
**Step 5 — Inspect mail logs for rejection detail**
```bash
grep 'Relay access denied' /var/log/mail.log | tail -20
# Note the client IP — if it is an application server, add it to mynetworks
```
Résolution
**Fix 1 — Add permit_sasl_authenticated to Postfix restrictions**
```ini
# /etc/postfix/main.cf
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_tls_auth_only = yes
```
```bash
sudo postfix check && sudo systemctl reload postfix
```
**Fix 2 — Add trusted IPs to mynetworks**
```ini
# /etc/postfix/main.cf
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.0.0.0/8
```
**Fix 3 — Switch application to port 587 with auth**
```python
# Django settings.py
EMAIL_HOST = 'mail.yourdomain.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True # STARTTLS on port 587
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'secret'
```
**Fix 4 — Enable and configure Dovecot SASL socket**
```ini
# /etc/dovecot/conf.d/10-master.conf
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
```
```ini
# /etc/postfix/main.cf
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_tls_auth_only = yes
```
```bash
sudo postfix check && sudo systemctl reload postfix
```
**Fix 2 — Add trusted IPs to mynetworks**
```ini
# /etc/postfix/main.cf
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.0.0.0/8
```
**Fix 3 — Switch application to port 587 with auth**
```python
# Django settings.py
EMAIL_HOST = 'mail.yourdomain.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True # STARTTLS on port 587
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'secret'
```
**Fix 4 — Enable and configure Dovecot SASL socket**
```ini
# /etc/dovecot/conf.d/10-master.conf
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
```
Prévention
- Always use port 587 (submission) with SMTP AUTH for application-level mail sending
- Never open port 25 for inbound relay from untrusted IPs — this creates an open relay
- Enforce smtpd_tls_auth_only = yes so credentials are never sent in plaintext
- Use application-specific SMTP credentials (not your personal mailbox password)
- Prefer a managed ESP (SES, SendGrid) for application email to avoid relay configuration entirely
- Never open port 25 for inbound relay from untrusted IPs — this creates an open relay
- Enforce smtpd_tls_auth_only = yes so credentials are never sent in plaintext
- Use application-specific SMTP credentials (not your personal mailbox password)
- Prefer a managed ESP (SES, SendGrid) for application email to avoid relay configuration entirely