Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoC: complete XGo based build solution with HSM support #277

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
COMMIT?=$(shell git describe HEAD)$(shell git diff --quiet || echo '+dirty')

# Use linker flags to provide commit info
LDFLAGS=-ldflags "-X=github.com/foundriesio/fioctl/subcommands/version.Commit=$(COMMIT)"
VERSION_LDFLAGS=-X=github.com/foundriesio/fioctl/subcommands/version.Commit=$(COMMIT)
BUILD_STATIC=1
PREFIX=bin/fioctl

linter:=$(shell which golangci-lint 2>/dev/null || echo $(HOME)/go/bin/golangci-lint)
builder:=$(shell which xgo 2>/dev/null || echo $(HOME)/go/bin/xgo)
xgopkg::=src.techknowlogick.com/[email protected]+1.19.5
xgoimg::=ghcr.io/crazy-max/xgo:1.21.0

# Platforms listed in build and build-hsm targets are fully supported and tested.
# See the README for a full list of platforms tentatively supported by our XGo cross-compiler toolchain.

# Statically linked binary without HSM support on platforms that support static binaries.
# On platforms not supporting static binaries (e.g. Darwin) this builds dynamic library without HSM support.
build: fioctl-linux-amd64 fioctl-linux-arm64 fioctl-windows-amd64 fioctl-darwin-amd64 fioctl-darwin-arm64
@true

fioctl-static:
CGO_ENABLED=0 go build -a -ldflags '-w -extldflags "-static"' -o ./bin/fioctl-static ./main.go

fioctl-linux-amd64:
fioctl-linux-arm64:
fioctl-linux-armv7:
fioctl-windows-amd64:
fioctl-darwin-amd64:
fioctl-darwin-arm64:
fioctl-%:
CGO_ENABLED=0 \
GOOS=$(shell echo $* | cut -f1 -d\- ) \
GOARCH=$(shell echo $* | cut -f2 -d\-) \
go build $(LDFLAGS) -o bin/$@ main.go
@if [ "$@" = "fioctl-windows-amd64" ]; then mv bin/$@ bin/[email protected]; fi
# Dynamically linked binary with HSM support.
# There is no way to build static binary with HSM support due to the PKCS11 design choice to use dlopen.
# For Darwin and Windows we link against the lowest possible library version for the greatest compatibility.
# For Linux we link against GNU Libc 6; so it must be installed on a target system.
build-hsm: fioctl-hsm-darwin-amd64 fioctl-hsm-darwin-arm64 fioctl-hsm-windows-amd64 fioctl-hsm-libc6-linux-amd64
@true

# Below 3 targets allow you to build the local binary using your host toolchain
fioctl-local-dynlink:
go build -ldflags '-s -w' -o ./bin/fioctl-local-dynlink ./main.go

fioctl-hsm-local-dynlink:
go build -tags=hsm -ldflags '-s -w' -o ./bin/fioctl-hsm-local-dynlink ./main.go
StealthyCoder marked this conversation as resolved.
Show resolved Hide resolved

fioctl-local-static:
go build -tags=netgo,osusergo -ldflags '-s -w -extldflags=-static' -o ./bin/fioctl-local-static ./main.go

fioctl-%: has-builder
@echo "Bulding for $*"; \
PLATFORM=$* \
IMAGE=$(xgoimg) \
BUILDER=$(builder) \
EXTRA_LDFLAGS=$(VERSION_LDFLAGS) \
./build.sh

has-builder:
@test -x $(builder) || (echo 'Please install xgo toolchain using "make install-builder"' && exit 1)

install-builder:
@go install $(xgopkg)
@docker pull $(xgoimg)

format:
@gofmt -l -w ./
Expand Down
58 changes: 58 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash
if test -n "${XXX_INSIDE_CONTAINER}"; then
# A crazy-max/xgo creates files as root. The below script sets proper ownership.
xgo-build "$@" && chown --reference $(dirname /build/${OUT}) /build/${OUT}-*
exit $?
fi

TARGET_PREFIX=bin/fioctl
TARGET_HSM=0
TARGET_STATIC=1
TARGET_LDFLAGS="'-extldflags=-O1'"
TARGET_GOTAGS=netgo,osusergo
GOOS=$(echo ${PLATFORM} | cut -f1 -d-)
GOARCH=$(echo ${PLATFORM} | cut -f2- -d-)

# Check if the binary should support HSM devices via PKCS11
if test "x${GOOS}" = "xhsm"; then
GOOS=$(echo ${GOARCH} | cut -f1 -d-)
GOARCH=$(echo ${GOARCH} | cut -f2- -d-)
TARGET_HSM=1
TARGET_STATIC=0
TARGET_PREFIX=${TARGET_PREFIX}-hsm
fi

# For dynamically linked binaries this is just a fancy way to tell which Libc it requires.
# Currently, the XGo image we use only supports linking against the Libc.
if test "x${GOOS}" = "xlibc6"; then
GOOS=$(echo ${GOARCH} | cut -f1 -d-)
GOARCH=$(echo ${GOARCH} | cut -f2- -d-)
TARGET_STATIC=0
TARGET_PREFIX=${TARGET_PREFIX}-libc6
fi

if test "x${TARGET_STATIC}" = "x1"; then
# Darwin officially disallows building static binaries.
# Even internal linker always dynlinks libSystem.B.dylib, libresolv.9.dylib, CoreFoundation, and Security.
test "x${GOOS}" = "xwindows" && TARGET_LDFLAGS="'-extldflags=-static -O1'"
test "x${GOOS}" = "xlinux" && TARGET_LDFLAGS="'-extldflags=-static -O1'"
if test "x${GOOS}-${GOARCH}" = "xlinux-amd64"; then
# For Amd64 Linux add binary hardening using PIE and Full RELRO.
StealthyCoder marked this conversation as resolved.
Show resolved Hide resolved
# Static PIE is not supported on Arm Linux.
TARGET_GOTAGS=${TARGET_GOTAGS},static_build
TARGET_LDFLAGS="-buildmode=pie '-extldflags=-static-pie -O1'"
fi
else
test "x${TARGET_HSM}" = "x1" && TARGET_GOTAGS=${TARGET_GOTAGS},hsm
# For Linux add binary hardening using PIE and Full RELRO.
test "x${GOOS}" = "xlinux" && TARGET_LDFLAGS="-buildmode=pie '-extldflags=-pie -O1 -z relro -z now'"
fi

${BUILDER} \
-image=${IMAGE} \
-targets=${GOOS}/${GOARCH} \
-out ${TARGET_PREFIX} \
-tags=${TARGET_GOTAGS} \
-ldflags="-v -s -w -linkmode=external ${TARGET_LDFLAGS} ${EXTRA_LDFLAGS}" \
-dockerargs "-v=$(pwd)/build.sh:/xxxbin/build,-e=XXX_INSIDE_CONTAINER=1,--entrypoint=/xxxbin/build" \
.