Plugin: check-helo


This plugin provides an ability to reject, defer or add it's helo name checking results to message header.

IMPORTANT: This plugin is written for and tested with mailfront 2.00 but should work with version 1.12 and above.

Configuration (checks sequence)

(1). $HELO_CHECK_SKIP

If set, is set, this plugin will be skipped.

(2). $RELAYCLIENT

If set, add to message header and skip the remaining checks. Example of message header added:

X-HELO-Check-Result: SKIPPED: $RELAYCLIENT is set for 1.2.3.4
(3). authenticated user

If sender is authenticated, add to message header and skip the remaining checks. Example of message header added:

X-HELO-Check-Result: SKIPPED: authenticated user from 1.2.3.4
(4). $RBLSMTPD

If set, and empty, add to message header and skip the remaining checks.

(5). $HELO_CHECK_REMOTEHOST or $HELO_CHECK_REMOTEHOST_MATCH

If set, this plugin will check ${PROTO}REMOTEHOST is not empty. If is empty, will do a DNS PTR lookup using ${PROTO}REMOTEIP and use the return value as ${PROTO}REMOTEHOST.

(6). $HELO_CHECK_REMOTEHOST

If set, this plugin will check HELO name is not empty. If it is empty, add to message header or defer or reject accordingly and skip the remaining checks. (Refer to $HELO_CHECK_ADD_HEADER, $HELO_CHECK_DEFER and $HELO_CHECK_REJECT) Example of message header added:

X-HELO-Check-Result: FAILED
X-HELO-Check-Summary: REMOTEHOST is empty and PTR DNS lookup for IP 1.2.3.4 failed
(7). $HELO_CHECK_REMOTEHOST_MATCH

is set, this plugin will check HELO name and ${PROTO}REMOTEHOST whether both are the same otherwise add to message header or defer or reject accordingly and skip the remaining checks. (Refer to $HELO_CHECK_ADD_HEADER, $HELO_CHECK_DEFER and $HELO_CHECK_REJECT) Example of message header added:

X-HELO-Check-Result: FAILED
X-HELO-Check-Summary: HELO name and REMOTEHOST doesn't match
(8). Check HELO name for the following:

(8.1). Cannot starts with ".", "[" and "-"
(8.2). Cannot ends with ".", "]" and "-"
(8.3). Must have at least a "." (dot)
(8.4). Cannot have any of the following characters besides TAB and SPACE:
~!@#$%^&*()_+={}[]:;"'<>,?/|
(8.5). Cannot use a valid IPv4 address

NOTE: If any of the above checks failed, the remaining checks will be skipped. (Refer to $HELO_CHECK_ADD_HEADER, $HELO_CHECK_DEFER and $HELO_CHECK_REJECT) Example of message header added:

X-HELO-Check-Result: FAILED
X-HELO-Check-Summary: '.' found in last character of HELO name sender_set_HELO_name
(9). HELO name DNS Check

Do a DNS lookup for HELO name for A, AAAA and PTR records. If the DNS lookup failed due to no such name exists will skip all remaining checks and add to message header or defer or reject. (Refer to $HELO_CHECK_ADD_HEADER, $HELO_CHECK_DEFER and $HELO_CHECK_REJECT) Any other errors such as timeout etc. will result in skipping the remaining checks and message will be deferred with reply code 451 if $HELO_CHECK_REJECT or $HELO_CHECK_DEFER is set otherwise if $HELO_CHECK_ADD_HEADER is set will add to message header. Example of message header added:

X-HELO-Check-Result: FAILED
X-HELO-Check-Summary: DNS lookup error for HELO name sender_set_HELO_name
(10). $HELO_CHECK_REMOTEIP

If set, this plugin will check for a match of ${PROTO}REMOTEIP and HELO name IP. If there is a match, skip the remaining checks and add header if $HELO_CHECK_ADD_HEADER is set. If there is no match, add to message header or defer or reject. (Refer to $HELO_CHECK_ADD_HEADER, $HELO_CHECK_DEFER and $HELO_CHECK_REJECT) Example of message header added:

