Tag: exim

  • Correctly configuring incoming SPF in Exim on Debian

    The Debian documentation is sparse on how to correctly configure incoming SPF checks in the Debian Exim package.

    It is sparse in the sense that it tells you what to install (spf-tools-perl) but it is not clear WHERE to put the very important macro. It only says:

    This is provided via the macro CHECK_RCPT_SPF, set it to true.

    Fine, but where!?

    Answer: you should put this macro at the top of your configuration file (/etc/exim4/exim4.conf.template).

    At least I did and put it on line 23. After trying out different places.

    Next, you run:
    update-exim4.conf
    /etc/init.d/exim4 restart

    And that’s it. I couldn’t find it anywhere so I put it here.

    More on SPF

    With this setting, Exim will check your incoming mail for valid SPF records. Because the check was not in place on my server it was possible for spammers to say to my mailserver that they were sending mail on behalf of my mailserver!

    This is *not* what you want.

    SPF best practices

    When configuring this I also found I had a couple of mistakes in my SPF records.

    server.j11g.com instead of *.j11g.com
    1. I had set a SPF record on a wildcard (*.j11g.com) subdomain. But this does not work properly. Specify the subdomain, and configure the record.
    2. I was missing a MX record for the subdomain. Also specifically set this.
    3. There was an IPv6 error in my SPF record. A semicolon (of course). There are lots of sites to test your SPF records. Here is a good one and another. They will point out errors.
    4. I use an include in my SPF record. I am still not sure where to put it, but it looks like the best practice is to put it before the IP addresses. Like so:

      v=spf1 mx include:spf.solcon.nl ip4:157.90.24.20 ip4:212.84.154.148 ip6:2001:9e0:8606:8f00::/56 ip6:2a01:4f8:1c1c:79a1::/56 -all
    5. I switched from ~all to -all. To drop all mail that does comply with the SPF record.

    Tests

    me@remoteserver:~# telnet server.j11g.com 25
    Trying 157.90.24.20...
    Connected to server.j11g.com.
    Escape character is '^]'.
    220 server.j11g.com ESMTP Exim 4.92 Sat, 22 Jul 2023 10:17:30 +0200
    ehlo jan.com
    250-server.j11g.com Hello remotemachine.test [77.72.*.*]
    250-SIZE 52428800
    250-8BITMIME
    250-PIPELINING
    250-CHUNKING
    250-STARTTLS
    250 HELP
    MAIL FROM:info@posthistorie.nl
    250 OK
    RCPT TO:janvdberg@gmail.com
    550 relay not permitted
    RCPT TO: jan@server.j11g.com
    550-[SPF] 77.72.150.187 is not allowed to send mail from posthistorie.nl. 
    550 Please see http://www.openspf.org/Why?scope=mfrom;identity=info@posthistorie.nl;ip=77.72.*.*

    The log on the server looks like this:

    2023-07-22 10:18:03 H=remoteserver (jan.com) [77.72.*.*] F=<info@posthistorie.nl> rejected RCPT janvdberg@gmail.com: relay not permitted
    2023-07-22 10:18:29 H=remoteserver (jan.com) [77.72.*.*] F=<info@posthistorie.nl> rejected RCPT jan@server.j11g.com: SPF check failed.
  • Bypassing Hetzner mail port block (port 25/465)

    I recently switched my VPS from Linode to Hetzner. I got more CPU, RAM and storage for less money. Pretty good right?

    However it wasn’t after I migrated that I found out Hetzner blocks all outgoing port 25 and 465 traffic.

    At least; for the first month for new customers.

    This means my new server cannot talk SMTP with the rest of the world i.e. my server cannot send mail!

    (Note: you can however connect to mailservers that listen on port 587).

    I can see why they would do this, however this is less than ideal if you have a production server with a couple of webshops.

    So, now what?

    My server cannot send mail itself but it can also not connect to a smarthost (a different server that does the mail sending), because smarthosts are typically also on port 25/465.

    I do however have a Raspberry Pi in my home network. What if I run a mail server on a different port there, say 2500?

    So, my VPS can relay the mail there. But I don’t want my Pi to be connected to the internet and send mail. So then what? Why not relay from the Pi to an actual smarthost. Which smarthost? Well my ISP offers authenticated SMTP so I can relay mail from my VPS to my Pi and from my Pi to my ISP. And my ISP can send the mail to anywhere.

    This could work.

    The setup

    This is what it looks like.

    There are two mail server configurations in place. I use exim4 on Debian and you can easily run dpkg-reconfigure exim4-config to (re)create a valid Exim config.

    This command will (re)create a file which holds all specific Exim configuration: /etc/exim4/update-exim4.conf.conf

    It’s a small and easy to understand file. Here follow the complete contents of both files, for reference.

    Hetzner VPS exim4 config

    dc_eximconfig_configtype='satellite'
    dc_other_hostnames='topicalcovers.com;brug.info;piks.nl;j11g.com;posthistorie.nl;server.j11g.com'
    dc_local_interfaces='157.90.24.20'
    dc_readhost=''
    dc_relay_domains=''
    dc_minimaldns='false'
    dc_relay_nets=''
    dc_smarthost='212.84.154.148::2500'
    CFILEMODE='644'
    dc_use_split_config='false'
    dc_hide_mailname='false'
    dc_mailname_in_oh='true'
    dc_localdelivery='mail_spool'

    Note: use a double semi-colon to specify a mailserver that listens on a different port.

    Raspberry Pi exim4 config

    dc_eximconfig_configtype='smarthost'
    dc_other_hostnames=''
    dc_local_interfaces='192.168.178.135'
    dc_readhost=''
    dc_relay_domains='posthistorie.nl,topicalcovers.com,piks.nl,j11g.com,server.j11g.com,willempasterkamp.nl'
    dc_minimaldns='false'
    dc_relay_nets='157.90.24.20'
    dc_smarthost='mail.solcon.nl'
    CFILEMODE='644'
    dc_use_split_config='false'
    dc_hide_mailname='false'
    dc_mailname_in_oh='true'
    dc_localdelivery='mail_spool'

    For this to work you also need to edit your file /etc/exim4/passwd.client with the a valid mailboxname and password:

    mail.solcon.nl:authorizedmailboxname:pa$$word

    Or use an asterisk ( * ) to use the credentials for every mailserver. If you (only) use a smarthost, this is fine.

    SPF records

    The above configs are what you need to do on your Hetzner VPS and your Pi. Next, you need to change your SPF records.

    The SPF records tell the receiving mailserver that the sending mailserver is allowed to relay/send mail for a specific domain.

    As you can tell I have multiple domains, so that means editting multiple SPF records. Here is what one SPF records looks like. This is public information, anyone can (and should) look up your domain SPF records.

    This is the raw SPF record:

    v=spf1 mx ip4:212.84.154.148 ip4:157.90.24.20 ip4:212.45.32.0/24 ip6:2001:9e0:8606:8f00::1 ip6:2a01:7e01::f03c:91ff:fe02:b21b ip6:2001:9e0:4:32::107 ip6:2001:9e0:4:32::108 ip6:2a01:4f8:1c1c:79a1::1 ~all

    You can see it’s a mix of IPv4 and IPv6. For readability, the next image is what it actually says.

    MX – All mail for this domain should be send TO a specific IPv4 or IPv6 address.

    Next: you can see which IPv4 and IPv6 addresses are allowed to send mail for this domain. So where mail is accepted FROM.

    So if my VPS wants to send a mail to @gmail.com it will relay the mail to my Pi, which will happily accept the mail, and will relay it to my ISP mail server, and my ISP mail server will try to deliver the mail to Google Mail. Google Mail however will CHECK if the IP address for my ISP mail server MATCHES the SPF records. If Google finds that the IP addresses from my ISP mail servers are not in the SPF records, it will not accept the mail. But if they match, Google Mail will accept the mail.