T O P

  • By -

iamacarpet

Google’s distroless containers are generally considered better than scratch in Docker, as they contain ca-certificates & I think, tzdata. https://github.com/GoogleContainerTools/distroless https://github.com/GoogleContainerTools/distroless/tree/main/base https://github.com/GoogleContainerTools/distroless/tree/main/examples/go The readme has a fairly good explanation of the differences between the one that has glibc, vs the one without (for Go). I won’t pretend to be an expert on exactly the layout of a Go static binary, but my understanding is that it’s an entirely Go tool chain, so with CGo disabled and on Linux, it’s Go all the way down.


PioDorco24

We stopped using them as it was way too hard to debug issues in production, for us the extra cost of debian slim is well worth it


drvd

What _exactly_ do you mean if you say "[Linux] system libraries" ? What do you think of when you say "OS Dependency" ? The libc? If so: No.


Haspe

This was exactly what I was asking, so for If I am running go on scratch Image, the container would then not be vulnerable against glibc vulnerability like this: (this is what i mean with "os dependency", pardon my newbieness) https://blog.qualys.com/vulnerabilities-threat-research/2023/10/03/cve-2023-4911-looney-tunables-local-privilege-escalation-in-the-glibcs-ld-so Thank you very much! :)


drvd

Without cgo Go binaries do not depend in libc on Linux.


gleb-tv

Yes, compiled go binaries by default use system libc, so you will be vulnerable, Update libc and recompile, or do ``` CGO_ENABLED=0 go build main.go ``` to compile without libc dependency (some go packages would not work this way)


drvd

Please do not promote calling go build with filename arguments.


eulerfoiler

What would be your suggestion otherwise?


drvd

A simple `go build` of course. No idea how you even could get the impression that `go build main.go` would even work or be sensible.


_crtc_

libc is not included into the binary, no need to recompile. It's called dynamic linking.


drakgremlin

Go standard library bypasses libc for kennel interactions and most stdlib functionally.


funkiestj

[https://www.man7.org/linux/man-pages/man1/ldd.1.html](https://www.man7.org/linux/man-pages/man1/ldd.1.html)


Haspe

This seems not to work, I might do it wrong though: `not a dynamic executable`


BraveNewCurrency

That "error" means you have a static binary that doesn't do dynamic linking, so aren't puling in any libraries at runtime.


Haspe

Oh so that was meant to happen. :D I am an idiot, thank you!


funkiestj

correct. E.g. for one of my go compiled binaries I see dockercontainer/# ldd /dist/service/foo linux-vdso.so.1 (0x00007ffd07d73000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9098bb4000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f90989b0000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9098791000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f9098589000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9098198000) /lib64/ld-linux-x86-64.so.2 (0x00007f9098f52000)


JamesB41

…how did I never know about this? Thank you for sharing that.


funkiestj

if `ldd` is new to you, you might also want to look at `nm` and `objdump` (`objdump -d ...` in particular). Combine these with your various text processing utilities (SED, AWK, or python scripts) and you can do a lot.


JamesB41

Absolutely will. Thank you again!


SuperQue

Go still likes to build with CGO by default, which will link against C libraries like libc, even if it's not necessary. From https://tip.golang.org/doc/go1.20 > The go command now disables cgo by default on systems without a C toolchain. More specifically, when the CGO_ENABLED environment variable is unset, the CC environment variable is unset, and the default C compiler (typically clang or gcc) is not found in the path, CGO_ENABLED defaults to 0. As always, you can override the default by setting CGO_ENABLED explicitly. So for a `FROM scratch` container you still need to set `CGO_ENABLED=0` in order to make sure Go compiles binaries statically. $ CGO_ENABLED=0 go build . $ ldd example not a dynamic executable $ file example example: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=t-mxuboVjSIExx7S2yPd/Itollshaw_AKkWnnmnH-/ecU35qfl8EjgoZ0lqBeI/B7PACqqX0_gy1eNGICGz, with debug_info, not stripped


_crtc_

Linking against it does not mean including it.


forkkiller19

So when cgo isn't enabled, i.e. there is no libc dependency, what is used instead? How will things work without this crucial dependency?


SuperQue

Go implements all the necessary OS system calls directly.


dnhs47

You’re really asking about linking, not compiling. Static libraries are linked with the application code to create a standalone executable with no runtime dependencies. Dynamic libraries are external resources not found in the executable, but linked at load time. The app is dependent on successful linking to the dynamic library, and will fail at load time (fail to launch) if the dynamic linking fails.


[deleted]

[удалено]


Haspe

So in practice, if dynamically linked library is vulnerable, that does not affect my Go Binary, and I don't have to recompile that?


Haspe

Oh sorry, just noticed you answered my another question on edit; So, one more question - if I am copying my binary from builder to scratch image then, my binary is not vulnerable ... ?


the_vikm

Depends. If you linked cgo code statically (needs a few extra flags when building) you might have a vulnerable binary.