# Prevent internal email spoofing with sendmail



## reddy (Jan 24, 2019)

Hello,

The way MTAs work, relaying can be configured to allow or not certain hosts to relay emails using the server. However after searching for quite a few days, I found no way to prevent user1@trustedhost.com from impersonating user2@trustedhost.com. The way I understand it, sendmail would allow the user to relay the email (which is what I call internal spoofing).

I'd be very surprised if no milter or mailer configuration already existed to address this concern which is why I am asking. Maybe I am not searching using the right keywords as I am not sure if this problem has a specific technical name.

The ideal behavior I am after is that virtusertable be used to determine whether or not a user is allowed to relay an email using the from/sender address he is trying to use. So the virtusertable would be used in the opposite direction for outgoing emails. I hope this makes sense.

Could someone please comment / point in the right direction?
Thanks!


----------



## SirDice (Jan 24, 2019)

This is a direct consequence of the SMTP protocol itself. The only way you could prevent it is by enforcing authentication.



reddy said:


> I'd be very surprised if no milter or mailer configuration already existed to address this concern which is why I am asking.


This is not possible as the MTA has no way to tell if user1 is really user1 without some form of authentication.


----------



## xtaz (Jan 24, 2019)

Yep. I would solve this by not allowing relaying via IP address alone. I would remove the subnets from any whitelisting and only allow relaying if the user is logged in via SASL authentication.

That alone won't prevent the spoofing, but you could at least see who did it from the logs. To enforce it would depend on the MTA, but for example postfix has the option _smtpd_sender_restrictions = reject_sender_login_mismatch _along with configuring _smtpd_sender_login_maps _and such like.


----------



## usdmatt (Jan 24, 2019)

I'm a big fan of Postfix due to it being far simpler to configure and use than Sendmail (Especially when it comes to sender/recipient restrictions).

As already said, you want to make sure everyone is authenticating for a start. Then, with Postfix at least, you can restrict the from address that each user uses. I've done this for a customer previously but unfortunately the server has long gone now and I don't have a copy of the config I used.

If you're building a new server I'd highly recommend using Postfix for SMTP & Dovecot for POP/IMAP/LDA. Postfix has support to authenticate against Dovecot built in, but there's also a separate mail/postfix-sasl port that uses cyrus saslauthd.

I started using Courier and I'm now stuck wanting to move to Dovecot, which seems to perform better, work nicer with most clients and supports sieve LDA filters, but I can't change without high risk of screwing peoples mailboxes up.


----------



## reddy (Jan 27, 2019)

Hum... this is embarrassing. 

As far as tooling is concerned, I prefer sendmail, I looked into the alternatives but find sendmail better documented and am actually starting to like the configuration style. I also found that other mail servers weren't as simple to configure compared to sendmail than what people make it. They all have their learning curve.

I want to stay away from enabling SMTP authentication on port 25, as I do not want to enable any bruteforce vector. I could investigate enabling it on some other port behind the ssh tunnel but as you pointed, at least with sendmail this authentication is not enough to prevent this type of spoofing.

It looks like the only mitigation measure would be to log every email sent, check it against virtusertable or some other mapping file and append the event to a file if there is forgery. However, if I have to go through this hassle, I could equally implement a proper milter, which we will probably do once the risk level justifies the investment (which should be the case shortly).


----------



## SirDice (Jan 28, 2019)

reddy said:


> It looks like the only mitigation measure would be to log every email sent, check it against virtusertable or some other mapping file and append the event to a file if there is forgery.


The MTA doesn't know it's a forgery, it has no way of telling the difference.


----------



## xtaz (Jan 28, 2019)

Quite. Think of it like delivering mail in the normal post. If I write you a letter and sign it from President Trump, pop it into an envelope, write your address on the front, and deliver it to you, how can you tell if it came from him or me? Answer, you can't. Your postbox has no magical way to check that the sender is who they claim to be.

There are two options really. Either your postbox is locked and I need to use my own pin number to unlock it so that you know who I am, and if I'm not who I say I am then you can divert the mail into the shredder.

Or the other option is that I sign the mail with a private key before I send it. You can check that the signature is real by validating it with a public key that I securely sent you before. If the mail isn't signed then you treat it as a possible forgery by default and you check using some other method that it's real.


----------



## reddy (Jan 28, 2019)

My thinking was that the Milter API would expose the name of the user relaying the email as an environment variable so that I can implement the logic myself.

In my situation, all users relay their emails using their own Unix system account (this is not for example a webmail situation).

I haven't looked at the milter API in absolute depth so maybe my assumption is wrong. If I understand correctly, what you are saying is that in the absence of SMTP authentication, the sendmail delivery pipeline keeps no knowledge of which user presented a mail for delivery.


----------



## SirDice (Jan 28, 2019)

reddy said:


> My thinking was that the Milter API would expose the name of the user relaying the email as an environment variable so that I can implement the logic myself.


A user's environment variables aren't passed to the MTA so the filter has no access to them either. Any MTA simply assumes the From: header is correct, there's no validation at all. This is a problem with the SMTP protocol itself. SMTP was designed when security wasn't an issue, and we're basically still using the same 40 year old protocol. No amount of filtering on the MTA side is going to change the way SMTP works. The only way to be reasonable sure is to enable authentication. 



reddy said:


> If I understand correctly, what you are saying is that in the absence of SMTP authentication, the sendmail delivery pipeline keeps no knowledge of which user presented a mail for delivery.


Correct.


----------



## usdmatt (Jan 28, 2019)

Surprised to hear anyone prefer Sendmail configuration over Postfix...

Anyway, if the users all send from the local system, _maybe _there might be a way of seeing what user is sending the email, but I suspect this would need to be done during submission. Once Sendmail has the message and further processing will almost certainly be done using the standard sendmail user accounts.
(Before posting this SirDice suggests this may be impossible)

Regarding a bruteforce vector, practically anything open to the Internet gets hammered, even if it's futile. You could enable auth on port 587, which is the port clients submitting smtp email should of always been using anyway, and lock that port down if all submission is local. If submission is at all possible from other hosts they you likely want smtp auth anyway. Setting up something like fail2ban is easy enough to automatically block any bruteforce attacks if the port is open globally, and will also catch attacks that aren't just authentication attempts.


----------

