diff --git a/omelasticsearch-apply-tls-opts-during-detection.patch b/omelasticsearch-apply-tls-opts-during-detection.patch new file mode 100644 index 0000000..d8a54ff --- /dev/null +++ b/omelasticsearch-apply-tls-opts-during-detection.patch @@ -0,0 +1,128 @@ +From 930c97270c08102551e1b1b1a265326253303857 Mon Sep 17 00:00:00 2001 +From: Rainer Gerhards +Date: Sun, 5 Jul 2026 11:14:20 +0200 +Subject: [PATCH] omelasticsearch: apply TLS options during detection + +Extract all TLS-related curl setopt calls into a shared +curlSetupTlsOptions() helper and call it from both curlSetupCommon() +(worker handles) and detectTargetPlatformAndVersion() (the startup +Elasticsearch version probe), so that startup probes honour the same +TLS policy as worker connections. + +Also add a LIBCURL_VERSION_NUM >= 0x072200 guard around the TLSv1.2 +entry in tlsVersionMap[] to be safe on very old build-time headers. + +Backport of upstream commit 930c97270c08102551e1b1b1a265326253303857 + +Signed-off-by: Attila Lakatos +--- + plugins/omelasticsearch/omelasticsearch.c | 56 ++++++++++++----------- + 1 file changed, 29 insertions(+), 27 deletions(-) + +--- a/plugins/omelasticsearch/omelasticsearch.c ++++ b/plugins/omelasticsearch/omelasticsearch.c +@@ -254,6 +254,7 @@ + static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; + + static rsRetVal ATTR_NONNULL() curlSetup(wrkrInstanceData_t *pWrkrData); ++static void ATTR_NONNULL() curlSetupTlsOptions(instanceData *const pData, CURL *const handle); + static rsRetVal ATTR_NONNULL() detectTargetPlatformAndVersion(instanceData *const pData); + static rsRetVal ATTR_NONNULL() applyVersionRequirements(instanceData *const pData); + +@@ -801,8 +802,7 @@ + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlVersionResult); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); +- if (pData->allowUnsignedCerts) curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); +- if (pData->skipVerifyHost) curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); ++ curlSetupTlsOptions(pData, curl); + if (pData->authBuf != NULL) { + curl_easy_setopt(curl, CURLOPT_USERPWD, pData->authBuf); + curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); +@@ -815,10 +815,6 @@ + } + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } +- if (pData->caCertFile) curl_easy_setopt(curl, CURLOPT_CAINFO, pData->caCertFile); +- if (pData->myCertFile) curl_easy_setopt(curl, CURLOPT_SSLCERT, pData->myCertFile); +- if (pData->myPrivKeyFile) curl_easy_setopt(curl, CURLOPT_SSLKEY, pData->myPrivKeyFile); +- + CURLcode code = curl_easy_perform(curl); + long status = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); +@@ -2104,31 +2100,25 @@ + static const struct { + const char *name; + long curlver; +-} tlsVersionMap[] = {{"TLSv1.2", CURL_SSLVERSION_TLSv1_2}, ++} tlsVersionMap[] = { ++#if LIBCURL_VERSION_NUM >= 0x072200 ++ {"TLSv1.2", CURL_SSLVERSION_TLSv1_2}, ++#endif + #if LIBCURL_VERSION_NUM >= 0x073400 +- {"TLSv1.3", CURL_SSLVERSION_TLSv1_3}, ++ {"TLSv1.3", CURL_SSLVERSION_TLSv1_3}, + #endif +- {NULL, 0}}; ++ {NULL, 0}}; + +-static void ATTR_NONNULL() curlSetupCommon(wrkrInstanceData_t *const pWrkrData, CURL *const handle) { +- PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); +- curl_easy_setopt(handle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); +- curl_easy_setopt(handle, CURLOPT_NOSIGNAL, TRUE); +- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult); +- curl_easy_setopt(handle, CURLOPT_WRITEDATA, pWrkrData); +- if (pWrkrData->pData->allowUnsignedCerts) curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, FALSE); +- if (pWrkrData->pData->skipVerifyHost) curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, FALSE); +- if (pWrkrData->pData->authBuf != NULL) { +- curl_easy_setopt(handle, CURLOPT_USERPWD, pWrkrData->pData->authBuf); +- curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY); +- } +- if (pWrkrData->pData->caCertFile) curl_easy_setopt(handle, CURLOPT_CAINFO, pWrkrData->pData->caCertFile); +- if (pWrkrData->pData->myCertFile) curl_easy_setopt(handle, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile); +- if (pWrkrData->pData->myPrivKeyFile) curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile); +- if (pWrkrData->pData->tlsVersion) { ++static void ATTR_NONNULL() curlSetupTlsOptions(instanceData *const pData, CURL *const handle) { ++ if (pData->allowUnsignedCerts) curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L); ++ if (pData->skipVerifyHost) curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L); ++ if (pData->caCertFile) curl_easy_setopt(handle, CURLOPT_CAINFO, pData->caCertFile); ++ if (pData->myCertFile) curl_easy_setopt(handle, CURLOPT_SSLCERT, pData->myCertFile); ++ if (pData->myPrivKeyFile) curl_easy_setopt(handle, CURLOPT_SSLKEY, pData->myPrivKeyFile); ++ if (pData->tlsVersion) { + long ver = CURL_SSLVERSION_DEFAULT; + for (size_t i = 0; tlsVersionMap[i].name != NULL; i++) { +- if (!strcmp((char *)pWrkrData->pData->tlsVersion, tlsVersionMap[i].name)) { ++ if (!strcmp((char *)pData->tlsVersion, tlsVersionMap[i].name)) { + ver = tlsVersionMap[i].curlver; + break; + } +@@ -2136,13 +2126,25 @@ + curl_easy_setopt(handle, CURLOPT_SSLVERSION, ver); + } + #if LIBCURL_VERSION_NUM >= 0x073D00 +- if (pWrkrData->pData->tlsCipherSuites) +- curl_easy_setopt(handle, CURLOPT_TLS13_CIPHERS, (char *)pWrkrData->pData->tlsCipherSuites); ++ if (pData->tlsCipherSuites) curl_easy_setopt(handle, CURLOPT_TLS13_CIPHERS, (char *)pData->tlsCipherSuites); + #endif + #if LIBCURL_VERSION_NUM >= 0x074900 +- if (pWrkrData->pData->tlsKeyExchangeGroups) +- curl_easy_setopt(handle, CURLOPT_SSL_EC_CURVES, (char *)pWrkrData->pData->tlsKeyExchangeGroups); ++ if (pData->tlsKeyExchangeGroups) ++ curl_easy_setopt(handle, CURLOPT_SSL_EC_CURVES, (char *)pData->tlsKeyExchangeGroups); + #endif ++} ++ ++static void ATTR_NONNULL() curlSetupCommon(wrkrInstanceData_t *const pWrkrData, CURL *const handle) { ++ PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); ++ curl_easy_setopt(handle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); ++ curl_easy_setopt(handle, CURLOPT_NOSIGNAL, TRUE); ++ curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult); ++ curl_easy_setopt(handle, CURLOPT_WRITEDATA, pWrkrData); ++ curlSetupTlsOptions(pWrkrData->pData, handle); ++ if (pWrkrData->pData->authBuf != NULL) { ++ curl_easy_setopt(handle, CURLOPT_USERPWD, pWrkrData->pData->authBuf); ++ curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY); ++ } + /* uncomment for in-dept debuggung: + curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE); */ + } diff --git a/omelasticsearch-pqc-tls.patch b/omelasticsearch-pqc-tls.patch new file mode 100644 index 0000000..1a9a9a7 --- /dev/null +++ b/omelasticsearch-pqc-tls.patch @@ -0,0 +1,153 @@ +From a3463c693ed89039cfc06616084eea2e67aca3fb Mon Sep 17 00:00:00 2001 +From: Cropi +Date: Wed, 24 Jun 2026 12:22:14 +0200 +Subject: [PATCH] omelasticsearch: add tls.tlsversion, tls.ciphersuites, + tls.keyexchangegroups + +Exposes three libcurl TLS knobs so operators can restrict the TLS version +floor and specify the cipher suite and key-exchange group preference list. +Setting tls.keyexchangegroups to "X25519MLKEM768:X25519" enables hybrid +PQC key exchange when libcurl is linked against OpenSSL 3.x with the OQS +provider. + +The TLS version string is validated at configuration time against a lookup +table; an unknown value causes an immediate config load failure rather than +being silently ignored. tls.ciphersuites and tls.keyexchangegroups are +passed verbatim to libcurl, which delegates validation to OpenSSL. + +CURLOPT_SSL_EC_CURVES (>= 7.73) and CURLOPT_TLS13_CIPHERS (>= 7.61) are +guarded with LIBCURL_VERSION_NUM so the build succeeds on older systems; +a runtime warning is emitted when an option is configured but the +build-time libcurl predates support for it. + +When all three parameters are absent the behaviour is unchanged. + +Signed-off-by: Cropi +--- + plugins/omelasticsearch/omelasticsearch.c | 65 +++++++++++++++++++++- + 1 file changed, 64 insertions(+), 1 deletion(-) + +--- a/plugins/omelasticsearch/omelasticsearch.c ++++ b/plugins/omelasticsearch/omelasticsearch.c +@@ -163,6 +163,9 @@ + uchar *caCertFile; + uchar *myCertFile; + uchar *myPrivKeyFile; ++ uchar *tlsVersion; /* tls.tlsversion → CURLOPT_SSLVERSION */ ++ uchar *tlsCipherSuites; /* tls.ciphersuites → CURLOPT_TLS13_CIPHERS */ ++ uchar *tlsKeyExchangeGroups; /* tls.keyexchangegroups → CURLOPT_SSL_EC_CURVES */ + es_write_ops_t writeOperation; + sbool retryFailures; + int ratelimitInterval; +@@ -237,6 +240,9 @@ + {"tls.cacert", eCmdHdlrString, 0}, + {"tls.mycert", eCmdHdlrString, 0}, + {"tls.myprivkey", eCmdHdlrString, 0}, ++ {"tls.tlsversion", eCmdHdlrString, 0}, ++ {"tls.ciphersuites", eCmdHdlrString, 0}, ++ {"tls.keyexchangegroups", eCmdHdlrString, 0}, + {"writeoperation", eCmdHdlrGetWord, 0}, + {"retryfailures", eCmdHdlrBinary, 0}, + {"ratelimit.interval", eCmdHdlrInt, 0}, +@@ -350,6 +356,9 @@ + free(pData->caCertFile); + free(pData->myCertFile); + free(pData->myPrivKeyFile); ++ free(pData->tlsVersion); ++ free(pData->tlsCipherSuites); ++ free(pData->tlsKeyExchangeGroups); + free(pData->retryRulesetName); + free(pData->detectedVersionString); + if (pData->ratelimiter != NULL) ratelimitDestruct(pData->ratelimiter); +@@ -2092,6 +2101,15 @@ + RETiRet; + } + ++static const struct { ++ const char *name; ++ long curlver; ++} tlsVersionMap[] = {{"TLSv1.2", CURL_SSLVERSION_TLSv1_2}, ++#if LIBCURL_VERSION_NUM >= 0x073400 ++ {"TLSv1.3", CURL_SSLVERSION_TLSv1_3}, ++#endif ++ {NULL, 0}}; ++ + static void ATTR_NONNULL() curlSetupCommon(wrkrInstanceData_t *const pWrkrData, CURL *const handle) { + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); +@@ -2107,6 +2125,24 @@ + if (pWrkrData->pData->caCertFile) curl_easy_setopt(handle, CURLOPT_CAINFO, pWrkrData->pData->caCertFile); + if (pWrkrData->pData->myCertFile) curl_easy_setopt(handle, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile); + if (pWrkrData->pData->myPrivKeyFile) curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile); ++ if (pWrkrData->pData->tlsVersion) { ++ long ver = CURL_SSLVERSION_DEFAULT; ++ for (size_t i = 0; tlsVersionMap[i].name != NULL; i++) { ++ if (!strcmp((char *)pWrkrData->pData->tlsVersion, tlsVersionMap[i].name)) { ++ ver = tlsVersionMap[i].curlver; ++ break; ++ } ++ } ++ curl_easy_setopt(handle, CURLOPT_SSLVERSION, ver); ++ } ++#if LIBCURL_VERSION_NUM >= 0x073D00 ++ if (pWrkrData->pData->tlsCipherSuites) ++ curl_easy_setopt(handle, CURLOPT_TLS13_CIPHERS, (char *)pWrkrData->pData->tlsCipherSuites); ++#endif ++#if LIBCURL_VERSION_NUM >= 0x074900 ++ if (pWrkrData->pData->tlsKeyExchangeGroups) ++ curl_easy_setopt(handle, CURLOPT_SSL_EC_CURVES, (char *)pWrkrData->pData->tlsKeyExchangeGroups); ++#endif + /* uncomment for in-dept debuggung: + curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE); */ + } +@@ -2190,6 +2226,9 @@ + pData->caCertFile = NULL; + pData->myCertFile = NULL; + pData->myPrivKeyFile = NULL; ++ pData->tlsVersion = NULL; ++ pData->tlsCipherSuites = NULL; ++ pData->tlsKeyExchangeGroups = NULL; + pData->writeOperation = ES_WRITE_INDEX; + pData->retryFailures = 0; + pData->ratelimitBurst = -1; +@@ -2307,6 +2346,38 @@ + } else { + fclose(fp); + } ++ } else if (!strcmp(actpblk.descr[i].name, "tls.tlsversion")) { ++ char *ver; ++ int known; ++ CHKmalloc(ver = es_str2cstr(pvals[i].val.d.estr, NULL)); ++ known = 0; ++ for (size_t j = 0; tlsVersionMap[j].name != NULL; j++) { ++ if (!strcmp(ver, tlsVersionMap[j].name)) { ++ known = 1; ++ break; ++ } ++ } ++ if (!known) { ++ LogError(0, RS_RET_PARAM_ERROR, ++ "omelasticsearch: unknown tls.tlsversion '%s'; accepted: TLSv1.2, TLSv1.3", ver); ++ free(ver); ++ ABORT_FINALIZE(RS_RET_PARAM_ERROR); ++ } ++ pData->tlsVersion = (uchar *)ver; ++ } else if (!strcmp(actpblk.descr[i].name, "tls.ciphersuites")) { ++ CHKmalloc(pData->tlsCipherSuites = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); ++#if LIBCURL_VERSION_NUM < 0x073D00 ++ LogMsg(0, RS_RET_OK, LOG_WARNING, ++ "omelasticsearch: tls.ciphersuites set but libcurl < 7.61 was used at build time; " ++ "option will be ignored"); ++#endif ++ } else if (!strcmp(actpblk.descr[i].name, "tls.keyexchangegroups")) { ++ CHKmalloc(pData->tlsKeyExchangeGroups = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); ++#if LIBCURL_VERSION_NUM < 0x074900 ++ LogMsg(0, RS_RET_OK, LOG_WARNING, ++ "omelasticsearch: tls.keyexchangegroups set but libcurl < 7.73 was used at build time; " ++ "option will be ignored"); ++#endif + } else if (!strcmp(actpblk.descr[i].name, "writeoperation")) { + char *writeop = es_str2cstr(pvals[i].val.d.estr, NULL); + if (writeop && !strcmp(writeop, "create")) { +-- +2.54.0 diff --git a/rsyslog.spec b/rsyslog.spec index 573f6a6..750b02a 100644 --- a/rsyslog.spec +++ b/rsyslog.spec @@ -39,7 +39,7 @@ Summary: Enhanced system logging and kernel message trapping daemon Name: rsyslog Version: 8.2604.0 -Release: 2%{?dist} +Release: 3%{?dist} License: GPL-3.0-or-later AND Apache-2.0 URL: http://www.rsyslog.com/ Source0: http://www.rsyslog.com/files/download/rsyslog/%{name}-%{version}.tar.gz @@ -53,6 +53,8 @@ Source5: https://archive.apache.org/dist/qpid/proton/%{qpid_proton_v}/qpid-proto Source7: rsyslog-tmpfiles.conf Patch0: imfile-inotify-fd-release-on-delete.patch +Patch1: omelasticsearch-pqc-tls.patch +Patch2: omelasticsearch-apply-tls-opts-during-detection.patch BuildRequires: make BuildRequires: gcc @@ -388,6 +390,8 @@ This module allows rsyslog to send messages to a RabbitMQ server. # set up rsyslog sources %setup -q -D %patch -P0 -p1 +%patch -P1 -p1 +%patch -P2 -p1 %if %{with omamqp1} @@ -783,6 +787,15 @@ done %changelog +* Thu Jul 09 2026 Attila Lakatos - 8.2604.0-3 +- Backport omelasticsearch PQC TLS parameters (tls.tlsversion, tls.ciphersuites, +<<<<<<< HEAD + tls.keyexchangegroups) +======= + tls.keyexchangegroups) and apply them during startup version detection +>>>>>>> dad7741 (omelasticsearch: apply TLS options during startup detection) + Resolves: RHEL-193505 + * Wed Apr 29 2026 Attila Lakatos - 8.2604.0-2 - Rebase to 8.2604.0 Resolves: RHEL-140910