我有一个 VPS,它原本打算用作网络服务器,但也需要部署一些最小的邮件功能,包括作为独立服务器发送和接收。
当前设置如下:
- Postfix 接收邮件,用户位于虚拟表中,存储在 MySQL 中
- 在连接时,所有服务器都针对某些 DNSBL 使用 policyd-weight 服务进行测试
- 所有邮件均在 spamc 客户端的帮助下通过 SpamAssassin spamd 运行
- 然后邮件通过 Dovecot 2 的 LDA(本地投递代理)和虚拟用户进行投递
正如您所看到的...
- 没有运行病毒扫描程序,这是有原因的:clamav 占用了所有可能的内存,而且,使用此设置会过滤掉所有病毒邮件(我已经对启用 ClamAV 进行了 1.5 年的测试,没有一封病毒邮件到达 ClamAV)
- 我不用 amavisd,也不想用。只有内存足够的时候才需要这个怪物和很多扫描仪同时扫描。手动微调也是一场噩梦。
- 我在 postfix 中运行 policyd-weight,而不是 policyd 和本机 DNSBL。我不喜欢因为一项服务列出了某人而将他们赶走。
重要声明:一切正常。我收到的垃圾邮件数量非常少,几乎从未收到过误报,大多数坏邮件都被 policyd-weight 阻止了。我觉得唯一的“问题”是这些服务总体上占用了太多内存。
我已经删减了 spamassassin 的模块(见下文),但我真的很想听听一些关于如何尽可能减少内存占用的建议,主要是:就我目前的 postfix 和 policyd-weight 设置而言,SpamAssassin 真正需要哪些插件,哪些插件或多或少是无用的?
SpamAssassin 规则也使用 sa-compile 进行编译(sa-update 每周从 cron 运行一次,编译随后立即运行)
这些是一些可能重要的当前配置,如果您需要更多信息,请告诉我。
postfix/master.cf
(仅限零件)
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/bin/spamc -e /usr/lib/dovecot/deliver -d ${recipient} -f {sender}
postfix/main.cf
(仅限零件)
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks,
reject_invalid_hostname,
permit
smtpd_recipient_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unauth_pipelining,
reject_unauth_destination,
check_policy_service inet:127.0.0.1:12525,
permit
policyd-weight.conf
(仅限零件)
$REJECTMSG = "550 Mail appeared to be SPAM or forged. Ask your Mail/DNS-Administrator to correct HELO and DNS MX settings or to get removed from DNSBLs";
$REJECTLEVEL = 4;
$DEFER_STRING = 'IN_SPAMCOP= BOGUS_MX=';
$DEFER_ACTION = '450';
$DEFER_LEVEL = 5;
$DNSERRMSG = '450 No DNS entries for your MTA, HELO and Domain. Contact YOUR administrator';
# 1: ON, 0: OFF (default)
# If ON request that ALL clients are only checked against RBLs
$dnsbl_checks_only = 0;
# 1: ON (default), 0: OFF
# When set to ON it logs only RBLs which affect scoring (positive or negative)
$LOG_BAD_RBL_ONLY = 1;
## DNSBL settings
@dnsbl_score = (
# host, hit, miss, log name
'dnsbl.ahbl.org', 3, -1, 'dnsbl.ahbl.org',
'dnsbl.njabl.org', 3, -1, 'dnsbl.njabl.org',
'dnsbl.sorbs.net', 3, -1, 'dnsbl.sorbs.net',
'bl.spamcop.net', 3, -1, 'bl.spamcop.net',
'zen.spamhaus.org', 3, -1, 'zen.spamhaus.org',
'pbl.spamhaus.org', 3, -1, 'pbl.spamhaus.org',
'cbl.abuseat.org', 3, -1, 'cbl.abuseat.org',
'list.dsbl.org', 3, -1, 'list.dsbl.org',
);
# If Client IP is listed in MORE DNSBLS than this var, it gets REJECTed immediately
$MAXDNSBLHITS = 3;
# alternatively, if the score of DNSBLs is ABOVE this level, reject immediately
$MAXDNSBLSCORE = 9;
$MAXDNSBLMSG = '550 Az levelezoszerveruk IP cime tul sok spamlistan talahato, kerjuk ellenorizze! / Your MTA is listed in too many DNSBLs; please check.';
## RHSBL settings
@rhsbl_score = (
'multi.surbl.org', 4, 0, 'multi.surbl.org',
'rhsbl.ahbl.org', 4, 0, 'rhsbl.ahbl.org',
'dsn.rfc-ignorant.org', 4, 0, 'dsn.rfc-ignorant.org',
# 'postmaster.rfc-ignorant.org', 0.1, 0, 'postmaster.rfc-ignorant.org',
# 'abuse.rfc-ignorant.org', 0.1, 0, 'abuse.rfc-ignorant.org'
);
# skip a RBL if this RBL had this many continuous errors
$BL_ERROR_SKIP = 2;
# skip a RBL for that many times
$BL_SKIP_RELEASE = 10;
## cache stuff
# must be a directory (add trailing slash)
$LOCKPATH = '/var/run/policyd-weight/';
# socket path for the cache daemon.
$SPATH = $LOCKPATH.'/polw.sock';
# how many seconds the cache may be idle before starting maintenance routines
#NOTE: standard maintenance jobs happen regardless of this setting.
$MAXIDLECACHE = 60;
# after this number of requests do following maintenance jobs: checking for config changes
$MAINTENANCE_LEVEL = 5;
# negative (i.e. SPAM) result cache settings ##################################
# set to 0 to disable caching for spam results. To this level the cache will be cleaned.
$CACHESIZE = 2000;
# at this number of entries cleanup takes place
$CACHEMAXSIZE = 4000;
$CACHEREJECTMSG = '550 temporarily blocked because of previous errors';
# after NTTL retries the cache entry is deleted
$NTTL = 1;
# client MUST NOT retry within this seconds in order to decrease TTL counter
$NTIME = 30;
# positve (i.,e. HAM) result cache settings ###################################
# set to 0 to disable caching of HAM. To this number of entries the cache will be cleaned
$POSCACHESIZE = 1000;
# at this number of entries cleanup takes place
$POSCACHEMAXSIZE = 2000;
$POSCACHEMSG = 'using cached result';
#after PTTL requests the HAM entry must succeed one time the RBL checks again
$PTTL = 60;
# after $PTIME in HAM Cache the client must pass one time the RBL checks again.
#Values must be nonfractal. Accepted time-units: s, m, h, d
$PTIME = '3h';
# The client must pass this time the RBL checks in order to be listed as hard-HAM
# After this time the client will pass immediately for PTTL within PTIME
$TEMP_PTIME = '1d';
## DNS settings
# Retries for ONE DNS-Lookup
$DNS_RETRIES = 1;
# Retry-interval for ONE DNS-Lookup
$DNS_RETRY_IVAL = 5;
# max error count for unresponded queries in a complete policy query
$MAXDNSERR = 3;
$MAXDNSERRMSG = 'passed - too many local DNS-errors';
# persistent udp connection for DNS queries.
#broken in Net::DNS version 0.51. Works with Net::DNS 0.53; DEFAULT: off
$PUDP= 0;
# Force the usage of Net::DNS for RBL lookups.
# Normally policyd-weight tries to use a faster RBL lookup routine instead of Net::DNS
$USE_NET_DNS = 0;
# A list of space separated NS IPs
# This overrides resolv.conf settings
# Example: $NS = '1.2.3.4 1.2.3.5';
# DEFAULT: empty
$NS = '';
# timeout for receiving from cache instance
$IPC_TIMEOUT = 2;
# If set to 1 policyd-weight closes connections to smtpd clients in order to avoid too many
#established connections to one policyd-weight child
$TRY_BALANCE = 0;
# scores for checks, WARNING: they may manipulate eachother
# or be factors for other scores.
# HIT score, MISS Score
@client_ip_eq_helo_score = (1.5, -1.25 );
@helo_score = (1.5, -2 );
@helo_score = (0, -2 );
@helo_from_mx_eq_ip_score= (1.5, -3.1 );
@helo_numeric_score= (2.5, 0 );
@from_match_regex_verified_helo= (1,-2 );
@from_match_regex_unverified_helo = (1.6, -1.5 );
@from_match_regex_failed_helo = (2.5, 0 );
@helo_seems_dialup = (1.5, 0 );
@failed_helo_seems_dialup= (2, 0 );
@helo_ip_in_client_subnet= (0,-1.2 );
@helo_ip_in_cl16_subnet = (0,-0.41 );
#@client_seems_dialup_score = (3.75, 0 );
@client_seems_dialup_score = (0, 0 );
@from_multiparted = (1.09, 0 );
@from_anon= (1.17, 0 );
@bogus_mx_score = (2.1, 0 );
@random_sender_score = (0.25, 0 );
@rhsbl_penalty_score = (3.1, 0 );
@enforce_dyndns_score = (3, 0 );
spamassassin/init.pre
(我已将 .pre 文件放在一起)
loadplugin Mail::SpamAssassin::Plugin::Hashcash
loadplugin Mail::SpamAssassin::Plugin::SPF
loadplugin Mail::SpamAssassin::Plugin::Pyzor
loadplugin Mail::SpamAssassin::Plugin::Razor2
loadplugin Mail::SpamAssassin::Plugin::AutoLearnThreshold
loadplugin Mail::SpamAssassin::Plugin::MIMEHeader
loadplugin Mail::SpamAssassin::Plugin::ReplaceTags
loadplugin Mail::SpamAssassin::Plugin::Check
loadplugin Mail::SpamAssassin::Plugin::HTTPSMismatch
loadplugin Mail::SpamAssassin::Plugin::URIDetail
loadplugin Mail::SpamAssassin::Plugin::Bayes
loadplugin Mail::SpamAssassin::Plugin::BodyEval
loadplugin Mail::SpamAssassin::Plugin::DNSEval
loadplugin Mail::SpamAssassin::Plugin::HTMLEval
loadplugin Mail::SpamAssassin::Plugin::HeaderEval
loadplugin Mail::SpamAssassin::Plugin::MIMEEval
loadplugin Mail::SpamAssassin::Plugin::RelayEval
loadplugin Mail::SpamAssassin::Plugin::URIEval
loadplugin Mail::SpamAssassin::Plugin::WLBLEval
loadplugin Mail::SpamAssassin::Plugin::VBounce
loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody
spamassassin/local.cf
(部分)
use_bayes 1
bayes_auto_learn 1
bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
bayes_sql_dsn DBI:mysql:db:127.0.0.1:3306
bayes_sql_username user
bayes_sql_password pass
bayes_ignore_header X-Bogosity
bayes_ignore_header X-Spam-Flag
bayes_ignore_header X-Spam-Status
### User settings
user_scores_dsn DBI:mysql:db:127.0.0.1:3306
user_scores_sql_password user
user_scores_sql_username pass
user_scores_sql_custom_query SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '$GLOBAL' OR username = CONCAT('%',_DOMAIN_) ORDER BY username ASC
# for better speed
score DNS_FROM_AHBL_RHSBL 0
score __RFC_IGNORANT_ENVFROM 0
score DNS_FROM_RFC_DSN 0
score DNS_FROM_RFC_BOGUSMX 0
score __DNS_FROM_RFC_POST 0
score __DNS_FROM_RFC_ABUSE 0
score __DNS_FROM_RFC_WHOIS 0
更新 01
根据 adaptr 的建议,我删除了 policyd-weight 并配置了 postfix postscreen,这导致 RAM 使用量减少了大约 15-20 MB,并且工作速度大大加快。我不确定它是否能满负荷运行,但看起来很有希望。
答案1
我建议你升级到 postfix 2.8+ 并部署后筛选;这是专门设计为僵尸/DNSBL分类服务器并高速处理多个黑名单。
它还提供完全加权的黑/白名单评分、明确的白名单等。
关于你的第二个问题,我建议你看看spamass milter - 垃圾邮件过滤器;在线过滤器比外部过程效率高得多。