后缀 – 被未知的收件人电子邮件拒绝垃圾邮件学习邮箱拒绝

我有Postfix + BitDefender FRAMS作为卫生网关在less数交换之前运行。 BD FRAMS可以通过从专用邮箱下载垃圾邮件和HAM邮件来学习它的Baesianfilter。 因为我们已经支持垃圾邮件stream向未知收件人,所以我有意将这个有用的垃圾邮件源直接redirect到垃圾邮件学习邮箱。

我的configuration:

main.cf:

myhostname = posfix.example.com smtpd_banner = $myhostname #myorigin = example.com mydestination = local_recipient_maps = #virtual_alias_maps = hash:/etc/postfix/virtual local_transport = error:local mail delivery is disabled mynetworks = /etc/postfix/mynetworks smtpd_use_tls = yes #smtpd_tls_auth_only = yes smtpd_tls_key_file = /etc/ssl/certs/posfix.example.com.pem smtpd_tls_cert_file = /etc/ssl/certs/posfix.example.com.pem smtpd_tls_CApath = /etc/ssl/certs smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s relay_domains = mysql:/etc/postfix/relay_domains transport_maps = mysql:/etc/postfix/transport relay_recipient_maps = mysql:/etc/postfix/relay_recipient_maps show_user_unknown_table_name = no unknown_local_recipient_reject_code = 550 mailbox_size_limit = 102400000000 message_size_limit = 102400000 smtpd_delay_reject = yes smtpd_helo_required = yes #smtpd_helo_restrictions = # permit_mynetworks # reject_invalid_hostname # permit smtpd_restriction_classes = verify_sender verify_sender = reject_unverified_sender smtpd_sender_restrictions = permit_mynetworks smtpd_recipient_restrictions = reject_unknown_recipient_domain reject_non_fqdn_recipient permit_mynetworks reject_authenticated_sender_login_mismatch reject_unauth_destination check_recipient_access hash:/etc/postfix/recipient_access check_sender_access hash:/etc/postfix/sender_access #check_helo_access pcre:/etc/postfix/helo_access reject_non_fqdn_sender reject_unknown_sender_domain reject_unlisted_sender reject_invalid_hostname reject_unauth_pipelining check_sender_mx_access cidr:/etc/postfix/sender_mx_access #reject_non_fqdn_hostname #reject_unverified_sender #reject_multi_recipient_bounce permit #smtpd_data_restrictions = #reject_multi_recipient_bounce # Added by BitDefender on Mon Nov 3 15:27:43 EET 2014 smtpd_milters=unix:/var/spool/postfix/BitDefender/bdmilterd.sock milter_protocol = 2 milter_default_action = tempfail milter_connect_timeout = 30s milter_command_timeout = 30s milter_content_timeout = 30s # End of added lines 

/等/后缀/ relay_domains:

 user = postfix password = postfix dbname = postfix query = SELECT name FROM relay_domains WHERE name='%s' 

在/ etc /后缀/运输:

 user = postfix password = postfix dbname = postfix query = SELECT nexthop FROM relay_domains WHERE name='%s' 

/等/后缀/ relay_recipient_maps:

 user = postfix password = postfix dbname = postfix query = SELECT email FROM relay_users WHERE email='%s' 

