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

chore: modify dockerfile to build with stbernard #578

Merged
merged 13 commits into from
Jun 18, 2024
Merged
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
1 change: 0 additions & 1 deletion .github/workflows/edge-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,3 @@ jobs:
checkout_hash=$GITHUB_SHA
provenance: false
push: true

39 changes: 9 additions & 30 deletions dockerfiles/bloodhound.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,48 +26,27 @@ ARG AZUREHOUND_VERSION=v2.1.9
FROM --platform=$BUILDPLATFORM docker.io/library/node:20-alpine AS deps
ARG version=v999.999.999
ARG checkout_hash=""
ENV PYTHONUNBUFFERED=1
ENV VERSION=${version}
ENV SB_LOG_LEVEL=debug
ENV SB_VERSION=${version}
ENV CHECKOUT_HASH=${checkout_hash}
WORKDIR /bloodhound

RUN apk add --update --no-cache python3 git go
RUN find /usr/lib -name EXTERNALLY-MANAGED -delete
RUN python3 -m ensurepip
RUN pip3 install --no-cache --upgrade pip setuptools
RUN apk add --update --no-cache git go

COPY . /bloodhound
RUN go run github.com/specterops/bloodhound/packages/go/stbernard deps

########
# Build UI
# Build
################
FROM deps AS ui-builder

WORKDIR /bloodhound/packages/javascript/bh-shared-ui
RUN yarn install
RUN yarn build

WORKDIR /bloodhound/packages/javascript/js-client-library
RUN yarn install
RUN yarn build

WORKDIR /bloodhound
RUN python3 packages/python/beagle/main.py build bh-ui -v

########
# Build API
################
FROM deps AS api-builder
FROM deps AS builder
ARG TARGETOS
ARG TARGETARCH
ENV GOOS=${TARGETOS}
ENV GOARCH=${TARGETARCH}
ENV CGO_ENABLED=0
ENV SB_VERSION=${version}
WORKDIR /bloodhound

COPY --from=ui-builder /bloodhound/dist /bloodhound/dist

RUN python3 packages/python/beagle/main.py build bh -v -d
RUN go run github.com/specterops/bloodhound/packages/go/stbernard build --os ${TARGETOS} --arch ${TARGETARCH}

########
# Package other assets
Expand Down Expand Up @@ -118,7 +97,7 @@ ARG SHARPHOUND_VERSION
ARG AZUREHOUND_VERSION

COPY dockerfiles/configs/bloodhound.config.json /bloodhound.config.json
COPY --from=api-builder /bloodhound/dist/bhapi /bloodhound
COPY --from=builder /bloodhound/dist/bhapi /bloodhound
COPY --from=hound-builder /opt/bloodhound /etc/bloodhound /var/log /
COPY --from=hound-builder /tmp/sharphound/sharphound-$SHARPHOUND_VERSION.zip /etc/bloodhound/collectors/sharphound/
COPY --from=hound-builder /tmp/sharphound/sharphound-$SHARPHOUND_VERSION.zip.sha256 /etc/bloodhound/collectors/sharphound/
Expand Down
9 changes: 9 additions & 0 deletions packages/go/stbernard/command/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func (s *command) Name() string {
// Parse command flags
func (s *command) Parse(cmdIndex int) error {
cmd := flag.NewFlagSet(Name, flag.ExitOnError)
targetOs := cmd.String("os", "", "Specify the OS to build for. This will override anything in GOOS.")
targetArch := cmd.String("arch", "", "Specify the architecture to build for. This will override anything in GOARCH.")

cmd.Usage = func() {
w := flag.CommandLine.Output()
Expand All @@ -71,6 +73,13 @@ func (s *command) Parse(cmdIndex int) error {
return fmt.Errorf("parsing %s command: %w", Name, err)
}

if *targetOs != "" {
s.env.Override("GOOS", *targetOs)
}
if *targetArch != "" {
s.env.Override("GOARCH", *targetArch)
}

return nil
}

Expand Down
3 changes: 1 addition & 2 deletions packages/go/stbernard/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,14 @@ type usageFunc func()
//
// It does not support flags of its own, each subcommand is responsible for parsing
// their flags.
func ParseCLI() (CommandRunner, error) {
func ParseCLI(env environment.Environment) (CommandRunner, error) {
var (
verboseEnabled *bool
debugEnabled *bool
cmdStartIdx int
currentCmd command
helpRequested bool

env = environment.NewEnvironment()
commands = []command{
envdump.Create(env),
deps.Create(env),
Expand Down
13 changes: 13 additions & 0 deletions packages/go/stbernard/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ package environment
import (
"os"
"strings"

"github.com/specterops/bloodhound/log"
)

const (
LogLevelVarName = "SB_LOG_LEVEL"
VersionVarName = "SB_VERSION"
)

// Environment is a string map representation of env vars
Expand Down Expand Up @@ -46,6 +53,12 @@ func (s Environment) SetIfEmpty(key string, value string) {
}
}

// Overrides an environment variable with a new value
func (s Environment) Override(key string, value string) {
log.Infof("Overriding environment variable %s with %s", key, value)
s[key] = value
}

// Slice converts the Environment to a slice of strings in the form `KEY=VALUE` to send to external libraries
func (s Environment) Slice() []string {
var envSlice = make([]string, 0, len(s))
Expand Down
10 changes: 5 additions & 5 deletions packages/go/stbernard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ package main

import (
"errors"
"os"

"github.com/specterops/bloodhound/log"
"github.com/specterops/bloodhound/packages/go/stbernard/command"
"github.com/specterops/bloodhound/packages/go/stbernard/environment"
)

func main() {
const LogLevelVarName = "SB_LOG_LEVEL"
var rawLvl = os.Getenv(LogLevelVarName)
env := environment.NewEnvironment()
var rawLvl = env[environment.LogLevelVarName]

log.ConfigureDefaults()

Expand All @@ -37,12 +37,12 @@ func main() {
}

if lvl, err := log.ParseLevel(rawLvl); err != nil {
log.Errorf("Could not parse log level from %s: %v", LogLevelVarName, err)
log.Errorf("Could not parse log level from %s: %v", environment.LogLevelVarName, err)
} else {
log.SetGlobalLevel(lvl)
}

if cmd, err := command.ParseCLI(); errors.Is(err, command.ErrNoCmd) {
if cmd, err := command.ParseCLI(env); errors.Is(err, command.ErrNoCmd) {
log.Fatalf("No valid command specified")
} else if errors.Is(err, command.ErrHelpRequested) {
// No need to exit 1 if help was requested
Expand Down
12 changes: 9 additions & 3 deletions packages/go/stbernard/workspace/golang/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,21 @@ import (
// BuildMainPackages builds all main packages for a list of module paths
func BuildMainPackages(workRoot string, modPaths []string, env environment.Environment) error {
var (
err error
errs []error
wg sync.WaitGroup
mu sync.Mutex
version semver.Version
buildDir = filepath.Join(workRoot, "dist") + string(filepath.Separator)
)

version, err := git.ParseLatestVersionFromTags(workRoot, env)
if err != nil {
return fmt.Errorf("parse latest version from git tags: %w", err)
if version, err = git.ParseLatestVersionFromTags(workRoot, env); err != nil {
log.Warnf("Failed to parse version from git tags, falling back to environment variable: %v", err)
parsedVersion, err := semver.NewVersion(env[environment.VersionVarName])
if err != nil {
return fmt.Errorf("error parsing version from environment variable: %w", err)
}
version = *parsedVersion
}

log.Infof("Building for version %s", version.Original())
Expand Down
Loading