Contents

Monitoring Connection Quality With Smokeping

Have you ever wanted to monitor the quality of your internet connection over time? Do you notice that your internet connection sometimes feels sluggish, but it is difficult to prove or provide sufficient information to your ISP for them to investigate? Then smokeping might be able to help.

What is Smokeping?

Smokeping is a tool/service that monitors latency and packet loss to a configurable set of servers. It stores the results over time and can visualize it in graphs:

A graph from smokeping showing the latency and packet loss to Cloudflare DNS for 3 hours.

Smokeping latency and packet loss graph

Installing Smokeping

Smokeping requires a Unix OS and has some dependencies (RRDtool, FPing etc). One can install it directly on a GNU/Linux OS, or we could use Docker.

If you are not familiar with Docker I recommend taking a look at it. It allows one to deploy images to run software/services in containers on a machine. It makes it a lot easier to run a number of services on one machine, with configurable network interfaces, port mapping and mapping local directories as volumes into each running container instance. Effectively one can run many services on one machine that are isolated from one another (or multiple services such as a DB services and webapp that can communicate on a specific network interface managed by Docker).

Many popular tools have Docker images, such as PostgreSQL and NGINX. For Smokeping there is a Docker image available that is maintained by linuxserver.io.

A convenient place to run small services, such as Smokeping, is a Raspberry Pi. In the next section we shall cover installing Docker on a Raspberry Pi.

Installing Docker on a Raspberry Pi

