post

Fix bouncing mail from a GNU Mailman server on Dreamhost

GNU Mailman is free software for managing electronic mail discussion and e-newsletter lists. I started using it back in 1998 for managing internal email lists at a company I worked for. I’ve used it many times over the years, but stopped when email lists fell out of fashion. I liked it because it’s pretty easy to set up an actual discussion list, where replies go to the list (not the sender), which results in actual discussion.

I recently set one up again, using a my Dreamhost account and their automated web panel to deploy a discussion list for a volunteer group I manage. I was having a problem though, some of the people on the list weren’t getting all of the mail.

Mostly it was anyone with an @gmail.com mailing address. The odd part was that they were getting some messages, just not all messages. I had people check their spam folders but that wasn’t it.

Since messages weren’t ending up in SPAM folders that usually means that (a) the recipient’s email server is bouncing the message (refusing the message) or (b) something was wrong with Mailman’s settings.

I did some Googling today and found that many other people were reporting similar problems, but no one had a good solution other than to turn on bounced message troubleshooting, so I did that.

I logged into the list’s mailing list administration page, selected the “Bounce processing” setup option, and made sure that all notifications were turned ON.

After I did that I sent a message to the mailing list. Almost immediately I got back a bounce message from sbcglobal.net:

<listsubscriber@sbcglobal.net>: host ff-ip4-mx-vip1.prodigy.net[144.160.159.21]
    said: 553 5.3.0 flpd577 DNSBL:RBL 521< [Mailman's IP] >_is_blocked.For
    assistance forward this error to abuse_rbl@abuse-att.net (in reply to MAIL FROM command)

DNSBL:RBL is a realtime DNS blacklist designed to block spam. I went to DNSBL.info and checked my Mailmain server’s IP address. It wasn’t listed:

Next I went to check the DNS SPF record for the mailing list’s domain name. I had assumed that since I’d used Dreamhost’s web panel to install the Mailman service that Dreamhost would automatically take care of the SPF record.

I was wrong, there was no SPF record.

Well that explains a lot.

When a mail server (technically a “mail exchanger” or “MX” server) receives mail from another mail server one of the things that it will do is ask two questions:

  • What domain did this email come from?
  • Is the server that sent this mail allowed to send mail for that domain?

The way that the second question is answered is an SPF record. The receiving mail server looks up the DNS SPF record for the domain that sent the mail. If the SPF record says that the server sending the mail is allowed to send mail for the domain the SPF check passes and all is well. If the SPF record doesn’t exist, or doesn’t list the server that the mail came from, the SPF check fails and the mail gets bounced.

Dreamhost installs Mailman on a subdomain. My Mailman subdomain name didn’t have an SPF record. I was somewhat surprised that any mail was getting though. Usually a missing SPF record will stop all mail coming from a domain to be bounced.

So I added an SPF record for my subdomain. In my case I allow-listed the following:

  • Any IP with an A record for my subdomain. The mailing is is on a subdomain with one A record that points to the VM running the Mailman server.
  • Any IP with an MX record for my subdomain, so any assigned mail exchangers.
  • netblocks.dreamhost.com and relay.mailchannels.net – Suggested by Dreamhost tech support. I’m guessing “all netblocks assigned to Dreamhost” and “all mail relays operated by Dreamhost.”

The subdomain’s DNS entry is a type “TXT” record with the contents:

"v=spf1 a mx include:netblocks.dreamhost.com
include:relay.mailchannels.net ~all"

The ~all at the end says that anyone attempting to send mail from my domain using a server that isn’t in the list will “soft fail” the SPF test, which is interpreted by most mail exchange servers to mean “mark it as spam if it doesn’t come from one of the listed hosts.” If you want the MX server to “hard fail” (bounce) the message use -all (hard fail) instead.

I tend to use soft fail just in case the list subscriber’s server is misconfigured or there’s some other failure. In that case the MX server will send list messages to spam (so the list subscriber will still see it) rather than bounce the message.

If you need to set this up for yourself make sure that you list all hosts that send mail for your domain. There are a number of web tools available to help you create an SPF record with the correct parameters, just Google “create an spf record” and you’ll find half a dozen.

Hope you find this useful.

post

AI without GPUs: Using Intel AMX CPUs on VMware vSphere with Tanzu Kubernetes

I was invited to AI Field Day 4 in Santa Clara last week to present a couple of talks on running AI workloads on Intel AMX CPUs. This is a recording of the talk I did on setting up Tanzu Kubernetes for running workloads that use Intel AMX CPUs.

Hope you find this useful.

post

Posting to Google Spaces from Bash

I recently started using Google Spaces and wanted to have some automations send me messages when certain things happened on my systems, so I wrote a simple bash script to send a notification message.

If you’re the Space Manager of a Google Space you can create webhooks to send messages to that space. You can create a webhook for Google Spaces by going into Google Chat and selecting the Space you want to send messages to. Click on the Space name at the top of the screen then choose “Apps & integrations” from the drop-down menu. Then select “Webhooks” and create a webhook.

Each webhook has a name, an icon, and a URL. I wanted three types of messages: info, warning, and critical, so I created three webhooks named Info, Warning, and Critical, each with an appropriate icon.

Then I created the notify.sh script, copying the URLs for my space into an associative array. (Associative arrays were only introduced in Bash v4, so if you’re using an older version of bash this won’t work.)

#!/bin/bash

# List of webhooks from Google Spaces.
declare -A webhooks
webhooks=(
    ["info"]="https://chat.googleapis.com/v1/spaces/..."
    ["warning"]="https://chat.googleapis.com/v1/spaces/..."
    ["critical"]="https://chat.googleapis.com/v1/spaces/..."
)

# Use the first argument -- "info", "warning",
# or "critical" -- to pick a webhook URL.
GCHAT_WEBHOOK_URL="${webhooks[$1]}"

if [[ -z $GCHAT_WEBHOOK_URL ]]; then
    # If the first argument wasn't "info", "warning",
    # or "critical", use the "critical" webhook.
    GCHAT_WEBHOOK_URL="${webhooks["critical"]}"
else
    # Remove the first argument from the arg list.
    shift
fi

# Everything after the first argument becomes the message.
msg="$*"

# Escape the message text to make it "safe".
escapedText=$(echo "$msg" | sed 's/\n/\\n/g' \
    | sed 's/"/\\"/g' | sed "s/'/\\'/g" )

# Create a json object with the text.
json="{\"text\": \"$escapedText\"}"

# Use curl to send the JSON to Google.
curl -X POST -H 'Content-Type: application/json' \
    -d "$json" "${GCHAT_WEBHOOK_URL}" 

Now I can call the script like so:

notify.sh info "You should know about this."
notify.sh warning "There's a problem but it's not that bad."
notify.sh critical "There's a bad problem."

If I have another script that needs to get my attention I just have it call notify.sh.

Hope you found this useful.