2

I noticed a spammer got through postgrey AND SpamAssassin, which was very strange. I examined /var/log/mail.log and saw some suspect lines:

Log below, or on Pastebin: http://pastebin.com/k7sKnvGE

Jul 19 07:59:06 mail postfix/smtpd[15492]: connect from unknown[37.215.63.185]
Jul 19 07:59:07 mail postfix/smtpd[15492]: NOQUEUE: reject_warning: RCPT from unknown[37.215.63.185]: 504 5.5.2 <37.215.63.185>: Helo command rejected: need fully-qualified hostname; from=<> to=<[email protected]> proto=SMTP helo=<37.215.63.185>
Jul 19 07:59:07 mail postgrey[13086]: action=pass, reason=triplet found, delay=316, client_name=unknown, client_address=37.215.63.185, [email protected]
Jul 19 07:59:07 mail postfix/smtpd[15492]: B8D5D20BDD: client=unknown[37.215.63.185]
Jul 19 07:59:09 mail postfix/cleanup[15500]: B8D5D20BDD: message-id=<>
Jul 19 07:59:09 mail postfix/qmgr[3224]: B8D5D20BDD: from=<>, size=493, nrcpt=1 (queue active)
Jul 19 07:59:09 mail amavis[11960]: (11960-14) NOTICE: reconnecting in response to: err=2006, HY000, DBD::mysql::st execute failed: MySQL server has gone away at (eval 111) line 170, <GEN39> line 9463.
Jul 19 07:59:10 mail postfix/smtpd[15492]: disconnect from unknown[37.215.63.185]
Jul 19 07:59:11 mail postfix/smtpd[15505]: connect from localhost[127.0.0.1]
Jul 19 07:59:11 mail postfix/smtpd[15505]: 96E1820C16: client=localhost[127.0.0.1]
Jul 19 07:59:11 mail postfix/cleanup[15500]: 96E1820C16: message-id=<[email protected]>
Jul 19 07:59:11 mail postfix/qmgr[3224]: 96E1820C16: from=<>, size=1166, nrcpt=1 (queue active)
Jul 19 07:59:11 mail postfix/smtpd[15505]: disconnect from localhost[127.0.0.1]
Jul 19 07:59:11 mail amavis[11960]: (11960-14) Passed CLEAN {RelayedInbound}, [37.215.63.185]:55743 <> -> <[email protected]>, Queue-ID: B8D5D20BDD, mail_id: d6hKjzEiMtex, Hits: 1.296, size: 493, queued_as: 96E1820C16, 2128 ms
Jul 19 07:59:11 mail postfix/smtp[15502]: B8D5D20BDD: to=<[email protected]>, relay=127.0.0.1[127.0.0.1]:10024, delay=4.2, delays=2.1/0.01/0.01/2.1, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 96E1820C16)
Jul 19 07:59:11 mail postfix/qmgr[3224]: B8D5D20BDD: removed
Jul 19 07:59:11 mail dovecot: auth-worker(15508): mysql(localhost): Connected to database vimbadmin
Jul 19 07:59:11 mail dovecot: lda([email protected]): sieve: msgid=<[email protected]>: stored mail into mailbox 'INBOX'
Jul 19 07:59:11 mail postfix/pipe[15506]: 96E1820C16: to=<[email protected]>, relay=dovecot, delay=0.05, delays=0/0/0/0.04, dsn=2.0.0, status=sent (delivered via dovecot service)
Jul 19 07:59:11 mail postfix/qmgr[3224]: 96E1820C16: removed

I can't tell if someone exploited the server to spoof localhost, or if Amavis or MySQL failed on my end and then allowed the email to come through. Any insight into this would be greatly appreciated!

/etc/postfix/main.cf:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version

# The first text sent to a connecting process.
smtpd_banner = $myhostname ESMTP $mail_name
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
readme_directory = no

# SASL parameters
# ---------------------------------

# Use Dovecot to authenticate.
smtpd_sasl_type = dovecot
# Referring to /var/spool/postfix/private/auth
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
smtpd_sasl_authenticated_header = yes

# TLS parameters
# ---------------------------------

# The default snakeoil certificate. Comment if using a purchased
# SSL certificate.
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

# Uncomment if using a purchased SSL certificate.
smtpd_tls_cert_file=/etc/ssl/mail.myhost.com/crt
smtpd_tls_key_file=/etc/ssl/mail.myhost.com/key

# The snakeoil self-signed certificate has no need for a CA file. But
# if you are using your own SSL certificate, then you probably have
# a CA certificate bundle from your provider. The path to that goes
# here.
smtpd_tls_CAfile=/etc/ssl/mail.myhost.com/ca-bundle

