Skip to content

Commit 70e675f

Browse files
committed
TUN-5551: Reintroduce FIPS compliance for linux amd64 now as separate binaries
This is a cherry-pick of 157f5d1 followed by build/CI changes so that amd64/linux FIPS compliance is provided by new/separate binaries/artifacts/packages. The reasoning being that FIPS compliance places excessive requirements in the encryption algorithms used for regular users that do not care about that. This can cause cloudflared to reject HTTPS origins that would otherwise be accepted without FIPS checks. This way, by having separate binaries, existing ones remain as they were, and only FIPS-needy users will opt-in to the new FIPS binaries.
1 parent 8f46065 commit 70e675f

22 files changed

+154
-59
lines changed

Makefile

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,33 @@ MSI_VERSION := $(shell git tag -l --sort=v:refname | grep "w" | tail -1 | cut
44
#e.g. w3.0.1 or w4.2.10. It trims off the w character when creating the MSI.
55

66
ifeq ($(FIPS), true)
7-
GO_BUILD_TAGS := $(GO_BUILD_TAGS) fips
8-
endif
9-
10-
ifneq ($(GO_BUILD_TAGS),)
11-
GO_BUILD_TAGS := -tags $(GO_BUILD_TAGS)
7+
BINARY_NAME := cloudflared-fips
8+
else
9+
BINARY_NAME := cloudflared
1210
endif
1311

1412
ifeq ($(NIGHTLY), true)
13+
# We do not release FIPS in NIGHTLY, so no need to consider that case here.
1514
DEB_PACKAGE_NAME := cloudflared-nightly
1615
NIGHTLY_FLAGS := --conflicts cloudflared --replaces cloudflared
1716
else
18-
DEB_PACKAGE_NAME := cloudflared
17+
DEB_PACKAGE_NAME := $(BINARY_NAME)
1918
endif
2019

2120
DATE := $(shell date -u '+%Y-%m-%d-%H%M UTC')
22-
VERSION_FLAGS := -ldflags='-X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"'
21+
VERSION_FLAGS := -X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"
22+
23+
LINK_FLAGS :=
24+
ifeq ($(FIPS), true)
25+
LINK_FLAGS := -linkmode=external -extldflags=-static $(LINK_FLAGS)
26+
# Prevent linking with libc regardless of CGO enabled or not.
27+
GO_BUILD_TAGS := $(GO_BUILD_TAGS) osusergo netgo fips
28+
endif
29+
30+
LDFLAGS := -ldflags='$(VERSION_FLAGS) $(LINK_FLAGS)'
31+
ifneq ($(GO_BUILD_TAGS),)
32+
GO_BUILD_TAGS := -tags "$(GO_BUILD_TAGS)"
33+
endif
2334

2435
IMPORT_PATH := github.com/cloudflare/cloudflared
2536
PACKAGE_DIR := $(CURDIR)/packaging
@@ -61,9 +72,9 @@ else
6172
endif
6273

6374
ifeq ($(TARGET_OS), windows)
64-
EXECUTABLE_PATH=./cloudflared.exe
75+
EXECUTABLE_PATH=./$(BINARY_NAME).exe
6576
else
66-
EXECUTABLE_PATH=./cloudflared
77+
EXECUTABLE_PATH=./$(BINARY_NAME)
6778
endif
6879

6980
ifeq ($(FLAVOR), centos-7)
@@ -80,17 +91,15 @@ clean:
8091
go clean
8192

8293
.PHONY: cloudflared
83-
cloudflared:
94+
cloudflared:
8495
ifeq ($(FIPS), true)
8596
$(info Building cloudflared with go-fips)
86-
-test -f fips/fips.go && mv fips/fips.go fips/fips.go.linux-amd64
87-
mv fips/fips.go.linux-amd64 fips/fips.go
97+
cp -f fips/fips.go.linux-amd64 cmd/cloudflared/fips.go
8898
endif
89-
90-
GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) go build -v -mod=vendor $(GO_BUILD_TAGS) $(VERSION_FLAGS) $(IMPORT_PATH)/cmd/cloudflared
91-
99+
GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) go build -v -mod=vendor $(GO_BUILD_TAGS) $(LDFLAGS) $(IMPORT_PATH)/cmd/cloudflared
92100
ifeq ($(FIPS), true)
93-
mv fips/fips.go fips/fips.go.linux-amd64
101+
rm -f cmd/cloudflared/fips.go
102+
./check-fips.sh cloudflared
94103
endif
95104

