Update all Secure analyzer alpine Docker images to include /etc/nsswitch.conf file
Problem to solve
The Secure team uses alpine
linux based Docker images for many of our tools. These alpine
images are missing an important /etc/nsswitch.conf
file which Go-based binaries use to determine the order for hostname lookups. This means that any Secure team tool that uses a Go-based binary and attempts to communicate with an external service hosted inside the same Docker container using the localhost
alias for 127.0.0.1
may fail in some circumstances.
I spent quite a bit time tracking down a bug in Container Scanning which was ultimately caused by the lack of an /etc/nsswitch.conf
file. The purpose of this issue is to prevent these types of bugs from occurring in the future.
Intended users
Further details
The file /etc/nsswitch.conf
is used by Name Service Switch (NSS) to determine where the system finds things like host names, passwords, and protocol numbers.
Here’s a snippet from a sample /etc/nsswitch.conf
file:
hosts: files dns
In this example, host information first comes from /etc/hosts
(files), then a DNS server (dns). See The Non-complexity of /etc/nsswitch.conf for more details.
alpine
linux based images use the musl implementation of the C standard library instead of the GNU C Library (glibc). Unlike glibc
, the musl
implementation of libc
doesn't support NSS
, and therefore these alpine
linux based images don't include an /etc/nsswitch.conf
file.
Go is hardcoded to behave as glibc (dns first and then use hosts if it fails) if there is no /etc/nsswitch.conf
. This means that on alpine
based images, if the localhost
hostname is used as an alias for 127.0.0.1
, a Go-based binary will ignore this value and issue an external DNS lookup for localhost
, which in some cases will return one of the Docker-assigned IP addresses and may cause the program to fail.
Note: This behaviour was changed in go 1.16 so that entries in the /etc/hosts
file will take precedence.
Proposal
This issue can be fixed using either of the following approaches:
-
Update all of the
alpine
based Docker images used by the Secure team to include an/etc/nsswitch.conf
file using the pattern introduced in the Container Scanning tool:RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf
-
Update all of the
alpine
based Docker images used by the Secure team to useGo >= 1.16
.
The following analyzers need to be updated:
-
No longer necessary now that the
Dockerfile
has been updated to Go 1.18 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.19 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.18 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.19 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17 -
No longer necessary now that the
Dockerfile
has been updated to Go 1.17
What does success look like, and how can we measure that?
Go-based binaries inside an alpine
linux based Docker container use 127.0.0.1
when resolving localhost
. The following code can be used to confirm this.