Skip to content

Commit 4815b15

Browse files
committed
Bump Go version to 1.25.1 (#5562)
* Bump Go version to 1.25.1 * Update CHANGELOG entry * Bump the version of golangci-lint * Remove references to the ms_tls13kdf build tag * Download go module dependencies before GODEBUG=fips140=only is set * Exclude X25519 curve types when testing in FIPS-140 mode * Stricter check * Add missing license header * Exclude X25519 curve types when testing in FIPS-140-only mode * Use stricter check * Update NOTICE files * Remove IsFIPS140Only helper function * Set GODEBUG=tlsmlkem=0 for FIPS140-only unit tests * Remove replace directive from go.mod * Try not pre-downloading dependencies (cherry picked from commit 15b8c8a)
1 parent c64b724 commit 4815b15

File tree

8 files changed

+275
-5
lines changed

8 files changed

+275
-5
lines changed

.go-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.24.7
1+
1.25.1

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ run:
44
timeout: 1m
55
build-tags:
66
- integration
7-
go: "1.24.7"
7+
go: "1.25.1"
88

99
issues:
1010
# Maximum count of issues with the same text.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: enhancement
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Update Go to v1.25.1
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
#description:
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component: fleet-server
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
pr: https://github.com/elastic/fleet-server/pull/5562
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
#issue: https://github.com/owner/repo/1234

dev-tools/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/elastic/fleet-server/dev-tools
22

3-
go 1.24.7
3+
go 1.25.1
44

55
tool (
66
github.com/elastic/go-json-schema-generate/cmd/schema-generate

docs/fips.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# FIPS support
2+
3+
**NOTE: FIPS Support is in-progress**
4+
5+
The fleet-server can be built in a FIPS capable mode.
6+
This forces the use of a FIPS provider to handle any cryptographic calls.
7+
8+
Currently FIPS is provided by compiling with the [microsoft/go](https://github.com/microsoft/go) distribution.
9+
This toolchain must be present for local compilation.
10+
11+
## Build changes
12+
13+
As we are using micrsoft/go as a base we follow their conventions.
14+
15+
Our FIPS changes require the `requirefips` build tag.
16+
When compiling `GOEXPERIMENT=systemcrypto` and `CGO_ENABLED=1` must be set.
17+
Additionally the `MS_GOTOOLCHAIN_TELEMETRY_ENABLED=0` env var is set to disable telemetry for [microsoft/go](https://github.com/microsoft/go).
18+
19+
The `FIPS=true` env var is used by our magefile as the FIPS toggle.
20+
This env var applies to all targets, at a minimum the `requirefips` tag will be set.
21+
For targets that compile binaries, the `GOEXPERIMENT=systemcrypto` and `CGO_ENABLED=1` env vars are set.
22+
23+
For developer conveniance, running `FIPS=true mage multipass` will provision a multipass VM with the Microsoft/go toolchain.
24+
See [Multipass VM Usage](#multipass-vm-usage) for additional details.
25+
26+
### Multipass VM Usage
27+
28+
A Multipass VM created with `FIPS=true mage multipass` is able to compile FIPS enabled golang programs, but is not able to run them.
29+
When you try to run one the following error occurs:
30+
```
31+
GODEBUG=fips140=on ./bin/fleet-server -c fleet-server.yml
32+
panic: opensslcrypto: can't enable FIPS mode for OpenSSL 3.0.13 30 Jan 2024: openssl: FIPS mode not supported by any provider
33+
34+
goroutine 1 [running]:
35+
crypto/internal/backend.init.1()
36+
/usr/local/go/src/crypto/internal/backend/openssl_linux.go:85 +0x210
37+
```
38+
39+
In order to be able to run a FIPS enabled binary, openssl must have a fips provider.
40+
Openssl [provides instructions on how to do this](https://github.com/openssl/openssl/blob/master/README-FIPS.md).
41+
42+
A TLDR for our multipass container is:
43+
44+
1. Download and compile the FIPS provider for openssl in the VM by running:
45+
```
46+
wget https://github.com/openssl/openssl/releases/download/openssl-3.0.13/openssl-3.0.13.tar.gz
47+
tar -xzf openssl-3.0.13.tar.gz
48+
cd openssl-3.0.13
49+
./Configure enable-fips
50+
make test
51+
sudo make install_fips
52+
sudo openssl fipsinstall -out /usr/local/ssl/fipsmodule.cnf -module /usr/local/lib/ossl-modules/fips.so
53+
```
54+
55+
2. Copy the `fips.so` module to the system library, in order to find the location run:
56+
```
57+
openssl version -m
58+
```
59+
60+
On my VM I would copy the `fips.so` module with:
61+
```
62+
sudo cp /usr/local/lib/ossl-modules/fips.so /usr/lib/aarch64-linux-gnu/ossl-modules/fips.so
63+
```
64+
65+
3. Create an openssl.cnf for the program to use with the contents:
66+
```
67+
config_diagnostics = 1
68+
openssl_conf = openssl_init
69+
70+
.include /usr/local/ssl/fipsmodule.cnf
71+
72+
[openssl_init]
73+
providers = provider_sect
74+
alg_section = algorithm_sect
75+
76+
[provider_sect]
77+
fips = fips_sect
78+
base = base_sect
79+
80+
[base_sect]
81+
activate = 1
82+
83+
[algorithm_sect]
84+
default_properties = fips=yes
85+
```
86+
87+
4. Run the program with the `OPENSSL_CONF=openssl.cnf` and `GODEBUG=fips140=on` env vars, i.e.,
88+
```
89+
OPENSSL_CONF=./openssl.cnf GODEBUG=fips140=on ./bin/fleet-server -c fleet-server.yml
90+
23:48:47.871 INF Boot fleet-server args=["-c","fleet-server.yml"] commit=55104f6f ecs.version=1.6.0 exe=./bin/fleet-server pid=65037 ppid=5642 service.name=fleet-server service.type=fleet-server version=9.0.0
91+
i...
92+
```
93+
94+
## Usage
95+
96+
Binaries produced with the `FIPS=true` env var will panic on startup if they cannot find a FIPS provider.
97+
The system/image is required to have a FIPS provider available.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/elastic/fleet-server/v7
22

3-
go 1.24.7
3+
go 1.25.1
44

55
require (
66
github.com/Pallinder/go-randomdata v1.2.0

magefile.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,12 @@ var (
309309
if isSnapshot() {
310310
tags = append(tags, "snapshot")
311311
}
312+
<<<<<<< HEAD
313+
=======
314+
if isFIPS() {
315+
tags = append(tags, "requirefips")
316+
}
317+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
312318
return strings.Join(tags, ",")
313319
})
314320

@@ -453,11 +459,50 @@ func (Check) Notice() {
453459
mg.SerialDeps(mg.F(genNotice))
454460
}
455461

462+
<<<<<<< HEAD
456463
// genNotice generates the NOTICE.txt
457464
func genNotice() error {
458465
tags := []string{}
459466
outFile := "NOTICE.txt"
460467
log.Println("Generating NOTICE.txt.")
468+
=======
469+
// DetectFIPSCryptoImports will do a best effort attempt to ensure that the imports list for FIPS compatible artifacts does not contain any external crypto libraries.
470+
// Specifically it will fail if the modules list contains an entry with: "crypto", "gokrb5", or "pbkdf2"
471+
func (Check) DetectFIPSCryptoImports() error {
472+
tags := []string{"requirefips"}
473+
mods, err := getModules(tags...)
474+
if err != nil {
475+
return err
476+
}
477+
478+
args := append([]string{"list", "-m"}, mods...)
479+
output, err := sh.Output("go", args...)
480+
if err != nil {
481+
return err
482+
}
483+
for _, line := range strings.Split(output, "\n") {
484+
// keywords are crypto for x/crypto imports, gokrb5 for kerberos, and pbkdf2 for pbkdf2 generation
485+
for _, keyword := range []string{"crypto", "gokrb5", "pbkdf2"} {
486+
if strings.Contains(line, keyword) {
487+
err = errors.Join(err, fmt.Errorf("Detected import %s may implement crypto functionality", line))
488+
}
489+
}
490+
}
491+
return err
492+
}
493+
494+
// genNotice generates the NOTICE.txt or the NOTICE-fips.txt file.
495+
func genNotice(fips bool) error {
496+
tags := []string{}
497+
outFile := "NOTICE.txt"
498+
if fips {
499+
log.Println("Generating NOTICE-fips.txt.")
500+
tags = append(tags, "requirefips")
501+
outFile = "NOTICE-fips.txt"
502+
} else {
503+
log.Println("Generating NOTICE.txt.")
504+
}
505+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
461506

462507
// Clean up modfile and download all needed files before building NOTICE
463508
err := sh.Run("go", "mod", "tidy")
@@ -1072,15 +1117,46 @@ func (Docker) CustomAgentImage() error {
10721117
// Unit runs unit tests.
10731118
// Produces a unit test output file, and test coverage file in the build directory.
10741119
// SNAPSHOT adds the snapshot build tag.
1120+
<<<<<<< HEAD
1121+
=======
1122+
// FIPS adds the requirefips build tag.
1123+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
10751124
func (Test) Unit() error {
10761125
mg.Deps(mg.F(mkDir, "build"))
10771126
output, err := teeCommand(environMap(), "go", "test", "-tags="+getTagsString(), "-v", "-race", "-coverprofile="+filepath.Join("build", "coverage-"+runtime.GOOS+".out"), "./...")
10781127
err = errors.Join(err, os.WriteFile(filepath.Join("build", "test-unit-"+runtime.GOOS+".out"), output, 0o644))
10791128
return err
10801129
}
10811130

1131+
<<<<<<< HEAD
10821132
// Integration provisions the integration test environment with docker compose, runs the integration tests, then destroys the environment.
10831133
// SNAPSHOT runs integration tests with the snapshot build tag.
1134+
=======
1135+
// UnitFIPSOnly runs unit tests and injects GODEBUG=fips140=only into the environment.
1136+
// This is done because mage may have issues when running with fips140=only set.
1137+
// Produces a unit test output file, and test coverage file in the build directory.
1138+
// SNAPSHOT adds the snapshot build tag.
1139+
// FIPS adds the requirefips build tag.
1140+
func (Test) UnitFIPSOnly() error {
1141+
mg.Deps(mg.F(mkDir, "build"))
1142+
1143+
// We also set GODEBUG=tlsmlkem=0 to disable the X25519MLKEM768 TLS key
1144+
// exchange mechanism; without this setting and with the GODEBUG=fips140=only
1145+
// setting, we get errors in tests like so:
1146+
// Failed to connect: crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode
1147+
// Note that we are only disabling this TLS key exchange mechanism in tests!
1148+
env := environMap()
1149+
env["GODEBUG"] = "fips140=only,tlsmlkem=0"
1150+
1151+
output, err := teeCommand(env, "go", "test", "-tags="+getTagsString(), "-v", "-race", "-coverprofile="+filepath.Join("build", "coverage-"+runtime.GOOS+".out"), "./...")
1152+
err = errors.Join(err, os.WriteFile(filepath.Join("build", "test-unit-fipsonly-"+runtime.GOOS+".out"), output, 0o644))
1153+
return err
1154+
}
1155+
1156+
// Integration provisions the integration test environment with docker compose, runs the integration tests, then destroys the environment.
1157+
// SNAPSHOT runs integration tests with the snapshot build tag.
1158+
// FIPS runs the integration tests the requirefips build tag.
1159+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
10841160
func (Test) Integration() {
10851161
mg.SerialDeps(mg.F(mkDir, "build"), Test.IntegrationUp, Test.IntegrationRun, Test.IntegrationDown)
10861162
}
@@ -1094,6 +1170,10 @@ func (Test) IntegrationUp() error {
10941170
// Assumes that the integration test environment is up.
10951171
// Produces an integration test output file in the build directory.
10961172
// SNAPSHOT runs integration tests with the snapshot build tag.
1173+
<<<<<<< HEAD
1174+
=======
1175+
// FIPS runs the integration tests the requirefips build tag.
1176+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
10971177
func (Test) IntegrationRun(ctx context.Context) error {
10981178
env, err := readEnvFile(filepath.Join("dev-tools", "integration", ".env"))
10991179
if err != nil {
@@ -1419,6 +1499,59 @@ func unzip(sourceFile, destinationDir string) error {
14191499
return nil
14201500
}
14211501

1502+
<<<<<<< HEAD
1503+
=======
1504+
// checkFIPSBinary ensures the binary located at path has fips capable markers set.
1505+
func checkFIPSBinary(path string) error {
1506+
log.Printf("Verifiying binary in %q for FIPS capable markers.", path)
1507+
info, err := buildinfo.ReadFile(path)
1508+
if err != nil {
1509+
return fmt.Errorf("unable to read buildinfo: %w", err)
1510+
}
1511+
var checkLinks, foundTags, foundExperiment bool
1512+
1513+
for _, setting := range info.Settings {
1514+
switch setting.Key {
1515+
case "-tags":
1516+
foundTags = true
1517+
if !strings.Contains(setting.Value, "requirefips") {
1518+
return fmt.Errorf("requirefips tag not found in %s", setting.Value)
1519+
}
1520+
continue
1521+
case "GOEXPERIMENT":
1522+
foundExperiment = true
1523+
if !strings.Contains(setting.Value, "systemcrypto") {
1524+
return fmt.Errorf("did not find GOEXPIRIMENT=systemcrypto")
1525+
}
1526+
continue
1527+
case "-ldflags":
1528+
if !strings.Contains(setting.Value, "-s") {
1529+
checkLinks = true
1530+
continue
1531+
}
1532+
}
1533+
}
1534+
1535+
if !foundTags {
1536+
return fmt.Errorf("did not find build tags")
1537+
}
1538+
if !foundExperiment {
1539+
return fmt.Errorf("did not find GOEXPERIMENT")
1540+
}
1541+
if checkLinks {
1542+
log.Println("Binary is not stripped, checking symbols table.")
1543+
output, err := sh.Output("go", "tool", "nm", path)
1544+
if err != nil {
1545+
return fmt.Errorf("go tool nm failed: %w", err)
1546+
}
1547+
if runtime.GOOS == "linux" && !strings.Contains(output, "OpenSSL_version") { // TODO may need different check for windows/darwin
1548+
return fmt.Errorf("failed to find OpenSSL symbol links within binary")
1549+
}
1550+
}
1551+
return nil
1552+
}
1553+
1554+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
14221555
// JunitReport produces junit report files from test-output files in the build dir.
14231556
func (Test) JunitReport() error {
14241557
return filepath.WalkDir("build", func(name string, d fs.DirEntry, err error) error {
@@ -1455,13 +1588,21 @@ func (Test) JunitReport() error {
14551588

14561589
// All runs unit and integration tests and produces junit reports for all the tests.
14571590
// SNAPSHOT adds the snapshot build tag.
1591+
<<<<<<< HEAD
1592+
=======
1593+
// FIPS adds the requirefips build tag.
1594+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
14581595
func (Test) All() {
14591596
mg.SerialDeps(mg.F(mkDir, "build"), Test.Unit, Test.Integration, Test.JunitReport)
14601597
}
14611598

14621599
// Benchmark runs the included benchmarks
14631600
// Produces a benchmark file in the build directory.
14641601
// SNAPSHOT adds the snapshot build tag.
1602+
<<<<<<< HEAD
1603+
=======
1604+
// FIPS adds the requirefips build tag.
1605+
>>>>>>> 15b8c8a (Bump Go version to 1.25.1 (#5562))
14651606
// BENCHMARK_FILTER can be used to filter what benchmarks run.
14661607
// BENCHMARK_ARGS can be used to change what is being benchmarked. Default: -count=10 -benchtime=3s -benchmem.
14671608
// BENCH_BASE can be used to change the output file name.

testing/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/elastic/fleet-server/testing
22

3-
go 1.24.7
3+
go 1.25.1
44

55
replace (
66
github.com/elastic/fleet-server/pkg/api => ../pkg/api

0 commit comments

Comments
 (0)