96105
.PHONY: container
@@ -100,10 +109,10 @@ container:
100109
.PHONY: test
101110
test: vet
102111
ifndef CI
103-
go test -v -mod=vendor -race $(VERSION_FLAGS) ./...
112+
go test -v -mod=vendor -race $(LDFLAGS) ./...
104113
else
105114
@mkdir -p .cover
106-
go test -v -mod=vendor -race $(VERSION_FLAGS) -coverprofile=".cover/c.out" ./...
115+
go test -v -mod=vendor -race $(LDFLAGS) -coverprofile=".cover/c.out" ./...
107116
go tool cover -html ".cover/c.out" -o .cover/all.html
108117
endif
109118

@@ -112,10 +121,10 @@ test-ssh-server:
112121
docker-compose -f ssh_server_tests/docker-compose.yml up
113122

114123
define publish_package
115-
chmod 664 cloudflared*.$(1); \
124+
chmod 664 $(BINARY_NAME)*.$(1); \
116125
for HOST in $(CF_PKG_HOSTS); do \
117126
ssh-keyscan -t ecdsa $$HOST >> ~/.ssh/known_hosts; \
118-
scp -p -4 cloudflared*.$(1) cfsync@$$HOST:/state/cf-pkg/staging/$(2)/$(TARGET_PUBLIC_REPO)/cloudflared/; \
127+
scp -p -4 $(BINARY_NAME)*.$(1) cfsync@$$HOST:/state/cf-pkg/staging/$(2)/$(TARGET_PUBLIC_REPO)/$(BINARY_NAME)/; \
119128
done
120129
endef
121130

@@ -127,6 +136,8 @@ publish-deb: cloudflared-deb
127136
publish-rpm: cloudflared-rpm
128137
$(call publish_package,rpm,yum)
129138

139+
# When we build packages, the package name will be FIPS-aware.
140+
# But we keep the binary installed by it to be named "cloudflared" regardless.
130141
define build_package
131142
mkdir -p $(PACKAGE_DIR)
132143
cp cloudflared $(PACKAGE_DIR)/cloudflared
@@ -247,8 +258,8 @@ tunnelrpc-deps:
247258
capnp compile -ogo tunnelrpc/tunnelrpc.capnp
248259

249260
.PHONY: quic-deps
250-
quic-deps:
251-
which capnp
261+
quic-deps:
262+
which capnp
252263
which capnpc-go
253264
capnp compile -ogo quic/schema/quic_metadata_protocol.capnp
254265

@@ -258,9 +269,9 @@ vet:
258269
# go get github.com/sudarshan-reddy/go-sumtype (don't do this in build directory or this will cause vendor issues)
259270
# Note: If you have github.com/BurntSushi/go-sumtype then you might have to use the repo above instead
260271
# for now because it uses an older version of golang.org/x/tools.
261-
which go-sumtype
272+
which go-sumtype
262273
go-sumtype $$(go list -mod=vendor ./...)
263274

264275
.PHONY: goimports
265276
goimports:
266-
for d in $$(go list -mod=readonly -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc) ; do goimports -format-only -local github.com/cloudflare/cloudflared -w $$d ; done
277+
for d in $$(go list -mod=readonly -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc) ; do goimports -format-only -local github.com/cloudflare/cloudflared -w $$d ; done

build-packages-fips.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
VERSION=$(git describe --tags --always --match "[0-9][0-9][0-9][0-9].*.*")
2+
echo $VERSION
3+
4+
# This controls the directory the built artifacts go into
5+
export ARTIFACT_DIR=built_artifacts/
6+
mkdir -p $ARTIFACT_DIR
7+
8+
arch=("amd64")
9+
export TARGET_ARCH=$arch
10+
export TARGET_OS=linux
11+
export FIPS=true
12+
# For BoringCrypto to link, we need CGO enabled. Otherwise compilation fails.
13+
export CGO_ENABLED=1
14+
15+
make cloudflared-deb
16+
mv cloudflared-fips\_$VERSION\_$arch.deb $ARTIFACT_DIR/cloudflared-fips-linux-$arch.deb
17+
18+
# rpm packages invert the - and _ and use x86_64 instead of amd64.
19+
RPMVERSION=$(echo $VERSION|sed -r 's/-/_/g')
20+
RPMARCH="x86_64"
21+
make cloudflared-rpm
22+
mv cloudflared-fips-$RPMVERSION-1.$RPMARCH.rpm $ARTIFACT_DIR/cloudflared-fips-linux-$RPMARCH.rpm
23+
24+
# finally move the linux binary as well.
25+
mv ./cloudflared $ARTIFACT_DIR/cloudflared-fips-linux-$arch

