@cryptotaxi247 / netdata / commits / b795f12a2

Fix SSL certificate detection for Rocky Linux and static curl (#20695)

* Add Rocky Linux certificate path to SSL detection Rocky Linux provides CA certificates at /etc/ssl/certs/ca-bundle.crt via symlinks, but this path was not included in our certificate detection logic. This caused SSL verification failures during claiming on Rocky Linux systems. Added this path to the detect_ca_path() function to ensure Rocky Linux systems can properly find their CA certificates. * Fix static curl certificate detection on all Linux distributions The static curl binary is compiled to look for CA certificates at /opt/netdata/etc/ssl/certs/ca-certificates.crt, but different Linux distributions use different certificate bundle names: - Debian/Ubuntu: ca-certificates.crt - RHEL/Rocky/CentOS: ca-bundle.crt - Alpine: cert.pem (directly in /etc/ssl/) - OpenSUSE: ca-bundle.pem (directly in /etc/ssl/) This caused SSL verification failures on non-Debian systems. On Rocky Linux specifically, the test_certs() function would fail because curl couldn't find certificates, causing the installer to fall back to bundled certificates instead of using system certificates. Added ensure_static_curl_certificates() function that: 1. Finds the system's certificate bundle using the same paths as detect_ca_path() in the C code 2. Creates the certs directory only if a certificate is found (to avoid polluting the filesystem) 3. Creates a symlink to make it available where curl expects it The function is called from select_system_certs() to ensure the symlink exists before test_certs() runs, fixing the issue where Rocky Linux users would incorrectly end up with bundled certificates. * Fix issues with implementation, and simplify code overall. - Prioritize our static build certificate path in agent code for TLS configuration. This ensures that the certificates used by the agent always match those used by the standalone copy of cURL shipped as part of the static build (which is important for debugging, among other things). - Use a relative symlink instead of an absolute symlink for the certificate link. In general, relative symlinks should always be preferred in situations like this where the actual intent of the symlink is to provide an alias for a file name in the same or almost the same directory, as it makes the link behave more consistently. - Don’t check for the existence of `/opt/netdata/etc/ssl/certs` before creating it. `mkdir -p` is idempotent and returns success whether it needed to create the directory or not, so it’s kind of pointless for us to check for it ourselves. - Only handle the cases of distros that do not already have a `certs/ca-certificates.crt` path within their SSL/TLS config directory. We should not be messing with our own certificate path (since it already gets handled elsewhere) or with an existing `certs/ca-certificates.crt` path (since we obviously do not need a symlink in that case anyway). - More liberaly use variables to avoid duplication and reduce the possibility of paths being out of sync within the function. - Remove trailing spaces on empty lines. * Fixes based on Copilot review. * fix rel symlink creation * apply formatting --------- Co-authored-by: Austin S. Hemmelgarn <austin@netdata.cloud> Co-authored-by: ilyam8 <ilya@netdata.cloud>

Costa Tsaousis committed Jul 24, 2025 at 15:37 UTC b795f12a2085d4b4847d42bf825809830c4e12f7
2 files changed +64 -15
packaging/makeself/install-or-update.sh
+62 -14
@@ -9,7 +9,7 @@ export LC_ALL=C
9 umask 002
10
11 # Be nice on production environments
12 -renice 19 $$ > /dev/null 2> /dev/null
12 +renice 19 $$ >/dev/null 2>/dev/null
13
14 NETDATA_PREFIX="/opt/netdata"
15 NETDATA_USER_CONFIG_DIR="${NETDATA_PREFIX}/etc/netdata"
@@ -52,10 +52,13 @@ while [ "${1}" ]; do
52 ;;
53 "--certificates")
54 case "${2}" in
55 - auto|system) NETDATA_CERT_MODE="auto" ;;
55 + auto | system) NETDATA_CERT_MODE="auto" ;;
56 check) NETDATA_CERT_MODE="check" ;;
57 bundled) NETDATA_CERT_MODE="bundled" ;;
58 - *) run_failed "Unknown certificate handling mode '${2}'. Supported modes are auto, check, system, and bundled."; exit 1 ;;
58 + *)
59 + run_failed "Unknown certificate handling mode '${2}'. Supported modes are auto, check, system, and bundled."
60 + exit 1
61 + ;;
62 esac
63 shift 1
64 ;;
@@ -246,20 +249,56 @@ done
249 # -----------------------------------------------------------------------------
250
251 replace_symlink() {
249 - target="${1}"
250 - name="${2}"
251 - rm -f "${name}"
252 - ln -s "${target}" "${name}"
252 + target="${1}"
253 + name="${2}"
254 + rm -f "${name}"
255 + ln -s "${target}" "${name}"
256 +}
257 +
258 +ensure_ca_certificates_link() {
259 + local ssl_prefix="/opt/netdata/etc/ssl/"
260 + local link_path="${ssl_prefix}/certs/ca-certificates.crt"
261 +
262 + # If ca-certificates.crt already exists, we're done
263 + [ -e "${link_path}" ] && return 0
264 +
265 + local cert_names=(
266 + "certs/ca-bundle.crt" # RHEL, Fedora, RHEL clones
267 + "ca-bundle.pem" # SLE, OpenSUSE
268 + "cert.pem" # Alpine
269 + )
270 +
271 + mkdir -p "$(dirname "${link_path}")"
272 +
273 + for cert_name in "${cert_names[@]}"; do
274 + local target="${ssl_prefix}/${cert_name}"
275 +
276 + if [ -f "${target}" ] && [ -r "${target}" ]; then
277 + # Create relative symlink to avoid breaking if Netdata is uninstalled
278 + if command -v realpath >/dev/null 2>&1; then
279 + ln -s "$(realpath --relative-to="$(dirname "${link_path}")" "${target}")" "${link_path}"
280 + else
281 + ln -s "../${cert_name}" "${link_path}"
282 + fi
283 + return 0
284 + fi
285 + done
286 +
287 + echo "Warning: No valid certificate bundle found"
288 + return 1
289 }
290
291 select_system_certs() {
256 - if [ -d /etc/pki/tls ] ; then
292 + if [ -d /etc/pki/tls ]; then
293 echo "${1} /etc/pki/tls for TLS configuration and certificates"
294 replace_symlink /etc/pki/tls /opt/netdata/etc/ssl
259 - elif [ -d /etc/ssl ] ; then
295 + elif [ -d /etc/ssl ]; then
296 echo "${1} /etc/ssl for TLS configuration and certificates"
297 replace_symlink /etc/ssl /opt/netdata/etc/ssl
298 fi
299 +
300 + # Ensure static curl can find the certificates
301 + ensure_ca_certificates_link
302 }
303
304 select_internal_certs() {
@@ -275,16 +314,25 @@ test_certs() {
314 /opt/netdata/bin/curl --fail --max-time 300 --silent --output /dev/null "${NETDATA_CERT_TEST_URL}"
315
316 case "$?" in
278 - 35|77) echo "Failed to load certificate files for test." ; return 1 ;;
279 - 60|82|83) echo "Certificates cannot be used to connect to ${NETDATA_CERT_TEST_URL}" ; return 1 ;;
280 - 53|54|66) echo "Unable to use OpenSSL configuration associated with certificates" ; return 1 ;;
317 + 35 | 77)
318 + echo "Failed to load certificate files for test."
319 + return 1
320 + ;;
321 + 60 | 82 | 83)
322 + echo "Certificates cannot be used to connect to ${NETDATA_CERT_TEST_URL}"
323 + return 1
324 + ;;
325 + 53 | 54 | 66)
326 + echo "Unable to use OpenSSL configuration associated with certificates"
327 + return 1
328 + ;;
329 0) echo "Successfully connected to ${NETDATA_CERT_TEST_URL} using certificates" ;;
330 *) echo "Unable to test certificates due to networking problems, blindly assuming they work" ;;
331 esac
332 }
333
334 # If the user has manually set up certificates, don’t mess with it.
287 -if [ ! -L /opt/netdata/etc/ssl ] && [ -d /opt/netdata/etc/ssl ] ; then
335 +if [ ! -L /opt/netdata/etc/ssl ] && [ -d /opt/netdata/etc/ssl ]; then
336 echo "Preserving existing user configuration for TLS"
337 else
338 echo "Configure TLS certificate paths (mode: ${NETDATA_CERT_MODE})"
@@ -310,7 +358,7 @@ fi
358 # -----------------------------------------------------------------------------
359
360 echo "Save install options"
313 -grep -qv 'IS_NETDATA_STATIC_BINARY="yes"' "${NETDATA_PREFIX}/etc/netdata/.environment" || echo IS_NETDATA_STATIC_BINARY=\"yes\" >> "${NETDATA_PREFIX}/etc/netdata/.environment"
361 +grep -qv 'IS_NETDATA_STATIC_BINARY="yes"' "${NETDATA_PREFIX}/etc/netdata/.environment" || echo IS_NETDATA_STATIC_BINARY=\"yes\" >>"${NETDATA_PREFIX}/etc/netdata/.environment"
362 REINSTALL_OPTIONS="$(echo "${REINSTALL_OPTIONS}" | awk '{gsub("/", "\\/"); print}')"
363 sed -i "s/REINSTALL_OPTIONS=\".*\"/REINSTALL_OPTIONS=\"${REINSTALL_OPTIONS}\"/" "${NETDATA_PREFIX}/etc/netdata/.environment"
364
src/daemon/config/netdata-conf-ssl.c
+2 -1
@@ -55,11 +55,12 @@ const char *detect_libcurl_default_ca() {
55
56 static inline const char *detect_ca_path(void) {
57 static const char *paths[] = {
58 + "/opt/netdata/etc/ssl/certs/ca-certificates.crt", // Netdata static build (needs to come first for consistency with standalone cURL in static builds)
59 "/etc/ssl/certs/ca-certificates.crt", // Debian, Ubuntu, Arch
60 + "/etc/ssl/certs/ca-bundle.crt", // Rocky Linux (via symlinks)
61 "/etc/pki/tls/certs/ca-bundle.crt", // RHEL, CentOS, Fedora
62 "/etc/ssl/ca-bundle.pem", // OpenSUSE
63 "/etc/ssl/cert.pem", // Alpine
62 - "/opt/netdata/etc/ssl/certs/ca-certificates.crt", // Netdata static build
64 "/opt/netdata/share/ssl/certs/ca-certificates.crt", // Netdata static build - fallback
65 NULL
66 };