From 638004cfb26102ff3c06a6b12f5db3f950375979 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 12 Apr 2021 12:25:16 -0400 Subject: [PATCH] build: Build AppImage with appimagetool instead of appimage-builder --- deployment_scripts/appimage/.gitignore | 1 + deployment_scripts/appimage/AppRun | 41 ++++++++++ deployment_scripts/appimage/README.md | 5 +- deployment_scripts/appimage/build_appimage.sh | 74 ++++++++----------- .../appimage/monkey-island.desktop | 8 ++ 5 files changed, 83 insertions(+), 46 deletions(-) create mode 100644 deployment_scripts/appimage/.gitignore create mode 100755 deployment_scripts/appimage/AppRun create mode 100644 deployment_scripts/appimage/monkey-island.desktop diff --git a/deployment_scripts/appimage/.gitignore b/deployment_scripts/appimage/.gitignore new file mode 100644 index 000000000..5a7692e9a --- /dev/null +++ b/deployment_scripts/appimage/.gitignore @@ -0,0 +1 @@ +*.AppImage diff --git a/deployment_scripts/appimage/AppRun b/deployment_scripts/appimage/AppRun new file mode 100755 index 000000000..322f4a5d9 --- /dev/null +++ b/deployment_scripts/appimage/AppRun @@ -0,0 +1,41 @@ +#! /bin/bash + +# Export APPRUN if running from an extracted image +self="$(readlink -f -- $0)" +here="${self%/*}" +APPDIR="${APPDIR:-${here}}" + +# Export TCl/Tk +export TCL_LIBRARY="${APPDIR}/usr/share/tcltk/tcl8.4" +export TK_LIBRARY="${APPDIR}/usr/share/tcltk/tk8.4" +export TKPATH="${TK_LIBRARY}" + +# Export SSL certificate +export SSL_CERT_FILE="${APPDIR}/opt/_internal/certs.pem" + +# Call the entry point +for opt in "$@" +do + [ "${opt:0:1}" != "-" ] && break + if [[ "${opt}" =~ "I" ]] || [[ "${opt}" =~ "E" ]]; then + # Environment variables are disabled ($PYTHONHOME). Let's run in a safe + # mode from the raw Python binary inside the AppImage + "$APPDIR/opt/python3.7/bin/python3.7" "$@" + exit "$?" + fi +done + +# Get the executable name, i.e. the AppImage or the python binary if running from an +# extracted image +executable="${APPDIR}/opt/python3.7/bin/python3.7" +if [[ "${ARGV0}" =~ "/" ]]; then + executable="$(cd $(dirname ${ARGV0}) && pwd)/$(basename ${ARGV0})" +elif [[ "${ARGV0}" != "" ]]; then + executable=$(which "${ARGV0}") +fi + +# Wrap the call to Python in order to mimic a call from the source +# executable ($ARGV0), but potentially located outside of the Python +# install ($PYTHONHOME) +(PYTHONHOME="${APPDIR}/opt/python3.7" exec "/bin/bash" "${APPDIR}/usr/src/monkey_island/linux/run_appimage.sh") +exit "$?" diff --git a/deployment_scripts/appimage/README.md b/deployment_scripts/appimage/README.md index 37321378f..7a76a7275 100644 --- a/deployment_scripts/appimage/README.md +++ b/deployment_scripts/appimage/README.md @@ -18,10 +18,9 @@ NOTE: This script is intended to be run from a clean VM. You can also manually remove build artifacts by removing the following files and directories. - $HOME/.monkey_island (optional) -- $HOME/monkey-appdir +- $HOME/squashfs-root - $HOME/git/monkey -- $HOME/appimage/appimage-builder-cache -- $HOME/appimage/"Monkey\ Island-\*-x86-64.Appimage" +- $HOME/appimage/Infection_Monkey-x86_64.AppImage After removing the above files and directories, you can again execute `bash build_appimage.sh`. diff --git a/deployment_scripts/appimage/build_appimage.sh b/deployment_scripts/appimage/build_appimage.sh index a1c384801..81c08629a 100755 --- a/deployment_scripts/appimage/build_appimage.sh +++ b/deployment_scripts/appimage/build_appimage.sh @@ -1,7 +1,7 @@ #!/bin/bash -python_cmd="python3.7" -APPDIR="$HOME/monkey-appdir" +APPDIR="$HOME/squashfs-root" +CONFIG_URL="https://raw.githubusercontent.com/guardicore/monkey/develop/deployment_scripts/config" INSTALL_DIR="$APPDIR/usr/src" GIT=$HOME/git @@ -33,16 +33,18 @@ log_message() { echo -e "DEPLOYMENT SCRIPT: $1" } -setup_appdir() { +setup_python_37_appdir() { + PYTHON_APPIMAGE_URL="https://github.com/niess/python-appimage/releases/download/python3.7/python3.7.9-cp37-cp37m-manylinux1_x86_64.AppImage" + PYTHON_APPIMAGE="python3.7.9_x86_64.AppImage" rm -rf "$APPDIR" || true - mkdir -p "$INSTALL_DIR" -} + curl -L -o "$PYTHON_APPIMAGE" "$PYTHON_APPIMAGE_URL" -install_pip_37() { - pip_url=https://bootstrap.pypa.io/get-pip.py - curl $pip_url -o get-pip.py - ${python_cmd} get-pip.py - rm get-pip.py + chmod u+x "$PYTHON_APPIMAGE" + + ./"$PYTHON_APPIMAGE" --appimage-extract + rm "$PYTHON_APPIMAGE" + mv ./squashfs-root "$APPDIR" + mkdir -p "$INSTALL_DIR" } install_nodejs() { @@ -63,21 +65,14 @@ install_build_prereqs() { #monkey island prereqs sudo apt install -y curl libcurl4 python3.7 python3.7-dev openssl git build-essential moreutils - install_pip_37 install_nodejs } -install_appimage_builder() { - sudo pip3 install appimage-builder - - install_appimage_tool -} - install_appimage_tool() { APP_TOOL_BIN=$HOME/bin/appimagetool APP_TOOL_URL=https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-x86_64.AppImage - mkdir "$HOME"/bin + mkdir -p "$HOME"/bin curl -L -o "$APP_TOOL_BIN" "$APP_TOOL_URL" chmod u+x "$APP_TOOL_BIN" @@ -88,7 +83,7 @@ load_monkey_binary_config() { tmpfile=$(mktemp) log_message "downloading configuration" - curl -L -s -o "$tmpfile" "$config_url" + curl -L -s -o "$tmpfile" "$CONFIG_URL" log_message "loading configuration" source "$tmpfile" @@ -103,14 +98,14 @@ clone_monkey_repo() { branch=${2:-"develop"} git clone --single-branch --recurse-submodules -b "$branch" "${MONKEY_GIT_URL}" "${REPO_MONKEY_HOME}" 2>&1 || handle_error - chmod 774 -R "${MONKEY_HOME}" + chmod 774 -R "${REPO_MONKEY_HOME}" } copy_monkey_island_to_appdir() { cp "$REPO_MONKEY_SRC"/__init__.py "$INSTALL_DIR" cp "$REPO_MONKEY_SRC"/monkey_island.py "$INSTALL_DIR" - cp -r "$REPO_MONKEY_SRC"/common "$INSTALL_DIR" - cp -r "$REPO_MONKEY_SRC"/monkey_island "$INSTALL_DIR" + cp -r "$REPO_MONKEY_SRC"/common "$INSTALL_DIR/" + cp -r "$REPO_MONKEY_SRC"/monkey_island "$INSTALL_DIR/" cp ./run_appimage.sh "$INSTALL_DIR"/monkey_island/linux/ cp ./island_logger_config.json "$INSTALL_DIR"/ cp ./server_config.json.standard "$INSTALL_DIR"/monkey_island/cc/ @@ -128,7 +123,7 @@ install_monkey_island_python_dependencies() { # dependencies and should not be installed as a runtime requirement. cat "$requirements_island" | grep -Piv "virtualenv|pyinstaller" | sponge "$requirements_island" - ${python_cmd} -m pip install -r "${requirements_island}" --ignore-installed --prefix /usr --root="$APPDIR" || handle_error + "$APPDIR"/AppRun -m pip install -r "${requirements_island}" --ignore-installed || handle_error } download_monkey_agent_binaries() { @@ -170,22 +165,7 @@ build_frontend() { build_appimage() { log_message "Building AppImage" - appimage-builder --recipe monkey_island_builder.yml --log DEBUG --skip-appimage - - # There is a bug or unwanted behavior in appimage-builder that causes issues - # if 32-bit binaries are present in the appimage. To work around this, we: - # 1. Build the AppDir with appimage-builder and skip building the appimage - # 2. Add the 32-bit binaries to the AppDir - # 3. Build the AppImage with appimage-builder from the already-built AppDir - # - # Note that appimage-builder replaces the interpreter on the monkey agent binaries - # when building the AppDir. This is unwanted as the monkey agents may execute in - # environments where the AppImage isn't loaded. - # - # See https://github.com/AppImageCrafters/appimage-builder/issues/93 for more info. - download_monkey_agent_binaries - - appimage-builder --recipe monkey_island_builder.yml --log DEBUG --skip-build + ARCH="x86_64" appimagetool "$APPDIR" } if is_root; then @@ -199,18 +179,18 @@ Run \`sudo -v\`, enter your password, and then re-run this script." exit 1 fi -config_url="https://raw.githubusercontent.com/guardicore/monkey/develop/deployment_scripts/config" - -setup_appdir install_build_prereqs -install_appimage_builder +install_appimage_tool + +setup_python_37_appdir load_monkey_binary_config clone_monkey_repo "$@" copy_monkey_island_to_appdir +download_monkey_agent_binaries # Create folders log_message "Creating island dirs under $ISLAND_PATH" @@ -224,8 +204,16 @@ generate_ssl_cert build_frontend +unlink "$APPDIR"/python.png mkdir -p "$APPDIR"/usr/share/icons cp "$REPO_MONKEY_SRC"/monkey_island/cc/ui/src/images/monkey-icon.svg "$APPDIR"/usr/share/icons/monkey-icon.svg +ln -s "$APPDIR"/usr/share/icons/monkey-icon.svg "$APPDIR"/monkey-icon.svg + +unlink "$APPDIR"/python3.7.9.desktop +cp ./monkey-island.desktop "$APPDIR"/usr/share/applications +ln -s "$APPDIR"/usr/share/applications/monkey-island.desktop "$APPDIR"/monkey-island.desktop + +cp ./AppRun "$APPDIR" build_appimage diff --git a/deployment_scripts/appimage/monkey-island.desktop b/deployment_scripts/appimage/monkey-island.desktop new file mode 100644 index 000000000..07c01ea08 --- /dev/null +++ b/deployment_scripts/appimage/monkey-island.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Name=Infection Monkey +Exec=bash +Comment=Infection Monkey FILL ME IN +Icon=monkey-icon +Categories=Development; +Terminal=true