osquery-1/tools/deployment/make_osx_package.sh

376 lines
13 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Copyright (c) 2014-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under both the Apache 2.0 license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# You may select, at your option, one of the above-listed licenses.
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
2014-12-04 17:33:04 +00:00
SOURCE_DIR="$SCRIPT_DIR/../.."
2016-02-02 00:42:37 +00:00
BUILD_DIR="$SOURCE_DIR/build/"
if [[ ! -z "$DEBUG" ]]; then
BUILD_DIR="${BUILD_DIR}debug_"
fi
if [[ "$BUILD_VERSION" == "10.11" ]]; then
2016-02-02 00:42:37 +00:00
BUILD_DIR="${BUILD_DIR}darwin"
else
2016-02-02 00:42:37 +00:00
BUILD_DIR="${BUILD_DIR}darwin$BUILD_VERSION"
fi
OSQUERY_DEPS="${OSQUERY_DEPS:-/usr/local/osquery}"
source "$SOURCE_DIR/tools/lib.sh"
distro "darwin" BUILD_VERSION
2014-10-04 01:09:37 +00:00
# Binary identifiers
VERSION=`(cd $SOURCE_DIR; git describe --tags HEAD) || echo 'unknown-version'`
APP_VERSION=${OSQUERY_BUILD_VERSION:="$VERSION"}
2014-12-10 01:30:43 +00:00
APP_IDENTIFIER="com.facebook.osquery"
2015-07-13 19:24:58 +00:00
KERNEL_APP_IDENTIFIER="com.facebook.osquery.kernel"
2015-01-04 06:51:09 +00:00
LD_IDENTIFIER="com.facebook.osqueryd"
2015-01-08 02:55:14 +00:00
LD_INSTALL="/Library/LaunchDaemons/$LD_IDENTIFIER.plist"
OUTPUT_PKG_PATH="$BUILD_DIR/osquery-$APP_VERSION.pkg"
OUTPUT_DEBUG_PKG_PATH="$BUILD_DIR/osquery-debug-$APP_VERSION.pkg"
KERNEL_OUTPUT_PKG_PATH="$BUILD_DIR/osquery-kernel-${APP_VERSION}.pkg"
SIGNING_IDENTITY=""
SIGNING_IDENTITY_COMMAND=""
KEYCHAIN_IDENTITY=""
KEYCHAIN_IDENTITY_COMMAND=""
AUTOSTART=false
CLEAN=false
2015-01-08 02:55:14 +00:00
# Config files
LAUNCHD_SRC="$SCRIPT_DIR/$LD_IDENTIFIER.plist"
LAUNCHD_DST="/private/var/osquery/$LD_IDENTIFIER.plist"
2015-05-11 17:42:41 +00:00
NEWSYSLOG_SRC="$SCRIPT_DIR/$LD_IDENTIFIER.conf"
NEWSYSLOG_DST="/private/var/osquery/$LD_IDENTIFIER.conf"
PACKS_SRC="$SOURCE_DIR/packs"
PACKS_DST="/private/var/osquery/packs/"
LENSES_LICENSE="${OSQUERY_DEPS}/Cellar/augeas/*/COPYING"
LENSES_SRC="${OSQUERY_DEPS}/share/augeas/lenses/dist"
LENSES_DST="/private/var/osquery/lenses/"
2015-01-08 02:55:14 +00:00
OSQUERY_EXAMPLE_CONFIG_SRC="$SCRIPT_DIR/osquery.example.conf"
OSQUERY_EXAMPLE_CONFIG_DST="/private/var/osquery/osquery.example.conf"
2015-01-08 02:55:14 +00:00
OSQUERY_CONFIG_SRC=""
OSQUERY_CONFIG_DST="/private/var/osquery/osquery.conf"
OSQUERY_DB_LOCATION="/private/var/osquery/osquery.db/"
OSQUERY_LOG_DIR="/private/var/log/osquery/"
OSQUERY_TLS_CERT_CHAIN_BUILTIN_SRC="${OSQUERY_DEPS}/etc/openssl/cert.pem"
OSQUERY_TLS_CERT_CHAIN_BUILTIN_DST="/private/var/osquery/certs/certs.pem"
TLS_CERT_CHAIN_DST="/private/var/osquery/tls-server-certs.pem"
FLAGFILE_DST="/private/var/osquery/osquery.flags"
OSQUERY_PKG_INCLUDE_DIRS=()
2014-10-04 01:09:37 +00:00
WORKING_DIR=/tmp/osquery_packaging
INSTALL_PREFIX="$WORKING_DIR/prefix"
DEBUG_PREFIX="$WORKING_DIR/debug"
SCRIPT_ROOT="$WORKING_DIR/scripts"
PREINSTALL="$SCRIPT_ROOT/preinstall"
POSTINSTALL="$SCRIPT_ROOT/postinstall"
OSQUERYCTL_PATH="$SCRIPT_DIR/osqueryctl"
2014-10-04 01:09:37 +00:00
2015-07-13 19:24:58 +00:00
# Kernel extension identifiers and config files
KERNEL_INLINE=false
KERNEL_UNLOAD_SCRIPT="$SOURCE_DIR/kernel/tools/unload_with_retry.sh"
KERNEL_EXTENSION_IDENTIFIER="com.facebook.security.osquery"
KERNEL_EXTENSION_SRC="$BUILD_DIR/kernel/osquery.kext"
KERNEL_EXTENSION_DST="/Library/Extensions/osquery.kext"
KERNEL_WORKING_DIR=/tmp/osquery_kernel_packaging
KERNEL_INSTALL_PREFIX="$KERNEL_WORKING_DIR/prefix"
KERNEL_SCRIPT_ROOT="$KERNEL_WORKING_DIR/scripts"
KERNEL_PREINSTALL="$KERNEL_SCRIPT_ROOT/preinstall"
KERNEL_POSTINSTALL="$KERNEL_SCRIPT_ROOT/postinstall"
2015-07-13 19:24:58 +00:00
2014-10-04 01:09:37 +00:00
SCRIPT_PREFIX_TEXT="#!/usr/bin/env bash
set -e
"
POSTINSTALL_UNLOAD_TEXT="
if launchctl list | grep -qcm1 $LD_IDENTIFIER; then
2015-01-08 02:55:14 +00:00
launchctl unload $LD_INSTALL
2014-10-04 01:09:37 +00:00
fi
"
2015-07-13 19:24:58 +00:00
POSTINSTALL_AUTOSTART_TEXT="
cp $LAUNCHD_DST $LD_INSTALL
touch $FLAGFILE_DST
launchctl load $LD_INSTALL
2014-10-04 01:09:37 +00:00
"
2015-07-13 19:24:58 +00:00
KERNEL_POSTINSTALL_UNLOAD_TEXT="
./unload_with_retry.sh
"
2015-07-13 19:24:58 +00:00
KERNEL_POSTINSTALL_AUTOSTART_TEXT="
kextload $KERNEL_EXTENSION_DST
"
2014-10-04 01:09:37 +00:00
POSTINSTALL_CLEAN_TEXT="
rm -rf $OSQUERY_DB_LOCATION
"
2014-10-04 01:09:37 +00:00
function usage() {
2015-01-08 02:55:14 +00:00
fatal "Usage: $0 [-c path/to/your/osquery.conf] [-l path/to/osqueryd.plist]
2015-01-04 06:51:09 +00:00
-c PATH embed an osqueryd config.
2015-01-08 02:55:14 +00:00
-l PATH override the default launchd plist.
-t PATH to embed a certificate chain file for TLS server validation
2015-01-08 02:55:14 +00:00
-o PATH override the output path.
-a start the daemon when the package is installed
-x force the daemon to start fresh, removing any results previously stored in the database
2015-01-08 02:55:14 +00:00
This will generate an OSX package with:
(1) An example config /var/osquery/osquery.example.config
(2) An optional config /var/osquery/osquery.config if [-c] is used
(3) A LaunchDaemon plist /var/osquery/com.facebook.osqueryd.plist
2017-02-03 04:46:13 +00:00
(4) A default TLS certificate bundle (provided by cURL)
(5) The osquery toolset /usr/local/bin/osquery*
2015-01-08 02:55:14 +00:00
To enable osqueryd to run at boot using Launchd, pass the -a flag.
2015-01-08 02:55:14 +00:00
If the LaunchDaemon was previously installed a newer version of this package
will reload (unload/load) the daemon."
2014-10-04 01:09:37 +00:00
}
function parse_args() {
while [ "$1" != "" ]; do
case $1 in
-c | --config ) shift
2015-01-08 02:55:14 +00:00
OSQUERY_CONFIG_SRC=$1
2014-10-04 01:09:37 +00:00
;;
2015-01-08 02:55:14 +00:00
-l | --launchd ) shift
LAUNCHD_SRC=$1
;;
-t | --cert-chain ) shift
TLS_CERT_CHAIN_SRC=$1
;;
-i | --include-dir ) shift
OSQUERY_PKG_INCLUDE_DIRS[${#OSQUERY_PKG_INCLUDE_DIRS}]=$1
;;
2015-01-08 02:55:14 +00:00
-o | --output ) shift
OUTPUT_PKG_PATH=$1
2014-11-18 20:54:05 +00:00
;;
-s | --sign ) shift
SIGNING_IDENTITY=$1
SIGNING_IDENTITY_COMMAND="--sign "$1
;;
-k | --keychain ) shift
KEYCHAIN_IDENTITY=$1
KEYCHAIN_IDENTITY_COMMAND="--keychain "$1
;;
-a | --autostart ) AUTOSTART=true
;;
-x | --clean ) CLEAN=true
;;
2014-10-04 01:09:37 +00:00
-h | --help ) usage
;;
* ) usage
esac
shift
done
}
function check_parsed_args() {
2015-01-08 02:55:14 +00:00
if [[ $OSQUERY_CONFIG_SRC = "" ]]; then
log "notice: no config source specified"
else
log "using $OSQUERY_CONFIG_SRC as the config source"
2014-10-04 01:09:37 +00:00
fi
2015-01-08 02:55:14 +00:00
log "using $LAUNCHD_SRC as the launchd source"
2015-01-08 02:55:14 +00:00
if [ "$OSQUERY_CONFIG_SRC" != "" ] && [ ! -f $OSQUERY_CONFIG_SRC ]; then
log "$OSQUERY_CONFIG_SRC is not a file."
2014-10-04 01:09:37 +00:00
usage
fi
}
2014-10-03 20:29:46 +00:00
function main() {
2014-10-04 01:09:37 +00:00
parse_args $@
check_parsed_args
platform OS
if [[ ! "$OS" = "darwin" ]]; then
fatal "This script must be run on macOS"
fi
2015-07-13 19:24:58 +00:00
2014-10-04 01:09:37 +00:00
rm -rf $WORKING_DIR
rm -f $OUTPUT_PKG_PATH
mkdir -p $INSTALL_PREFIX
mkdir -p $SCRIPT_ROOT
# we don't need the preinstall for anything so let's skip it until we do
# echo "$SCRIPT_PREFIX_TEXT" > $PREINSTALL
# chmod +x $PREINSTALL
2014-10-04 01:09:37 +00:00
log "copying osquery binaries"
BINARY_INSTALL_DIR="$INSTALL_PREFIX/usr/local/bin/"
mkdir -p $BINARY_INSTALL_DIR
2014-12-04 17:33:04 +00:00
cp "$BUILD_DIR/osquery/osqueryd" $BINARY_INSTALL_DIR
ln -s osqueryd $BINARY_INSTALL_DIR/osqueryi
2015-01-08 23:53:51 +00:00
strip $BINARY_INSTALL_DIR/*
2015-02-24 20:27:06 +00:00
cp "$OSQUERYCTL_PATH" $BINARY_INSTALL_DIR
2015-01-08 02:55:14 +00:00
if [[ ! "$SIGNING_IDENTITY" = "" ]]; then
log "signing release binaries"
codesign -s $SIGNING_IDENTITY --keychain \"$KEYCHAIN_IDENTITY\" $BINARY_INSTALL_DIR/osqueryd
fi
BINARY_DEBUG_DIR="$DEBUG_PREFIX/private/var/osquery/debug"
mkdir -p "$BINARY_DEBUG_DIR"
cp "$BUILD_DIR/osquery/osqueryd" $BINARY_DEBUG_DIR/osqueryd.debug
ln -s osqueryd.debug $BINARY_DEBUG_DIR/osqueryi.debug
# Create the prefix log dir and copy source configs.
2014-10-04 01:09:37 +00:00
mkdir -p $INSTALL_PREFIX/$OSQUERY_LOG_DIR
2015-01-08 02:55:14 +00:00
mkdir -p `dirname $INSTALL_PREFIX$OSQUERY_CONFIG_DST`
if [[ "$OSQUERY_CONFIG_SRC" != "" ]]; then
cp $OSQUERY_CONFIG_SRC $INSTALL_PREFIX$OSQUERY_CONFIG_DST
fi
2014-10-04 01:09:37 +00:00
# Move configurations into the packaging root.
2014-10-04 01:09:37 +00:00
log "copying osquery configurations"
2015-01-08 02:55:14 +00:00
mkdir -p `dirname $INSTALL_PREFIX$LAUNCHD_DST`
mkdir -p $INSTALL_PREFIX$PACKS_DST
mkdir -p $INSTALL_PREFIX$LENSES_DST
2015-01-08 02:55:14 +00:00
cp $LAUNCHD_SRC $INSTALL_PREFIX$LAUNCHD_DST
2015-05-11 17:42:41 +00:00
cp $NEWSYSLOG_SRC $INSTALL_PREFIX$NEWSYSLOG_DST
2015-01-08 02:55:14 +00:00
cp $OSQUERY_EXAMPLE_CONFIG_SRC $INSTALL_PREFIX$OSQUERY_EXAMPLE_CONFIG_DST
cp $PACKS_SRC/* $INSTALL_PREFIX$PACKS_DST
cp $LENSES_LICENSE $INSTALL_PREFIX/$LENSES_DST
cp $LENSES_SRC/*.aug $INSTALL_PREFIX$LENSES_DST
if [[ "$TLS_CERT_CHAIN_SRC" != "" && -f "$TLS_CERT_CHAIN_SRC" ]]; then
cp $TLS_CERT_CHAIN_SRC $INSTALL_PREFIX$TLS_CERT_CHAIN_DST
fi
2017-02-03 04:46:13 +00:00
if [[ $OSQUERY_TLS_CERT_CHAIN_BUILTIN_SRC != "" ]] && [[ -f $OSQUERY_TLS_CERT_CHAIN_BUILTIN_SRC ]]; then
mkdir -p `dirname $INSTALL_PREFIX/$OSQUERY_TLS_CERT_CHAIN_BUILTIN_DST`
cp $OSQUERY_TLS_CERT_CHAIN_BUILTIN_SRC $INSTALL_PREFIX/$OSQUERY_TLS_CERT_CHAIN_BUILTIN_DST
fi
# Move/install pre/post install scripts within the packaging root.
2014-10-04 01:09:37 +00:00
log "finalizing preinstall and postinstall scripts"
if [ $AUTOSTART == true ] || [ $CLEAN == true ]; then
echo "$SCRIPT_PREFIX_TEXT" > $POSTINSTALL
chmod +x $POSTINSTALL
if [ $CLEAN == true ]; then
echo "$POSTINSTALL_CLEAN_TEXT" >> $POSTINSTALL
fi
if [ $AUTOSTART == true ]; then
echo "$POSTINSTALL_UNLOAD_TEXT" >> $POSTINSTALL
echo "$POSTINSTALL_AUTOSTART_TEXT" >> $POSTINSTALL
fi
fi
# Copy extra files to the install prefix so that they get packaged too.
# NOTE: Files will be overwritten.
for include_dir in ${OSQUERY_PKG_INCLUDE_DIRS[*]}; do
log "adding $include_dir in the package prefix to be included in the package"
cp -fR $include_dir/* $INSTALL_PREFIX/
done
if [[ ! "$SIGNING_IDENTITY" = "" ]]; then
log "creating signed release package"
else
log "creating package"
fi
2014-10-04 01:09:37 +00:00
pkgbuild --root $INSTALL_PREFIX \
--scripts $SCRIPT_ROOT \
--identifier $APP_IDENTIFIER \
--version $APP_VERSION \
$SIGNING_IDENTITY_COMMAND \
$KEYCHAIN_IDENTITY_COMMAND \
2014-10-04 01:09:37 +00:00
$OUTPUT_PKG_PATH 2>&1 1>/dev/null
log "package created at $OUTPUT_PKG_PATH"
2015-07-13 19:24:58 +00:00
log "creating debug package"
pkgbuild --root $DEBUG_PREFIX \
--identifier $APP_IDENTIFIER.debug \
--version $APP_VERSION \
$OUTPUT_DEBUG_PKG_PATH 2>&1 1>/dev/null
log "package created at $OUTPUT_DEBUG_PKG_PATH"
# We optionally create an RPM equivalent.
FPM=$(which fpm || true)
RPMBUILD=$(which rpmbuild || true)
if [[ ! "$FPM" = "" && ! "$RPMBUILD" = "" ]]; then
rm -f "$OUTPUT_RPM_PATH"
log "creating RPM equivalent"
# Yes, RPMs on OS X like i386 as the arch.
PACKAGE_ARCH=i386
PACKAGE_ITERATION="1.darwin"
RPM_APP_VERSION=$(echo ${APP_VERSION}|tr '-' '_')
OUTPUT_RPM_PATH="$BUILD_DIR/osquery-$RPM_APP_VERSION-$PACKAGE_ITERATION.$PACKAGE_ARCH.rpm"
rm -f $OUTPUT_RPM_PATH
CMD="$FPM -s dir -t rpm \
-n osquery \
-v $RPM_APP_VERSION \
--iteration $PACKAGE_ITERATION -a $PACKAGE_ARCH \
-p $OUTPUT_RPM_PATH \
--url https://osquery.io -m osquery@osquery.io \
--vendor Facebook --license BSD \
\"$INSTALL_PREFIX/=/\""
eval "$CMD"
log "RPM package (also) created at $OUTPUT_RPM_PATH"
OUTPUT_DEBUG_RPM_PATH="$BUILD_DIR/osquery-debug-$RPM_APP_VERSION-$PACKAGE_ITERATION.$PACKAGE_ARCH.rpm"
rm -f $OUTPUT_DEBUG_RPM_PATH
CMD="$FPM -s dir -t rpm \
-n osquery-debug \
-v $RPM_APP_VERSION \
--iteration $PACKAGE_ITERATION -a $PACKAGE_ARCH \
-p $OUTPUT_DEBUG_RPM_PATH \
--url https://osquery.io -m osquery@osquery.io \
--vendor Facebook --license BSD \
\"$DEBUG_PREFIX/=/\""
eval "$CMD"
log "RPM package (also) created at $OUTPUT_DEBUG_RPM_PATH"
else
log "Skipping OS X RPM package build: Cannot find fpm and rpmbuild"
fi
2015-07-13 19:24:58 +00:00
# Check if a kernel extension should be built alongside.
if [[ -d "$KERNEL_EXTENSION_SRC" ]]; then
rm -rf $KERNEL_WORKING_DIR
rm -f $KERNEL_OUTPUT_PKG_PATH
mkdir -p $KERNEL_INSTALL_PREFIX
mkdir -p $KERNEL_SCRIPT_ROOT
log "copying osquery kernel bundles"
mkdir -p $KERNEL_INSTALL_PREFIX$KERNEL_EXTENSION_DST
cp -R $KERNEL_EXTENSION_SRC/ $KERNEL_INSTALL_PREFIX$KERNEL_EXTENSION_DST
log "finalizing kernel preinstall and postinstall scripts"
if [ $AUTOSTART == true ]; then
echo "$SCRIPT_PREFIX_TEXT" > $KERNEL_POSTINSTALL
chmod +x $KERNEL_POSTINSTALL
# Install the normal post install unload to unload the daemons.
echo "$POSTINSTALL_UNLOAD_TEXT" >> $KERNEL_POSTINSTALL
# Handler kernel extension unloading/reloading.
cp $KERNEL_UNLOAD_SCRIPT $KERNEL_SCRIPT_ROOT
echo "$KERNEL_POSTINSTALL_UNLOAD_TEXT" >> $KERNEL_POSTINSTALL
echo "$KERNEL_POSTINSTALL_AUTOSTART_TEXT" >> $KERNEL_POSTINSTALL
# Install the normal post install reload to reload daemons.
echo "$POSTINSTALL_AUTOSTART_TEXT" >> $KERNEL_POSTINSTALL
fi
log "creating kernel package"
pkgbuild --root $KERNEL_INSTALL_PREFIX \
--scripts $KERNEL_SCRIPT_ROOT \
--identifier $KERNEL_APP_IDENTIFIER \
--version ${APP_VERSION} \
2015-07-13 19:24:58 +00:00
$KERNEL_OUTPUT_PKG_PATH 2>&1 1>/dev/null
log "kernel package created at $KERNEL_OUTPUT_PKG_PATH"
else
log "skipping kernel package, no kext found"
2015-07-13 19:24:58 +00:00
fi
}
2014-10-04 01:09:37 +00:00
main $@