Postfix
Postfix - 將被未知收件人拒絕的電子郵件轉發到垃圾郵件學習郵箱
在少數交易所之前,我有 Postfix + BitDefender FRAMS 作為衛生網關執行。BD FRAMS 可以通過從專用郵箱下載垃圾郵件和 HAM 電子郵件來學習它的貝斯過濾器。因為我們有持續向未知收件人發送垃圾郵件,所以我有想法將這個有用的垃圾郵件來源直接重定向到垃圾郵件學習郵箱。
我的配置:
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
/etc/postfix/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'
/etc/postfix/relay_recipient_maps:
user = postfix password = postfix dbname = postfix query = SELECT email FROM relay_users WHERE email='%s'
我為 cron 從 AD 填充中繼使用者的腳本(請為您分享):
#!/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()
如果有人知道如何做到這一點,我將不勝感激。謝謝。
您的請求有點複雜,因為這很重要。根據設計,Postfix 將根據 maps 的積極結果執行某些操作。例如,在您的
transport_maps
中,如果收件人從地圖查找中獲得肯定結果,它將向特定主機發送電子郵件。relay_recipient_maps
但是,如果您的查找有負面結果,您想要執行某些操作 - 重定向到另一個郵箱。由於您的地圖類型是hash,我認為沒有其他方法,除非涉及 sql/tcp 地圖以在地圖中實現否定結果邏輯。對於 sql 解決方案,這是一個想法:
在這個例子中,我將使用 sqlite。假設您有一個表,其中有一列名為 relay_recipient。現在查詢
select ifnull(select relay_recipient from mytable WHERE relay_recipient = %s, 'mailboxspam@example.com')
mailboxspam@example.com
只要接收者在 relay_recipient_maps 中不存在,就會返回。將這些地圖放在virtual_alias
參數上。然後每當電子郵件發送給未知使用者時,它就會別名為mailboxspam@example.com