smtp_tls_note_starttls_offer = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
#smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# Note that forcing use of TLS is going to cause breakage - most mail servers
# don't offer it and so delivery will fail, both incoming and outgoing. This is
# unfortunate given what various governmental agencies are up to these days.
#
# Enable (but don't force) all incoming smtp connections to use TLS.
smtpd_tls_security_level = may
# Enable (but don't force) all outgoing smtp connections to use TLS.
smtp_tls_security_level = may

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

# SMTPD parameters
# ---------------------------------

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
# will it be a permanent error or temporary
unknown_local_recipient_reject_code = 450
# how long to keep message on queue before return as failed.
# some have 3 days, I have 16 days as I am backup server for some people
# whom go on holiday with their server switched off.
maximal_queue_lifetime = 7d
# max and min time in seconds between retries if connection failed
minimal_backoff_time = 1000s
maximal_backoff_time = 8000s
# how long to wait when servers connect before receiving rest of data
smtp_helo_timeout = 60s
# how many address can be used in one message.
# effective stopper to mass spammers, accidental copy in whole address list
# but may restrict intentional mail shots.
smtpd_recipient_limit = 16
# how many error before back off.
smtpd_soft_error_limit = 3
# how many max errors before blocking it.
smtpd_hard_error_limit = 12

# This next set are important for determining who can send mail and relay mail
# to other servers. It is very important to get this right - accidentally producing
# an open relay that allows unauthenticated sending of mail is a Very Bad Thing.
#
# You are encouraged to read up on what exactly each of these options accomplish.

# Requirements for the HELO statement
smtpd_helo_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_hostname, reject_invalid_hostname, permit
# Requirements for the sender details
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_pipelining, permit
# Requirements for the connecting server
smtpd_client_restrictions = 
# Requirement for the recipient address. Note that the entry for
# "check_policy_service inet:127.0.0.1:10023" enables Postgrey.
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit
smtpd_data_restrictions = reject_unauth_pipelining
# This is a new option as of Postfix 2.10, and is required in addition to
# smtpd_recipient_restrictions for things to work properly in this setup.
#smtpd_relay_restrictions = reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit

# require proper helo at connections
smtpd_helo_required = yes
# waste spammers time before rejecting them
smtpd_delay_reject = yes
disable_vrfy_command = yes

# General host and delivery info
# ----------------------------------

myhostname = mail.myhost.com
#myorigin = /etc/hostname
# Some people see issues when setting mydestination explicitly to the server
# subdomain, while leaving it empty generally doesn't hurt. So it is left empty here.
# mydestination = mail.example.com, localhost
mydestination = mail.myhost.com, localhost.localdomain, localhost
# If you have a separate web server that sends outgoing mail through this
# mailserver, you may want to add its IP address to the space-delimited list in
# mynetworks, e.g. as 10.10.10.10/32.
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
mynetworks_style = host

# This specifies where the virtual mailbox folders will be located.
virtual_mailbox_base = /var/vmail
# This is for the mailbox location for each user. The domainaliases
# map allows us to make use of Postfix Admin's domain alias feature.
#virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf, mysql:/etc/postfix/mysql_virtual_mailbox_domainaliases_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/vimb/virtual_mailbox_maps.cf
# and their user id
virtual_uid_maps = static:150
# and group id
virtual_gid_maps = static:8
# This is for aliases. The domainaliases map allows us to make
# use of Postfix Admin's domain alias feature.
#virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf, mysql:/etc/postfix/mysql_virtual_alias_domainaliases_maps.cf
virtual_alias_maps = mysql:/etc/postfix/vimb/virtual_alias_maps.cf
# This is for domain lookups.
#virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/vimb/virtual_domains_maps.cf

alias_maps=hash:/etc/aliases

# Integration with other packages
# ---------------------------------------

# Tell postfix to hand off mail to the definition for dovecot in master.cf
virtual_transport = dovecot
#dovecot_destination_recipient_limit = 1

# Use amavis for virus and spam scanning
content_filter = amavis:[127.0.0.1]:10024

# Header manipulation
# --------------------------------------

# Getting rid of unwanted headers. See: https://posluns.com/guides/header-removal/
header_checks = regexp:/etc/postfix/header_checks
# getting rid of x-original-to
enable_original_recipient = no

/etc/postfix/master.cf:

#
# Postfix master process configuration file.  For details on the format
# of the file, see the master(5) manual page (command: "man 5 master").
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       -       -       -       smtpd
#smtp      inet  n       -       -       -       1       postscreen
#smtpd     pass  -       -       -       -       -       smtpd
#dnsblog   unix  -       -       -       -       0       dnsblog
#tlsproxy  unix  -       -       -       -       0       tlsproxy
#submission inet n       -       -       -       -       smtpd
#  -o syslog_name=postfix/submission
#  -o smtpd_tls_security_level=encrypt
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#smtps     inet  n       -       -       -       -       smtpd
#  -o syslog_name=postfix/smtps
#  -o smtpd_tls_wrappermode=yes
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#628       inet  n       -       -       -       -       qmqpd
pickup    fifo  n       -       -       60      1       pickup
  -o content_filter=
  -o receive_override_options=no_header_body_checks
cleanup   unix  n       -       -       -       0       cleanup
qmgr      fifo  n       -       n       300     1       qmgr
#qmgr     fifo  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       -       1000?   1       tlsmgr
rewrite   unix  -       -       -       -       -       trivial-rewrite
bounce    unix  -       -       -       -       0       bounce
defer     unix  -       -       -       -       0       bounce
trace     unix  -       -       -       -       0       bounce
verify    unix  -       -       -       -       1       verify
flush     unix  n       -       -       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       -       -       -       smtp
relay     unix  -       -       -       -       -       smtp
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       -       -       -       showq
error     unix  -       -       -       -       -       error
retry     unix  -       -       -       -       -       error
discard   unix  -       -       -       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       -       -       -       lmtp
anvil     unix  -       -       -       -       1       anvil
scache    unix  -       -       -       -       1       scache
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent.  See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
#   lmtp    cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
#  mailbox_transport = lmtp:inet:localhost
#  virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus     unix  -       n       n       -       -       pipe
#  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
# Old example of delivery via Cyrus.
#
#old-cyrus unix  -       n       n       -       -       pipe
#  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix  -   n   n   -   2   pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
  ${nexthop} ${user}

# The next two entries integrate with Amavis for anti-virus/spam checks.
amavis      unix    -       -       -       -       2       smtp
  -o smtp_data_done_timeout=1200
  -o smtp_send_xforward_command=yes
  -o disable_dns_lookups=yes
  -o max_use=20
127.0.0.1:10025 inet    n       -       -       -       -       smtpd
  -o content_filter=
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_delay_reject=no
  -o smtpd_client_restrictions=permit_mynetworks,reject
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o smtpd_data_restrictions=reject_unauth_pipelining
  -o smtpd_end_of_data_restrictions=
  -o mynetworks=127.0.0.0/8
  -o smtpd_error_sleep_time=0
  -o smtpd_soft_error_limit=1001
  -o smtpd_hard_error_limit=1000
  -o smtpd_client_connection_count_limit=0
  -o smtpd_client_connection_rate_limit=0
  -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

# Integration with Dovecot - hand mail over to it for local delivery, and
# run the process under the vmail user and mail group.
dovecot      unix   -        n      n       -       -   pipe
  flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(recipient)
11
  • It was just a reject warning, not an actual rejection. I didn't remove any in-between lines in this log, it's all sequential. So 37.215.63.185 connected, passed my greylist because they had connected before, then there was a MySQL failure of some sort, and suddenly (literally a second later) I get a connection from localhost which is able to send an email and not get flagged since localhost is trusted. Jul 19, 2014 at 19:55
  • If you suspect an open relay than post all your config, main.cf and master.cf. We don't have access to your server to read them ourselves, are not your service contractor and our Crystal Ball is currently under repair.
    – sebix
    Jul 19, 2014 at 20:44
  • Updated question to include main.cf and master.cf. Jul 20, 2014 at 1:04
  • Ooooh, you aren't rejecting for real. That's why stuff is getting through. Jul 20, 2014 at 1:05
  • What am I missing, @MichaelHampton? Jul 20, 2014 at 1:18

2 Answers 2

6

The logs above is expected behavior from postfix and amavis. For after queue content filter like amavis, the filter needs reinject email to postfix. For more info please refers to official documentation. Here some explanation of postfix and amavis action.

Jul 19 07:59:06 mail postfix/smtpd[15492]: connect from unknown[37.215.63.185]

Client from 37.215.63.185 connect to your mail server.

Jul 19 07:59:07 mail postfix/smtpd[15492]: NOQUEUE: reject_warning: RCPT from unknown[37.215.63.185]: 504 5.5.2 <37.215.63.185>: Helo command rejected: need fully-qualified hostname; from=<> to=<[email protected]> proto=SMTP helo=<37.215.63.185>

Postfix warns you because HELO command contains non-fully-qualified hostname, but it still pass the email because you specify warn_if_reject in main.cf.

Jul 19 07:59:07 mail postgrey[13086]: action=pass, reason=triplet found, delay=316, client_name=unknown, client_address=37.215.63.185, [email protected]

Postgrey doesn't reject the email because the client has pass the postgrey's check before.

