Robert Elz wrote in
 <[email protected]>:
 |    Date:        Fri, 09 Jan 2026 13:34:42 -0500
 |    From:        Paul Fox <[email protected]>
 |    Message-ID:  <[email protected]>
 |
 || I'm surprised at this, since to my knowledge neither my wife nor I
 || have ever had trouble sending to a gmail recipient.
 |
 |It depends what hoops your MTA admin is willing to jump through to
 |keep up with their nonsense rules.   I'm not willing to adjust my
 |system for any of them.   I have no SPF records (though I do have
 |a couple of TXT records, from before SPF became a thing, which look
 |a bit like SPF records) and I don't do DKIM (or anything similar).

I like DKIM, and DKIM only.  If only iterated a bit.
(I wrote a very simple and easy sign-only ISO C POSIX postfix
milter that does not need any external dependencies, practically
no config, and does not make any problems (to the best of my
knowledge).  I know it is conscient of yours, but just in case.)

 |One of the issues they dislike is that munnari.oz.au mostly sends
 |using IPv6 when it can, but its v6 addr has no IP6.ARPA entry.
 |I consider those entries (v4 as well, but it happens that munnari
 |has an IN-ADDR.ARPA entry from the distant past) a waste of time,
 |as in the vast majority of cases these days all that is ever
 |reported is stuff like a.b.c.d.random.ISP.COM (for IPv4, and similar,
 |but longer, for IPv6) where the IP address is either a.b.c.d or d.c.b.a.
 |Since the IP addr was already known (the key for the lookup) this
 |doesn't tell anyone anything useful at all, so it is a waste of time
 |looking it up.  If searching for it is useless, then providing some
 |other info must be similarly useless.   Requiring it "to stop spam"
 |is obvious nonsense, actually registering something which works is
 |trivial (just wasteful for everyone), so any spammer aware that check
 |is made will certainly do that.   In effect, mail these days is less
 |likely to be spam if there's no reverse lookup available (but, of course,
 |only because that is one of the tests used, which is something of a
 |catch-22).

Not providing reverse lookup does indeed break
"configuration hints" i have seen, for postfix
reject_unknown_reverse_client_hostname for example, seems to be
used often!
(For access to my HTTP server i even blacklist all of those
"suckers" automatically that cannot be resolved.  (And those which
come over with multiple IPs per mask; for fun i will attach that
(Linux) mess right away.  (Note: no file locking for DB, simply
moved from .new to X.))

 || Do the gmail issues that you and others have had
 || result in a bounce, or a drop?
 |
 |>From gmail a bounce, though whether the bounce contains the
 |original message or not, I have no idea, I filter bounce messages
 |info a junkmail/bounces folder, and never bother looking there.
 |
 |>From outlook a bounce as well, from my local MTA, after it eventually
 |gives up attempting to send the message (that one includes no useful
 |information other than that the recipient's system couldn't be
 |contacted.)
 |
 |And in case it wasn't clear, which it almost certainly wasn't,
 |the messages I am referring to are all ones from munnari.oz.au
 |direct to gmail or outlook(etc). (Those are the only two receiving MTAs
 |I have issues with).   Messages that go from me via a list (like
 |this one) can (sometimes) reach recipients with gmail or outlook
 |mailboxes.

All i know is that Gmail started traffic-rate bouncing messages
months ago, even with SPF and DKIM, if only more than X (whatever
that X is) messages are sent from IPs they have not seen sending
Y per Z (all ditto).  They pointed to a page without much content
but at least it was said one cannot do anything about that.  (I
wonder(ed) whether it caused people to start sending "ping" emails
to keep that thing "hot", if doable; i have not tried it.)

 |kre
 |
 |ps: we could discuss this forever, but it all has nothing to do with nmh

Sorry.  Interesting topics!

 --End of <[email protected]>

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)
#!/bin/sh -
#@ /root/bin/cron-fw.sh -- act for
#@ - IPs with NXDOMAIN reverse DNS
#@ - multiple IPs per $MASK4/6 network (with $DISALLOW_MULTI_IP_MASK)