build-packages.sh

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1-
VERSION=$(git describe --tags --always --dirty="-dev" --match "[0-9][0-9][0-9][0-9].*.*")
1+
VERSION=$(git describe --tags --always --match "[0-9][0-9][0-9][0-9].*.*")
22
echo $VERSION
3+
4+
# Avoid depending on C code since we don't need it.
35
export CGO_ENABLED=0
6+
47
# This controls the directory the built artifacts go into
58
export ARTIFACT_DIR=built_artifacts/
69
mkdir -p $ARTIFACT_DIR
710
windowsArchs=("amd64" "386")
811
export TARGET_OS=windows
9-
for arch in ${windowsArchs[@]}; do
12+
for arch in ${windowsArchs[@]}; do
1013
export TARGET_ARCH=$arch
1114
make cloudflared-msi
1215
mv ./cloudflared.exe $ARTIFACT_DIR/cloudflared-windows-$arch.exe
1316
mv cloudflared-$VERSION-$arch.msi $ARTIFACT_DIR/cloudflared-windows-$arch.msi
1417
done
1518

1619

17-
export FIPS=true
18-
linuxArchs=("amd64" "386" "arm" "arm64")
20+
linuxArchs=("386" "amd64" "arm" "arm64")
1921
export TARGET_OS=linux
20-
for arch in ${linuxArchs[@]}; do
22+
for arch in ${linuxArchs[@]}; do
2123
export TARGET_ARCH=$arch
2224
make cloudflared-deb
2325
mv cloudflared\_$VERSION\_$arch.deb $ARTIFACT_DIR/cloudflared-linux-$arch.deb
2426

25-
# rpm packages invert the - and _ and use x86_64 instead of amd64.
27+
# rpm packages invert the - and _ and use x86_64 instead of amd64.
2628
RPMVERSION=$(echo $VERSION|sed -r 's/-/_/g')
2729
RPMARCH=$arch
2830
if [ $arch == "amd64" ];then
@@ -37,4 +39,3 @@ for arch in ${linuxArchs[@]}; do
3739
# finally move the linux binary as well.
3840
mv ./cloudflared $ARTIFACT_DIR/cloudflared-linux-$arch
3941
done
40-

cfsetup.yaml

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
11
pinned_go: &pinned_go go=1.17-1
2-
pinned_go_fips: &pinned_go_fips go-boring=1.16.6-6
2+
pinned_go_fips: &pinned_go_fips go-boring=1.16.6-7
33

