Skip to content

Commit

Permalink
fips: otelcol binaries for linux and windows
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreyc-splunk committed Sep 17, 2024
1 parent 8026a6f commit 79edb47
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 2 deletions.
81 changes: 81 additions & 0 deletions .github/workflows/otelcol-fips.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: "otelcol-fips"

on:
push:
branches:
- main
pull_request:
paths:
- '.github/workflows/otelcol-fips.yml'
- 'cmd/otelcol/**'
- 'internal/**'
- 'pkg/**'
- 'tests/**'
- 'Makefile'
- 'Makefile.Common'
- 'go.mod'
- 'go.sum'
- '!**.md'
- '!internal/buildscripts/**'

concurrency:
group: otelcol-fips-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
GO_VERSION: "1.22.7"

jobs:
otelcol-fips:
runs-on: ${{ fromJSON('["ubuntu-20.04", "otel-arm64"]')[matrix.GOARCH == 'arm64'] }}
strategy:
matrix:
include:
- GOOS: linux
GOARCH: amd64
- GOOS: linux
GOARCH: arm64
- GOOS: windows
GOARCH: amd64
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache-dependency-path: '**/go.sum'
- run: make otelcol-fips
env:
GOOS: ${{ matrix.GOOS }}
GOARCH: ${{ matrix.GOARCH }}
- uses: actions/upload-artifact@v4
with:
name: otelcol-fips-${{ matrix.GOOS }}-${{ matrix.GOARCH }}
path: ./bin/*

win-binary-test:
runs-on: windows-2022
needs: [ otelcol-fips ]
strategy:
matrix:
FIPSMODE: [ "1", "0" ]
fail-fast: false
steps:
- uses: actions/download-artifact@v4
with:
name: otelcol-fips-windows-amd64
path: ./bin
- run: Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy -Name Enabled -Value ${{ matrix.FIPSMODE }}
- run: ./bin/otelcol-fips_windows_amd64.exe --version
id: run-otelcol
continue-on-error: true
- run: echo "FIPS enabled, started successfully"
if: matrix.FIPSMODE == '1' && steps.run-otelcol.outcome == 'success'
- run: throw "FIPS enabled, should not have failed"
if: matrix.FIPSMODE == '1' && steps.run-otelcol.outcome == 'failure'
- run: echo "FIPS disabled, failed successfully"
if: matrix.FIPSMODE == '0' && steps.run-otelcol.outcome == 'failure'
- run: throw "FIPS disabled, should have failed"
if: matrix.FIPSMODE == '0' && steps.run-otelcol.outcome == 'success'
39 changes: 38 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,40 @@ compile:
- bin/otelcol_*
- bin/migratecheckpoint_*

otelcol-fips:
image: '${DOCKER_CICD_REPO}/ci-container/golang-1.22:3.4.0'
extends:
- .trigger-filter
stage: build
needs: []
parallel:
matrix:
- GOOS: linux
GOARCH: amd64
TAG: main
- GOOS: linux
GOARCH: arm64
TAG: arm
- GOOS: windows
GOARCH: amd64
TAG: main
tags:
- $TAG
id_tokens: # http://go/gitlab-17
CI_JOB_JWT:
aud: $CICD_VAULT_ADDR
script:
- *docker-reader-role
- |
if [[ -n "${CI_COMMIT_TAG:-}" ]]; then
make otelcol-fips VERSION=${CI_COMMIT_TAG} DOCKER_REPO=${DOCKER_HUB_REPO}
else
make otelcol-fips DOCKER_REPO=${DOCKER_HUB_REPO}
fi
artifacts:
paths:
- bin/otelcol-fips_*

libsplunk:
extends: .trigger-filter
stage: build
Expand Down Expand Up @@ -437,9 +471,10 @@ sign-exe:
retry: 2
needs:
- compile
- otelcol-fips
parallel:
matrix:
- TARGET: [otelcol]
- TARGET: [otelcol, otelcol-fips]
variables:
ARTIFACT: bin/${TARGET}_windows_amd64.exe
SIGN_TYPE: WIN
Expand Down Expand Up @@ -1299,6 +1334,7 @@ github-release:
stage: github-release
dependencies:
- compile
- otelcol-fips
- libsplunk
- sign-exe
- sign-osx
Expand All @@ -1312,6 +1348,7 @@ github-release:
script:
- mkdir -p dist/assets
- cp bin/otelcol_linux_* dist/assets/
- cp bin/otelcol-fips_linux_* dist/assets/
- cp instrumentation/dist/libsplunk_*.so dist/assets/
- cp dist/signed/* dist/assets/
- |
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

- (Splunk) Initial release of standalone collector binaries for Linux (amd64/arm64) and Windows (amd64) with FIPS 140-2 support. These are experimental (alpha) binaries, and it is not suitable to use them in production environments. ([#5378](https://github.com/signalfx/splunk-otel-collector/pull/5378)):
- `otelcol-fips_linux_<amd64|arm64>`: Built with [`GOEXPERIMENT=boringcrypto`](https://go.dev/src/crypto/internal/boring/README) and [`crypto/tls/fipsonly`](https://go.dev/src/crypto/tls/fipsonly/fipsonly.go).
- `otelcol-fips_windows_amd64.exe`: Built with [`GOEXPERIMENT=cngcrypto`](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/fips/README.md) and [`requirefips`](https://github.com/microsoft/go/blob/microsoft/main/eng/doc/fips/README.md#build-option-to-require-fips-mode) (the collector will panic if FIPS is not enabled on the Windows host).
- Smart Agent components are not currently supported.
- Download the binaries from the list of assets below.

## v0.109.0

### 🛑 Breaking changes 🛑
Expand Down
29 changes: 28 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ BUILD_X1=-X $(BUILD_INFO_IMPORT_PATH).Version=$(VERSION)
BUILD_X2=-X $(BUILD_INFO_IMPORT_PATH_CORE).Version=$(VERSION)
BUILD_INFO=-ldflags "${BUILD_X1} ${BUILD_X2}"
BUILD_INFO_TESTS=-ldflags "-X $(BUILD_INFO_IMPORT_PATH_TESTS).Version=$(VERSION)"
CGO_ENABLED?=0

JMX_METRIC_GATHERER_RELEASE=$(shell cat internal/buildscripts/packaging/jmx-metric-gatherer-release.txt)
SKIP_COMPILE=false
Expand Down Expand Up @@ -135,7 +136,7 @@ generate-metrics:
.PHONY: otelcol
otelcol:
go generate ./...
GO111MODULE=on CGO_ENABLED=0 go build -trimpath -o ./bin/otelcol_$(GOOS)_$(GOARCH)$(EXTENSION) $(BUILD_INFO) ./cmd/otelcol
GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED) go build -trimpath -o ./bin/otelcol_$(GOOS)_$(GOARCH)$(EXTENSION) $(BUILD_INFO) ./cmd/otelcol
ln -sf otelcol_$(GOOS)_$(GOARCH)$(EXTENSION) ./bin/otelcol

.PHONY: migratecheckpoint
Expand Down Expand Up @@ -233,3 +234,29 @@ install-test-tools:
integration-test-split: install-test-tools
@set -e; cd tests && gotesplit --total=$(GOTESPLIT_TOTAL) --index=$(GOTESPLIT_INDEX) ./... -- -p 1 $(BUILD_INFO_TESTS) --tags=integration -v -timeout 5m -count 1

.PHONY: otelcol-fips
otelcol-fips:
ifeq ($(GOOS), linux)
ifeq ($(filter $(GOARCH), amd64 arm64),)
$(error GOOS=$(GOOS) GOARCH=$(GOARCH) not supported)
endif
$(eval BUILD_INFO = -ldflags "${BUILD_X1} ${BUILD_X2} -linkmode=external -extldflags=-static")
else ifeq ($(GOOS), windows)
ifeq ($(filter $(GOARCH), amd64),)
$(error GOOS=$(GOOS) GOARCH=$(GOARCH) not supported)
endif
$(eval EXTENSION = .exe)
else
$(error GOOS=$(GOOS) GOARCH=$(GOARCH) not supported)
endif
docker buildx build --pull \
--tag otelcol-fips-builder-$(GOOS)-$(GOARCH) \
--platform linux/$(GOARCH) \
--build-arg DOCKER_REPO=$(DOCKER_REPO) \
--build-arg BUILD_INFO='$(BUILD_INFO)' \
--file cmd/otelcol/fips/Dockerfile.$(GOOS) ./
@docker rm -f otelcol-fips-builder-$(GOOS)-$(GOARCH) >/dev/null 2>&1 || true
@mkdir -p ./bin
docker create --platform linux/$(GOARCH) --name otelcol-fips-builder-$(GOOS)-$(GOARCH) otelcol-fips-builder-$(GOOS)-$(GOARCH) true >/dev/null
docker cp otelcol-fips-builder-$(GOOS)-$(GOARCH):/src/bin/otelcol_$(GOOS)_$(GOARCH)$(EXTENSION) ./bin/otelcol-fips_$(GOOS)_$(GOARCH)$(EXTENSION)
@docker rm -f otelcol-fips-builder-$(GOOS)-$(GOARCH) >/dev/null
39 changes: 39 additions & 0 deletions cmd/otelcol/fips/Dockerfile.linux
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
ARG DOCKER_REPO=docker.io
ARG GO_VERSION=1.22.7
FROM ${DOCKER_REPO}/golang:${GO_VERSION}

# https://splunk.atlassian.net/wiki/x/qYqRDfs
ENV BORING_SHA="c1dd71f0ea77e385796db11102c461896ee0824825c773979751983e2bf49912"
ENV BORING_PATH="src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso"
RUN echo "$BORING_SHA" "$( go env GOROOT )/${BORING_PATH}" | sha256sum --check || ( echo "$BORING_PATH SHA256 doesn't match $BORING_SHA" && exit 1 )

# install toolchain to build a statically linked binary with cgo enabled
RUN apt-get update && \
apt-get install -y --no-install-recommends file musl-dev musl-tools

COPY cmd /src/cmd
COPY internal /src/internal
COPY pkg /src/pkg
COPY Makefile /src/
COPY Makefile.Common /src/
COPY go.mod /src/
COPY go.sum /src/

ARG TARGETARCH
ARG BUILD_INFO
ENV GOOS=linux
ENV GOARCH=${TARGETARCH}
ENV GOEXPERIMENT=boringcrypto
ENV GOMODCACHE=/go/pkg/mod
ENV CGO_ENABLED=1
ENV CC=musl-gcc

WORKDIR /src
RUN --mount=type=cache,target=${GOMODCACHE} make otelcol BUILD_INFO="${BUILD_INFO}"

# check the binary
RUN file ./bin/otelcol_${GOOS}_${GOARCH} | grep -i "statically linked" || ( echo "the binary is not statically linked" && exit 1 )
RUN go version ./bin/otelcol_${GOOS}_${GOARCH} | grep "X:${GOEXPERIMENT}"
RUN go tool nm ./bin/otelcol_${GOOS}_${GOARCH} > symbols
RUN grep -i "fipsonly" symbols
RUN grep -m5 "_Cfunc__goboringcrypto" symbols
35 changes: 35 additions & 0 deletions cmd/otelcol/fips/Dockerfile.windows
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
ARG GO_VERSION=1.22.7
FROM mcr.microsoft.com/oss/go/microsoft/golang:${GO_VERSION}

ARG TARGETARCH

# install toolchain for cgo
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc-mingw-w64

COPY cmd /src/cmd
COPY internal /src/internal
COPY pkg /src/pkg
COPY Makefile /src/
COPY Makefile.Common /src/
COPY go.mod /src/
COPY go.sum /src/

ARG BUILD_INFO
ENV GOOS=windows
ENV GOARCH=${TARGETARCH}
ENV GOEXPERIMENT=cngcrypto
ENV GOMODCACHE=/go/pkg/mod
ENV CGO_ENABLED=1
ENV CC=x86_64-w64-mingw32-gcc
ENV CXX=x86_64-w64-mingw32-g++
ENV GOFLAGS="-tags=requirefips"
ENV EXTENSION=.exe

WORKDIR /src
RUN --mount=type=cache,target=${GOMODCACHE} make otelcol BUILD_INFO="${BUILD_INFO}"

# check the binary
RUN go version ./bin/otelcol_${GOOS}_${GOARCH}${EXTENSION} | grep "X:${GOEXPERIMENT}"
RUN go tool nm ./bin/otelcol_${GOOS}_${GOARCH}${EXTENSION} > symbols
RUN grep -m5 "github.com/microsoft/go-crypto-winnative" symbols
20 changes: 20 additions & 0 deletions cmd/otelcol/main_fipsonly.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright Splunk, Inc.
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build linux && boringcrypto && cgo && (amd64 || arm64)

package main

import _ "crypto/tls/fipsonly"

0 comments on commit 79edb47

Please sign in to comment.