# DBG: dry-run if non-empty; if value is "y", use example address set
: ${DBG=}
: ${DISALLOW_MULTI_IP_MASK=y} # whether we also blacklist networks with multiple different IP currently sucking
: ${LOG=y}

: ${DB:=/run/.fw-ss-http}
: ${DBTYPE:=httpnodom}
: ${LOGFAC:=daemon.notice}
: ${MASK4:=24}
: ${MASK6:=64}
: ${SECS:=21000}
: ${TBL:=drop}

: ${AWK:=awk}
: ${IPCALC:=ipcalc}
: ${NSLOOKUP:=nslookup}
: ${SED:=sed}
: ${SS:=ss}

ep=$(date +%s)

ipa_prep() {
	ip=$1
	ws_trim ip "$ip"
	if [ "$ip" = "${ip#*[^0-9.]}" ]; then
		:
	elif [ "$ip" != "${ip%]*}" ] || [ "$ip" = "${ip#*[!0-9a-fA-F:]}" ]; then
		ip=${ip%]*}
		ip=${ip#*[*}
		ws_trim ip "$ip"
		[ "$ip" != "${ip#*[!0-9a-fA-F:]}" ] && ip=
	else
		ip=
	fi
	echo "$ip"
}

keyit() {
	echo $* | $SED -E -e 's/\./Y/g' -e 's/:/Z/g'
}