我的脚本填补继电器 – 用户从公元(好心分享给你)的cron:

 #!/usr/bin/python __author__ = 'tiv' import ldap import MySQLdb connections = { 1: ['dc.example.com', # AD domain controller 'EXAMPLE\\user', # AD user 'password', # AD user password 'dc=example, dc=local', # AD root DN 'mail.example.com'], # Exchange server 2: ['dc.example1.com', # AD domain controller 'EXAMPLE1\\user', # AD user 'password', # AD user password 'dc=example1, dc=local', # AD root DN 'mail.example1.com'], # Exchange server #3: 'dc.example2.com', # AD domain controller # 'EXAMPLE2\\user', # AD user # 'password', # AD user password # 'dc=example2, dc=local', # AD root DN # 'mail.example2.com'], # Exchange server } mysql = ['localhost', # host 'postfix', # user 'postfix', # password 'postfix'] # schema def main(): try: emails = [] domains = [] for i in connections: connection = connections[i] print('Processing LDAP server ' + connection[0] + ':') basedn = connections[i][3] nexthop = connections[i][4] lc = ldapconnection(connection) ls = ldapsearch(lc, basedn) rl = resultlist(ls) emails.extend(rl[0]) for domain in rl[1]: domains.append([domain, nexthop]) print('Processing of LDAP server ' + connection[0] + ' completed.') createdb(emails, domains, mysql) print('Operation completed successfully!') except: print('Error processing of LDAP server ' + connection[0] + '!') pass def ldapconnection(ldapserver): try: print(' Trying to connect to LDAP server ' + ldapserver[0] + '...') ldapconnection = ldap.initialize('ldap://' + ldapserver[0]) ldapconnection.simple_bind_s(ldapserver[1], ldapserver[2]) ldapconnection.protocol_version = ldap.VERSION3 ldapconnection.set_option(ldap.OPT_REFERRALS, 0) print(' Connection to LDAP server ' + ldapserver[0] + ' succesfull.') except: print('Error connecting to LDAP server ' + ldapserver[0] + '!') pass return ldapconnection def ldapsearch(ldapconnection, basedn): try: print(' Sending LDAP query request...') scope = ldap.SCOPE_SUBTREE filter = '(&(proxyAddresses=smtp:*)(!(objectClass=contact)))' attributes = ['proxyAddresses'] searchresults = ldapconnection.search_s(basedn, scope, filter, attributes) print(' LDAP query request results received.') except: print('Error sending LDAP query request!') pass return searchresults def resultlist(searchresults): try: print(' Processing LDAP query results...') emails = [] domains = [] for i in range(len(searchresults)): try: for j in range(len(searchresults[i][1]['proxyAddresses'])): r = searchresults[i][1]['proxyAddresses'][j].lower() if 'smtp:' in r: email = r[5:] emails.append(email) domain = email.split("@")[1] domains.append(domain) except: pass print(' LDAP query results processed.') except: print('Error processing LDAP query results!') pass return removedublicates(emails), removedublicates(domains) def createdb(emails, domains, mysql): try: print('Connecting to DB ' + mysql[3] + '...') try: db = MySQLdb.connect(host=mysql[0], user=mysql[1], passwd=mysql[2]) cursor = db.cursor() sql = 'CREATE SCHEMA IF NOT EXISTS ' + mysql[3] cursor.execute(sql) db.commit() except: pass try: db = MySQLdb.connect(host=mysql[0], user=mysql[1], passwd=mysql[2], db=mysql[3]) cursor = db.cursor() except: print('Error connecting to DB ' + mysql[3] + '!') print(' Check schemas and tables...') sql = ['CREATE TABLE IF NOT EXISTS ' + mysql[3] + '.relay_users (id INT NOT NULL, email LONGTEXT NULL, PRIMARY KEY (id))', 'CREATE TABLE IF NOT EXISTS ' + mysql[3] + '.relay_domains (id INT NOT NULL, name LONGTEXT NULL, nexthop LONGTEXT NULL, PRIMARY KEY (id))', 'TRUNCATE ' + mysql[3] + '.relay_users', 'TRUNCATE ' + mysql[3] + '.relay_domains'] for i in range(len(sql)): cursor.execute(sql[i]) db.commit() print(' Inserting domains...') for i in range(len(domains)): sql = 'INSERT INTO postfix.relay_domains (id, name, nexthop)' \ 'VALUES ("' + str(i) + '", "' + domains[i][0] + '", "smtp:[' + domains[i][1] + ']")' cursor.execute(sql) db.commit() print(' Inserting emails...') for i in range(len(emails)): sql = 'INSERT INTO postfix.relay_users (id, email)' \ 'VALUES ("' + str(i) + '", "' + emails[i] + '")' cursor.execute(sql) db.commit() db.close() print('Connection to DB ' + mysql[3] + ' closed.') except: print('Error while operating with DB ' + mysql[3] + '!') pass def removedublicates(input): seen = set() seen_add = seen.add return [x for x in input if not (x in seen or seen_add(x))] if __name__ == '__main__': main() 

如果有人知道,如何做到这一点,我将不胜感激。 谢谢。

你的要求有点复杂,因为这个事情。 根据devise,Postfix将根据地图的正面结果执行某些操作 。 例如,在您的transport_maps ,如果收件人从地图查找获得肯定的结果,它将发送电子邮件到特定的主机。 但是,如果您的relay_recipient_maps查找结果为负,则您希望执行某些操作(redirect到另一个邮箱)。 与你的地图types是哈希我认为除非涉及实施负面的结果逻辑在地图上的sql / tcp地图没有其他的方式

对于sql解决scheme,这里是这样的想法:

在这个例子中,我将使用sqlite。 假设你有一个名为relay_recipient的列。 现在查询

 select ifnull(select relay_recipient from mytable WHERE relay_recipient = %s, '[email protected]') 

将在relay_recipient_maps中不存在收件人时返回[email protected]。 将这些映射放在virtual_alias参数上。 然后,每当发送给未知用户的电子邮件,它将被别名为[email protected]

@ tmpl7的+1有一个关于如何用sqlite实现你的场景的好主意

现在,问题是你还没有在virtual_alias_maps参数中为ifnull实现sql查询。 首先在main.cf定义virtual_alias_maps

 virtual_alias_maps = mysql:/etc/postfix/redirect2spamlearning 

/etc/postfix/redirect2spamlearning

 user = postfix password = postfix dbname = postfix query = SELECT IFNULL((SELECT email FROM relay_users WHERE email='%s'), '[email protected]') 

逻辑是:如果SELECT email FROM relay_users WHERE email='%s'不返回任何空值,那么电子邮件将被redirect到[email protected]

  • 在这里看到SQL小提琴
  • 请参阅postconf(5)和virtual(5)中的virtual_alias_maps文档,