In this post we’re going to focus on the container scanning functionality available through the Snyk CLI, and how that can integrate with Podman and the new Podman API which landed in Podman 2.x and is available in Red Hat Enterprise Linux 8.3. Using Snyk and the Podman API in this way provides container image scanning directly in your local command line, helping developers and admins to scan images and check for vulnerabilities right from the start of the image development process.
What's Snyk? Snyk is a developer-first cloud native security platform that provides security insights and remediation throughout the software development lifecycle. Snyk’s integrated service covers dependency scanning for your applications across a variety of languages, security scanning for Terraform, Helm, Kubernetes, and of course container image scanning, with integrations into everything from the IDE, through source code repositories to your CI/CD and orchestration platforms.
Getting started
The first thing we need to do is install the latest version of Podman.
[matt@localhost ~]$ sudo yum -y install podman
Next, let’s install the Snyk CLI :
[matt@localhost ~]$ sudo yum install npm [matt@localhost ~]$ sudo npm install -g snyk
You’ll need a free Snyk account for this next bit, so go ahead and sign up here. Once you have your account set up, you can authenticate the Snyk CLI by running :
[matt@localhost ~]$ snyk auth
Firstly, let’s pull an older version of Red Hat’s Universal Base Image (UBI) from the public RedHat registry, which we know has some security vulnerabilities:
[matt@localhost ~]$ podman pull registry.access.redhat.com/ubi7/ubi:7.6 [matt@localhost ~]$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.access.redhat.com/ubi7/ubi 7.6 247ee58855fd 15 months ago 214 MB
Since Podman is based around open standards and works with OCI-compliant images, Snyk has always been able to scan images created or pulled by Podman, by using Podman to save the image to disk and scanning it from the filesystem. Podman can save images in the Docker archive format, or in OCI archive format, both of which Snyk supports.
[matt@localhost ~]$ podman save 247ee58855fd -o ubi76.tar [matt@localhost ~]$ snyk container test docker-archive:ubi76.tar Testing docker-archive:ubi76.tar... [ TRUNCATED FOR BREVITY ] ✗ High severity vulnerability found in dbus Description: RHSA-2020:2894 Info: https://snyk.io/vuln/SNYK-RHEL7-DBUS-584292 Introduced through: dbus@1:1.10.24-13.el7_6 From: dbus@1:1.10.24-13.el7_6 Fixed in: 1:1.10.24-14.el7_8 Organization: matt-jarvis-snyk Package manager: rpm Project name: docker-image|ubi76.tar Docker image: docker-archive:ubi76.tar Platform: linux/amd64 Licenses: enabled Tested 161 dependencies for known issues, found 68 issues. Pro tip: use `--file` option to get base image remediation advice. Example: $ snyk test --docker docker-archive:ubi76.tar --file=path/to/Dockerfile To remove this message in the future, please run `snyk config set disableSuggestions=true`
Now since this is a public image in an standards compliant registry, if we want to scan this image using Snyk CLI at this point, we can also just do :
[matt@localhost ~]$ snyk container test registry.access.redhat.com/ubi7/ubi:7.6
Snyk has a built-in library for pulling from standards compliant registries, even if it doesn’t find Docker on the host.
However, if the upstream image is in a private repository which requires a login, this won’t work because Snyk would normally use Docker to handle the registry login. This behaviour is the same even if we log in using Podman, since at this point Snyk doesn’t know how to use Podman to handle this :
[matt@localhost ~]$ podman login registry.redhat.io [matt@localhost ~]$ snyk container test registry.redhat.io/ubi7/ubi:latest Please login to the Red Hat Registry using your Customer Portal credentials. Further instructions can be found here: https://access.redhat.com/RegistryAuthentication
Similarly, if the image only exists locally in Podman, this will also not work, as Snyk expects to talk to a local Docker client, and at this point has no knowledge of local images in Podman. As an example, let’s tag our UBI image locally and try to scan it :
[matt@localhost ~]$ podman tag 247ee58855fd mytest [matt@localhost ~]$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.access.redhat.com/ubi7/ubi 7.6 247ee58855fd 15 months ago 214 MB localhost/mytest latest 247ee58855fd 15 months ago 214 MB [matt@localhost ~]$ snyk container test localhost/mytest connect ECONNREFUSED 127.0.0.1:443
In both those use cases, Snyk would normally use the local Docker client, either through the Registry API or by using the Docker socket. Since there is no Docker binary on the system, here Snyk has attempted to use the Registry API, and failed to connect. By default Snyk doesn’t know those images exist locally in Podman, or how to use Podman to interface with upstream.
Luckily, Podman provides us with some easy compatibility features through the podman-docker package. This gives us a fake Docker binary, which is basically just a shell wrapper to the Podman binary, and adds a symlink between the Podman API socket and the default location of the Docker socket file. Out of the box, this package creates a symlink to /var/run/podman/podman.sock
, which is the default when running the Podman API as root.
[matt@localhost ~]$ sudo yum install podman-docker
Now let’s try and scan our local image again :
[matt@localhost ~]$ snyk container test localhost/mytest connect ENOENT /var/run/docker.sock
Well it still doesn’t work, but this time we’ve got a different error. Snyk has detected a binary called docker
, and is now trying to connect to the default location of the privileged Docker socket. Since we are not yet running the Podman API, it can’t connect and so fails again.
Now as we saw earlier, the podman-docker package creates a symlink from /var/run/podman/podman.sock
to /var/run/docker.sock
, assuming that the Podman API is going to be run privileged.
[matt@localhost ~]$ ls -l /var/run/docker.sock lrwxrwxrwx. 1 root root 23 Nov 3 13:19 /var/run/docker.sock -> /run/podman/podman.sock
One of the main issues with the Docker socket is that by default it runs privileged, which is considered a security risk in certain enterprise environments. For most local development environments we don’t need to run the Podman API that way, and can run an unprivileged socket somewhere else. We also have a method for communicating that location to Snyk by using the DOCKER_HOST environment variable, which supports both tcp:// and unix:// URL formats.
In a different shell, let’s run the Podman API with an unprivileged socket:
[matt@localhost ~]$ podman system service --time=0 unix://home/matt/podman.sock
This will run foregrounded, so you will have to Ctrl-C the process when finishing the test. Now we need to set the DOCKER_HOST
environment variable :
[matt@localhost ~]$ export DOCKER_HOST=unix:///home/matt/podman.sock
And finally let’s try and scan our local image again with Snyk :
[matt@localhost ~]$ snyk container test localhost/mytest Testing localhost/mytest... [ TRUNCATED FOR BREVITY ] ✗ High severity vulnerability found in dbus Description: RHSA-2020:2894 Info: https://snyk.io/vuln/SNYK-RHEL7-DBUS-584292 Introduced through: dbus@1:1.10.24-13.el7_6 From: dbus@1:1.10.24-13.el7_6 Fixed in: 1:1.10.24-14.el7_8 Organization: matt-jarvis-snyk Package manager: rpm Project name: docker-image|localhost/mytest Docker image: localhost/mytest Platform: linux/amd64 Licenses: enabled Tested 161 dependencies for known issues, found 68 issues. Pro tip: use `--file` option to get base image remediation advice. Example: $ snyk test --docker localhost/mytest --file=path/to/Dockerfile To remove this message in the future, please run `snyk config set disableSuggestions=true`
Success! Snyk is now working correctly, and talking to Podman using an unprivileged socket.
To configure DOCKER_HOST
permanently in your shell, you can add the export command to your .bashrc
file which will persist the setting.
Finally we’d really like to have this whole setup automatically available to us whenever we log in. To do this we can take advantage of the socket activation facilities in systemd to automatically start our socket when we log in and try to connect to it.
First we need to configure the socket :
[matt@localhost ~]$ cat .config/systemd/user/podman.socket [Unit] Description=Podman API Socket Documentation=man:podman-api(1) [Socket] ListenStream=/home/matt/podman.sock SocketMode=0660 [Install] WantedBy=sockets.target
And then tie the socket to a service :
[matt@localhost ~]$ cat .config/systemd/user/podman.service [Unit] Description=Podman API Service Requires=podman.socket After=podman.socket Documentation=man:podman-api(1) StartLimitIntervalSec=0 [Service] Type=oneshot Environment=REGISTRIES_CONFIG_PATH=/etc/containers/registries.conf ExecStart=/usr/bin/podman system service unix:///home/matt/podman.sock TimeoutStopSec=30 KillMode=process [Install] WantedBy=multi-user.target Also=podman.socket
Finally we reload the systemd configuration and enable the service !
[matt@localhost ~]$ systemctl --user daemon-reload [matt@localhost ~]$ systemctl --user enable --now podman.socket
Now whenever we log in as our local user, we have the Podman API available on demand locally from an unprivileged socket, which Snyk can connect to using the DOCKER_HOST
environment variable we set earlier.
Conclusion
So there we have it, Snyk CLI image scanning with Podman working in the same way as with Docker, allowing developers easy access to security scans of local container images as part of their development workflow.
All of the Snyk functionality is available via the CLI, including adding images to your Snyk dashboard for ongoing monitoring. Snyk collaborates with Red Hat to help developers automate security controls in application development, delivering actionable, scalable cloud native security without compromising speed or performance. Make sure your containers are scanned for security vulnerabilities, and build containers using established best practices. If you don’t already have a Snyk account, it’s free to sign up and use Snyk to scan container images and open source dependencies.
The Docker compatibility layer in Podman provides an easy pathway to transition to using Podman without changing existing workflows and integrations. As Podman grows in popularity, it would be great to see Snyk integration with the native Podman API, but for now these compatibility functions make it super easy to integrate Podman with Snyk.
저자 소개
Matt Jarvis is a Senior Developer Advocate at Snyk. He has spent more than 15 years building products and services around open source software, on everything from embedded devices to large scale distributed systems. Most recently he has been focused on the open cloud infrastructure space, and in emerging patterns for cloud native applications. Jarvis is a regular speaker at conferences and meetups across the world, including MesosCon, FOSDEM, Open Infrastructure Summit and All Things Open, and in his spare time runs several UK Cloud Native meetups.
채널별 검색
오토메이션
기술, 팀, 환경을 포괄하는 자동화 플랫폼에 대한 최신 정보
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
클라우드 서비스
관리형 클라우드 서비스 포트폴리오에 대해 더 보기
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.