ws_trim() {
	__ws__=$2
	__ws__=${__ws__#${__ws__%%[!    ]*}}
	__ws__=${__ws__%${__ws__##*[!   ]}}
	eval $1=\"$__ws__\"
}

nips=

act_dbg() {
	nips= xips='1/10.1.2.3 0/1:3:4::FF 0/10.1.3.1 0/10.1.3.33 0/10.1.4.100'
	for ip in $xips; do
		t=${ip%/*}
		ip=${ip#*/}
		ip="$t/$ip/"$(keyit "$ip")
		nips="$nips $ip"
	done
}

act_httpnodom() {
	nips=$($SS -H -Q -t '( sport = :http or sport = :https )' |
			while read l; do
				ip=$(echo "$l" | $SED -E 's/.*[[:space:]]+([^[:space:]]+):[[:alnum:]_-]+$/\1/')
				if [ $? -ne 0 ]; then
					echo >&2 'Failure extracting IP address: '$l
					continue
				fi
				ip=$(ipa_prep "$ip")
				if [ -z "$ip" ]; then
					echo >&2 'IP address extaction error: '$ip': '$l
					continue
				fi

				ipm=$(keyit "$ip")

				eval l=\$ipdns_$ipm ipdns_$ipm=y
				if [ -n "$l" ]; then
					[ -n "$DBG" ] && echo >&2 '.. DNS lookup cached: '$ip
					continue
				elif [ -n "$DBG" ]; then
					echo >&2 'DNS PTR lookup: '$NSLOOKUP' '$ip
				else
					m=$($NSLOOKUP "$ip" 2>/dev/null)
				fi
				echo $?/$ip/$ipm
			done)
}

if [ "$DBG" = y ]; then
	act_dbg
elif [ "$DBTYPE" = httpnodom ]; then
	act_httpnodom
else
	echo >&2 'unknown DBTYPE: '$DBTYPE
	exit 64
fi

if [ -n "$nips" ]; then
	nnips=
	for a in $nips; do
		t=${a%%/*}
		a=${a#*/}
		am=${a#*/}
		a=${a%/*}

		m=$MASK4
		[ "${a}" != "${a%:*}" ] && m=$MASK6
		an=$($IPCALC -n $a/$m)
		if [ $? -ne 0 ]; then
			echo >&2 'ipcalc failed for '$a/$m
			continue
		fi
		an=${an##NETWORK=}

		anm=$(keyit "$an")

		eval i=\$a_$anm
		if [ -n "$i" ]; then
			[ -n "$DBG" ] && echo >&2 '.. network already listed: '$an
			continue
		fi

		# PTR failure
		if [ "$t" -ne 0 ]; then
			nnips="$nnips $an"
			eval a_$anm=y
			[ -n "$DBG" ] && echo >&2 '+ listing: DNS failure: '$an
		elif [ -n "$DISALLOW_MULTI_IP_MASK" ]; then
			eval aem=\$xi_$am
			[ -z "$aem" ] && aem=0
			aem=$((aem + 1))
			eval xi_$am=$aem

			eval anem=\$xi_$anm
			[ -z "$anem" ] && anem=0
			anem=$((anem + 1))
			eval xi_$anm=$anem

			if [ $aem -ne $anem ]; then
				nnips="$nnips $an"
				eval a_$anm=y
				[ -n "$DBG" ] && echo >&2 '+ listing: multiple IP/network: '$an
			fi
		fi
	done
	nips=$nnips
fi

[ -f "$DB" ] || > "$DB"

< "$DB" > "$DB".new \
	$AWK -v DBG="$DBG" -v DBTYPE="$DBTYPE" -v EP="$ep" \
		-v LOG="$LOG" -v LOGFAC="$LOGFAC" \
		-v MASK4="$MASK4" -v MASK6="$MASK6" -v NE="$nips" \
		-v SECS="$SECS" -v TBL="$TBL" '
BEGIN{ split("", xa); split("", da); }
{
	if($2 + SECS > EP)
		xa[$1] = $2
	else
		da[$1] = $2
}
END{
	oen = length(xa)
	den = length(da)
	split(NE, pnxa)
	split("", nxa)
	for(n in pnxa){
		n = pnxa[n]
		if(!nxa[n])
			nxa[n] = n
	}
	nen = length(nxa)

	# Any new one that actually is not is neither deleted nor readded
	if(nen > 0 && (oen > 0 || den > 0)){
		for(e in nxa){
			i = 0

			if(xa[e])
				i = 1

			if(da[e]){
				xa[e] = EP
				++oen
				--den
				i = 1
			}

			if(i){
				delete nxa[e]
				if(--nen == 0)
					break
			}
		}
	}

	# stock
	m = "=" oen
	for(e in xa){
		if(!xa[e])
			continue
		print e " " xa[e]
	}

	act = ""

	# removals
	m = m ", -" den
	if(den > 0){
		des = ""
		for(e in da){
			if(!da[e])
				continue
			if(des)
				des = des " "
			if(e ~ ":")
				des = des e "/" MASK6
			else
				des = des e "/" MASK4
		}
		if(des){
			#if(act) act = act " "
			act = act "del " TBL " " des
			if(DBG)
				m = m " (" des ")"
		}
	}

	# additions
	m = m ", +" nen
	if(nen > 0){
		nes = ""
		for(e in nxa){
			if(!nxa[e])
				continue
			if(nes)
				nes = nes " "
			if(e ~ ":")
				nes = nes e "/" MASK6
			else
				nes = nes e "/" MASK4
			print e " " EP
		}

		if(nes){
			if(act) act = act " "
			act = act " add " TBL " " nes
			if(DBG)
				m = m " (" nes ")"
		}
	}

	if(DBG){
		if(act)
			print "/root/bin/net-qos.sh adddel " act >> "/dev/stderr"
		print "logger -p " LOGFAC " -t /root/bin/cron-fw.sh:" DBTYPE " \"" m "\"" >> "/dev/stderr"
	}else{
		if(act)
			system("/root/bin/net-qos.sh adddel " act)
		if(LOG)
			system("logger -p " LOGFAC " -t /root/bin/cron-fw.sh:" DBTYPE " \"" m "\"")
	}
}'

mv "$DB".new "$DB"

# s-sht-mode

Reply via email to