Exercise 1.5 - Atomic Scanner

Return to Workshop

atomic scan

The atomic command-line tool provides a way to interact and manage Atomic Host systems and containers. It provides a high level, coherent entrypoint to the system and makes it easier to interact with special kinds of containers, such as super-privileged containers, and debugging tools.

The atomic command uses tools such as docker, ostree and skopeo to manage containers and container host systems. There are also a lot of features built into the atomic command that are not available in the docker command. These features allow you to use special commands for image signing, image verification, the ability to install a container - mounting file systems and opening privileges.

Before containers are run, it makes good sense to be able to scan container images for known vulnerabilities and configuration problems. A number of container scanning tools are beginning to appear including RHEL’s atomic scan command.

Atomic Scan

This lab will get you familiar with the atomic scan command and also how to extend atomic scan with a custom scanner.

Step 1:

Pull some images

Pull a RHEL 7.1 & 7.6 image
sudo docker pull registry.access.redhat.com/rhel7.1

sudo docker pull registry.access.redhat.com/rhel7.6

Let’s see what types of scanners are available

List scanners
sudo atomic scan --list

First lets take a look at RHEL7.1

Atomic default scan OpenSCAP
sudo atomic scan registry.access.redhat.com/rhel7.1
Atomic Compliance scan
sudo atomic scan --scan_type standards_compliance
registry.access.redhat.com/rhel7.1

Now let’s take a look at RHEL7.6 (latest)

Atomic default scan OpenSCAP
sudo atomic scan registry.access.redhat.com/rhel7.6
Atomic Compliance scan
sudo atomic scan --scan_type standards_compliance
registry.access.redhat.com/rhel7.6

You will notice that over time vulnerabilities are found in OS and applications. So you can see that security is more of a race against time to find and patch vulnerabilities before an attacker can exploit them. This is where containers can really help to enhance security by being able to make a security fix to a base image and have OpenShift deploy that image to all containers that are running outdated versions.

Step 2:

Writing a Custom Scanner

The atomic scanner was designed with a pluggable architecture to allow developers to write custom scanners using any programming language supported by RHEL. Adding a scanner plugin involves the following:

  • Make atomic aware of your plug­in.

  • Ensure the plugin obtains the proper input from the / scanin directory.

  • Ensure the plugin writes the results to the /scanout directory.

cd into /home/ec2-user/workshopfiles
cd /home/ec2-user/workshopfiles
build the Dockerfile
sudo docker build --rm=true --force-rm=true --tag=example_plugin .
Important
Notice . it means in the current directory.
see the newly built container
sudo docker images

...

REPOSITORY          TAG          IMAGE ID         CREATED             SIZE
example_plugin      latest       008f60125ce5     16 seconds ago      192.5 MB
install the new plugin
sudo atomic install --name example_plugin example_plugin
docker run -it --rm --privileged -v /etc/atomic.d/:/host/etc/atomic.d/ example_plugin sh /install.sh
Copying example_plugin configuration file to host filesystem...
'/example_plugin' -> '/host/etc/atomic.d/example_plugin'
view the new scanner as a operation
sudo atomic scan --list

Now lets try the get rpms scan

