anchore / syft

CLI tool and library for generating a Software Bill of Materials from container images and filesystems
Apache License 2.0
6.24k stars 574 forks source link

Feature: OpenWrt specific cataloger #1847

Open spiffcs opened 1 year ago

spiffcs commented 1 year ago

What would you like to be added: I followed these instructions to generate an Open WRT docker image: OpenWrt as a Docker Image

After scanning the image with syft I found only kernel modules being detected:

syft openwrt-x86-generic-rootfs:latest
 ✔ Loaded image
 ✔ Parsed image
 ✔ Cataloged packages      [48 packages]

NAME     VERSION         TYPE
                         linux-kernel-module
         0.9.28          linux-kernel-module
         2.3LK-NAPI      linux-kernel-module
         3.122           linux-kernel-module
         3.5.24-k2-NAPI  linux-kernel-module
         7.3.21-k8-NAPI  linux-kernel-module
busybox  1.19.4          binary

When I query the images package manager I see:

/ # opkg list-installed
base-files - 117-r36088
busybox - 1.19.4-6
dnsmasq - 2.62-2
dropbear - 2011.54-2
firewall - 2-55.1
grub - 0.97-3
hotplug2 - 1.0-beta-4
iptables - 1.4.10-4
jshn - 2013-01-29-0bc317aa4d9af44806c28ca286d79a8b5a92b2b8
kernel - 3.3.8-1-fa7af62e0ef1d529ecb7f7efccc706c3
kmod-3c59x - 3.3.8-1
kmod-8139too - 3.3.8-1
kmod-e100 - 3.3.8-1
kmod-e1000 - 3.3.8-1
kmod-ipt-conntrack - 3.3.8-1
kmod-ipt-core - 3.3.8-1
kmod-ipt-nat - 3.3.8-1
kmod-ipt-nathelper - 3.3.8-1
kmod-lib-crc-ccitt - 3.3.8-1
kmod-libphy - 3.3.8-1
kmod-natsemi - 3.3.8-1
kmod-ne2k-pci - 3.3.8-1
kmod-pcnet32 - 3.3.8-1
kmod-ppp - 3.3.8-1
kmod-pppoe - 3.3.8-1
kmod-pppox - 3.3.8-1
kmod-r8169 - 3.3.8-1
kmod-sis900 - 3.3.8-1
kmod-tg3 - 3.3.8-1
kmod-via-rhine - 3.3.8-1
kmod-via-velocity - 3.3.8-1
libblobmsg-json - 2013-01-29-0bc317aa4d9af44806c28ca286d79a8b5a92b2b8
libc - 0.9.33.2-1
libgcc - 4.6-linaro-1
libip4tc - 1.4.10-4
libiwinfo - 36
libiwinfo-lua - 36
libjson - 0.9-2
liblua - 5.1.4-8
libnl-tiny - 0.1-3
libubox - 2013-01-29-0bc317aa4d9af44806c28ca286d79a8b5a92b2b8
libubus - 2013-01-13-bf566871bd6a633e4504c60c6fc55b2a97305a50
libubus-lua - 2013-01-13-bf566871bd6a633e4504c60c6fc55b2a97305a50
libuci - 2013-01-04.1-1
libuci-lua - 2013-01-04.1-1
libxtables - 1.4.10-4
lua - 5.1.4-8
luci - 0.11+svn9769-1
luci-app-firewall - 0.11+svn9769-1
luci-i18n-english - 0.11+svn9769-1
luci-lib-core - 0.11+svn9769-1
luci-lib-ipkg - 0.11+svn9769-1
luci-lib-nixio - 0.11+svn9769-1
luci-lib-sys - 0.11+svn9769-1
luci-lib-web - 0.11+svn9769-1
luci-mod-admin-core - 0.11+svn9769-1
luci-mod-admin-full - 0.11+svn9769-1
luci-proto-core - 0.11+svn9769-1
luci-proto-ppp - 0.11+svn9769-1
luci-sgi-cgi - 0.11+svn9769-1
luci-theme-base - 0.11+svn9769-1
luci-theme-openwrt - 0.11+svn9769-1
mtd - 18.1
netifd - 2013-01-29.2-4bb99d4eb462776336928392010b372236ac3c93
opkg - 618-3
ppp - 2.4.5-8
ppp-mod-pppoe - 2.4.5-8
ubus - 2013-01-13-bf566871bd6a633e4504c60c6fc55b2a97305a50
ubusd - 2013-01-13-bf566871bd6a633e4504c60c6fc55b2a97305a50
uci - 2013-01-04.1-1
uhttpd - 2012-10-30-e57bf6d8bfa465a50eea2c30269acdfe751a46fd