Jul 19 07:59:07 mail postfix/smtpd[15492]: B8D5D20BDD: client=unknown[37.215.63.185]
Jul 19 07:59:09 mail postfix/cleanup[15500]: B8D5D20BDD: message-id=<>
Jul 19 07:59:09 mail postfix/qmgr[3224]: B8D5D20BDD: from=<>, size=493, nrcpt=1 (queue active)

Postfix assign queue-id to email because the pass all restriction. In this stage, posfix have ACCEPTED the email.

Jul 19 07:59:09 mail amavis[11960]: (11960-14) NOTICE: reconnecting in response to: err=2006, HY000, DBD::mysql::st execute failed: MySQL server has gone away at (eval 111) line 170, <GEN39> line 9463.

Postfix has began transfer your email to amavis, then amavis is notifying you that mysql connection was unsuccessfull.

Jul 19 07:59:10 mail postfix/smtpd[15492]: disconnect from unknown[37.215.63.185]

The client from 37.215.63.185 disconnect from your server because Postfix accept the email.

Jul 19 07:59:11 mail postfix/smtpd[15505]: connect from localhost[127.0.0.1]

Amavis trying to re-inject email to port 10025. By default, Amavis ONLY re-inject message if email status is PASSED CLEAN (based on log line below).

Jul 19 07:59:11 mail postfix/smtpd[15505]: 96E1820C16: client=localhost[127.0.0.1]
Jul 19 07:59:11 mail postfix/cleanup[15500]: 96E1820C16: message-id=<[email protected]>
Jul 19 07:59:11 mail postfix/qmgr[3224]: 96E1820C16: from=<>, size=1166, nrcpt=1 (queue active)

Obviously Postfix accepted email from amavis.

Jul 19 07:59:11 mail postfix/smtpd[15505]: disconnect from localhost[127.0.0.1]

Amavis has finished sending process

Jul 19 07:59:11 mail amavis[11960]: (11960-14) Passed CLEAN {RelayedInbound}, [37.215.63.185]:55743 <> -> <[email protected]>, Queue-ID: B8D5D20BDD, mail_id: d6hKjzEiMtex, Hits: 1.296, size: 493, queued_as: 96E1820C16, 2128 ms

Amavis logs his action in maillog. SpamAssasin score is relatively low (1.296) and the email passed all amavis checks.

Jul 19 07:59:11 mail postfix/smtp[15502]: B8D5D20BDD: to=<[email protected]>, relay=127.0.0.1[127.0.0.1]:10024, delay=4.2, delays=2.1/0.01/0.01/2.1, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 96E1820C16)

Postfix notify that email scan was successful.

Jul 19 07:59:11 mail postfix/qmgr[3224]: B8D5D20BDD: removed

Queue was removed. Then email delivered to dovecot below.

Jul 19 07:59:11 mail dovecot: auth-worker(15508): mysql(localhost): Connected to database vimbadmin
Jul 19 07:59:11 mail dovecot: lda([email protected]): sieve: msgid=<[email protected]>: stored mail into mailbox 'INBOX'
Jul 19 07:59:11 mail postfix/pipe[15506]: 96E1820C16: to=<[email protected]>, relay=dovecot, delay=0.05, delays=0/0/0/0.04, dsn=2.0.0, status=sent (delivered via dovecot service)
Jul 19 07:59:11 mail postfix/qmgr[3224]: 96E1820C16: removed
1
  • Thanks for the log walkthrough. Very useful resource for novices.
    – ychaouche
    Jul 28, 2015 at 8:45
5

Additionally to the explanations from masegaloeh, I want to point out, why the spammer got through in your case. Look at the following line in the logs:

Jul 19 07:59:07 mail postfix/smtpd[15492]: NOQUEUE: reject_warning: RCPT from unknown[37.215.63.185]: 504 5.5.2 <37.215.63.185>: Helo command rejected: need fully-qualified hostname; from=<> to=<[email protected]> proto=SMTP helo=<37.215.63.185>

This is already the instruction to solve your problem, so let's take a look on your config (note the warn_if_reject:

smtpd_helo_restrictions = [...] warn_if_reject reject_non_fqdn_hostname, [...], permit
smtpd_sender_restrictions = [...], warn_if_reject reject_non_fqdn_sender, [...], permit

Your logs says, that the reject_non_fqdn_hostname got triggerd, but was held back and got converted to a warning (which you see in your logs). Remove it, and the spammer is rejected.

You won't lose any valid senders using reject_non_fqdn_hostname, every mailserver properly set up, uses a valid FQDN for helo.

EDIT: Please consider tidying up your config :) Both others and you could orient oneselves better in a config without three commented out variants of each line.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .