isp-status

Documents

Ubuntu 24.04 Dynamic MOTD (Console + SSH) — Working Recipe + Lessons Learned

Goal: A single dynamic banner (MOTD) that appears once on SSH and console, updates correctly, and survives reboot on Ubuntu Server 24.04.

This document is written from a real-world troubleshooting session and captures the known-good setup and the gotchas that caused the “works on console but not on SSH” loop.


What you end up with

  • A custom MOTD generator script at: /etc/update-motd.d/50-ops
  • A dynamic MOTD file at: /run/motd.dynamic (tmpfs; wiped on reboot)
  • A symlink so SSH reliably displays it: /etc/motd -> /run/motd.dynamic
  • PAM configured to display/update MOTD for SSH and display once on console
  • Optional boot-time generation so /run/motd.dynamic exists immediately after reboot

Step-by-step (known-good)

1) Create your MOTD script

Create /etc/update-motd.d/50-ops and make it executable:

sudo nano /etc/update-motd.d/50-ops
sudo chmod 755 /etc/update-motd.d/50-ops
sudo chown root:root /etc/update-motd.d/50-ops

Your script should print the banner to stdout. Don’t try to write /run/motd.dynamic inside the script unless you have a reason.

Test it prints output:

sudo run-parts /etc/update-motd.d

Because /run is tmpfs, it is empty after every reboot. Create a oneshot service to generate the file at boot so it always exists before any login.

Create /etc/systemd/system/build-motd.service:

sudo tee /etc/systemd/system/build-motd.service >/dev/null <<'EOF'
[Unit]
Description=Generate /run/motd.dynamic from /etc/update-motd.d
After=local-fs.target
ConditionPathExists=/etc/update-motd.d

[Service]
Type=oneshot
ExecStart=/usr/bin/env bash -lc 'run-parts /etc/update-motd.d > /run/motd.dynamic'
ExecStartPost=/bin/chmod 0644 /run/motd.dynamic

[Install]
WantedBy=multi-user.target
EOF

Enable it:

sudo systemctl daemon-reload
sudo systemctl enable --now build-motd.service

Verify after reboot (or immediately):

ls -l /run/motd.dynamic
head -n 5 /run/motd.dynamic

3) The critical Ubuntu 24.04 fix: align /etc/motd

Ubuntu 24.04 SSH display behavior strongly assumes /etc/motd is the display endpoint.

Create the symlink:

sudo ln -sf /run/motd.dynamic /etc/motd

Verify:

ls -l /etc/motd

You should see:

/etc/motd -> /run/motd.dynamic

4) SSH daemon settings

Edit /etc/ssh/sshd_config and ensure:

UsePAM yes
PrintMotd no
PrintLastLog yes

Reload ssh (no reboot required):

sudo systemctl reload ssh

5) PAM: SSH MOTD must run before common-session (Ubuntu 24.04)

Edit /etc/pam.d/sshd.

Add (or ensure) exactly one MOTD pair BEFORE @include common-session:

# MOTD must run BEFORE common-session on 24.04
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate

@include common-session

Do not leave additional pam_motd duplicates elsewhere in the file.


6) PAM: console login should display once

Console uses /etc/pam.d/login.

To avoid the “double banner on console” issue, use one display-only line:

session optional pam_motd.so motd=/run/motd.dynamic noupdate

(If you have two lines like motd=... and then noupdate on the next line, console can print twice.)

No service restart needed; just log out/in on console.


Validation checklist

After reboot

ls -l /run/motd.dynamic || echo "missing"

SSH

Open a fresh session:

ssh sysops@your-host

Expected: - The dynamic banner prints once - Then Last login: ... - Then prompt

![[Pasted image 20260210153707.png]]

Console

Log out and log back in. Expected: - The banner prints once, not twice


Troubleshooting (fast, practical)

A) SSH shows only “Last login”, no banner

Check:

1) Is /run/motd.dynamic present and non-empty?

ls -l /run/motd.dynamic
head -n 3 /run/motd.dynamic

2) Is /etc/motd aligned?

ls -l /etc/motd

3) Is SSH using PAM?

sudo sshd -T | egrep -i "usepam|printmotd"

4) Does SSH open a PAM session?

sudo journalctl -b -t sshd --no-pager | tail -n 50

You should see: - pam_unix(sshd:session): session opened ...

B) Console shows MOTD twice

Fix /etc/pam.d/login to have only one effective pam_motd display line (use noupdate on the same line).

C) “It worked until reboot”

That’s /run being wiped. Enable the boot oneshot generator and/or ensure PAM updates the file.


Lessons learned (what caused the 3‑day loop)

1) /run is tmpfs: /run/motd.dynamic disappears every reboot. 2) Console ≠ SSH: different PAM stacks (login vs sshd). 3) Ubuntu 24.04 ordering matters: pam_motd needs to run before common-session in sshd. 4) pam_motd is quiet: when skipped, you often get no obvious error—just no banner. 5) SSH display path expects /etc/motd: the symlink /etc/motd -> /run/motd.dynamic is the stabilizer that made SSH consistently display the banner. 6) Avoid “clever” fixes when tired: freeze state, test one change, confirm with a reboot.


“Shareable” quick fix summary

If someone says: “Console banner works, SSH shows nothing on Ubuntu 24.04”:

1) Ensure:

UsePAM yes
PrintMotd no

2) Ensure /etc/pam.d/sshd has pam_motd before common-session.

3) Ensure:

sudo ln -sf /run/motd.dynamic /etc/motd

4) Ensure /run/motd.dynamic exists after reboot (boot oneshot service).


End of document.