Exim restrict one “from address” domain to to o​ne system user

exim

I run a shared server for my clients' websites (ubuntu 16.04). I run exim to allow the websites to send out email. It also acts as a mail forwarder and smtp server for my cleints' email software (or just gmail) to allow them to send email from their forwarders.

I currently restrict sending emails for remote users to allow the "from" address only if it matches their smtp username (to stop one client being able to send email as another client). The remote smtp users are not system users, they are just credentials stored in a passwd file. That works great.

The only email sent by local users are from php scripts. Each website runs as a different user. E.g. example.com runs as user "example", test.com runs as user "test". My question is, how can I restrict the local user accounts to only be able to send email from one domain? So that user "test" can send from anyaddress@test.com but can't send from anyaddress@example.com?

Ideally, I would like the test script to look in a file such as conf/env{USER}/allowed-from-domains and test the domain of the From: field to make sure it was in that file.

Best Answer

The configuration below makes exim block messages from users example and test when the From header does not contain "@example.com" or "@test.net", respectively.

I use the system filter to inspect the From header line, which is available only after the message is accepted.

exim.conf:

system_filter  = /etc/exim/system_filter.conf
qualify_domain = mydomain.net

system_filter.conf:

if $sender_address is "example@$qualify_domain" and not $h_from contains "@example.com"
or $sender_address is    "test@$qualify_domain" and not $h_from contains "@test.net"
then
  seen finish
endif

test outgoing mail for local user test

test.php

#!/bin/php
<?php
mail( "me@gmail.com", "Pass Test", "My message", "From: Me <anything@test.net>" );
mail( "me@gmail.com", "Fail Test", "My message", "From: Me <anything@nottest.net>" );
?>

Web Server Notes

This all assumes php is somehow being invoked by the clients' user account. You'll probably need to reconfigure your webserver to do this. For example, the apache webserver usually runs scripts as user "apache", rather than "test" or "example", which is what we want. Apache would need to be configured with something like mod_privileges.c, or mpm-itk.

If your webserver is configured to use CGI/FastCGI mode, you might be able to do this by adding [HOST=example.com] and [HOST=test.net] sections to php.ini.

References:

Related Topic