Installation:
The starting point for this script was from here:
http://web.archive.org/web/20151128083440/https://www.kutukupret.com/2011/05/29/postfix-geoip-based-rejections/
You need:
- Linux machine with-
- Perl
- Perl Geo::IP module
- and of course "Postfix" (MTA)
-
You will need to add the script above somewhere on your system.
/etc/postfix/scripts/postfix-geoip.pl
would probably be a good place. It doesn't really matter where it is placed, though. Keep in mind the permissions & owner will need to be correct no matter where you put it.Once placed, make sure it's owned by root and can be run by the "nobody" user. (It should be owned by root to avoid postfix warnings):
sudo chown root: /etc/postfix/scripts /etc/postfix/scripts/postfix-geoip.pl sudo chmod 755 /etc/postfix/scripts/postfix-geoip.pl
-
Once the script is owned correctly and executable on the Postfix system, you will need to edit the Postfix configuration.
Edit
sudo nano /etc/postfix/main.cf
and findsmtpd_client_restrictions =
and add a 'check_client_access' directive under it (just make sure it has a comma on end and is above the final 'permit') Leave any other directives you may see (the dots '...') in place.:smtpd_client_restrictions = ... check_client_access tcp:[127.0.0.1]:2528, ... permit
Example:
NOTE: It may be a better idea to place this under
smtpd_helo_restrictions
since this is the very first check. If it's a bad IP, it should go no further. Less system resources would be used to check and 'block' a connected IP under HELO hypothetically. I usedsmtpd_client_restrictions
for my own reasons. Either area should work. I haven't tested it under helo restrictions, though. -
Next, edit the
/etc/postfix/master.cf
file and put this bit at the very bottom of this file:127.0.0.1:2528 inet n n n - 0 spawn user=nobody argv=/etc/postfix/scripts/postfix-geoip.pl
-
Next install GeoIP system wide. Debian/Ubuntu
apt
example:sudo apt update -y && sudo apt install libgeo-ip-perl
OR: If using cpan to install the module:
sudo cpan install Geo::IP
Configuration is complete. Restart Postfix:
sudo systemctl restart postfix
Test / check mail.log / etc.
Hi @bmatthewshea,
First, thanks for the detailed reply! Though you underestimate my ability to break things. :)
I can't get any response on 2528 with netstat. I confirmed the 755 permissions set on the script directory, and the script itself, so Postfix should definitely be able to access it. If the script was accessed but failed to run, would it also give a connection refused?
My master.cf line is actually this:
127.0.0.1:2528 inet n n n - 0 spawn
user=nobody argv=perl /etc/postfix/scripts/postfix-geoip.pl
... on AlmaLinux / CentOS, perl scripts can't be run natively, they need to be an argument of the perl command. So I don't know if the space in there would cause an issue -- I'd think not. Other than that, if Geo::IP is not installed (which I don't believe it is), the script should also fail (or hang), causing a "connection refused" too?
I tried completely disabling the firewall, but still no dice. I wonder if there's a setting somewhere preventing the port connection on loopback. In main.cf I do have inet_interfaces = all, and I tried uncommenting mynetworks = 127.0.0.0/8, but no effect.
@ShamimIslam,
Yeah, I don't know about that. There's well over a hundred perl modules installed on my system right now, and if I yank them all off to install the CPAN thing, that WILL break everything. CPAN itself appears to install fine, but using it to then install the Geo::IP module hangs: "Fetching with LWP: http://www.cpan.org/authors/01mailrc.txt.gz..." . I suspect that my system is blocking a download from an http: site, which in 2024 is no-bueno (indeed, trying to download it on my Windows browser also results in the file being blocked). Googling this issue doesn't result in anything useful that I could find.