44
build_dir: &build_dir /cfsetup_build
55
default-flavor: buster
66
stretch: &stretch
77
build:
88
build_dir: *build_dir
99
builddeps:
10-
- *pinned_go_fips
10+
- *pinned_go
1111
- build-essential
1212
post-cache:
1313
- export GOOS=linux
1414
- export GOARCH=amd64
15-
- export FIPS=true
1615
- make cloudflared
17-
build-non-fips: # helpful to catch problems with non-fips (only used for releasing non-linux artifacts) before releases
16+
build-fips:
1817
build_dir: *build_dir
1918
builddeps:
20-
- *pinned_go
19+
- *pinned_go_fips
2120
- build-essential
2221
post-cache:
2322
- export GOOS=linux
2423
- export GOARCH=amd64
24+
- export FIPS=true
2525
- make cloudflared
26-
build-all-packages: #except osxpkg
26+
# except FIPS (handled in github-fips-release-pkgs) and macos (handled in github-release-macos-amd64)
27+
github-release-pkgs:
2728
build_dir: *build_dir
2829
builddeps:
29-
- *pinned_go_fips
30+
- *pinned_go
3031
- build-essential
3132
- fakeroot
3233
- rubygem-fpm
@@ -35,15 +36,21 @@ stretch: &stretch
3536
# libmsi and libgcab are libraries the wixl binary depends on.
3637
- libmsi-dev
3738
- libgcab-dev
38-
pre-cache:
39-
# TODO: https://jira.cfops.it/browse/TUN-4792 Replace this wixl with the official one once msitools supports
40-
# environment.
39+
- python3-dev
40+
- libffi-dev
41+
- python3-setuptools
42+
- python3-pip
43+
pre-cache: &github_release_pkgs_pre_cache
4144
- wget https://github.com/sudarshan-reddy/msitools/releases/download/v0.101b/wixl -P /usr/local/bin
4245
- chmod a+x /usr/local/bin/wixl
46+
- pip3 install pygithub
4347
post-cache:
44-
- export FIPS=true
48+
# build all packages (except macos and FIPS) and move them to /cfsetup/built_artifacts
4549
- ./build-packages.sh
46-
github-release-pkgs:
50+
# release the packages built and moved to /cfsetup/built_artifacts
51+
- make github-release-built-pkgs
52+
# handle FIPS separately so that we built with gofips compiler
53+
github-fips-release-pkgs:
4754
build_dir: *build_dir
4855
builddeps:
4956
- *pinned_go_fips
@@ -59,18 +66,25 @@ stretch: &stretch
5966
- libffi-dev
6067
- python3-setuptools
6168
- python3-pip
62-
pre-cache:
63-
- wget https://github.com/sudarshan-reddy/msitools/releases/download/v0.101b/wixl -P /usr/local/bin
64-
- chmod a+x /usr/local/bin/wixl
65-
- pip3 install pygithub
69+
pre-cache: *github_release_pkgs_pre_cache
6670
post-cache:
67-
# build all packages and move them to /cfsetup/built_artifacts
68-
- ./build-packages.sh
69-
# release the packages built and moved to /cfsetup/built_artifacts
71+
# same logic as above, but for FIPS packages only
72+
- ./build-packages-fips.sh
7073
- make github-release-built-pkgs
7174
build-deb:
7275
build_dir: *build_dir
7376
builddeps: &build_deb_deps
77+
- *pinned_go
78+
- build-essential
79+
- fakeroot
80+
- rubygem-fpm
81+
post-cache:
82+
- export GOOS=linux
83+
- export GOARCH=amd64
84+
- make cloudflared-deb
85+
build-fips-deb:
86+
build_dir: *build_dir
87+
builddeps:
7488
- *pinned_go_fips
7589
- build-essential
7690
- fakeroot
@@ -86,7 +100,6 @@ stretch: &stretch
86100
post-cache:
87101
- export GOOS=linux
88102
- export GOARCH=amd64
89-
- export FIPS=true
90103
- export NIGHTLY=true
91104
- make cloudflared-deb
92105
build-deb-arm64:
@@ -99,15 +112,14 @@ stretch: &stretch
99112
publish-deb:
100113
build_dir: *build_dir
101114
builddeps:
102-
- *pinned_go_fips
115+
- *pinned_go
103116
- build-essential
104117
- fakeroot
105118
- rubygem-fpm
106119
- openssh-client
107120
post-cache:
108121
- export GOOS=linux
109122
- export GOARCH=amd64
110-
- export FIPS=true
111123
- make publish-deb
112124
github-release-macos-amd64:
113125
build_dir: *build_dir
@@ -125,12 +137,25 @@ stretch: &stretch
125137
test:
126138
build_dir: *build_dir
127139
builddeps:
128-
- *pinned_go_fips
140+
- *pinned_go
129141
- build-essential
130142
- gotest-to-teamcity
131-
pre-cache:
143+
pre-cache: &test_pre_cache
132144
- go get golang.org/x/tools/cmd/goimports
133145
- go get github.com/sudarshan-reddy/[email protected]
146+
post-cache:
147+
- export GOOS=linux
148+
- export GOARCH=amd64
149+
- export PATH="$HOME/go/bin:$PATH"
150+
- ./fmt-check.sh
151+
- make test | gotest-to-teamcity
152+
test-fips:
153+
build_dir: *build_dir
154+
builddeps:
155+
- *pinned_go_fips
156+
- build-essential
157+
- gotest-to-teamcity
158+
pre-cache: *test_pre_cache
134159
post-cache:
135160
- export GOOS=linux
136161
- export GOARCH=amd64

check-fips.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Pass the path to the executable to check for FIPS compliance
2+
exe=$1
3+
4+
if [ "$(go tool nm "${exe}" | grep -c '_Cfunc__goboringcrypto_')" -eq 0 ]; then
5+
# Asserts that executable is using FIPS-compliant boringcrypto
6+
echo "${exe}: missing goboring symbols" >&2
7+
exit 1
8+
fi
9+
if [ "$(go tool nm "${exe}" | grep -c 'crypto/internal/boring/sig.FIPSOnly')" -eq 0 ]; then
10+
# Asserts that executable is using FIPS-only schemes
11+
echo "${exe}: missing fipsonly symbols" >&2
12+
exit 1
13+
fi
14+
15+
echo "${exe} is FIPS-compliant"

cmd/cloudflared/generic_service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build !windows && !darwin && !linux
12
// +build !windows,!darwin,!linux
23

34
package main

cmd/cloudflared/linux_service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build linux
12
// +build linux
23

34
package main

cmd/cloudflared/macos_service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build darwin
12
// +build darwin
23

34
package main

cmd/cloudflared/tunnel/configuration_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
//go:build ignore
12
// +build ignore
3+
24
// TODO: Remove the above build tag and include this test when we start compiling with Golang 1.10.0+
35

46
package tunnel

0 commit comments

Comments
 (0)