Home / Alt manpages / rtmon(8)

  • rtmon(8)
  • Admin command
  • linux

Capture and Replay Linux Network Changes with rtmon

A route silently drops at 2am, and rtmon is the tool that shows what changed and when. It logs every RTnetlink link, address and route change as it happens, so you finish with a log file containing a network state snapshot plus every subsequent change, and the command for reading it back. The examples use rtmon from iproute2 6.1.0-1ubuntu6.4, as installed on the machine used for this guide.

Allow about fifteen minutes. You need a shell, the rtmon and ip commands, write access to the chosen log directory, and permission to bind the netlink socket. Capturing is normally an elevated operation. Reading an existing log is separate and may not need elevation.

1. Check the installed interface

Start with the command's built-in help. This is read-only and does not need sudo:

$ dpkg-query -W -f='${Package} ${Version}\n' iproute2
iproute2 6.1.0-1ubuntu6.4
$ rtmon help
Usage: rtmon [ OPTIONS ] file FILE [ all | LISTofOBJECTS ]
OPTIONS := { -f[amily] { inet | inet6 | link | help } |
             -4 | -6 | -0 | -V[ersion] }
LISTofOBJECTS := [ link ] [ address ] [ route ]

The spelling is easy to misread: file is a required subcommand, followed by the output path. rtmon --help is not the documented form on this installation; use rtmon help or rtmon -Version.

Checkpoint

Confirm the executable and version before troubleshooting output from a different iproute2 installation:

$ command -v rtmon
/usr/sbin/rtmon
$ rtmon -Version
rtmon utility, iproute2-6.1.0

2. Choose a log path and scope

Use a new path that is writable by the account running rtmon. An object list controls what gets watched:

  • link covers network devices.
  • address covers IPv4 or IPv6 addresses on devices.
  • route covers routing entries.
  • all requests all three categories at once.

Start with a temporary log while learning the workflow. This avoids overwriting an operational history:

$ log=/tmp/rtmon-network.log
$ sudo rtmon file "$log" all

This command stays in the foreground and continues listening. Press Ctrl-C when the capture window ends. The file is a stateful record for ip monitor, not a plain text report intended for a text editor.

Tip

Rtmon prepends the current state snapshot when it starts. That means a log made after a problem began still gives you a baseline, followed by changes observed from that point. It cannot recover events that happened before it started.

Checkpoint

In a second terminal, confirm that the process is running and that the file exists:

$ pgrep -a rtmon
12345 sudo rtmon file /tmp/rtmon-network.log all
$ ls -l /tmp/rtmon-network.log
-rw-r--r-- 1 root root 4096 Sep 26 20:50 /tmp/rtmon-network.log

Your process ID, file size and timestamp will differ. An empty file is not proof that capture is working; check for the bind error described in step 4.

3. Reproduce the event and stop capture

With rtmon listening, perform the ordinary network operation you are investigating in another terminal, such as reconnecting a test interface or applying a change through your normal network manager. Do not use an unfamiliar destructive networking command just to create activity. A route or address change can interrupt remote access.

When you have enough evidence, return to the rtmon terminal and press Ctrl-C. The captured file remains on disk. If you need a long-lived history, choose an explicit path such as /var/log/rtmon.log and arrange rotation separately; rtmon's manpage does not describe rotation or retention.

There is no rtmon undo operation. Stopping the process stops future capture; it does not remove the log or reverse network changes made during the test. Remove only a temporary log that you no longer need:

$ sudo rm -- /tmp/rtmon-network.log

Warning

Do not run that removal against a production history or a path supplied by an untrusted source. If you need the evidence, copy or archive it before cleanup.

4. Read the capture with ip monitor

Use the companion reader from the same iproute2 family:

$ sudo ip monitor file /tmp/rtmon-network.log

The command displays the snapshot and recorded link, address or route events. It is the documented way to view an rtmon file. If you selected a narrower scope, the absence of another object type is expected, not evidence that the kernel never changed it.

For a quick check without changing the host, pipe the reader into a bounded command:

$ sudo ip monitor file /tmp/rtmon-network.log | sed -n '1,80p'

If the file is owned by root and your account cannot read it, use sudo for this read or make a deliberate, access-controlled copy. Avoid making network logs world-readable: addresses, routes and interface names can reveal useful information about a host.

5. Narrow the next capture

Once you know which event matters, reduce noise with an object list. For example, a route-only capture is:

$ sudo rtmon file /tmp/rtmon-routes.log route

The family filter and the object list answer different questions: one selects the protocol family, the other selects link, address or route objects.

  • -4 is the shortcut for -family inet.
  • -6 selects IPv6 with -family inet6.
  • -0 selects the link family, where no networking protocol is involved.

For example, capture IPv4 routes only:

$ sudo rtmon -4 file /tmp/rtmon-ipv4-routes.log route

If a command fails with Cannot bind netlink socket: Operation not permitted, first check that the path is writable, then retry with the required privilege on the host. The exact permission needed depends on the host's security policy and container capabilities. Do not treat an empty log as a successful capture.

Done means

  • Versions confirmed. You checked the installed iproute2 and rtmon versions.
  • Scope chosen. You picked a new log path and an explicit object scope.
  • Capture started. You started rtmon with the permission needed to bind netlink and confirmed the file was created.
  • Capture stopped deliberately. You kept or removed the file according to its evidence value.
  • Capture replayed. You read it back with ip monitor file and understood that the first output is a start-time snapshot.