From 3f18bfc064621719788d72bdccfe53e798010931 Mon Sep 17 00:00:00 2001 From: michel-laterman <michel.laterman@elastic.co> Date: Fri, 17 Jan 2025 13:13:00 -0800 Subject: [PATCH] WIP try to get fips package available --- dev-tools/mage/build.go | 10 ++++++++++ dev-tools/mage/crossbuild.go | 5 +++++ dev-tools/mage/settings.go | 9 +++++++++ internal/pkg/release/version.go | 14 ++++++++++++++ magefile.go | 18 ++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/dev-tools/mage/build.go b/dev-tools/mage/build.go index 190efa543ea..576035692fd 100644 --- a/dev-tools/mage/build.go +++ b/dev-tools/mage/build.go @@ -53,6 +53,10 @@ func DefaultBuildArgs() BuildArgs { args.ExtraFlags = append(args.ExtraFlags, "-buildmode", "pie") } + if FIPSBuild { + args.ExtraFlags = append(args.ExtraFlags, "-tags=fipsrequired") + } + if DevBuild { // Disable optimizations (-N) and inlining (-l) for debugging. args.ExtraFlags = append(args.ExtraFlags, `-gcflags=all=-N -l`) @@ -151,6 +155,12 @@ func Build(params BuildArgs) error { if params.CGO { cgoEnabled = "1" } + + if FIPSBuild { + cgoEnabled = "1" + env["GOEXPERIMENT"] = "systemcrypto" + } + env["CGO_ENABLED"] = cgoEnabled // Spec diff --git a/dev-tools/mage/crossbuild.go b/dev-tools/mage/crossbuild.go index 30750602118..c7ef65b640b 100644 --- a/dev-tools/mage/crossbuild.go +++ b/dev-tools/mage/crossbuild.go @@ -249,6 +249,10 @@ func CrossBuildImage(platform string) (string, error) { return "", err } + if FIPSBuild { + return FIPSBuildImage + ":" + goVersion + "-1-fips-bookworm", nil + } + return BeatsCrossBuildImage + ":" + goVersion + "-" + tagSuffix, nil } @@ -332,6 +336,7 @@ func (b GolangCrossBuilder) Build() error { "--env", fmt.Sprintf("SNAPSHOT=%v", Snapshot), "--env", fmt.Sprintf("DEV=%v", DevBuild), "--env", fmt.Sprintf("EXTERNAL=%v", ExternalBuild), + "--env", fmt.Sprintf("FIPS=%v", FIPSBuild), "-v", repoInfo.RootDir+":"+mountPoint, "-w", workDir, image, diff --git a/dev-tools/mage/settings.go b/dev-tools/mage/settings.go index 143baf4dcff..1e1f118e637 100644 --- a/dev-tools/mage/settings.go +++ b/dev-tools/mage/settings.go @@ -35,6 +35,8 @@ const ( beatsFPMImage = "docker.elastic.co/beats-dev/fpm" // BeatsCrossBuildImage is the image used for crossbuilding Beats. BeatsCrossBuildImage = "docker.elastic.co/beats-dev/golang-crossbuild" + //FIPSBuildImage is the image used for building FIPS compliant artifacts + FIPSBuildImage = "mcr.microsoft.com/oss/go/microsoft/golang" elasticAgentImportPath = "github.com/elastic/elastic-agent" @@ -88,6 +90,7 @@ var ( Snapshot bool DevBuild bool ExternalBuild bool + FIPSBuild bool versionQualified bool versionQualifier string @@ -153,6 +156,11 @@ func initGlobals() { panic(fmt.Errorf("failed to parse EXTERNAL env value: %w", err)) } + FIPSBuild, err = strconv.ParseBool(EnvOr("FIPS", "false")) + if err != nil { + panic(fmt.Errorf("failed to parse FIPS env value: %w", err)) + } + versionQualifier, versionQualified = os.LookupEnv("VERSION_QUALIFIER") agentPackageVersion = EnvOr(agentPackageVersionEnvVar, "") @@ -210,6 +218,7 @@ func varMap(args ...map[string]interface{}) map[string]interface{} { "Snapshot": Snapshot, "DEV": DevBuild, "EXTERNAL": ExternalBuild, + "FIPS": FIPSBuild, "Qualifier": versionQualifier, "CI": CI, } diff --git a/internal/pkg/release/version.go b/internal/pkg/release/version.go index ba7b01ac657..6b6d44e3686 100644 --- a/internal/pkg/release/version.go +++ b/internal/pkg/release/version.go @@ -20,6 +20,9 @@ const ( // snapshot is a flag marking build as a snapshot. var snapshot = "" +// fips is a flag for marking a FIPS compliant build. +var fips = "false" + // complete is an environment variable marking the image as complete. var complete = "ELASTIC_AGENT_COMPLETE" @@ -77,12 +80,18 @@ func Complete() bool { return ok && isComplete == "true" } +func FIPS() bool { + f, err := strconv.ParseBool(fips) + return err == nil && f +} + // VersionInfo is structure used by `version --yaml`. type VersionInfo struct { Version string `yaml:"version"` Commit string `yaml:"commit"` BuildTime time.Time `yaml:"build_time"` Snapshot bool `yaml:"snapshot"` + FIPS bool `yaml:"fips"` } // Info returns current version information. @@ -92,6 +101,7 @@ func Info() VersionInfo { Commit: Commit(), BuildTime: BuildTime(), Snapshot: Snapshot(), + FIPS: FIPS(), } } @@ -105,8 +115,12 @@ func (v VersionInfo) String() string { } sb.WriteString(" (build: ") sb.WriteString(v.Commit) + if v.FIPS { + sb.WriteString(" fips: true") + } sb.WriteString(" at ") sb.WriteString(v.BuildTime.Format("2006-01-02 15:04:05 -0700 MST")) sb.WriteString(")") + return sb.String() } diff --git a/magefile.go b/magefile.go index cddd7e17466..6f59e4216ff 100644 --- a/magefile.go +++ b/magefile.go @@ -81,6 +81,7 @@ const ( metaDir = "_meta" snapshotEnv = "SNAPSHOT" devEnv = "DEV" + fipsEnv = "FIPS" externalArtifacts = "EXTERNAL" platformsEnv = "PLATFORMS" packagesEnv = "PACKAGES" @@ -786,6 +787,9 @@ func (Cloud) Image(ctx context.Context) { variant := os.Getenv(dockerVariants) defer os.Setenv(dockerVariants, variant) + fips := os.Getenv(fipsEnv) + defer os.Setenv(fipsEnv, fips) + os.Setenv(platformsEnv, "linux/amd64") os.Setenv(packagesEnv, "docker") os.Setenv(devEnv, "true") @@ -800,6 +804,14 @@ func (Cloud) Image(ctx context.Context) { devtools.Snapshot = true } + if f, err := strconv.ParseBool(fips); err == nil && !f { + os.Setenv(fipsEnv, "false") + devtools.FIPSBuild = false + } else { + os.Setenv(fipsEnv, "true") + devtools.FIPSBuild = true + } + devtools.DevBuild = true devtools.Platforms = devtools.Platforms.Filter("linux/amd64") devtools.SelectedPackageTypes = []devtools.PackageType{devtools.Docker} @@ -1756,6 +1768,12 @@ func buildVars() map[string]string { isSnapshot, _ := os.LookupEnv(snapshotEnv) vars["github.com/elastic/elastic-agent/internal/pkg/release.snapshot"] = isSnapshot + if fipsFlag, fipsFound := os.LookupEnv(fipsEnv); fipsFound { + if fips, err := strconv.ParseBool(fipsFlag); err == nil && fips { + vars["github.com/elastic/elastic-agent/internal/pkg/release.fips"] = "true" + } + } + if isDevFlag, devFound := os.LookupEnv(devEnv); devFound { if isDev, err := strconv.ParseBool(isDevFlag); err == nil && isDev { vars["github.com/elastic/elastic-agent/internal/pkg/release.allowEmptyPgp"] = "true"