X-HELO-Check-Result: PASSED
X-HELO-Check-Summary: REMOTEIP matches sender_set_HELO_name's IP
(11). $HELO_CHECK_REMOTEIP_MATCH

If set, this plugin will check for a match the first 3 octets (within same class C) of ${PROTO}REMOTEIP if is a valid IPv4 address against helo name A records. If there isn't a match, add headers or defer or reject accordingly. If there is a match, add headers if $HELO_CHECK_ADD_HEADER and skip the rest of the checks. Example of message header added:

X-HELO-Check-Result: SKIPPED
X-HELO-Check-Summary: REMOTEIP 1.2.3.4 matches first 3 octets of sender_set_HELO_name's IP 1.2.3.50 (same class C)
(12). $HELO_CHECK_PTR

If set, this plugin will check the HELO name's A records to have at least one PTR record. If the check failed, it will add to message header or defer or reject accordingly. Example of message header added:

X-HELO-Check-Result: FAILED
X-HELO-Check-Summary: X-HELO-Check-Summary: PTR record not found for HELO name sender_set_HELO_name
(13). $HELO_CHECK_PTR_MATCH

If set, this plugin will check there is at least one of the PTR record resolves to the same given HELO name. If the check failed, it will add to message header or defer or reject accordingly. Example of message header added:

X-HELO-Check-Result: FAILED
X-HELO-Check-Summary: X-HELO-Check-Summary: PTR record doesn't resolves back to HELO name sender_set_HELO_name
(14). $HELO_CHECK_REJECT

If set, sender will be rejected with reply code 553 if any of the above checks failed. NOTE: $HELO_CHECK_DEFER takes precedence over $HELO_CHECK_DEFER.

(15). $HELO_CHECK_DEFER

If set, sender will be deferred with reply code 451 if any of the above checks failed.

(16). $HELO_CHECK_ADD_HEADER

If set, this plugin will add its checking result to each mail message header accepted.

(17). $HELO_CHECK_VERBOSE

If set, this plugin will log all its checking to stderr.

Sender Action

When sender issue HELO command, this plugin will set the environment variable $SENDER_HELO_HOSTNAME to the sender given helo name and do it's helo checking.

The following will be rejected, deferred or add to message headers accordingly to the environment variables configuration:

HELO (empty)
HELO localhost (without a period)
HELO .com (starts with a period)
HELO fake.com. (ends with a period)
HELO !@#$%^&* (characters not normally allowed in domain names)
HELO [192.168.1.1] (starts with [ or ends with ])
HELO 192.168.1.1 (IPv4 Address not allowed)

If $HELO_CHECK_REMOTEHOST is set, then the helo name must match the remotehost name.

If $HELO_CHECK_REMOTEIP is set, then one of the helo name's A record must match the remoteip.

If $HELO_CHECK_REMOTEIP_MATCH is set, then one of the helo name's A record must match the first 3 octets of remoteip (same class C).

Recipient Action

None

Data Action

If $HELO_CHECK_REJECT or $HELO_CHECK_DEFER not set, this plugin will add it's helo name checking result to the message header otherwise it will reject or defer accordingly if sender is not authenticated.

X-HELO-Check-Result: PASSED
X-HELO-Check-Summary: There is 1 A record for sender_helo_name, 1 PTR record and 1 PTR record resolves to the same hostname.

This plugin will log to stderr as an example below if $HELO_CHECK_VERBOSE is set:

mailfront-plugin-check-helo[pid]: Start checking heloname=sender_helo_name
mailfront-plugin-check-helo[pid]: ip[0]=sender_ip ptr[0]=sender_hostname_from_ptr_lookup ptr=YES|NO ipmatch=YES|NO ptrcheck=PASSED|FAILED

NOTE: If ip[N] and ptr[N] are the same means PTR DNS lookup for the ip failed.

Message Action

None