diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 437c8515..4559e8f5 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -19,7 +19,7 @@ jobs: - 6379:6379 steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -67,7 +67,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - mode: [synchronizer, proxy] + app: [synchronizer, proxy] + fips_mode: [enabled, disabled] steps: - name: Login to Artifactory uses: docker/login-action@v2 @@ -77,7 +78,7 @@ jobs: password: ${{ secrets.ARTIFACTORY_DOCKER_PASS }} - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get version run: echo "VERSION=$(awk '/^const Version/{gsub(/"/, "", $4); print $4}' splitio/version.go)" >> $GITHUB_ENV @@ -86,6 +87,9 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: docker/Dockerfile.${{ matrix.mode }} + file: docker/Dockerfile.${{ matrix.app }} push: true - tags: splitio-docker.jfrog.io/split-${{ matrix.mode }}:${{ env.VERSION }} + tags: splitio-docker.jfrog.io/split-${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || ''}}:${{ env.VERSION }} + build-args: | + FIPS_MODE=${{ matrix.fips_mode }} + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccffde93..cf59704f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - 6379:6379 steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -54,34 +54,38 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - mode: [synchronizer, proxy] + app: [synchronizer, proxy] + fips_mode: [enabled, disabled] steps: - name: Checkout code uses: actions/checkout@v3 - name: Docker Build and Push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . - file: docker/Dockerfile.${{ matrix.mode }} + file: docker/Dockerfile.${{ matrix.app }} push: false - tags: splitio-docker.jfrog.io/split-${{ matrix.mode }}:latest + tags: splitio-docker.jfrog.io/split-${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || '' }}:latest + build-args: | + FIPS_MODE=${{ matrix.fips_mode }} - name: Scan container using Lacework - uses: lacework/lw-scanner-action@v1.3.2 + uses: lacework/lw-scanner-action@v1.4.0 with: LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_NAME }} LW_ACCESS_TOKEN: ${{ secrets.LW_ACCESS_TOKEN }} - IMAGE_NAME: splitio-docker.jfrog.io/split-${{ matrix.mode }} + IMAGE_NAME: splitio-docker.jfrog.io/split-${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || '' }} IMAGE_TAG: latest SAVE_RESULTS_IN_LACEWORK: true SAVE_BUILD_REPORT: true - BUILD_REPORT_FILE_NAME: split-${{ matrix.mode }}.html + BUILD_REPORT_FILE_NAME: split-${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || '' }}.html - name: Save vulnerability report if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: vulnerability_report - path: split-${{ matrix.mode }}.html + name: vulnerability_report_${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || '' }} + path: split-${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || '' }}.html retention-days: 7 + overwrite: true diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index f6322be8..e2f943c8 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -10,7 +10,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - mode: [synchronizer, proxy] + app: [synchronizer, proxy] + fips_mode: [enabled, disabled] steps: - name: Login to Artifactory uses: docker/login-action@v2 @@ -20,15 +21,17 @@ jobs: password: ${{ secrets.ARTIFACTORY_DOCKER_PASS }} - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get short hash run: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Docker Build and Push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . - file: docker/Dockerfile.${{ matrix.mode }} + file: docker/Dockerfile.${{ matrix.app }} push: true - tags: splitio-docker-dev.jfrog.io/split-${{ matrix.mode }}:${{ env.SHORT_SHA }} + tags: splitio-docker-dev.jfrog.io/split-${{ matrix.app }}${{ matrix.fips_mode == 'enabled' && '-fips' || '' }}:${{ env.SHORT_SHA }} + build-args: | + FIPS_MODE=${{ matrix.fips_mode }} diff --git a/.github/workflows/update-license-year.yml b/.github/workflows/update-license-year.yml index 13aaac8a..74b65c53 100644 --- a/.github/workflows/update-license-year.yml +++ b/.github/workflows/update-license-year.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.gitignore b/.gitignore index 4235d749..7b269831 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ #Project files -split-synchronizer split-sync split-proxy +split-sync-fips +split-proxy-fips proxy-opts.md sync-opts.md @@ -70,3 +71,7 @@ build/* split-proxy split-sync /clilist + +windows/downloads +windows/unpacked +windows/build diff --git a/CHANGES.txt b/CHANGES.txt index 97a9d2f5..e91ac5af 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +5.7.0 (TD) + - Add support for FIPS-compliant binaries & docker images + 5.6.1 (Jan 29, 2024) - Fixed Data Inspector view. - Updated docker images for vulnerability fixes. @@ -12,6 +15,7 @@ - Updated go-split-commons version. - Updated how redis data is displayed in /info/configs. + 5.5.0 (Dec 12, 2023) - Added support for Flag Sets on Split Proxy and Synchronizer, which enables SDKs to interacting with the flag sets features (more details in our documentation): - Updated Proxy endpoints used by SDKs to fetch flags have been updated to handle any SDKs downloading flags in certain flag sets. diff --git a/Makefile b/Makefile index fefba63d..85a92525 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,24 @@ # Setup defaults GO ?= go +MAKE ?= make ZIP ?= zip ARCH ?= amd64 PYTHON ?= python3 DOCKER ?= docker BUILD ?= build +BUILD_FIPS ?= $(BUILD)/fips +BUILD_FIPS_WIN_TMP ?= windows/build SHELL = /usr/bin/env bash -o pipefail +ENFORCE_FIPS := -tags enforce_fips +CURRENT_OS = $(shell uname -a | awk '{print $$1}') PLATFORM ?= # Extra arguments EXTRA_BUILD_ARGS ?= # don't depend on commit version, to avoid rebuilding unnecessarily -sources := $(shell find . -name *.go -not -name "commitversion.go") -version := $(shell cat splitio/version.go | grep 'const Version' | sed 's/const Version = //' | tr -d '"') +sources := $(shell find . -name *.go -not -name "commitversion.go") +version := $(shell cat splitio/version.go | grep 'const Version' | sed 's/const Version = //' | tr -d '"') commit_version := $(shell git rev-parse --short HEAD) installer_tpl := ./release/install_script_template installer_tpl_lines := $(shell echo $$(( $$(wc -l $(installer_tpl) | awk '{print $$1}') +1 ))) @@ -51,6 +56,14 @@ split-sync: $(sources) go.sum split-proxy: $(sources) go.sum $(GO) build $(EXTRA_BUILD_ARGS) -o $@ cmd/proxy/main.go +## Build the split-sync executable +split-sync-fips: $(sources) go.sum + GOEXPERIMENT=boringcrypto $(GO) build $(EXTRA_BUILD_ARGS) -o $@ $(ENFORCE_FIPS) cmd/synchronizer/main.go + +## Build the split-proxy executable +split-proxy-fips: $(sources) go.sum + GOEXPERIMENT=boringcrypto $(GO) build $(EXTRA_BUILD_ARGS) -o $@ $(ENFORCE_FIPS) cmd/proxy/main.go + ## Run the unit tests test: $(sources) go.sum $(GO) test ./... -count=1 -race $(ARGS) @@ -63,7 +76,7 @@ test_coverage: $(sources) go.sum display-coverage: coverage.out go tool cover -html=coverage.out -## Generate binaires for all architectures, ready to upload for distribution (with and without version) +## Generate binaries for all architectures, ready to upload for distribution (with and without version) release_assets: \ $(BUILD)/synchronizer \ $(BUILD)/proxy @@ -92,13 +105,29 @@ entrypoints: entrypoint.synchronizer.sh entrypoint.proxy.sh ## Build release-ready docker images with proper tags and output push commands in stdout images_release: # entrypoints - $(DOCKER) build $(platform_str) -t splitsoftware/split-synchronizer:latest -t splitsoftware/split-synchronizer:$(version) -f docker/Dockerfile.synchronizer . - $(DOCKER) build $(platform_str) -t splitsoftware/split-proxy:latest -t splitsoftware/split-proxy:$(version) -f docker/Dockerfile.proxy . + $(DOCKER) build $(platform_str) \ + -t splitsoftware/split-synchronizer:latest -t splitsoftware/split-synchronizer:$(version) \ + -f docker/Dockerfile.synchronizer . + $(DOCKER) build $(platform_str) \ + -t splitsoftware/split-proxy:latest -t splitsoftware/split-proxy:$(version) \ + -f docker/Dockerfile.proxy . + $(DOCKER) build $(platform_str) \ + -t splitsoftware/split-synchronizer-fips:latest -t splitsoftware/split-synchronizer-fips:$(version) \ + --build-arg FIPS_MODE=enabled \ + -f docker/Dockerfile.synchronizer . + $(DOCKER) build $(platform_str) \ + -t splitsoftware/split-proxy-fips:latest -t splitsoftware/split-proxy-fips:$(version) \ + --build-arg FIPS_MODE=enabled \ + -f docker/Dockerfile.proxy . @echo "Images created. Make sure everything works ok, and then run the following commands to push them." @echo "$(DOCKER) push splitsoftware/split-synchronizer:$(version)" @echo "$(DOCKER) push splitsoftware/split-synchronizer:latest" @echo "$(DOCKER) push splitsoftware/split-proxy:$(version)" @echo "$(DOCKER) push splitsoftware/split-proxy:latest" + @echo "$(DOCKER) push splitsoftware/split-synchronizer-fips:$(version)" + @echo "$(DOCKER) push splitsoftware/split-synchronizer-fips:latest" + @echo "$(DOCKER) push splitsoftware/split-proxy-fips:$(version)" + @echo "$(DOCKER) push splitsoftware/split-proxy-fips:latest" # -------------------------------------------------------------------------- # @@ -115,10 +144,12 @@ coverage.out: test_coverage # because of windows .exe suffix, we need a macro on the right side, which needs to be executed # after the `%` evaluation, therefore, in a second expansion .SECONDEXPANSION: -$(BUILD)/split_%.zip: $(BUILD)/split_$$(call make_exec,%) +%.zip: $$(call mkexec,%) $(ZIP) -9 --junk-paths $@ $< -$(BUILD)/install_split_%.bin: $(BUILD)/split_%.zip +# factorized installer creation since it cannot be combined into a single +# target for both std & fips-compliant builds +define make-installer cat $(installer_tpl) \ | sed -e "s/AUTO_REPLACE_APP_NAME/$(call apptitle_from_zip,$<)/" \ | sed -e "s/AUTO_REPLACE_INSTALL_NAME/$(call installed_from_zip,$<)/" \ @@ -133,12 +164,44 @@ $(BUILD)/install_split_%.bin: $(BUILD)/split_%.zip chmod 755 $@ rm $@.tmp rm $< +endef + +$(BUILD)/install_split_%.bin: $(BUILD)/split_%.zip + $(make-installer) + +$(BUILD_FIPS)/install_split_%.bin: $(BUILD_FIPS)/split_%.zip + $(make-installer) -execs := split_sync_linux split_sync_osx split_sync_windows.exe split_proxy_linux split_proxy_osx split_proxy_windows.exe -.INTERMEDIATE: $(addprefix $(BUILD)/,$(execs)) +# Recipes to build main binaries (both std & fips-compliant) +# @{ +posix_execs := split_sync_linux split_sync_osx split_proxy_linux split_proxy_osx +windows_execs := split_sync_windows.exe split_proxy_windows.exe +execs := $(posix_execs) $(windows_execs) +.INTERMEDIATE: $(addprefix $(BUILD)/,$(execs)) $(addprefix $(BUILD_FIPS)/,$(execs)) + +# regular binaries recipe $(addprefix $(BUILD)/,$(execs)): $(BUILD)/split_%: $(sources) go.sum CGO_ENABLED=0 GOARCH=$(ARCH) GOOS=$(call parse_os,$@) $(GO) build -o $@ cmd/$(call cmdfolder_from_bin,$@)/main.go +# fips-compliant posix binaries recipe +$(addprefix $(BUILD_FIPS)/,$(posix_execs)): $(BUILD_FIPS)/split_%: $(sources) go.sum + mkdir -p $(BUILD_FIPS) + GOEXPERIMENT=boringcrypto CGO_ENABLED=0 GOARCH=$(ARCH) GOOS=$(call parse_os,$@) $(GO) build $(ENFORCE_FIPS) -o $@ cmd/$(call cmdfolder_from_bin,$@)/main.go + +# fips-compliant windows binaries recipe +ifeq ($(CURRENT_OS),Darwin) # we're on macos, we need to build using a dockerized linux +$(addprefix $(BUILD_FIPS)/,$(windows_execs)): $(BUILD_FIPS)/split_%: $(sources) go.sum + mkdir -p $(BUILD_FIPS) + bash -c 'pushd windows && ./build_from_mac.sh' + cp $(BUILD_FIPS_WIN_TMP)/$(shell basename $@) $(BUILD_FIPS) +else +$(addprefix $(BUILD_FIPS)/,$(windows_execs)): $(BUILD_FIPS)/split_%: $(sources) go.sum + mkdir -p $(BUILD_FIPS) # we're on linux, we can build natively + $(MAKE) -f Makefile -C ./windows setup_ms_go binaries + cp $(BUILD_FIPS_WIN_TMP)/$(shell basename $@) $(BUILD_FIPS) +endif +# @} + entrypoint.%.sh: clilist cat docker/entrypoint.sh.tpl \ | sed 's/{{ARGS}}/$(shell ./clilist -target=$*)/' \ @@ -147,23 +210,45 @@ entrypoint.%.sh: clilist > $@ chmod +x $@ +define copy-release-binaries + for f in $^; do \ + if [[ $$(dirname "$$f") == $(BUILD) ]]; then \ + cp $$f $@/$(version)/$$(basename "$${f%.*}")_$(version).$${f##*.}; \ + mv $$f $@; \ + elif [[ $$(dirname "$$f") == $(BUILD_FIPS) ]]; then \ + cp $$f $@/$(version)/$$(basename "$${f%.*}")_fips_$(version).$${f##*.}; \ + mv $$f $@/$$(basename "$${f%.*}")_fips.$${f##*.}; \ + fi \ + done +endef + + $(BUILD)/synchronizer: \ $(BUILD)/downloads.sync.html \ $(BUILD)/install_split_sync_linux.bin \ $(BUILD)/install_split_sync_osx.bin \ - $(BUILD)/split_sync_windows.zip + $(BUILD)/split_sync_windows.zip \ + $(BUILD_FIPS)/install_split_sync_linux.bin \ + $(BUILD_FIPS)/install_split_sync_osx.bin \ + $(BUILD_FIPS)/split_sync_windows.zip + mkdir -p $(BUILD)/synchronizer/$(version) - for f in $^; do cp $$f $(BUILD)/synchronizer/$(version)/$$(basename "$${f%.*}")_$(version).$${f##*.}; done - cp {$(subst $(space),$(comma),$^)} $(BUILD)/synchronizer + cp $(BUILD)/downloads.sync.html $(BUILD)/synchronizer + $(copy-release-binaries) + $(BUILD)/proxy: \ $(BUILD)/downloads.proxy.html \ $(BUILD)/install_split_proxy_linux.bin \ $(BUILD)/install_split_proxy_osx.bin \ - $(BUILD)/split_proxy_windows.zip + $(BUILD)/split_proxy_windows.zip \ + $(BUILD_FIPS)/install_split_proxy_linux.bin \ + $(BUILD_FIPS)/install_split_proxy_osx.bin \ + $(BUILD_FIPS)/split_proxy_windows.zip + mkdir -p $(BUILD)/proxy/$(version) - for f in $^; do cp $$f $(BUILD)/proxy/$(version)/$$(basename "$${f%.*}")_$(version).$${f##*.}; done - cp {$(subst $(space),$(comma),$^)} $(BUILD)/proxy + cp $(BUILD)/downloads.proxy.html $(BUILD)/proxy + $(copy-release-binaries) $(BUILD)/downloads.%.html: $(PYTHON) release/dp_gen.py --app $* > $@ @@ -201,12 +286,12 @@ help: to_uppercase = $(shell echo '$1' | tr a-z A-Z) remove_ext_path = $(basename $(notdir $1)) normalize_os = $(if $(subst osx,,$1),$1,darwin) -parse_os = $(call normalize_os,$(word 3,$(subst _, ,$(call remove_ext_path,$1)))) -make_exec = $(if $(findstring windows,$1),$1.exe,$1) -installed_from_zip = $(if $(findstring split_sync,$1),split-sync,split-proxy) +parse_os = $(call normalize_os,$(word 3,$(subst _, ,$(call remove_ext_path,$1)))) +mkexec = $(if $(findstring windows,$1),$1.exe,$1) +installed_from_zip = $(if $(findstring split_sync,$1),split-sync,split-proxy) apptitle_from_zip = $(if $(findstring split_sync,$1),Synchronizer,Proxy) cmdfolder_from_bin = $(if $(findstring split_sync,$1),synchronizer,proxy) -platform_str = $(if $(PLATFORM),--platform=$(PLATFORM),) +platform_str = $(if $(PLATFORM),--platform=$(PLATFORM),) # "constants" null := diff --git a/docker/Dockerfile.proxy b/docker/Dockerfile.proxy index b37cc0d1..a47bbc5c 100644 --- a/docker/Dockerfile.proxy +++ b/docker/Dockerfile.proxy @@ -1,26 +1,27 @@ # Build stage -FROM golang:1.21.6-alpine3.19 AS builder +FROM golang:1.21.6-bookworm AS builder ARG EXTRA_BUILD_ARGS +ARG FIPS_MODE -RUN apk add \ - bash \ - build-base \ - python3 \ - git +RUN apt update -y +RUN apt install -y build-essential ca-certificates python3 git WORKDIR /code COPY . . -RUN make clean split-proxy entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}" +RUN bash -c 'if [[ "${FIPS_MODE}" = "enabled" ]]; \ + then echo "building in fips mode"; make clean split-proxy-fips entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}"; mv split-proxy-fips split-proxy; \ + else echo "building in standard mode"; make clean split-proxy entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}"; \ + fi' # Runner stage -FROM alpine:3.19.1 AS runner +FROM debian:12.4 AS runner -RUN apk add bash - -RUN addgroup -g 1000 -S 'split-proxy' +RUN apt update -y +RUN apt install -y bash ca-certificates +RUN addgroup --gid 1000 --system 'split-proxy' RUN adduser \ --disabled-password \ --gecos '' \ diff --git a/docker/Dockerfile.synchronizer b/docker/Dockerfile.synchronizer index bac224a8..350009a7 100644 --- a/docker/Dockerfile.synchronizer +++ b/docker/Dockerfile.synchronizer @@ -1,26 +1,27 @@ # Build stage -FROM golang:1.21.6-alpine3.19 AS builder +FROM golang:1.21.6-bookworm AS builder ARG EXTRA_BUILD_ARGS +ARG FIPS_MODE -RUN apk add \ - bash \ - build-base \ - python3 \ - git +RUN apt update -y +RUN apt install -y build-essential ca-certificates python3 git WORKDIR /code COPY . . -RUN make clean split-sync entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}" +RUN bash -c 'if [[ "${FIPS_MODE}" = "enabled" ]]; \ + then echo "building in fips mode"; make clean split-sync-fips entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}"; mv split-sync-fips split-sync; \ + else echo "building in standard mode"; make clean split-sync entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}"; \ + fi' # Runner stage -FROM alpine:3.19.1 AS runner +FROM debian:12.4 AS runner -RUN apk add bash - -RUN addgroup -g 1000 -S 'split-synchronizer' +RUN apt update -y +RUN apt install -y bash ca-certificates +RUN addgroup --gid 1000 --system 'split-synchronizer' RUN adduser \ --disabled-password \ --gecos '' \ @@ -35,7 +36,7 @@ COPY docker/functions.sh . COPY --from=builder /code/split-sync /usr/bin/ COPY --from=builder /code/entrypoint.synchronizer.sh . -EXPOSE 3010 +EXPOSE 3000 3010 USER 'split-synchronizer' diff --git a/release/dp_gen.py b/release/dp_gen.py index 3633ca63..85576b8e 100644 --- a/release/dp_gen.py +++ b/release/dp_gen.py @@ -59,6 +59,8 @@ 'latest_linux': 'install_split_sync_linux.bin', 'latest_osx': 'install_split_sync_osx.bin', 'latest_windows': 'split_sync_windows.zip', + 'latest_linux_fips': 'install_split_sync_linux_fips.bin', + 'latest_windows_fips': 'split_sync_windows_fips.zip', } _PROXY_PRE_VARS = { @@ -70,6 +72,8 @@ 'latest_linux': 'install_split_proxy_linux.bin', 'latest_osx': 'install_split_proxy_osx.bin', 'latest_windows': 'split_proxy_windows.zip', + 'latest_linux_fips': 'install_split_proxy_linux_fips.bin', + 'latest_windows_fips': 'split_proxy_windows_fips.zip', } def make_row_vars_pre_multiexec(version: str) -> Dict[str,str]: diff --git a/release/versions.pre.html.tpl b/release/versions.pre.html.tpl index 80475e69..5cc07f70 100644 --- a/release/versions.pre.html.tpl +++ b/release/versions.pre.html.tpl @@ -70,14 +70,33 @@
+Build/OS | +OSX | +GNU/Linux | +Windows | +
Standard | +Download | +Download | +Download | +
FIPS-Compliant | +- | +Download | +Download | +