# apt-cache show icingadb | grep 'Version: 1.5.1' Version: 1.5.1-7+debian13 Version: 1.5.1-6+debian13 Version: 1.5.1-5+debian13 Version: 1.5.1-4+debian13 Version: 1.5.1-3+debian13 Version: 1.5.1-2+debian13 Version: 1.5.1-1+debian13
Three Categories of Icinga Packages
To start with a simplification, one can put Icinga packages in three categories:
- There are compiled binary packages relying on multiple other system libraries. Those are dynamically linked, and Icinga 2 is the most prominent.
- There are other compiled binaries, but those do not rely on other libraries and are mostly self-contained. This is the case for most Go applications such as Icinga DB, Icinga for Kubernetes, or Icinga Notifications.
- And lastly, there are scripts to be interpreted during runtime. While there might be a shell script or two within the Icinga 2 package, I am talking about all the PHP stuff, Icinga Web and its modules.
Both the dynamic Icinga 2 program and all web modules require other libraries or runtimes. For Icinga Web, these dependencies are obviously PHP and some PHP libraries.
# apt-cache show icingaweb2 | grep '^Depends' | head -1 Depends: apache2 | httpd, php, icingacli (= 2.14.0-2+debian13), icingaweb2-common (= 2.14.0-2+debian13), php-icinga (= 2.14.0-2+debian13), icinga-l10n (>= 1.1.0)
However, this output for Icinga Web 2 already foreshadows that there are more dependencies, transitive ones. Let’s count all dependencies down the tree with apt-rdepends(1):
# apt-rdepends icingaweb2 2>/dev/null | awk '/Depends:/ { print $2 }' | sort | uniq | wc -l
199
Since Icinga Web 2 was grouped together with Icinga 2, what’s the deal with this dynamically linked binary?
# apt-rdepends icinga2 2>/dev/null | awk '/Depends:/ { print $2 }' | sort | uniq | wc -l
50
Within this list, there are lots of libraries, starting from the C++ standard library, libstdc++, to multiple C++ Boost libraries. This results in Icinga 2 loading those libraries during startup, using the latest version the operating system provides. If there is, for example, a security issue in a depending library, the OS package manager ships a new version, and after an Icinga 2 daemon restart, all is fine. These are the obvious advantages of dynamically linked programs: There is no need for a new Icinga 2 package just because something got bumped down the road.
Go Package Insights
To get back to the opening question: What’s different with our Go packages?
# apt-rdepends icingadb 2>/dev/null | awk '/Depends:/ { print $2 }' | sort | uniq
gcc-14-base
libc6
libgcc-s1
This list contains three items, not nearly 200, not 50, only three. The Icinga DB package only requires an essential C runtime. Everything else is baked into the binary itself, including the Go standard library.
$ icingadb --version | grep 'Go version' Go version: go1.26.5 (linux, amd64)
This is not runtime information but built into the binary itself, as the Go tooling might reveal with additional information.
$ go version -m "$(which icingadb)"
/usr/sbin/icingadb: go1.26.5
path github.com/icinga/icingadb/cmd/icingadb
mod github.com/icinga/icingadb (devel)
dep filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
dep github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
dep github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
dep github.com/creasty/defaults v1.8.0 h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk=
dep github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
dep github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
dep github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
dep github.com/goccy/go-yaml v1.13.0 h1:0Wtp0FZLd7Sm8gERmR9S6Iczzb3vItJj7NaHmFg8pTs=
dep github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
dep github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
dep github.com/icinga/icinga-go-library v0.8.2 h1:/TwrRotn0QZl/2Vo1jCUaZs1isH5uve9lTnkRYTIHnI=
dep github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
dep github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
dep github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
dep github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
dep github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
dep github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
dep github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
dep github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI=
dep github.com/ssgreg/journald v1.0.0 h1:0YmTDPJXxcWDPba12qNMdO6TxvfkFSYpFIJ31CwmLcU=
dep go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
dep go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
dep golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
dep golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
dep golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
build -buildmode=exe
build -compiler=gc
build -trimpath=true
build DefaultGODEBUG=containermaxprocs=0,cryptocustomrand=1,decoratemappings=0,tlssecpmlkem=0,tlssha1=1,updatemaxprocs=0,urlstrictcolons=0,x509sha256skid=0
build CGO_ENABLED=1
build GOARCH=amd64
build GOOS=linux
build GOAMD64=v1
While we can guarantee that the package contains exactly those dependencies we need, it is now our – read, Icinga – responsibility to update them as well. Thus, if there are security issues in this list, including the Go standard library, we need to bump those and draft a new release. Every time a new Go security release was published, fixing a security vulnerability that might or might not affect one of our packages, we considered creating a new release. This release still contains the same code of ours but now references the fixed dependencies. And that’s why there are seven Icinga DB 1.5.1 releases at the time of writing.
However, one might ask themselves: Why even bother? Why draft a new release containing a fix for something Icinga DB never uses? Security scanners are the answer, especially the less capable ones.
Go Vulnerability Scanning
By the way, when scanning Go projects for security issues, I would highly recommend Go’s govulncheck, which excludes unreachable code based on the call-graph.
$ basename $(pwd); ~/go/bin/govulncheck ./... icingadb No vulnerabilities found.






