What exactly is being sent to Ubuntu in the MOTD?

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, December 28, 2019

Follow me on Twitter as @mattiasgeniar

There’s a tweet going around in the last few days that highlights that Ubuntu’s default MOTD (Message of the Day) fetches information from an Ubuntu server. In the process, it sends along quite a bit of personal & identifiable information of your desktop or server back to Ubuntu.

Let’s dive into what is being sent exactly.

What’s happening?

When you login to an Ubuntu server or desktop (or any Linux, for that matter), you trigger logic in “MOTD”. This is a message of the day that gets shown whenever you log into a machine over SSH.

By default, it shows you the system hostname, the kernel version and - in Ubuntu’s case - some ads.

Here’s the MOTD when I log into my home media server.

$ ssh mattias@mediaserver.home
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-72-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sat Dec 28 16:05:30 CET 2019

  System load:  0.04               Processes:             114
  Usage of /:   37.1% of 13.76GB   Users logged in:       1
  Memory usage: 71%                IP address for enp0s3: 192.168.126.50
  Swap usage:   14%

 * Overheard at KubeCon: "microk8s.status just blew my mind".

     https://microk8s.io/docs/commands#microk8s.status

 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

0 packages can be updated.
0 updates are security updates.


Last login: Sat Dec 28 16:03:46 2019 from 192.168.126.101

There are some useful bits in there, like the number of outstanding updates, my disk usage etc.

If you’ve logged into more than 5 Linux servers though, you quickly look over all this information. It’s the noise that comes with an SSH login and you just disregard it. It doesn’t help that large corporations overwrite this with sensible nonsense like their corporate disclaimer or e-policy.

It’s worthless, in most cases.

How is Ubuntu getting data to show in my MOTD?

In modern distro’s, the MOTD message is being built dynamically. It consists of several independent pieces.

All that data logic is held in /etc/update-motd.d/*. There are a dozen or so scripts in there to build your MOTD.

The one we’re interested today is /etc/update-motd.d/50-motd-news.

$ cat /etc/update-motd.d/50-motd-news
# (script summarized for readability)

# Piece together the user agent
USER_AGENT="curl/$curl_ver $lsb $platform $cpu $uptime cloud_id/$cloud_id"

# Fetch MOTD content
curl --connect-timeout "$WAIT" --max-time "$WAIT" -A "$USER_AGENT" -o- "$u" >"$NEWS" 2>"$ERR";

A custom user agent is generated with data from variables like $lsb, $platform, $uptime, …

So what’s in there?

What data is being sent to Ubuntu?

There are a couple of ways to see the data that Ubuntu is getting. You could echo the variables in the script, tcpdump the network, … But I’ll use a weird method, just for fun. Let’s strace and look at what’s sent and received.

(Note: to do this, I modified the /etc/default/ configs to fetch the MOTD data over HTTP instead of HTTPS, otherwise I’d just see encrypted blobs of binary data.)

$ rm -f /var/cache/motd-news

$ strace -f -e trace=network -s 9999 run-parts /etc/update-motd.d/
[...]
[pid 13676] getpeername(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("54.194.229.79")}, [128->16]) = 0
[pid 13676] getsockname(3, {sa_family=AF_INET, sin_port=htons(42720), sin_addr=inet_addr("192.168.126.50")}, [128->16]) = 0
[pid 13676] sendto(3, "GET /bionic/x86_64 HTTP/1.1\r\nHost: motd.ubuntu.com\r\nUser-Agent: curl/7.58.0-2ubuntu3.8 Ubuntu/18.04.3/LTS GNU/Linux/4.15.0-72-generic/x86_64 Intel(R)/Core(TM)/i5-8500B/CPU/@/3.00GHz uptime/108266.13/212047.71 cloud_id/unknown\r\nAccept: */*\r\n\r\n", 242, MSG_NOSIGNAL, NULL, 0) = 242
[pid 13676] recvfrom(3, "HTTP/1.1 301 Moved Permanently\r\nDate: Sat, 28 Dec 2019 15:39:41 GMT\r\nServer: Apache/2.4.18 (Ubuntu)\r\nLocation: https://motd.ubuntu.com/bionic/x86_64\r\nContent-Length: 326\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>301 Moved Permanently</title>\n</head><body>\n<h1>Moved Permanently</h1>\n<p>The document has moved <a href=\"https://motd.ubuntu.com/bionic/x86_64\">here</a>.</p>\n<hr>\n<address>Apache/2.4.18 (Ubuntu) Server at motd.ubuntu.com Port 80</address>\n</body></html>\n", 102400, 0, NULL, NULL) = 544

Ah super readable, isn’t it? 😬

We’re mostly interested in the HTTP bits, so let’s clean up this data.

GET /bionic/x86_64 HTTP/1.1
Host: motd.ubuntu.com
User-Agent: curl/7.58.0-2ubuntu3.8 Ubuntu/18.04.3/LTSGNU/Linux/4.15.0-72-generic
            /x86_64 Intel(R)/Core(TM)/i5-8500B/CPU/@/3.00GHz uptime/108266.13/21
            2047.71 cloud_id/unknown
Accept: */*

That User-Agent header contains … quite a bit.

In order, we see:

  • Ubuntu/18.04.3/LTS: this data comes from /etc/lsb-release
  • GNU/Linux/4.15.0-72-generic/x86_64: a combination of different kernel data, taken from $(uname -o)/$(uname -r)/$(uname -m)
  • Intel(R)/Core(TM)/i5-8500B/CPU/@/3.00GHz: the details of my brand of CPU, taken from grep -m1 "^model name" /proc/cpuinfo | sed -e "s/.*: //" -e "s:\s\+:/:g"
  • uptime/108266.13/212047.71: the uptime as read from /proc/uptime: read up idle < /proc/uptime; uptime="uptime/$up/$idle"
  • cloud_id/unknown: the cloud-id as taken from /usr/bin/cloud-id. At home, I’m running this in VirtualBox, but on a public cloud you’d get digitalocean, vultr, … as the name back.

For most of this data I can see a use case for sending it along. Except for the uptime counter and the cloud-id. What’s up with that? 🤔

The CPU info could be used to alert for the next Spectre or Meltdown, the kernel version can be used to show critical messages (that no one would read) in case there are kernel exploits.

But why would Ubuntu be interested in my uptime or name of the cloud provider (which, by the way, can already be determined because the HTTP call would show my source IP and that’s easily mapped back to a cloud provider, only a small portion of users would HTTP proxy all their outgoing traffic).

How do I disable this?

Whether it’s useful or not is entirely up to you. Here’s how you can disable it, in case you don’t want this.

$ vim /etc/default/motd-news
# Enable/disable the dynamic MOTD news service
# This is a useful way to provide dynamic, informative
# information pertinent to the users and administrators
# of the local system
ENABLED=0

Modify the file /etc/default/motd-news and set ENABLED=0. Save the file and it’s done, next login will no longer fetch new data over the internet.



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.