Recently, Microsoft  announced the general availability of Azure Linux, a new open source Linux distribution maintained by Microsoft. A core principle of this new offering is to keep the set of OS packages small and light-weight, in support of some of the key characteristics of the distribution as described in the Azure Linux GA Announcement and Azure Linux Intro pages.

As a Linux distribution that prominently highlights security in its list of core benefits, the Anchore team was thrilled to collaborate with Microsoft. Through the open source community, we’re bringing support for Azure Linux into Anchore's open source tool set, for end-to-end support for Azure Linux that includes:

  • New capabilities in Syft to generate SBOMs from Azure Linux OS container images and hosts.
  • A new provider for Vunnel that ingests Microsoft’s open vulnerability data feed for Azure Linux, ensuring accurate package-level vulnerability matching for their new operating system.
  • Assurance that Azure Linux SBOMs, whether generated directly or shared between organizations can be used to generate vulnerability reports with information about available fixes from Microsoft, using Grype.

Syft, Grype and Vunnel support an ever growing set of operating systems, but as new significant OS releases are infrequent, we want to highlight the concepts and technical process involved when bringing a new operating system into Anchore's OSS toolset. In this post, we’ll learn how Syft detects a supported OS and then catalogs that particular OS’s software package type, and critically, how to teach Grype to recognize vulnerabilities for a new distribution.

NOTE: throughout this post, you might see 'mariner' used in technical areas that involve the name of the OS distribution. While the formal name of the new OS is Azure Linux, the internal data sources (/etc/os-release, vulnerability namespaces) use 'mariner' to identify the OS name.

How does Grype recognize vulnerabilities in a new distribution?

In order to scan an image (or other filesystem) for vulnerabilities, Syft and Grype work together. Syft generates a Software Bill of Materials (SBOM), which is a manifest of all the packages we can detect in the image, and Grype reports vulnerabilities by comparing this list with a database of known vulnerabilities. But where does this database come from?

The first piece of the puzzle is a vulnerability feed. A vulnerability feed is a feed of new information, similar in many ways to how blogs and podcasts might have RSS feeds. The maintainers of a distribution often publish vulnerabilities to one of these feeds as they learn of them. However, there is a lot of variety in how these vulnerabilities are reported: how often are new vulnerabilities posted? How is the vulnerable software described? How does the feed reflect that a vulnerability has been fixed in a newer version?

In order to use these vulnerability feeds, Grype needs an aggregated and normalized view of the data they report. Enter Vunnel. Vunnel is a new, open source vulnerability feed aggregation tool from Anchore. When we need to add data from a new set of vulnerabilities to Grype, the first step is to build a provider for the feed in Vunnel. A Vunnel provider is a Python module inside Vunnel that knows how to download and normalize the vulnerabilities from a particular feed.

So in today’s announcement, when we say we Grype supports Azure Linux, what we mean is that Vunnel now has a vulnerability feed provider that pulls in vulnerabilities relating to Azure Linux and its packages, and makes them available to Grype. Let’s take a look at what went into adding this support end-to-end.

Detecting the Distro

Azure Linux is a Redhat Package Manager (RPM) based Linux distribution. Since Syft has long standing support for other RPM based distributions, we need to ensure that when an Azure Linux system is scanned and that the distro identifiers are picked up. This allows Syft to know how to correctly catalog the software installed using regular distro packaging mechanisms (in addition to non-distro software). This information will be used later by Grype during a vulnerability scan.  Last year, support for Mariner was added to Syft via contributions from the community here, here and here! (Can we just say, the open source community is awesome!)  

We can see what this looks like by inspecting the ‘distro’ section of an SBOM generated against a mariner linux container image, like so:

$ syft -q -o json mcr.microsoft.com/cbl-mariner/base/core:2.0 | jq '.distro'

{
  "prettyName": "CBL-Mariner/Linux",
  "name": "Common Base Linux Mariner",
  "id": "mariner",
  "version": "2.0.20230518",
  "versionID": "2.0",
  "homeURL": "https://aka.ms/cbl-mariner",
  "supportURL": "https://aka.ms/cbl-mariner",
  "bugReportURL": "https://aka.ms/cbl-mariner"
}

