Customised Server Login Message and WordPress Email Problem
# How Customising My Server’s Login Message Fixed a Years-Old WordPress Email Problem
I rarely log into my web server. Maybe a handful of times a year — when something breaks, when I’m curious about resource usage, or when I remember that I probably should check on things. The server runs WordPress, and WordPress mostly takes care of itself. Updates install automatically. Backups happen on schedule. The whole point of self-hosting on a managed droplet is that you set it up once and then forget about it.
But there’s a contradiction in that forgetting. If you never look at something, you never notice when it’s quietly broken.
* * *
Ubuntu servers display a Message of the Day when you connect via SSH. On a DigitalOcean WordPress droplet, this includes system statistics, pending security updates, and a verbose welcome message explaining setup steps you completed years ago. It’s useful the first time. By the tenth login, it’s noise.
I wanted something more practical. When I do log in, I want to know immediately if anything is wrong. Are the essential services running? Is my SSL certificate about to expire? A dashboard, essentially, but one that appears automatically without requiring me to remember commands.
The MOTD is generated by executable scripts in `/etc/update-motd.d/`. Each script runs in numerical order at login. Creating a custom one is straightforward:
sudo vim /etc/update-motd.d/52-custom
sudo chmod +x /etc/update-motd.d/52-custom
I added colour-coded service checks — green for running, red for down:
#!/bin/bash
# Colours
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No colour
echo ""
echo "=== Services ==="
systemctl is-active --quiet apache2 && echo -e "Apache: ${GREEN}Running${NC}" || echo -e "Apache: ${RED}DOWN${NC}"
systemctl is-active --quiet mysql && echo -e "MySQL: ${GREEN}Running${NC}" || echo -e "MySQL: ${RED}DOWN${NC}"
systemctl is-active --quiet php8.3-fpm && echo -e "PHP-FPM: ${GREEN}Running${NC}" || echo -e "PHP-FPM: ${RED}DOWN${NC}"
systemctl is-active --quiet ufw && echo -e "UFW: ${GREEN}Running${NC}" || echo -e "UFW: ${RED}DOWN${NC}"
systemctl is-active --quiet fail2ban && echo -e "Fail2Ban: ${GREEN}Running${NC}" || echo -e "Fail2Ban: ${RED}DOWN${NC}"
systemctl is-active --quiet redis-server && echo -e "Redis: ${GREEN}Running${NC}" || echo -e "Redis: ${RED}DOWN${NC}"
A small aside: the glob pattern `php*-fpm` doesn’t work with `systemctl`. You need the exact service name — `php8.3-fpm` in my case. I spent ten minutes puzzled by a false “DOWN” status before checking with `systemctl list-units | grep php`. Minor frustrations like this are part of the territory.
* * *
While reviewing running processes to decide what else to monitor, I noticed Postfix was active. Postfix is a mail transfer agent. It handles sending email from the server. And it was running fine, had apparently been running fine for years.
Which raised a question: when was the last time I received an email from WordPress?
I thought about it. Comment notifications? No. Password reset confirmations? No. Plugin update alerts? No. I couldn’t recall a single one.
A quick test:
echo "Test email" | mail -s "Test" my-email@example.com
The mail log showed the message being accepted locally. Then nothing. No delivery confirmation, no bounce, no error. The email simply vanished into the void.
This had been broken for years. Possibly since I first set up the droplet. And I’d never noticed because I never looked.
* * *
Here’s what I’d missed during initial setup: DigitalOcean blocks outbound traffic on port 25 at the infrastructure level. This isn’t a firewall rule you can modify from within your droplet. It’s a spam prevention measure applied by default, outside your control.
WordPress uses PHP’s `mail()` function, which hands messages to the local mail transfer agent. Postfix accepts the message, queues it, and attempts delivery on port 25. The connection fails silently. WordPress never receives an error. The mail log shows nothing obviously wrong.
The failure is invisible at every level. PHP thinks it succeeded. Postfix thinks it’s trying. WordPress has no idea. And because I rarely log in and never checked, the problem persisted for years.
You can request DigitalOcean remove this block, but they often decline for newer accounts. My account is over a decade old, so I might have had luck asking. But the cleaner solution is to relay mail through an authenticated SMTP server on port 587 or 465 — ports that aren’t blocked.
* * *
My email is hosted with the same provider that handles my domain. They offer SMTP access, which means I can configure Postfix to route all outbound mail through their servers instead of attempting direct delivery.
First, verify the port is reachable:
nc -zv mail.your-provider.com 587
If that succeeds, configure the relay:
sudo postconf -e "relayhost = [mail.your-provider.com]:587"
sudo postconf -e "smtp_sasl_auth_enable = yes"
sudo postconf -e "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd"
sudo postconf -e "smtp_sasl_security_options = noanonymous"
sudo postconf -e "smtp_tls_security_level = encrypt"
sudo postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt"
Create a credentials file:
sudo vim /etc/postfix/sasl_passwd
Add authentication details:
[mail.your-provider.com]:587 your-email@example.com:your-password
Secure the file, hash it, and restart:
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl restart postfix
Test again:
echo "Test from server" | mail -s "Relay test" your-email@example.com
sudo tail -f /var/log/mail.log
This time the log showed `status=sent` with `relay=mail.your-provider.com`. The email arrived within seconds.
* * *
My email hosting provider supports STARTTLS — the connection starts unencrypted and upgrades to TLS after a handshake. They also support implicit TLS — encrypted from the first byte.
Implicit TLS is _marginally_ more secure. STARTTLS is theoretically vulnerable to downgrade attacks where a man-in-the-middle strips the encryption command before the client can upgrade. The Postfix setting `smtp_tls_security_level = encrypt` mitigates this by refusing to send if TLS negotiation fails, so the practical difference is small.
Still, I prefer the belt-and-braces approach. My provider supports both, so I switched to implicit TLS:
sudo postconf -e "relayhost = [mail.your-provider.com]:465"
sudo postconf -e "smtp_tls_wrappermode = yes"
One fewer attack vector, even a theoretical one.
* * *
If your website and email share the same domain — as mine do — there’s a potential snag. Postfix might consider itself authoritative for that domain and attempt local delivery instead of relaying externally.
Check with:
postconf mydestination
If your domain appears in the output, you’ll need to remove it. In my case, only localhost variants were listed, so mail to my domain correctly relayed through the external server. Worth verifying, though.
* * *
The final MOTD script monitors all the services I care about:
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
echo ""
echo "=== Services ==="
systemctl is-active --quiet apache2 && echo -e "Apache: ${GREEN}Running${NC}" || echo -e "Apache: ${RED}DOWN${NC}"
systemctl is-active --quiet mysql && echo -e "MySQL: ${GREEN}Running${NC}" || echo -e "MySQL: ${RED}DOWN${NC}"
systemctl is-active --quiet php8.3-fpm && echo -e "PHP-FPM: ${GREEN}Running${NC}" || echo -e "PHP-FPM: ${RED}DOWN${NC}"
systemctl is-active --quiet ufw && echo -e "UFW: ${GREEN}Running${NC}" || echo -e "UFW: ${RED}DOWN${NC}"
systemctl is-active --quiet fail2ban && echo -e "Fail2Ban: ${GREEN}Running${NC}" || echo -e "Fail2Ban: ${RED}DOWN${NC}"
systemctl is-active --quiet redis-server && echo -e "Redis: ${GREEN}Running${NC}" || echo -e "Redis: ${RED}DOWN${NC}"
echo ""
echo "=== SSL Expiry ==="
echo -n "example.com: "
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2
echo ""
echo "=== Credentials ==="
echo "MySQL passwords: /some_protected_directory/.digitalocean_password"
Now every login gives me immediate visibility into service health, certificate status, and a reminder of where database credentials live. Useful when you only connect a few times a year.
* * *
The email problem wasn’t obscure. Thousands of people run WordPress on DigitalOcean droplets. The SMTP/port 25 block is documented. The failure mode is well-known. I just never looked.
That’s the uncomfortable part. The system worked exactly as designed — mine and theirs. DigitalOcean blocked spam. Postfix accepted mail. WordPress sent notifications. Everything was functioning correctly from its own perspective. The failure existed only in the gap between them, visible only if you checked.
I didn’t check. For years.
Sometimes the most mundane housekeeping — tidying up a login message — leads you to problems you didn’t know you had. Not because the problems were hidden, but because you never thought to look.
### Like this:
Like Loading...
#postfix #wordpressemail #implicittls
islandinthenet.com/customised-server-login-...
0
0
0
0