mirror of
https://github.com/milvus-io/milvus.git
synced 2026-07-21 02:05:41 +00:00
enhance: enable OpenSSL FIPS mode for Milvus (#48331)
Layer 2 (OpenSSL FIPS) changes: - Add programmatic FIPS activation via OSSL_LIB_CTX_load_config in boring_enabled.go (gated by //go:build boringcrypto) - Add openssl-fips.cnf with fips + default providers and default_properties = fips=yes - Use absolute .include path for fipsmodule.cnf — OpenSSL resolves relative .include from the process working directory, not the config file's directory, causing silent FIPS provider load failure - Add RAND_bytes probe after config load to verify the FIPS provider is truly functional (EVP_default_properties_is_fips_enabled only checks the property string, not whether the provider loaded) - Dockerfiles: add openssl fipsinstall + OPENSSL_MODULES env var - Log OpenSSL FIPS status from C++ via EVP_default_properties_is_fips_enabled Layer 1 (Go BoringCrypto) changes: - Add GOEXPERIMENT=boringcrypto build flag (conditional on MILVUS_FIPS_ENABLED=ON) - Add boringEnabled() build-tagged functions for startup logging s2n-tls upgrade: - Override s2n 1.4.1 (from aws-c-io) to 1.6.0 in conanfile.py. s2n 1.4.1 only detects FIPS via the legacy OPENSSL_FIPS define (not set by OpenSSL 3.x). s2n 1.6.0 adds EVP_default_properties_is_fips_enabled() detection so s2n enters FIPS mode and uses RAND_bytes() through the FIPS provider. See also: #48202, #48301 Signed-off-by: yangxuan <xuan.yang@zilliz.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
ebb648f647
commit
c54b34a880
@@ -57,6 +57,12 @@ use_opendal = OFF
|
||||
ifdef USE_OPENDAL
|
||||
use_opendal = ${USE_OPENDAL}
|
||||
endif
|
||||
|
||||
# FIPS: default OFF. Set MILVUS_FIPS_ENABLED=ON to enable BoringCrypto.
|
||||
GOEXPERIMENT_FLAG :=
|
||||
ifeq ($(MILVUS_FIPS_ENABLED),ON)
|
||||
GOEXPERIMENT_FLAG := GOEXPERIMENT=boringcrypto
|
||||
endif
|
||||
# golangci-lint
|
||||
GOLANGCI_LINT_VERSION := 1.64.7
|
||||
GOLANGCI_LINT_OUTPUT := $(shell $(INSTALL_PATH)/golangci-lint --version 2>/dev/null)
|
||||
@@ -106,7 +112,7 @@ build-go:
|
||||
@echo "Building Milvus ..."
|
||||
@source $(PWD)/scripts/setenv.sh && \
|
||||
mkdir -p $(INSTALL_PATH) && go env -w CGO_ENABLED="1" && \
|
||||
CGO_LDFLAGS="$${CGO_LDFLAGS} $(CGO_LDFLAGS)" CGO_CFLAGS="$${CGO_CFLAGS} $(CGO_CFLAGS)" GO111MODULE=on $(GO) build -pgo=$(PGO_PATH)/default.pgo -ldflags="-r $${RPATH} -X '$(OBJPREFIX).BuildTags=$(BUILD_TAGS)' -X '$(OBJPREFIX).BuildTime=$(BUILD_TIME)' -X '$(OBJPREFIX).GitCommit=$(GIT_COMMIT)' -X '$(OBJPREFIX).GoVersion=$(GO_VERSION)' -X '$(OBJPREFIX).MilvusVersion=$(MILVUS_VERSION)'" \
|
||||
$(GOEXPERIMENT_FLAG) CGO_LDFLAGS="$${CGO_LDFLAGS} $(CGO_LDFLAGS)" CGO_CFLAGS="$${CGO_CFLAGS} $(CGO_CFLAGS)" GO111MODULE=on $(GO) build -pgo=$(PGO_PATH)/default.pgo -ldflags="-r $${RPATH} -X '$(OBJPREFIX).BuildTags=$(BUILD_TAGS)' -X '$(OBJPREFIX).BuildTime=$(BUILD_TIME)' -X '$(OBJPREFIX).GitCommit=$(GIT_COMMIT)' -X '$(OBJPREFIX).GoVersion=$(GO_VERSION)' -X '$(OBJPREFIX).MilvusVersion=$(MILVUS_VERSION)'" \
|
||||
-tags $(MILVUS_GO_BUILD_TAGS) -o $(INSTALL_PATH)/milvus $(PWD)/cmd/main.go 1>/dev/null
|
||||
|
||||
milvus-gpu: build-cpp-gpu print-gpu-build-info
|
||||
|
||||
@@ -28,11 +28,15 @@ COPY --chown=root:root --chmod=774 ./configs/ /milvus/configs/
|
||||
|
||||
COPY --chown=root:root --chmod=774 ./lib/ /milvus/lib/
|
||||
|
||||
|
||||
ENV PATH=/milvus/bin:$PATH
|
||||
ENV LD_LIBRARY_PATH=/milvus/lib:$LD_LIBRARY_PATH:/usr/lib
|
||||
ENV LD_PRELOAD=${MILVUS_ASAN_LIB}:/milvus/lib/libjemalloc.so
|
||||
ENV MALLOC_CONF=background_thread:true
|
||||
ENV OPENSSL_MODULES=/milvus/lib/ossl-modules
|
||||
|
||||
# Generate fipsmodule.cnf for FIPS module integrity self-test.
|
||||
# FIPS activation is handled programmatically at startup — no OPENSSL_CONF needed.
|
||||
RUN openssl fipsinstall -out /milvus/configs/ssl/fipsmodule.cnf -module /milvus/lib/ossl-modules/fips.so
|
||||
|
||||
# Change user to milvus
|
||||
# protobuf 5.x RepeatedField adds container annotations that trigger ASAN
|
||||
|
||||
@@ -27,6 +27,11 @@ ENV PATH=/milvus/bin:$PATH
|
||||
ENV LD_LIBRARY_PATH=/milvus/lib:$LD_LIBRARY_PATH:/usr/lib
|
||||
ENV LD_PRELOAD=/milvus/lib/libjemalloc.so
|
||||
ENV MALLOC_CONF=background_thread:true
|
||||
ENV OPENSSL_MODULES=/milvus/lib/ossl-modules
|
||||
|
||||
# Generate fipsmodule.cnf for FIPS module integrity self-test.
|
||||
# FIPS activation is handled programmatically at startup — no OPENSSL_CONF needed.
|
||||
RUN openssl fipsinstall -out /milvus/configs/ssl/fipsmodule.cnf -module /milvus/lib/ossl-modules/fips.so
|
||||
|
||||
# Change user to milvus
|
||||
RUN groupadd -r milvus && useradd -r -g milvus milvus && \
|
||||
|
||||
@@ -36,6 +36,11 @@ ENV PATH=/milvus/bin:$PATH
|
||||
ENV LD_LIBRARY_PATH=/milvus/lib:$LD_LIBRARY_PATH:/usr/lib
|
||||
ENV LD_PRELOAD=${MILVUS_ASAN_LIB}:/milvus/lib/libjemalloc.so
|
||||
ENV MALLOC_CONF=background_thread:true
|
||||
ENV OPENSSL_MODULES=/milvus/lib/ossl-modules
|
||||
|
||||
# Generate fipsmodule.cnf for FIPS module integrity self-test.
|
||||
# FIPS activation is handled programmatically at startup — no OPENSSL_CONF needed.
|
||||
RUN openssl fipsinstall -out /milvus/configs/ssl/fipsmodule.cnf -module /milvus/lib/ossl-modules/fips.so
|
||||
|
||||
# Change user to milvus
|
||||
# protobuf 5.x RepeatedField adds container annotations that trigger ASAN
|
||||
|
||||
@@ -41,6 +41,11 @@ ENV PATH=/milvus/bin:$PATH
|
||||
ENV LD_LIBRARY_PATH=/milvus/lib:$LD_LIBRARY_PATH:/usr/lib
|
||||
ENV LD_PRELOAD=${MILVUS_ASAN_LIB}:/milvus/lib/libjemalloc.so
|
||||
ENV MALLOC_CONF=background_thread:true
|
||||
ENV OPENSSL_MODULES=/milvus/lib/ossl-modules
|
||||
|
||||
# Generate fipsmodule.cnf for FIPS module integrity self-test.
|
||||
# FIPS activation is handled programmatically at startup — no OPENSSL_CONF needed.
|
||||
RUN openssl fipsinstall -out /milvus/configs/ssl/fipsmodule.cnf -module /milvus/lib/ossl-modules/fips.so
|
||||
|
||||
# Change user to milvus
|
||||
# protobuf 5.x RepeatedField adds container annotations that trigger ASAN
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build !boringcrypto
|
||||
|
||||
package milvus
|
||||
|
||||
func boringEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func maybeEnableOpenSSLFIPS() {}
|
||||
@@ -0,0 +1,57 @@
|
||||
//go:build boringcrypto
|
||||
|
||||
package milvus
|
||||
|
||||
/*
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/provider.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static int enableOpenSSLFIPS() {
|
||||
unsigned char buf[1];
|
||||
|
||||
if (!OSSL_LIB_CTX_load_config(NULL, "/milvus/configs/ssl/openssl-fips.cnf")) {
|
||||
return -1; // config load failed
|
||||
}
|
||||
if (!EVP_default_properties_is_fips_enabled(NULL)) {
|
||||
return 0; // config loaded but fips=yes not set
|
||||
}
|
||||
// EVP_default_properties_is_fips_enabled only checks the property string,
|
||||
// not whether the FIPS provider is actually loaded. Verify by checking
|
||||
// that RAND_bytes works (requires a working FIPS DRBG).
|
||||
if (RAND_bytes(buf, 1) != 1) {
|
||||
return -2; // FIPS property set but provider not functional
|
||||
}
|
||||
return 1; // FIPS truly enabled and functional
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"crypto/boring"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func boringEnabled() bool {
|
||||
return boring.Enabled()
|
||||
}
|
||||
|
||||
var fipsOnce sync.Once
|
||||
|
||||
func maybeEnableOpenSSLFIPS() {
|
||||
fipsOnce.Do(func() {
|
||||
rc := C.enableOpenSSLFIPS()
|
||||
switch rc {
|
||||
case 1:
|
||||
log.Println("OpenSSL FIPS mode enabled")
|
||||
case 0:
|
||||
log.Println("WARNING: OpenSSL FIPS config loaded but fips=yes not set in default properties")
|
||||
case -2:
|
||||
log.Println("FATAL: OpenSSL FIPS property set but FIPS provider not functional (check OPENSSL_MODULES env var and .include path in openssl-fips.cnf)")
|
||||
default:
|
||||
log.Println("Failed to load OpenSSL FIPS config")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -37,6 +37,7 @@ func (c *run) execute(args []string, flags *flag.FlagSet) {
|
||||
runtimeDir := createRuntimeDir(serverType)
|
||||
filename := getPidFileName(serverType, roles.Alias)
|
||||
|
||||
maybeEnableOpenSSLFIPS()
|
||||
c.printBanner(flags.Output())
|
||||
c.injectVariablesToEnv()
|
||||
c.printHardwareInfo(flags.Output())
|
||||
@@ -60,6 +61,7 @@ func (c *run) printBanner(w io.Writer) {
|
||||
fmt.Fprintln(w, "Built: "+BuildTime)
|
||||
fmt.Fprintln(w, "GitCommit: "+GitCommit)
|
||||
fmt.Fprintln(w, "GoVersion: "+GoVersion)
|
||||
fmt.Fprintf(w, "Milvus FIPS in Go: BoringCrypto %v\n", boringEnabled())
|
||||
fmt.Fprintln(w)
|
||||
metrics.BuildInfo.WithLabelValues(getEffectiveVersion(), BuildTime, GitCommit).Set(1)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
config_diagnostics = 1
|
||||
openssl_conf = openssl_init
|
||||
|
||||
.include /milvus/configs/ssl/fipsmodule.cnf
|
||||
|
||||
[openssl_init]
|
||||
providers = provider_sect
|
||||
alg_section = algorithm_sect
|
||||
|
||||
[provider_sect]
|
||||
fips = fips_sect
|
||||
default = default_sect
|
||||
|
||||
[fips_sect]
|
||||
activate = 1
|
||||
|
||||
[default_sect]
|
||||
activate = 1
|
||||
|
||||
[algorithm_sect]
|
||||
default_properties = fips=yes
|
||||
@@ -111,6 +111,9 @@ class MilvusConan(ConanFile):
|
||||
if self.settings.os != "Macos":
|
||||
self.requires("libunwind/1.8.1#97965ef7da98cf1662e14219b14134f7")
|
||||
self.requires("aws-sdk-cpp/1.11.692@milvus/dev#1e17deac19383217d291a01c23147b33")
|
||||
# Override s2n 1.4.1 (from aws-c-io) to 1.6.0 for OpenSSL 3.x FIPS detection
|
||||
if self.settings.os in ["Linux", "FreeBSD"]:
|
||||
self.requires("s2n/1.6.0")
|
||||
|
||||
def imports(self):
|
||||
self.copy("*.dylib", "../lib", "lib")
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include "common/init_c.h"
|
||||
#include "common/Common.h"
|
||||
#include "common/Tracer.h"
|
||||
#include "common/init_c.h"
|
||||
@@ -25,6 +27,7 @@
|
||||
|
||||
std::once_flag traceFlag;
|
||||
std::once_flag cpuNumFlag;
|
||||
std::once_flag fipsFlag;
|
||||
|
||||
void
|
||||
InitCpuNum(const int value) {
|
||||
@@ -102,6 +105,15 @@ SetExprResCacheCapacityBytes(int64_t bytes) {
|
||||
static_cast<size_t>(bytes));
|
||||
}
|
||||
|
||||
void
|
||||
LogOpenSSLFIPSStatus() {
|
||||
std::call_once(fipsFlag, []() {
|
||||
LOG_INFO("Milvus FIPS in OpenSSL: {}",
|
||||
EVP_default_properties_is_fips_enabled(NULL) ? "enabled"
|
||||
: "disabled");
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
InitTrace(CTraceConfig* config) {
|
||||
auto traceConfig = milvus::tracer::TraceConfig{config->exporter,
|
||||
|
||||
@@ -71,6 +71,10 @@ InitTrace(CTraceConfig* config);
|
||||
void
|
||||
SetTrace(CTraceConfig* config);
|
||||
|
||||
// OpenSSL FIPS status
|
||||
void
|
||||
LogOpenSSLFIPSStatus();
|
||||
|
||||
// Expr result cache
|
||||
void
|
||||
SetExprResCacheEnable(bool val);
|
||||
|
||||
@@ -44,6 +44,8 @@ func InitSegcore(nodeID int64) error {
|
||||
C.IndexBuilderInit(cGlogConf)
|
||||
C.free(unsafe.Pointer(cGlogConf))
|
||||
|
||||
C.LogOpenSSLFIPSStatus()
|
||||
|
||||
// update log level based on current setup
|
||||
initcore.UpdateLogLevel(paramtable.Get().LogCfg.Level.GetValue())
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ func doInitQueryNodeOnce(ctx context.Context) error {
|
||||
C.SegcoreInit(cGlogConf)
|
||||
C.free(unsafe.Pointer(cGlogConf))
|
||||
|
||||
C.LogOpenSSLFIPSStatus()
|
||||
|
||||
// update log level based on current setup
|
||||
UpdateLogLevel(paramtable.Get().LogCfg.Level.GetValue())
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ mkdir -p "$LIBRARY_PATH"
|
||||
cp $PWD"/internal/core/output/lib/"*.dylib* "$LIBRARY_PATH" 2>/dev/null || true
|
||||
cp $PWD"/internal/core/output/lib/"*.so* "$LIBRARY_PATH" || true
|
||||
cp $PWD"/internal/core/output/lib64/"*.so* "$LIBRARY_PATH" 2>/dev/null || true
|
||||
cp -r $PWD"/internal/core/output/lib/ossl-modules" "$LIBRARY_PATH" 2>/dev/null || true
|
||||
|
||||
for LIB_PATH in $(ldd ./bin/milvus | grep -E '(asan|atomic)' | awk '{print $3}'); do
|
||||
cp "$LIB_PATH" "$LIBRARY_PATH" 2>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user