Cataloging the Distro Software

Now that we have the distro, and Syft knows that this particular distro uses RPM to manage packages, Syft will now automatically find and catalog any discovered RPMs, and add them to the ‘artifacts’ section of the generated SBOM. We won’t show all of the package metadata that is captured by Syft during analysis here (it’s quite a lot!), but importantly we can see that the Mariner RPMs are being identified correctly:

$ syft -q -o json mcr.microsoft.com/cbl-mariner/base/core:2.0 | jq '.artifacts[0].metadata' | more

{
  "name": "bash",
  "version": "5.1.8",
  "epoch": null,
  "architecture": "aarch64",
  "release": "1.cm2",
  "sourceRpm": "bash-5.1.8-1.cm2.src.rpm",
  
  
}

Understanding the Vulnerability Data

Grype has logic that it uses to determine what the best vulnerability data source is for any given software element in a provided SBOM. In the case of operating system managed software, where the OS maintainer additionally provides a high quality vulnerability data feed (as is the case for Azure Linux), we need to find and understand that data source (both in terms of access, as well as format and data characteristics). For Azure Linux, we collaborated with the Azure team who let us know that this repository on GitHub is one place where feeds that are appropriate for this use case are made available.

Add a Provider to Vunnel

The last step in this journey is to implement a provider in Vunnel that takes vulnerability feed data on one side and normalizes the data into an intermediate form that the Grype DB system understands, which then ultimately gets packaged up and made available to all users of Grype. Because of the way syft -> vunnel -> grype-db -> grype are designed, as long as there is agreement between the ‘distro’ that Syft is storing, and the ‘namespace’ that ultimately ends up in the grype vulnerability DB, then Grype will automatically begin matching any ‘mariner distro RPMs’ to the ‘mariner vulnerability data’, to get the most accurate results available. Take a look at this thread in grype and related links to vunnel to look at the discussion and resulting provider implementation. Once completed, we can see the new vunnel provider doing its work when asked to create a normalized set of data that grype-db can understand:

$ vunnel run mariner

[INFO ] running mariner provider
[INFO ] wrote 4025 entries
[INFO ] recording workspace state

Verify Matching in Grype

With all the pieces in hand, now all that’s left is to see all the pieces come together - using a very old mariner linux container image (so that we have some examples of vulnerabilities that have since fixed) shows a successful outcome:

$ grype -q mcr.microsoft.com/cbl-mariner/base/core@sha256:e20e222517e903144f01f4503ca6d5ab5f575669f7ac402bb85e2a1917511bf0


curl            7.82.0-1.cm2   0:7.86.0-1.cm2   rpm   CVE-2022-35252  Low
curl-libs       7.82.0-1.cm2   0:7.86.0-1.cm2   rpm   CVE-2022-35252  Low

With that final step, showing the culmination of Syft, Vunnel, and Grype interoperating to provide a distro-aware vulnerability scan of mariner linux systems, our journey of adding support for a new Linux distribution is complete!

Grype Now Supports the Azure Linux Vulnerability Feed

Azure Linux, also known as Mariner Linux, is an open source Linux distribution from Microsoft, optimized for performance on Azure. In this post, we’ve described the process of adding the Azure Linux vulnerability feed to Vunnel, Anchore’s open source tool for importing and normalizing different vulnerability feeds. This allows Grype to scan for vulnerabilities from this feed. Versions of Grype 0.62.0 and later support this new feed, and can find vulnerabilities reported against Azure Linux packages.

It’s great to see Anchore’s Syft and Grype add support for Azure Linux. Having accurate vulnerability data is critical for our customers, and these tools provide comprehensive open source options.

– Jim Perrin, Principal PM, Azure Linux

So if you’re using, or planning to use, Azure Linux, try out Syft and Grype for your SBOM and vulnerability scanning needs! Finally, as the full end-to-end stack of syft, vunnel, grype-db, grype, Azure Linux itself and Azure Linux Vulnerability Feeds are all open source, we hope that this post can be used to encourage community members to build providers for new vulnerability feeds just as described here, so that Grype can detect vulnerabilities from those feeds as well. 

To get started, please open an issue and read the DEVELOPING.md from Vunnel.