hardware / mailserver

:warning: UNMAINTAINED - Simple and full-featured mail server using Docker
https://store.docker.com/community/images/hardware/mailserver
MIT License
1.29k stars 322 forks source link

smtpd_sender_restrictions #314

Closed navossoc closed 6 years ago

navossoc commented 6 years ago

Classification

Reproducibility

Description

Well, I was doing some tests and found an odd case related to smtpd_sender_restrictions settings. Right now, it is possible to send an email from an nonexistent user (unauthenticated) to any user that has an mail registered on the mail server.

This is my temporary fix (reject_unlisted_sender):

postconf 'smtpd_sender_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain, reject_sender_login_mismatch, reject_unlisted_sender, reject_rhsbl_sender dbl.spamhaus.org'
postfix reload

Steps to reproduce

  1. Setup a domain in the mail server (mydomain.com)
  2. Create one mail account (rafael@mydomain.com)
  3. Send an email from PHPMailer (for example) from nonexistent@mydomain.com to rafael@mydomain.com.

Expected results

Not being able to send the email, since the user doesn't exists.

Mailer Error: SMTP Error: The following recipients failed: rafael@mydomain.com: : Sender address rejected: User unknown in virtual mailbox table

This can lead people to try to impersonate each other, like admin admln (with an L).

Actual results

Message sent!

Any thoughts about this?

hardware commented 6 years ago

I can't reproduce this.

screenshot_20181009_214139

reject_sender_login_mismatch prevent this kind of impersonation. Mail spoofing is denied with default configuration. Each user may only send with his own or his alias addresses. And a mailer like PHPMailer can't send an e-mail without being (SASL) logged.

Reject the request when $smtpd_sender_login_maps specifies an owner for the MAIL FROM address, but the client is not (SASL) logged in as that MAIL FROM address owner; or when the client is (SASL) logged in, but the client login name doesn't own the MAIL FROM address according to $smtpd_sender_login_maps.

http://www.postfix.org/postconf.5.html#reject_sender_login_mismatch

Check your custom postfix file, maybe you have a directive in conflict.

Error message when the client is unauthenticated :

postfix/submission/smtpd[xxxxx]: NOQUEUE: reject: RCPT from [x.x.x.x]: 554 5.7.1 <unknown[x.x.x.x]>: Client host rejected: Access denied; from=<nonexistent@mydomain.com> to=<rafael@mydomain.com> proto=ESMTP helo=<[x.x.x.x]>

Error message when the client is authenticated, but doesn't own the MAIL FROM address :

postfix/submission/smtpd[xxxxx]: NOQUEUE: reject: RCPT from [x.x.x.x]: 553 5.7.1 <nonexistent@mydomain.com>: Sender address rejected: not owned by user rafael@mydomain.com; from=<nonexistent@mydomain.com> to=<existent@mydomain.com> proto=ESMTP helo=<[x.x.x.x]>
navossoc commented 6 years ago

Yes, but you are authenticated as another user right? Try again without authenticating, port 25 instead.

I forgot to mention that, sorry.

On Tue, Oct 9, 2018, 16:45 hardware notifications@github.com wrote:

I can't reproduce this.

[image: screenshot_20181009_214139] https://user-images.githubusercontent.com/327354/46694164-396e3d80-cc0c-11e8-926a-0426208fa2a5.png

reject_sender_login_mismatch prevent this kind of impersonation. Mail spoofing is denied with default configuration. Each user may only send with his own or his alias addresses.

Reject the request when $smtpd_sender_login_maps specifies an owner for the MAIL FROM address, but the client is not (SASL) logged in as that MAIL FROM address owner; or when the client is (SASL) logged in, but the client login name doesn't own the MAIL FROM address according to $smtpd_sender_login_maps.

http://www.postfix.org/postconf.5.html#reject_sender_login_mismatch

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/hardware/mailserver/issues/314#issuecomment-428325601, or mute the thread https://github.com/notifications/unsubscribe-auth/ACV--tMArBqxNqYEoRN12EJrJusXHqRjks5ujPzdgaJpZM4XSRAY .

navossoc commented 6 years ago

Sample code:

<?php
ini_set('error_reporting', E_ALL);
ini_set("display_errors", "on");

date_default_timezone_set('Etc/UTC');

require 'PHPMailerAutoload.php';

//Create a new PHPMailer instance
$mail = new PHPMailer;
//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Custom connection options
//Note that these settings are INSECURE
$mail->SMTPOptions = array(
    'ssl' => [
        'verify_peer' => false,
        'allow_self_signed' => true
    ],
);

//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;

//Set the hostname of the mail server
$mail->Host = 'mail.mydomain.com';
//Set the SMTP port number - likely to be 25, 465 or 587
$mail->Port = 25;

//We don't need to set this as it's the default value
$mail->SMTPAuth = false;

//Set who the message is to be sent from
$mail->setFrom('nonexistent@mydomain.com', 'Non Existent');
//Set who the message is to be sent to
$mail->addAddress('rafael@mydomain.com', 'Rafael');
//Set the subject line
$mail->Subject = 'test - user not exists / not auth';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->Body = 'test - user not exists / not auth';
if (!$mail->send()) {
    echo "<b>Mailer Error: " . $mail->ErrorInfo . "</b>";
} else {
    echo "<b>Message sent!</b>";
}

I sent you a message, please check if you have received it.

hardware commented 6 years ago

Yes, but you are authenticated as another user right?

No, unauthenticated but on port 587.

Try again without authenticating, port 25 instead.

I can reproduce it on port 25. But I don't get it, why should I use reject_unlisted_sender while i'm explicitly telling postfix to prevent this with reject_sender_login_mismatch, this restriction works on port 587 and 465, but not on port 25 ? It does not make sense.

navossoc commented 6 years ago

@hardware I really don't know! What I've learned recently is that postfix has its own free will.

I saw it being used here too: https://github.com/mailcow/mailcow-dockerized/blob/4179cc74ecccc64930780a7a879d10d185639cc7/data/conf/postfix/main.cf#L88

I also tried to add permit_mynetworks on smtpd_sender_restrictions and it get ignored, doesn't work at all!

smtpd_sender_restrictions (default: empty) The following restrictions are specific to the sender address received with the MAIL FROM command. ... Other restrictions that are valid in this context: SMTP command specific restrictions described under smtpd_client_restrictions and smtpd_helo_restrictions.

http://www.postfix.org/postconf.5.html#smtpd_sender_restrictions

If you follow it, you will see permit_mynetworks listed there. IDK! 😕

hardware commented 6 years ago

Probably because SASL on port 25 is not managed in the same way by postfix like submission ports. 25 is designed to receive email without authentication, so reject_sender_login_mismatch can't fully apply with this port. I will add reject_unlisted_sender in the next commit to improve the spoofing protection. Thanks for pointing this out.