Add private relay.
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
Here is a history of user visible changes to Python milter.
|
Here is a history of user visible changes to Python milter.
|
||||||
|
0.8.8 move AddrCache, parse_addr, iniplist, parse_header to Milter package
|
||||||
|
fix plock for missing source and can't change owner/group
|
||||||
|
add sample spfmilter.py milter
|
||||||
0.8.7 Move spf module to pyspf
|
0.8.7 Move spf module to pyspf
|
||||||
Prevent PTR cache poisoning
|
Prevent PTR cache poisoning
|
||||||
More lame bounce heuristics
|
More lame bounce heuristics
|
||||||
|
|||||||
@@ -51,8 +51,9 @@ Xpythonfilter, S=local:/home/username/pythonsock
|
|||||||
Note that milters should almost certainly not run as root.
|
Note that milters should almost certainly not run as root.
|
||||||
|
|
||||||
That's it. Incoming mail will cause the milter to print some things, and
|
That's it. Incoming mail will cause the milter to print some things, and
|
||||||
some email will be rejected (see the "header" method). Edit and play. See
|
some email will be rejected (see the "header" method). Edit and play.
|
||||||
bms.py for an example milter used in production.
|
See spfmilter.py for a functional SPF milter, or see bms.py for an complex
|
||||||
|
milter used in production.
|
||||||
|
|
||||||
|
|
||||||
Not-so-quick Installation
|
Not-so-quick Installation
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
|
Need to use wildcards in blacklist.log: *.madcowsrecord.net
|
||||||
|
Need to exclude emails like !*-admin@example.com in whitelist_sender.
|
||||||
Need to exclude robot users from autowhitelist. Don't want to have to
|
Need to exclude robot users from autowhitelist. Don't want to have to
|
||||||
list all users, so implement something like !*-admin@bmsi.com,@bmsi.com.
|
list all users, so implement something like !*-admin@bmsi.com,@bmsi.com.
|
||||||
|
|
||||||
Milter won't start when a whitelist/blacklist file is missing.
|
|
||||||
|
|
||||||
Milter won't start when it can't change permissions on *.lock to match
|
|
||||||
*.log. Should maybe ignore that error - the effect will be to set
|
|
||||||
the permissions to default.
|
|
||||||
|
|
||||||
GOSSiP feedback from user training is ignored because UMIS has already been
|
GOSSiP feedback from user training is ignored because UMIS has already been
|
||||||
removed from queue. Maybe keep UMIS in queue, and add method to
|
removed from queue. Maybe keep UMIS in queue, and add method to
|
||||||
alter last feedback for ID.
|
alter last feedback for ID.
|
||||||
@@ -15,27 +11,17 @@ Generate DSNs according to RFC 3464
|
|||||||
|
|
||||||
Get temperror policy from access file.
|
Get temperror policy from access file.
|
||||||
|
|
||||||
When training with spam, REJECT after data so that mistakenly blacklisted
|
|
||||||
senders at least get an error.
|
|
||||||
|
|
||||||
Reporting explanation for failure should show source if sender
|
Reporting explanation for failure should show source if sender
|
||||||
provided explanation.
|
provided explanation.
|
||||||
|
|
||||||
Bug in Auto-whitelist. Recent Auto-whitelist doesn't override expired entry.
|
Bug in Auto-whitelist. Recent Auto-whitelist doesn't override expired entry.
|
||||||
|
|
||||||
Need to use wildcards in blacklist.log: *.madcowsrecord.net
|
|
||||||
Need to exclude emails like !*-admin@example.com in whitelist_sender.
|
|
||||||
|
|
||||||
SPF permerror diagnostics should include corrected mechanism.
|
SPF permerror diagnostics should include corrected mechanism.
|
||||||
|
|
||||||
Delay SPF check until RCPT TO. Cache result to avoid repeating
|
Delay SPF check until RCPT TO. Cache result to avoid repeating
|
||||||
for multiple RCPT. This avoids overhead for invalid RCPT, and
|
for multiple RCPT. This avoids overhead for invalid RCPT, and
|
||||||
allows for per RCPT local policy.
|
allows for per RCPT local policy.
|
||||||
|
|
||||||
Add auto-blacklisted senders to blacklist.log with timestamp.
|
|
||||||
|
|
||||||
Received-SPF header field should show identity that was checked.
|
|
||||||
|
|
||||||
Check SPF for outgoing mail (including local policy for internal addresses).
|
Check SPF for outgoing mail (including local policy for internal addresses).
|
||||||
This could also solve the second part of the mail from relay problem below.
|
This could also solve the second part of the mail from relay problem below.
|
||||||
|
|
||||||
@@ -47,6 +33,7 @@ For selected domains, check rcpts via CBV before accepting mail. Cache
|
|||||||
results. This will kick out dictonary attacks against a mail domain
|
results. This will kick out dictonary attacks against a mail domain
|
||||||
behind a gateway sooner.
|
behind a gateway sooner.
|
||||||
|
|
||||||
|
Add auto-blacklisted senders to blacklist.log with timestamp.
|
||||||
Add emails blacklisted via CBV so that they are remembered across milter
|
Add emails blacklisted via CBV so that they are remembered across milter
|
||||||
restarts.
|
restarts.
|
||||||
|
|
||||||
@@ -59,9 +46,6 @@ to train on error to minimize labor.
|
|||||||
Allow unsigned DSNs from selected domains (that don't accept signed MFROM,
|
Allow unsigned DSNs from selected domains (that don't accept signed MFROM,
|
||||||
e.g. verizon.net).
|
e.g. verizon.net).
|
||||||
|
|
||||||
Added Message-ID header to DSN with SRS signed sender. When seen on incoming
|
|
||||||
rfc ignorant failure message, blacklist sender.
|
|
||||||
|
|
||||||
Allow verified hostnames for trusted_relay. E.g. HELO name that
|
Allow verified hostnames for trusted_relay. E.g. HELO name that
|
||||||
passes SPF.
|
passes SPF.
|
||||||
|
|
||||||
@@ -86,11 +70,9 @@ wildcard (e.g. empty localpart).
|
|||||||
Quarantined mail is missing headers modified/added by milter after
|
Quarantined mail is missing headers modified/added by milter after
|
||||||
checking dspam.
|
checking dspam.
|
||||||
|
|
||||||
Require signed MFROM for all incoming bounces when signing all outgoing mail -
|
|
||||||
except from trusted relays.
|
|
||||||
|
|
||||||
Send DSN for permerror before processing extended result. An additional
|
Send DSN for permerror before processing extended result. An additional
|
||||||
DSN may be sent based on extended result.
|
DSN may be sent based on extended result. Send permerror DSN to
|
||||||
|
postmaster@sending_domain.
|
||||||
|
|
||||||
Rescind whitelist for banned extensions, in case sender is infected.
|
Rescind whitelist for banned extensions, in case sender is infected.
|
||||||
|
|
||||||
@@ -104,9 +86,6 @@ SPF-Neutral:aol.com ERROR:"550 AOL mail must get SPF PASS"
|
|||||||
Defer TEMPERROR in SPF evaluation - give precedence to security
|
Defer TEMPERROR in SPF evaluation - give precedence to security
|
||||||
(only defer for PASS mechanisms).
|
(only defer for PASS mechanisms).
|
||||||
|
|
||||||
Option to add Received-SPF header, but never reject on SPF.
|
|
||||||
I think the above will handle this.
|
|
||||||
|
|
||||||
Create null config that does nothing - except maybe add Received-SPF
|
Create null config that does nothing - except maybe add Received-SPF
|
||||||
headers. Many admins would like to turn features on one at a time.
|
headers. Many admins would like to turn features on one at a time.
|
||||||
|
|
||||||
@@ -153,6 +132,26 @@ Need a test module to feed sample messages to a milter though a live
|
|||||||
sendmail and SMTP. The mockup currently used is probably not very accurate,
|
sendmail and SMTP. The mockup currently used is probably not very accurate,
|
||||||
and doesn't test the threading code.
|
and doesn't test the threading code.
|
||||||
|
|
||||||
|
DONE Require signed MFROM for all incoming bounces when signing all outgoing
|
||||||
|
mail - except from trusted relays.
|
||||||
|
|
||||||
|
DONE Added Message-ID header to DSN with SRS signed sender. When seen on
|
||||||
|
incoming rfc ignorant failure message, blacklist sender.
|
||||||
|
|
||||||
|
DONE Option to add Received-SPF header, but never reject on SPF.
|
||||||
|
I think the above will handle this.
|
||||||
|
|
||||||
|
DONE Received-SPF header field should show identity that was checked.
|
||||||
|
|
||||||
|
DONE When training with spam, REJECT after data so that mistakenly blacklisted
|
||||||
|
senders at least get an error.
|
||||||
|
|
||||||
|
DONE Milter won't start when it can't change permissions on *.lock to match
|
||||||
|
*.log. Should maybe ignore that error - the effect will be to set
|
||||||
|
the permissions to default.
|
||||||
|
|
||||||
|
DONE Milter won't start when a whitelist/blacklist file is missing.
|
||||||
|
|
||||||
DONE Delayed failure detection should parse From header to find email address.
|
DONE Delayed failure detection should parse From header to find email address.
|
||||||
|
|
||||||
DONE When bms.py can't find templates, it passes None to dsn.create_msg(),
|
DONE When bms.py can't find templates, it passes None to dsn.create_msg(),
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# A simple milter that has grown quite a bit.
|
# A simple milter that has grown quite a bit.
|
||||||
# $Log$
|
# $Log$
|
||||||
|
# Revision 1.89 2007/01/22 02:46:01 customdesigned
|
||||||
|
# Convert tabs to spaces.
|
||||||
|
#
|
||||||
# Revision 1.88 2007/01/19 23:31:38 customdesigned
|
# Revision 1.88 2007/01/19 23:31:38 customdesigned
|
||||||
# Move parse_header to Milter.utils.
|
# Move parse_header to Milter.utils.
|
||||||
# Test case for delayed DSN parsing.
|
# Test case for delayed DSN parsing.
|
||||||
@@ -157,6 +160,7 @@ scan_html = True
|
|||||||
scan_rfc822 = True
|
scan_rfc822 = True
|
||||||
internal_connect = ()
|
internal_connect = ()
|
||||||
trusted_relay = ()
|
trusted_relay = ()
|
||||||
|
private_relay = ()
|
||||||
trusted_forwarder = ()
|
trusted_forwarder = ()
|
||||||
internal_domains = ()
|
internal_domains = ()
|
||||||
banned_users = ()
|
banned_users = ()
|
||||||
@@ -222,7 +226,7 @@ def read_config(list):
|
|||||||
tempfile.tempdir = cp.get('milter','tempdir')
|
tempfile.tempdir = cp.get('milter','tempdir')
|
||||||
global socketname, timeout, check_user, log_headers
|
global socketname, timeout, check_user, log_headers
|
||||||
global internal_connect, internal_domains, trusted_relay, hello_blacklist
|
global internal_connect, internal_domains, trusted_relay, hello_blacklist
|
||||||
global case_sensitive_localpart
|
global case_sensitive_localpart, private_relay
|
||||||
socketname = cp.get('milter','socket')
|
socketname = cp.get('milter','socket')
|
||||||
timeout = cp.getint('milter','timeout')
|
timeout = cp.getint('milter','timeout')
|
||||||
check_user = cp.getaddrset('milter','check_user')
|
check_user = cp.getaddrset('milter','check_user')
|
||||||
@@ -230,6 +234,7 @@ def read_config(list):
|
|||||||
internal_connect = cp.getlist('milter','internal_connect')
|
internal_connect = cp.getlist('milter','internal_connect')
|
||||||
internal_domains = cp.getlist('milter','internal_domains')
|
internal_domains = cp.getlist('milter','internal_domains')
|
||||||
trusted_relay = cp.getlist('milter','trusted_relay')
|
trusted_relay = cp.getlist('milter','trusted_relay')
|
||||||
|
private_relay = cp.getlist('milter','private_relay')
|
||||||
hello_blacklist = cp.getlist('milter','hello_blacklist')
|
hello_blacklist = cp.getlist('milter','hello_blacklist')
|
||||||
case_sensitive_localpart = cp.getboolean('milter','case_sensitive_localpart')
|
case_sensitive_localpart = cp.getboolean('milter','case_sensitive_localpart')
|
||||||
|
|
||||||
@@ -898,6 +903,10 @@ class bmsMilter(Milter.Milter):
|
|||||||
return self.forged_bounce()
|
return self.forged_bounce()
|
||||||
self.data_allowed = not srs_reject_spoofed
|
self.data_allowed = not srs_reject_spoofed
|
||||||
|
|
||||||
|
if not self.internal_connection and domain in private_relay:
|
||||||
|
self.log('REJECT: RELAY:',to)
|
||||||
|
self.setreply('550','5.7.1','Unauthorized relay for %s' % domain)
|
||||||
|
return Milter.REJECT
|
||||||
# non DSN mail to SRS address will bounce due to invalid local part
|
# non DSN mail to SRS address will bounce due to invalid local part
|
||||||
canon_to = '@'.join(t)
|
canon_to = '@'.join(t)
|
||||||
self.recipients.append(canon_to)
|
self.recipients.append(canon_to)
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ log_headers = 0
|
|||||||
# SPF checks are bypassed for internal connections and trusted relays.
|
# SPF checks are bypassed for internal connections and trusted relays.
|
||||||
;trusted_relay = 1.2.3.4, 66.12.34.56
|
;trusted_relay = 1.2.3.4, 66.12.34.56
|
||||||
|
|
||||||
|
# Relaying to these domains is allowed from internal connections only.
|
||||||
|
;private_relay = mycorp.com
|
||||||
|
|
||||||
# Reject external senders with hello names no legit external sender would use.
|
# Reject external senders with hello names no legit external sender would use.
|
||||||
# SPF will do this also, but listing your own domain and mailserver here
|
# SPF will do this also, but listing your own domain and mailserver here
|
||||||
# will save some DNS lookups when rejecting certain viruses.
|
# will save some DNS lookups when rejecting certain viruses.
|
||||||
|
|||||||
Reference in New Issue
Block a user