I would like the above packages to appear in the SBOM Why is this needed: Support for users who want to generate SBOM for software containerized with OpenWrt

Context:

/ # find ./usr/lib/opkg/info/ | grep control | head
./usr/lib/opkg/info/kmod-via-velocity.control
./usr/lib/opkg/info/libcomerr0.control
./usr/lib/opkg/info/ppp-mod-pppoe.control
./usr/lib/opkg/info/rpcd-mod-file.control
./usr/lib/opkg/info/opkg.control
./usr/lib/opkg/info/libjson-c2.control
./usr/lib/opkg/info/r8169-firmware.control
./usr/lib/opkg/info/rpcd.control
./usr/lib/opkg/info/dnsmasq.control
./usr/lib/opkg/info/kmod-e1000e.control
/ # cat ./usr/lib/opkg/info/dnsmasq.control
Package: dnsmasq
Version: 2.80-15
Depends: libc, libubus20191227
Source: package/network/services/dnsmasq
SourceName: dnsmasq
License: GPL-2.0
LicenseFiles: COPYING
Section: net
Require-User: dnsmasq=453:dnsmasq=453
Architecture: i386_pentium4
Installed-Size: 113565
Description:  It is intended to provide coupled DNS and DHCP service to a LAN.

looks like there are a bunch of flat files laying around that may indicate they are installed

johnDeSilencio commented 1 year ago

opkg is designed to be compatible with Debian. As far as I understand, .ipk and .opk packages use the same or nearly the same metadata as Debian packages.

opkg installs packages under the directory /var/lib/opkg/info/. Rather than create an entirely new cataloger, we could just add this directory to the list of directories that the Debian cataloger searches, e.g.

func NewDpkgdbCataloger() *generic.Cataloger {
    return generic.NewCataloger(catalogerName).
        // note: these globs have been intentionally split up in order to improve search performance,
        // please do NOT combine into: "**/var/lib/dpkg/{status,status.d/*}"
        WithParserByGlobs(parseDpkgDB, "**/var/lib/dpkg/status", "**/var/lib/dpkg/status.d/*", "**/var/lib/opkg/info/*", "**/var/lib/opkg/status")
}
johnDeSilencio commented 1 year ago

For example, I have a branch up in my forked repo that makes this change. When I run syft on an internal image we have at my company, this is all the output I get:

$> syft mycompany.repo.com/internalimage:latest
 ✔ Loaded image
 ✔ Parsed image
 ✔ Cataloged packages      [1 packages]
NAME     VERSION  TYPE
busybox  ...   binary

But when I build syft locally on my branch and run it against the image, I get a lot more output:

$> docker run -it anchore/syft:latest mycompany.repo.com/internalimage:latest
 ✔ Parsed image
 ✔ Cataloged packages      [53 packages]
NAME                      VERSION      TYPE
base-files                ...          deb
base-passwd               ...          deb
busybox                   ...          binary
busybox                   ...          deb
ca-certificates           ...          deb
// ...
wget                      ...          deb

If anyone knows of a public docker image that installs packages using opkg, let me know. I wasn't sure how to search on hub.docker.com for something like that

johnDeSilencio commented 1 year ago

Heads up that openwrt/rootfs is a great image to test this feature on. Running syft as-is on openwrt/rootfs:

$> syft openwrt/rootfs
 ✔ Loaded image
 ✔ Parsed image
 ✔ Cataloged packages      [1 packages]
NAME     VERSION  TYPE
busybox  0.45.6   binary

Running syft from the branch in my forked repo on openwrt/rootfs:

$> docker run anchore/syft:latest openwrt/rootfs
 ✔ Parsed image                                                                                                                                                                                                                                                                                                                    sha256:1bbaca497d1b2463463c525960e6556006a1785c2d03b8ea9405cc05346bc107
 ✔ Cataloged packages              [197 packages]
NAME                        VERSION                                      TYPE
base-files                  1234-r12345-f1234567                         deb
busybox                     0.45.6                                       binary
busybox                     0.45.6-1                                     deb
// ...
urngd                       2023-01-21-c7f7b6b6                          deb
usign                       2019-01-01-abcd12345                         deb