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.
This lab will get you familiar with the atomic scan
command and also how to
extend atomic scan
with a custom scanner.
Pull some images
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
sudo atomic scan --list
First lets take a look at RHEL7.1
sudo atomic scan registry.access.redhat.com/rhel7.1
sudo atomic scan --scan_type standards_compliance
registry.access.redhat.com/rhel7.1
Now let’s take a look at RHEL7.6 (latest)
sudo atomic scan registry.access.redhat.com/rhel7.6
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.
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 plugin.
Ensure the plugin obtains the proper input from the / scanin directory.
Ensure the plugin writes the results to the /scanout directory.
/home/ec2-user/workshopfiles
cd /home/ec2-user/workshopfiles
Dockerfile
sudo docker build --rm=true --force-rm=true --tag=example_plugin .
Important
|
Notice . it means in the current directory.
|
sudo docker images
...
REPOSITORY TAG IMAGE ID CREATED SIZE
example_plugin latest 008f60125ce5 16 seconds ago 192.5 MB
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'
sudo atomic scan --list
Now lets try the get rpms scan
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.
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;
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.