diff --git a/pkg/flatcar.arm64/Dockerfile b/pkg/flatcar.arm64/Dockerfile new file mode 100644 index 000000000..a8a8b96dc --- /dev/null +++ b/pkg/flatcar.arm64/Dockerfile @@ -0,0 +1,146 @@ +# This Dockerfile aims to make building Hubble v4 packages easier. +# Starting with version 4 building osquery is removed from individual Dockerfiles to its own. +# osquery needs to be built once. Resulting tar file can be used in hubblev4 Dockerfiles. +# Before building hubble, build osquery using a Dockerfile in pkg/osquery/ directory. +# To build this image: 1. copy previously built osquery_4hubble.x86_64.tar to directory with this Dockerfile +# 2. docker build -t --build-arg HUBBLE_CHECKOUT= --build-arg HUBBLE_VERSION= . +# The resulting image is ready to build and run pyinstaller on container start that should +# create hubble-debian.tar.gz in the /data directory inside the container. +# Mount /data volume into a directory on the host to access the package. +# To run the container: docker run -it --rm -v `pwd`:/data + +FROM debian:9 + +RUN apt-get update \ + && apt-get -y upgrade \ + && apt-get clean \ + && rm -rf /var/cache/apt + +# paths that hubble or hubble parts need in the package +RUN mkdir -p /etc/hubble/hubble.d /opt/hubble /opt/osquery /var/log/hubble_osquery/backuplogs + +# install packages that should be needed for ligbit2 compilation and successful pyinstaller run +RUN apt-get update \ + && apt-get -y install git curl \ + python-dev libffi-dev libssl-dev libyaml-dev libssh2-1 libssh2-1-dev autoconf automake libtool \ + libxml2-dev libxslt1-dev python-cffi zlib1g-dev python-setuptools \ + cmake gcc wget python-pip openssl \ + && apt-get clean \ + && rm -rf /var/cache/apt + +# libcurl install start +# install libcurl to avoid depending on host version +# requires autoconf libtool libssh2-devel zlib-devel autoconf +ENV LIBCURL_SRC_URL=https://github.com/curl/curl.git +ENV LIBCURL_SRC_VERSION=curl-7_64_1 +ENV LIBCURL_TEMP=/tmp/libcurl +ENV PATH=/opt/hubble/bin/:/opt/hubble/include:/opt/hubble/lib:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +RUN mkdir -p "$LIBCURL_TEMP" \ + && cd "$LIBCURL_TEMP" \ + && git clone "$LIBCURL_SRC_URL" \ + && cd curl \ + && git checkout "$LIBCURL_SRC_VERSION" \ + && ./buildconf \ + && ./configure --prefix=/opt/hubble --disable-ldap --without-nss --disable-manual --disable-gopher --disable-smtp --disable-smb --disable-imap --disable-pop3 --disable-tftp --disable-telnet --disable-dict --disable-ldaps --disable-ldap --disable-rtsp --with-libssh2 \ + && make \ + && make install \ + && rm -rf "$LIBCURL_TEMP" + +# git install start +# install git so that git package won't be a package dependency +# requires make git libcurl-devel autoconf zlib-devel gcc +ENV GIT_SRC_URL=https://github.com/git/git.git +ENV GIT_SRC_VERSION=v2.21.0 +ENV GITTEMP=/tmp/gittemp +RUN mkdir -p "$GITTEMP" \ + && cd "$GITTEMP" \ + && git clone "$GIT_SRC_URL" \ + && cd git \ + && git checkout "$GIT_SRC_VERSION" \ + && make configure \ + && ./configure --prefix=/opt/hubble --with-tcltk=no --with-expat=no --with-python=no --with-curl=/opt/hubble \ + && echo "NO_TCLTK=YesPlease" >> config.mak.autogen \ + && echo "NO_PERL=YesPlease" >> config.mak.autogen \ + && sed -i '0,/^NO_GETTEXT/s/^NO_GETTEXT.*/NO_GETTEXT=YesPlease/' config.mak.autogen \ + && make \ + && make install \ + && rm -rf "$GITTEMP" + +# clean up of /opt/hubble +RUN rm /opt/hubble/bin/curl* \ + && rm -rf /opt/hubble/include /opt/hubble/share + +# libgit2 install start +# must precede pyinstaller requirements +ENV LIBGIT2_SRC_VERSION=1.1.0 +ENV LIBGIT2_SRC_URL=https://github.com/libgit2/libgit2/archive/v${LIBGIT2_SRC_VERSION}.tar.gz +# it turns out github provided release files can change. so even though the +# code hopefully hasn't changed, the hash has. +ENV LIBGIT2_SRC_SHA256=41a6d5d740fd608674c7db8685685f45535323e73e784062cf000a633d420d1e +ENV LIBGIT2TEMP=/tmp/libgit2temp +RUN mkdir -p "$LIBGIT2TEMP" \ + && cd "$LIBGIT2TEMP" \ + && wget -q "$LIBGIT2_SRC_URL" -O libgit2.tar.gz \ + && echo "$LIBGIT2_SRC_SHA256 libgit2.tar.gz" | sha256sum -c - \ + && tar xzf libgit2.tar.gz \ + && cd libgit2-"$LIBGIT2_SRC_VERSION"/ \ + && export LIBGIT2=/usr/local/ \ + && cmake . -DCMAKE_INSTALL_PREFIX=$LIBGIT2 \ + && make \ + && make install \ + && rm -rf "$LIBGIT2TEMP" + +# fpm package making requirements start +RUN apt-get install -y ruby ruby-dev rubygems gcc make \ + && gem install --no-ri --no-rdoc ffi --version 1.12.2 \ + && gem install --no-ri --no-rdoc fpm \ + && apt-get clean \ + && rm -rf /var/cache/apt + +RUN apt-get install -y libbz2-dev libsqlite3-dev \ + && apt-get clean \ + && rm -rf /var/cache/apt + +# use pyenv +ARG PYENV_VERSION=3.7.9 +ENV PYENV_INSTALLER_URL=https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer +ENV PYENV_ROOT=/opt/hubble/pyenv +ENV PATH=$PYENV_ROOT/bin:$PATH +ENV PYTHON_CONFIGURE_OPTS="--enable-shared" +RUN umask 022 \ + && curl -s -S -L "$PYENV_INSTALLER_URL" -o /usr/bin/pyenv-installer \ + && chmod 0755 /usr/bin/pyenv-installer \ + && /usr/bin/pyenv-installer \ + && eval "$(pyenv init --path)" \ + && pyenv install $PYENV_VERSION \ + && pyenv global $PYENV_VERSION + +RUN eval "$(pyenv init --path)" \ + && pip -v install --upgrade pip + +# pyinstaller start +# commands specified for ENTRYPOINT and CMD are executed when the container is run, not when the image is built +# use the following variables to choose the version of hubble +ARG HUBBLE_CHECKOUT=v4.5.0 +ARG HUBBLE_VERSION=4.5.0 +ARG HUBBLE_GIT_URL=https://github.com/hubblestack/hubble.git +ENV HUBBLE_ITERATION=1 +ENV HUBBLE_URL=https://github.com/hubblestack/hubble +ENV HUBBLE_SRC_PATH=/hubble_src +ENV _HOOK_DIR="./pkg/" +ENV _BINARY_LOG_LEVEL="INFO" +ENV _INCLUDE_PATH="" +ENV LD_LIBRARY_PATH=/opt/hubble/lib:/lib:/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64 +ENV HUBBLE_CHECKOUT=$HUBBLE_CHECKOUT +ENV HUBBLE_VERSION=$HUBBLE_VERSION +ENV HUBBLE_GIT_URL=$HUBBLE_GIT_URL + +# leaving this blank will cause the entrypoint to look for either osquery_4hubble.tar +# or osquery_4_hubble.$(uname -m).tar +ARG OSQUERY_TAR_FILENAME= +ENV OSQUERY_TAR_FILENAME=$OSQUERY_TAR_FILENAME + +VOLUME /data +WORKDIR /hubble_build +COPY entrypoint.sh /entrypoint.sh +ENTRYPOINT [ "/bin/bash", "/entrypoint.sh" ] diff --git a/pkg/flatcar.arm64/entrypoint.sh b/pkg/flatcar.arm64/entrypoint.sh new file mode 100644 index 000000000..cc946a23b --- /dev/null +++ b/pkg/flatcar.arm64/entrypoint.sh @@ -0,0 +1,176 @@ +#!/bin/bash +#Moving hubble source code logic in the shell script + +# if ENTRYPOINT is given a CMD other than nothing +# abort here and do that other CMD +if [ $# -gt 0 ] +then exec "$@" +fi + +set -x -e +if [ ! -d "${HUBBLE_SRC_PATH}" ] +then git clone "${HUBBLE_GIT_URL}" "${HUBBLE_SRC_PATH}" +fi + +if [ -n "$OSQUERY_TAR_FILENAME" ] +then OSQUERY_TAR_FILENAMES=( /data/$OSQUERY_TAR_FILENAME ) +else OSQUERY_TAR_FILENAMES=( /data/osquery_4hubble.$(uname -m).tar /data/osquery_4hubble.tar ) +fi + +if [ ! -d /opt/osquery ] +then mkdir -vp /opt/osquery +fi + +for filename in "${OSQUERY_TAR_FILENAMES[@]}"; do + if [ -e "$filename" ]; then + # tar -C /opt/osquery -xvvf "$filename" + tar -C / -xvvf "$filename" + break + fi +done + +ls -l /opt/osquery/bin + +ln -s /opt/osquery/bin/osqueryd /opt/osquery/osqueryi +ln -s /opt/osquery/bin/osqueryd /opt/osquery/osqueryd + +if [ ! -L /opt/osquery/osqueryi ] +then echo please provide a working osquery tarfile; exit 1 +else /opt/osquery/osqueryi --version +fi + +cd "${HUBBLE_SRC_PATH}" +git checkout "${HUBBLE_CHECKOUT}" + +HUBBLE_VERSION="$( sed -e 's/^v//' -e 's/[_-]rc/rc/g' <<< "$HUBBLE_VERSION" )" + +cp -rf "${HUBBLE_SRC_PATH}"/* /hubble_build +rm -rf /hubble_build/.git + +cp /hubble_build/hubblestack/__init__.py /hubble_build/hubblestack/__init__.orig +sed -i -e "s/BRANCH_NOT_SET/${HUBBLE_CHECKOUT}/g" -e "s/COMMIT_NOT_SET/$(cd ${HUBBLE_SRC_PATH}; git describe --long --always --tags)/g" /hubble_build/hubblestack/__init__.py +cp /hubble_build/hubblestack/__init__.py /hubble_build/hubblestack/__init__.fixed + +sed -i -e "s/'.*'/'$HUBBLE_VERSION'/g" /hubble_build/hubblestack/version.py + +eval "$(pyenv init --path)" + +# from now on, exit on error (rather than && every little thing) +PS4=$'-------------=: ' + +# possibly replace the version file +if [ -f /data/hubble_buildinfo ]; then + echo >> /hubble_build/hubblestack/__init__.py + cat /data/hubble_buildinfo >> /hubble_build/hubblestack/__init__.py +fi 2>/dev/null + +cat > /data/pre_packaged_certificates.py << EOF +ca_crt = list() +public_crt = list() +EOF +do_pkg_crts=0 +if [ -f /data/certs/ca-root.crt ]; then + echo "ca_crt.append('''$(< /data/certs/ca-root.crt)''')" \ + >> /data/pre_packaged_certificates.py + do_pkg_crts=$(( do_pkg_crts + 1 )) + for item in /data/certs/int*.crt; do + if [ -f "$item" ] + then echo "ca_crt.append('''$(< "$item")''')" \ + >> /data/pre_packaged_certificates.py + do_pkg_crts=$(( do_pkg_crts + 1 )) + fi + done +fi +for item in /data/certs/{pub,sign}*.crt; do + if [ -f "$item" ] + then echo "public_crt.append('''$(< "$item")''')" \ + >> /data/pre_packaged_certificates.py + do_pkg_crts=$(( do_pkg_crts + 1 )) + fi +done +if [ $do_pkg_crts -gt 0 ] +then cp /data/pre_packaged_certificates.py /hubble_build/hubblestack +fi + +cd /hubble_build + +# we may have preinstalled requirements that may need upgrading +# pip install . might not upgrade/downgrade the requirements +pip install wheel +python setup.py egg_info +pip install --upgrade \ + -r hubblestack.egg-info/requires.txt \ + -r optional-requirements.txt \ + -r package-requirements.txt +pip freeze > /data/requirements.txt + +[ -f ${_HOOK_DIR:-./pkg}/hook-hubblestack.py ] || exit 1 + +rm -rf build dist /opt/hubble/hubble-libs /hubble_build/hubble.spec +export LD_LIBRARY_PATH=$(pyenv prefix)/lib:/opt/hubble/lib:/opt/hubble-libs +export LD_RUN_PATH=$LD_LIBRARY_PATH +pyinstaller --onedir --noconfirm --log-level ${_BINARY_LOG_LEVEL:-INFO} \ + --additional-hooks-dir ${_HOOK_DIR:-./pkg} \ + --runtime-hook pkg/runtime-hooks.py \ + ./hubble.py 2>&1 | tee /tmp/pyinstaller.log + +cp -pr dist/hubble /opt/hubble/hubble-libs + +cat > /opt/hubble/hubble << EOF +#!/bin/bash +exec /opt/hubble/hubble-libs/hubble "\$@" +exit 1 +EOF +chmod 0755 /opt/hubble/hubble + +[ -d /data/last-build.4 ] && rm -rf /data/last-build.4 +[ -d /data/last-build.3 ] && mv -v /data/last-build.3 /data/last-build.4 +[ -d /data/last-build.2 ] && mv -v /data/last-build.2 /data/last-build.3 +[ -d /data/last-build.1 ] && mv -v /data/last-build.1 /data/last-build.2 +cp -va build/ /data/last-build.1 +mv /tmp/pyinstaller.log /data/last-build.1 +cp -va /entrypoint.sh /data/last-build.1 + +mkdir -p /var/log/hubble_osquery/backuplogs + +mkdir -p /etc/systemd/system +mkdir -p /etc/profile.d +mkdir -p /etc/hubble/hubble.d + +cp -v /hubble_build/pkg/hubble.service /etc/hubble/hubble-example.service +cp -v /hubble_build/conf/hubble-profile.sh /etc/profile.d/ +cp -v /hubble_build/conf/hubble-d-conf /etc/hubble/hubble.d + +if [ -f /data/hubble ] +then cp -v /data/hubble /etc/hubble/ +else cp -v /hubble_build/conf/hubble /etc/hubble/ +fi + +if [ "X$NO_TAR" = X1 ]; then + echo "exiting (as requested by NO_TAR=$NO_TAR) without pre-tar-ing package" + exit 0 +fi 2>/dev/null + +# also bring in anything from a /data/opt/ directory so we can bundle other executables if needed +if [ -d /data/opt ] +then cp -r /data/opt/* /opt +fi + +PACKAGE_NAME_ARCH="${ARCH:-$(uname -m)}" + +# edit to change iteration number, if necessary +PKG_BASE_NAME=hubblestack-${HUBBLE_VERSION}-${HUBBLE_ITERATION} +PKG_OUT_EXT=$PACKAGE_NAME_ARCH.tar.gz +PKG_FIN_EXT=flatcar.$PKG_OUT_EXT +PKG_FNAME=$PKG_BASE_NAME.$PKG_FIN_EXT +PKG_FILE="/data/$PKG_FNAME" + +tar -cSPvvzf "$PKG_FILE" \ + --exclude opt/hubble/pyenv \ + /etc/hubble /opt/hubble /opt/osquery \ + /etc/profile.d/hubble-profile.sh \ + /var/log/hubble_osquery/backuplogs \ + /etc/hubble/hubble-example.service \ + 2>&1 | tee /hubble_build/deb-pkg-start-tar.log + +openssl dgst -sha256 "$PKG_FILE" > "$PKG_FILE".sha256