rpm-list
sudo atomic scan --scanner example_plugin --scan_type=rpm-list registry.access.redhat.com/rhel7.6
docker run -t --rm -v /etc/localtime:/etc/localtime -v /run/atomic/2018-11-13-01-50-10-642277:/scanin -v /var/lib/atomic/example_plugin/2018-11-13-01-50-10-642
277:/scanout:rw,Z -v /tmp/foobar:/foobar example_plugin python list_rpms.py list-rpms
registry.access.redhat.com/rhel7.6 (3da40a1670b5eee)
The following results were found:
       rpms:
         redhat-release-server-7.6-4.el7.x86_64
         filesystem-3.2-25.el7.x86_64
         basesystem-10.0-7.el7.noarch
         ncurses-base-5.9-14.20130511.el7_4.noarch
         glibc-common-2.17-260.el7.x86_64
         nspr-4.19.0-1.el7_5.x86_64
         libstdc++-4.8.5-36.el7.x86_64
         bash-4.2.46-31.el7.x86_64
         pcre-8.32-17.el7.x86_64
         zlib-1.2.7-18.el7.x86_64
         xz-libs-5.2.2-1.el7.x86_64
         libdb-5.3.21-24.el7.x86_64
         elfutils-libelf-0.172-2.el7.x86_64
         libgpg-error-1.12-3.el7.x86_64
         libacl-2.2.51-14.el7.x86_64
         chkconfig-1.7.4-1.el7.x86_64
         libxml2-2.9.1-6.el7_2.3.x86_64
         lua-5.1.4-15.el7.x86_64
         libuuid-2.23.2-59.el7.x86_64
         sqlite-3.7.17-8.el7.x86_64
         grep-2.20-3.el7.x86_64
         expat-2.1.0-10.el7_3.x86_64
         audit-libs-2.8.4-4.el7.x86_64
         libassuan-2.1.0-3.el7.x86_64
         xz-5.2.2-1.el7.x86_64
         findutils-4.5.11-6.el7.x86_64
         lz4-1.7.5-2.el7.x86_64
         pinentry-0.8.1-17.el7.x86_64
         tar-1.26-35.el7.x86_64
         kmod-libs-20-23.el7.x86_64
         libidn-1.28-4.el7.x86_64
         gmp-6.0.0-15.el7.x86_64
         libsmartcols-2.23.2-59.el7.x86_64
         ustr-1.0.4-16.el7.x86_64
         libverto-0.2.5-4.el7.x86_64
         qrencode-libs-3.4.1-3.el7.x86_64
         libtasn1-4.10-1.el7.x86_64
         ca-certificates-2018.2.22-70.0.el7_5.noarch
         coreutils-8.22-23.el7.x86_64
         python-libs-2.7.5-76.el7.x86_64
         libblkid-2.23.2-59.el7.x86_64
         glib2-2.56.1-2.el7.x86_64
         python-iniparse-0.4-9.el7.noarch
         cracklib-2.9.0-11.el7.x86_64
         cracklib-dicts-2.9.0-11.el7.x86_64
         pam-1.1.8-22.el7.x86_64
         libxml2-python-2.9.1-6.el7_2.3.x86_64
         python-six-1.9.0-2.el7.noarch
         python-gobject-base-3.22.0-1.el7_4.1.x86_64
         pkgconfig-0.27.1-4.el7.x86_64
         python-backports-1.0-8.el7.x86_64
         python-decorator-3.4.0-3.el7.noarch
         python-backports-ssl_match_hostname-3.5.0.1-1.el7.noarch
         python-inotify-0.9.4-4.el7.noarch
         pyxattr-0.5.1-5.el7.x86_64
         python-kitchen-1.1.1-5.el7.noarch
         nss-pem-1.0.3-5.el7.x86_64
         nss-sysinit-3.36.0-7.el7_5.x86_64
         binutils-2.27-34.base.el7.x86_64
         libcurl-7.29.0-51.el7.x86_64
         rpm-libs-4.11.3-35.el7.x86_64
         openldap-2.4.44-20.el7.x86_64
         passwd-0.79-4.el7.x86_64
         python-urlgrabber-3.10-9.el7.noarch
         util-linux-2.23.2-59.el7.x86_64
         kpartx-0.4.9-123.el7.x86_64
         device-mapper-libs-1.02.149-10.el7_6.1.x86_64
         dracut-033-554.el7.x86_64
         elfutils-libs-0.172-2.el7.x86_64
         dbus-libs-1.10.24-12.el7.x86_64
         dbus-1.10.24-12.el7.x86_64
         dbus-glib-0.100-7.el7.x86_64
         virt-what-1.18-4.el7.x86_64
         pth-2.0.7-23.el7.x86_64
         rpm-build-libs-4.11.3-35.el7.x86_64
         subscription-manager-rhsm-1.21.10-3.el7_6.x86_64
         pygpgme-0.3-9.el7.x86_64
         subscription-manager-1.21.10-3.el7_6.x86_64
         yum-plugin-ovl-1.1.31-50.el7.noarch
         vim-minimal-7.4.160-5.el7.x86_64
         rootfiles-8.1-11.el7.noarch
         libgcc-4.8.5-36.el7.x86_64
         setup-2.8.71-10.el7.noarch
         tzdata-2018g-1.el7.noarch
         subscription-manager-rhsm-certificates-1.21.10-3.el7_6.x86_64
         nss-softokn-freebl-3.36.0-5.el7_5.x86_64
         glibc-2.17-260.el7.x86_64
         nss-util-3.36.0-1.el7_5.x86_64
         ncurses-libs-5.9-14.20130511.el7_4.x86_64
         libsepol-2.5-10.el7.x86_64
         libselinux-2.5-14.1.el7.x86_64
         info-5.1-5.el7.x86_64
         bzip2-libs-1.0.6-13.el7.x86_64
         popt-1.13-16.el7.x86_64
         libffi-3.0.13-18.el7.x86_64
         libattr-2.4.46-13.el7.x86_64
         libcap-2.22-9.el7.x86_64
         libgcrypt-1.5.3-14.el7.x86_64
         readline-6.2-10.el7.x86_64
         sed-4.2.2-5.el7.x86_64
         libcom_err-1.42.9-13.el7.x86_64
         cpio-2.11-27.el7.x86_64
         diffutils-3.3-4.el7.x86_64
         libcap-ng-0.7.5-4.el7.x86_64
         nss-softokn-3.36.0-5.el7_5.x86_64
         p11-kit-0.23.5-3.el7.x86_64
         gawk-4.0.2-4.el7_3.1.x86_64
         file-libs-5.11-35.el7.x86_64
         keyutils-libs-1.5.8-3.el7.x86_64
         acl-2.2.51-14.el7.x86_64
         libdb-utils-5.3.21-24.el7.x86_64
         which-2.20-7.el7.x86_64
         ncurses-5.9-14.20130511.el7_4.x86_64
         dmidecode-3.1-2.el7.x86_64
         libnl-1.1.4-3.el7.x86_64
         libsemanage-2.5-14.el7.x86_64
         hardlink-1.0-19.el7.x86_64
         gdbm-1.10-8.el7.x86_64
         p11-kit-trust-0.23.5-3.el7.x86_64
         openssl-libs-1.0.2k-16.el7.x86_64
         krb5-libs-1.15.1-34.el7.x86_64
         python-2.7.5-76.el7.x86_64
         libmount-2.23.2-59.el7.x86_64
         shared-mime-info-1.8-4.el7.x86_64
         gzip-1.5-10.el7.x86_64
         shadow-utils-4.1.5.1-25.el7.x86_64
         libpwquality-1.2.3-5.el7.x86_64
         gobject-introspection-1.56.1-1.el7.x86_64
         python-dateutil-1.5-7.el7.noarch
         python-dmidecode-3.12.2-3.el7.x86_64
         libutempter-1.1.6-4.el7.x86_64
         yum-metadata-parser-1.1.4-10.el7.x86_64
         python-ethtool-0.8-7.el7.x86_64
         python-ipaddress-1.0.16-2.el7.noarch
         python-setuptools-0.9.8-7.el7.noarch
         pyliblzma-0.5.3-11.el7.x86_64
         python-chardet-2.2.1-1.el7_1.noarch
         cyrus-sasl-lib-2.1.26-23.el7.x86_64
         nss-3.36.0-7.el7_5.x86_64
         nss-tools-3.36.0-7.el7_5.x86_64
         libssh2-1.4.3-12.el7.x86_64
         curl-7.29.0-51.el7.x86_64
         rpm-4.11.3-35.el7.x86_64
         libuser-0.60-9.el7.x86_64
         python-pycurl-7.19.0-19.el7.x86_64
         json-c-0.11-4.el7_0.x86_64
         device-mapper-1.02.149-10.el7_6.1.x86_64
         procps-ng-3.3.10-23.el7.x86_64
         cryptsetup-libs-2.0.3-3.el7.x86_64
         kmod-20-23.el7.x86_64
         systemd-libs-219-62.el7.x86_64
         systemd-219-62.el7.x86_64
         elfutils-default-yama-scope-0.172-2.el7.noarch
         dbus-python-1.1.1-9.el7.x86_64
         usermode-1.111-5.el7.x86_64
         gnupg2-2.0.22-5.el7_5.x86_64
         rpm-python-4.11.3-35.el7.x86_64
         gpgme-1.3.2-5.el7.x86_64
         yum-3.4.3-161.el7.noarch
         yum-utils-1.1.31-50.el7.noarch
         gdb-gdbserver-7.6.1-114.el7.x86_64

Files associated with this scan are in /var/lib/atomic/example_plugin/2018-11-13-01-50-10-642277.

Additional Fun

Have a look at the files in the /home/ec2-user/workshopfiles directory. They contain the files that make up your new example_scanner. The meat of the scanner is the list_rpms.py Python file. This is a similar architecture to writing Ansible Module, by that as long as you adhere to the api you can write the plugin in any language you like. Basically returning proper json that is defined in example_plugin. Let see that now;

example_plugin
type: scanner
scanner_name: example_plugin
image_name: example_plugin
default_scan: rpm-list
custom_args: ['-v', '/tmp/foobar:/foobar']
scans: [
 { name: rpm-list,
   args: ['python', 'list_rpms.py', 'list-rpms'],
   description: "List all RPMS",
 },
 { name: get-os,
   args: ['python', 'list_rpms.py', 'get-os'],
   description: "Get the OS of the object",
 }
]

So you can see that as long as you package up the scanner code in the container and adhere to the api it should be easy to add your own custom scanner.

Return to Workshop