On September 26, 2024 the OSS team at Anchore released general support for Azure Linux 3, Microsoft’s new cloud-focused Linux distribution. This blog post will share some of the technical details of what goes into supporting a new Linux distribution in Grype.

Step 1: Make sure Syft identifies the distro correctly

In this case, this step happened automatically. Syft is pretty smart about parsing /etc/os-release in an image, and Microsoft has labeled Azure Linux in a standard way. Even before this release, if you’d run the following command, you would see Azure Linux 3 correctly identified.

syft -q -o json mcr.microsoft.com/azurelinux/base/core:3.0 | jq .distro

{
  "prettyName": "Microsoft Azure Linux 3.0",
  "name": "Microsoft Azure Linux",
  "id": "azurelinux",
  "version": "3.0.20241005",
  "versionID": "3.0",
  "homeURL": "https://aka.ms/azurelinux",
  "supportURL": "https://aka.ms/azurelinux",
  "bugReportURL": "https://aka.ms/azurelinux"
}

Step 2: Build a vulnerable image

You can’t test a vulnerability scanner without an image that has known vulnerabilities in it. So just about the first thing to do is make a test image that is known to have some problems.

In this case, we started with Azure’s base image and intentionally installed an old version of the golang RPM:

FROM mcr.microsoft.com/azurelinux/base/core:3.0@sha256:9c1df3923b29a197dc5e6947e9c283ac71f33ef051110e3980c12e87a2de91f1

RUN tdnf install -y golang-1.22.5-1.azl3

This has a couple of CVEs against it, so we can use it to test whether Grype is working end to end.

$ docker build -t azuretest:latest .
$ docker image save azuretest:latest > azuretest.tar
$ grype ./azuretest.tar
  Parsed image sha256:49edd6d1eff19d2b34c27a6ad11a4a8185d2764ae1182c17c563a597d173b8
  Cataloged contents e649de5ff4361e49e52ecdb8fe8acb854cf064247e377ba92669e7a33a228a00
   ├──  Packages                        [122 packages]
   ├──  File digests                    [11,141 files]
   ├──  File metadata                   [11,141 locations]
   └──  Executables                     [426 executables]
  Scanned for vulnerabilities     [84 vulnerability matches]
   ├── by severity: 3 critical, 57 high, 3 medium, 0 low, 0 negligible (21 unknown)
   └── by status:   84 fixed, 0 not-fixed, 0 ignored
NAME          INSTALLED      FIXED-IN         TYPE       VULNERABILITY   SEVERITY
coreutils     9.4-3.azl3     0:9.4-5.azl3     rpm        CVE-2024-0684   Medium
curl          8.8.0-1.azl3   0:8.8.0-2.azl3   rpm        CVE-2024-6197   High
curl-libs     8.8.0-1.azl3   0:8.8.0-2.azl3   rpm        CVE-2024-6197   High
expat         2.6.2-1.azl3   0:2.6.3-1.azl3   rpm        CVE-2024-45492  High
expat         2.6.2-1.azl3   0:2.6.3-1.azl3   rpm        CVE-2024-45491  High
expat         2.6.2-1.azl3   0:2.6.3-1.azl3   rpm        CVE-2024-45490  High
expat-libs    2.6.2-1.azl3   0:2.6.3-1.azl3   rpm        CVE-2024-45492  High
expat-libs    2.6.2-1.azl3   0:2.6.3-1.azl3   rpm        CVE-2024-45491  High
expat-libs    2.6.2-1.azl3   0:2.6.3-1.azl3   rpm        CVE-2024-45490  High
golang        1.22.5-1.azl3  0:1.22.7-2.azl3  rpm        CVE-2023-29404  Critical
golang        1.22.5-1.azl3  0:1.22.7-2.azl3  rpm        CVE-2023-29402  Critical
golang        1.22.5-1.azl3  0:1.22.7-2.azl3  rpm        CVE-2022-41722  High
krb5          1.21.2-1.azl3  0:1.21.3-1.azl3  rpm        CVE-2024-37371  Critical

Normally, we like to build test images with CVEs from 2021 or earlier against them because this set of vulnerabilities changes slowly. But hats off to the team at Microsoft. We could not find an easy way to get a three-year-old vulnerability into their distro. So, in this case, the team did some behind-the-scenes work to make it easier to add test images that only have newer vulnerabilities as part of this release.

Step 3: Write the vunnel provider

Vunnel is Anchore’s “vulnerability funnel,” the open-source project that downloads vulnerability data from many different sources and collects and normalizes them so that grype can match them. This step was pretty straightforward because Microsoft publishes complete and up-to-date OVAL XML, so the Vunnel provider can just download it, parse it into our own format, and pass it along.

Step 4: Wire it up in Grype, and profit scan away

Now Syft identifies the distro, we have test images to use in our CI/CD pipelines so that we’re sure we don’t regress, and Vunnel is downloading the Azure Linux 3 vulnerability data from Microsoft, we’re ready to release the Grype change. In this case, it was a simple change telling Grype where to look in its database for vulnerabilities about the new distro.

Conclusion

There are two big upshots of this post:

First, anyone running Grype v0.81.0 or later can scan images built from Azure Linux 3 and get accurate vulnerability information today, for free.

Second, Anchore’s tools make it possible to add a new Linux distro to Syft and Grype in just a few pull requests. All the work we did for this support was open source - you can go read the pull requests on GitHub if you’d like (vunnel, grype-db, grype, test-images). And that means that if your favorite Linux distribution isn’t covered yet, you can let us know or send us a PR.

If you'd like to discuss any topics this post raises, join us on discourse.