To install Docker on a Raspberry Pi running Raspbian 11 (bullseye) we shall follow the official guide to use the package respository.

  1. First, remove older versions of docker if installed (it is possible you previously installed it, or there were older packages that came with the OS repositories):
    sudo apt-get remove docker docker-engine docker.io containerd runc
    
    Docker images, containers, volumes and networks are stored in /var/lib/docker by default and are not automatically removed when you uninstall Docker.
  2. For Raspbian we have to use the convenience script (from https://get.docker.com as published on the Docker website:
    1. Download the script:
      $ curl -fsSL https://get.docker.com -o get-docker.sh
      
    2. Inspect the script to make sure you are comfortable with what it is going to do when executed:
      $ vim get-docker.sh
      
    3. You can also run the script with --dry-run to see what the script would do when invoked:
      $ sudo sh ./get-docker.sh --dry-run
      
    4. Finally, run the script to install and start Docker Engine:
      $ sudo sh et-docker.sh
      

At this point Docker should be installed and running. There are a couple of additional points to consider for installing/running Docker:

  1. By default the Docker service runs as root. To give non-root users access to Docker you can add the user to the docker group, more info is available here
  2. It is also possible to configure Docker to run in rootless mode, you can learn more about rootless mode here.

Docker Compose file for Smokeping

With Docker Engine installed and running we can proceed to downloading the image for the smokeping container and running it.

In order to make it a bit easier and more maintainble to run multiple containers, we can make use of Docker Compose.

Note: The Docker compose plugin should already be installed as part of the Docker installation, but if not, you can install it with:

$ sudo apt install docker-compose-plugin

With Docker compose available, we can go ahead and create our compose file for our smokeping service. Create a new directory that will contain our smokeping data, config and compose file:

$ mkdir smokeping

Inside this directory, create a file called docker-compose.yml with the following contents:

version: "2.1"
services:
  smokeping:
    image: lscr.io/linuxserver/smokeping
    container_name: smokeping
    environment:
      - PUID=<uid>
      - PGID=<gid>
      - TZ=Africa/Johannesburg
    volumes:
      - ./config:/config
      - ./data:/data
    ports:
      - 8080:80
    restart: unless-stopped

There is a bit to unpack here, so lets run over what this file is configuring. We are defining one service called smokeping. The line image: lscr.io/linuxserver/smokeping means that the smokeping service will use the image lscr.io/linuxserver/smokeping. We are giving the container a name: smokeping. We are setting 3 environment variables that will be available when container instance starts up:

  1. PUID: the user ID of the user to run the smokeping service as. You’ll have to set this to the user ID of the smokeping user we will create in the next section.
  2. PGID: the group ID of the group to run the smokeping service as. You’ll have to set this to the group ID of the smokeping group we will create in the next section.
  3. TZ: The timezone.

In the volumes section, we are mapping 2 local directories (./config and ./data )to /config and /data in the container. This means that the config and data directories are not actually going to be stored within the container/image itself, but will be stored in our local directory, which should be the smokeping directory we created earlier. This way we are free to destroy, delete, update, reinstall and restart the smokeping container and image without worrying about losing the config or data.

In the ports section we are mapping port 8080 on the host to port 80 in the container. When the smokeping service is running we will be able to visit http://<your_pi_hostname>:8080 in a web browser to access the smokeping web interface.

Create a user and group for smokeping

Lets create a smokeping user and group for the service to use, and which shall be the owner of the config and data directories:

$ sudo useradd --home-dir /home/smokeping --create-home --system --user-group --shell /usr/sbin/nologin smokeping

This should create a smokeping user with a primary group of smokeping. To get the user and group ids, you can use the id command:

$ id smokeping
uid=1002(smokeping) gid=1002(smokeping) groups=1002(smokeping)

Note: Remember to place the smokeping user and group ids in the PUID and GUID environment variable entries in the docker-compose.yml file.

Now, create the config and data directories and assign ownership to the smokeping user and group:

$ mkdir config data
$ sudo chown smokeping:smokeping config data
# Also, set the permissions on the directories to be rwxrwxr-x
$ sudo chmod 775 config data

Note: In order to simplify editing the config files later, you could add yourself to the smokeping group:

$ usermod -aG smokeping <your-username>

You likely have to log out and back in (or start a new login shell) for the group change to be effective.

At this point we are ready to start configuring our Smokeping instance. The config and data directories are still empty. In order to populate them we can start and then stop the Smokeping service.

To start the service:

$ sudo docker compose up -d

This will start the service in the background.

In order to take the service down:

$ sudo docker compose down

Now the default configuration files should be in the config directory.

Configuration

For the purposes of this guide we are only going to take a brief look at the Targets file where all the hosts that smokeping will run tests to are defined, and the Database file where we can set the default ping step and pings settings (the number of pings per interval).

Targets

Note: If you encounter permission errors when trying to save the Targets file, make sure that the file is group writable (sudo chmod 775 config/Targets).

The default Targets file contains quite a number of entries. The target entries are hierarichal (menus and submenus). The top level menu id is prefixed with a +, a submenu id is prefixed with ++ and so forth. Each menu entry has three fields menu, title and host. The host field is the FQDN of the host to run a test to. Additonally each entry can have probe entry. The default probe is FPing, which conducts a ping test. Another probe is DNS, which conducts a DNS query to test the response time and latency of a DNS server.

To comment out a line in the Targets file, prefix it with #.

Here is a small example that contains a ping probe and DNS probe to Cloudflare’s primary DNS service, 1.1.1.1:

*** Targets ***

probe = FPing

menu = Top
title = Network Latency Grapher

+ DNSPings
menu = DNS Pings
title = DNS Pings

++ CloudflareDNS1
menu = Cloudflare DNS 1
title = Cloudflare DNS 1.1.1.1
host = 1.1.1.1

+ DNSProbes
menu = DNS Probes
title = DNS Probes
probe = DNS

++ CloudflareDNS1
menu = Cloudflare DNS 1
title = Cloudflare DNS 1.1.1.1
host = 1.1.1.1

It is likely best that you set up your own Targets file with hosts that make sense for your location and for the latency you want to test (for example, if you want to test latency to another country or continent, your should include a host from there in your Targets file.)

Ping rate and interval

The config/Database file contains the following content by default:

*** Database ***

step     = 300
pings    = 20

# consfn mrhb steps total

AVERAGE  0.5   1  1008
AVERAGE  0.5  12  4320
    MIN  0.5  12  4320
    MAX  0.5  12  4320
AVERAGE  0.5 144   720
    MAX  0.5 144   720
    MIN  0.5 144   720

Take a look at the step and pings values: 300 and 20 respectively. This means that by default tests will use time steps of 300. Ping tests specifically will do 20 pings every 300 seconds. You can change these values here if you want to, and it is best to decide up front what settings you want to use. That is because the step/ping values are written into the database files when they are created, so if you change these values you will have to delete the existing result database files or somehow convert them.

More information about smokeping configuration and probes is available on the smokeping website: https://oss.oetiker.ch/smokeping/doc/index.en.html

Note: Do not choose excessively high ping rates, you do not want to inadvertently become a nuisance to any network/server operators, where you effectively spam them with tons and tongs of pings…

Conclusion

So, what kind of useful information can you get from smokeping? Here is an example, the following is my DNSProbe results for Google DNS, Cloudflare and Quad9:

A graph from smokeping showing the DNS query response time to Google DNS over a 3 hour period.

Smokeping DNS probe graph for Google DNS from my location

A graph from smokeping showing the DNS query response time to Cloudflare DNS over a 3 hour period.

Smokeping DNS probe graph for Cloudflare DNS from my location

A graph from smokeping showing the DNS query response time to Quad9 DNS over a 3 hour period.

Smokeping DNS probe graph for Quad9 DNS from my location

From these results we can see that, from my location with my ISP, Google DNS is not doing so well compared to Cloudflare and Quad9. With Google the average rtt 84.0ms, where with Cloudflare and Quad9 it is 2.1ms and 19.0ms respectively. So, in current conditions, I would be better off using Cloudflare with Quad9 as a secondary DNS, that using Google DNS in terms query response time. This can, of course, change and is likely a temporary issue with Google’s DNS servers in my location.

Notice how the graphs also contain a line that mentions packet loss:. In these 3 cases it is all 0, indicating no packets were lost during the tests (the DNS probe only does 5 requests every 300s though, so it is not the best indicator of packet loss, the ping probes are better used for that).

The next time you notice that your internet connection feels a bit sluggish, take a look at your smokeping graphs and see if you can spot higher latencies or packet loss. If you have it configured to ping to different locations, regions, countries or continents, you could also determine if the loss is local or if it is happening over an international link. All of this is information you can provide to your ISP when you open a support ticket because of poor connectivity/performance.

Thank you

Your comment has been submitted and will be published once it has been approved.

OOPS!

Your comment has not been submitted. Please go back and try again. Thank You!

Leave a comment