#!/usr/bin/env bash # # This script will tar lxc-pve AppArmor profiles and # upload archive to remote download server. # # Path to auth file that contains username and password. # Example # username=authuser # password=authpw auth_file=$HOME/.tar.lxc-apparmor-profiles.authfile # Do not edit anything below this line set -e _curl_opts='--silent' _wget_opts='--quiet' _ssh_opts='-q' if [ -n $DEBUG ] && [[ $DEBUG -ge 2 ]]; then set -x _tar_opts='-v' _curl_opts='--show-error --verbose' _wget_opts='--verbose' _ssh_opts='-vv' fi function debug { if test -n "$DEBUG"; then echo "[DEBUG] $1" fi } function cleanup { debug "Cleaning up temporary directory..." if test -d $_tmp_dir; then rm -r $_tmp_dir fi } function getfilehash { echo $(sha256sum $1|awk '{print $1}') } function _wget { wget $_wget_opts $1 2> /dev/null || true } function httpdownload { _wget $_dl_filedir/$_dl_filename _wget $_dl_filedir/$_dl_filesha256 if test ! -f $_dl_filename && test ! -f $_dl_filename.sha256; then echo "ERROR: Failed to download files"; exit 1; fi # TODO: rename $_dl_filename to $_tar_filename _file_hash=$(getfilehash $_dl_filename) _remote_hash=$(cat $_dl_filename.sha256) if [ $_file_hash != $_remote_hash ]; then echo "Downloaded file corrupted!" exit 1 fi } if test -n "$TESTING"; then _dl_server=http://localhost:8080 else # This is a temporary location, perhaps # permanent. dl.lhprojects.net is not configured # to execute PHP scripts _dl_server=https://www.lhprojects.net fi _tar_filename=apparmor-profiles.tgz _dl_scriptname=handleLXCAppArmorProfiles.php _dl_filedir=$_dl_server/apparmor _dl_filename=$_tar_filename _rsync_server=pve1.lhprojects.int _tmp_dir=/tmp/.tar.lxc-apparmor-profiles _rsync_user=apparmor_rsync _remote_script_path=/usr/local/bin/tar.lxc-apparmor-profiles function usage { echo "Usage: ${0}" echo "This script can upload an archive of LXC AppArmor profiles to a remote HTTP" echo "server via handleLXCAppArmorProfiles.php. Alternatively, you can use --download-scp." echo "" echo " --download" echo " Download and extract archive using http via handleLXCAppArmorProfiles.php" echo " NOTE: You need to upload the archive to a middleman HTTP server prior to using --download." echo " --download-scp" echo " Same as above however use scp for file transfer." echo " NOTE: the remote SSH server must have $_remote_script_path installed" echo " --download-test" echo " Same as --download, but extract in temp directory" echo " -h | --help" echo " Show this usage" exit 0 } # We going to attempt to create a tmp dir # and set the _tmp_dir variable if test -d $_tmp_dir && test ! -O $_tmp_dir; then debug "ERROR: We don't own $_tmp_dir!" _old_tmp_dir=$_tmp_dir for i in {1..5}; do __tmp_dir=$_tmp_dir$i if test -d $__tmp_dir && test -O $__tmp_dir || test ! -d $__tmp_dir; then debug "Setting _tmp_dir to '$__tmp_dir'" _tmp_dir=$__tmp_dir break fi done if [[ $_tmp_dir = $_old_tmp_dir ]]; then echo "ERROR: Unable to set a tmp dir" exit 1 fi fi _staging_dir=$_tmp_dir/stg case "$1" in -h | --help ) usage ;; --download | --download-scp) cleanup mkdir -p $_staging_dir cd $_tmp_dir if [ $1 = '--download-scp' ]; then echo "Archiving remote AppArmor profiles..." _result=$(ssh $_ssh_opts $_rsync_user@$_rsync_server || true) if [[ $_result != '200 OK' ]]; then echo "ERROR: Something went wrong: REMOTE $_result" cleanup exit 1 fi echo "Downloading archive..." scp $_ssh_opts $_rsync_user@$_rsync_server:$_tar_filename . scp $_ssh_opts $_rsync_user@$_rsync_server:$_tar_filename.sha256 . if test ! -f $_tar_filename && test ! -f $_tar_filename.sha256; then echo "ERROR: Failed to download files"; exit 1; fi _file_hash=$(getfilehash $_tar_filename) _remote_hash=$(cat $_tar_filename.sha256) if [ $_file_hash != $_remote_hash ]; then echo "Downloaded file corrupted!" exit 1 fi else httpdownload fi echo "Extracting archive..." cd / tar $_tar_opts -xf $_tmp_dir/$_dl_filename . cleanup exit 0 ;; --download-test ) echo "This is only a download test and archive extract" cleanup mkdir -p $_staging_dir cd $_tmp_dir httpdownload cd $_staging_dir tar $_tar_opts -xf ../$_dl_filename . echo "Download test completed successfully" cleanup exit 0 ;; * ) # Check if running under a SSH connection if [ -n "$SSH_CLIENT" ] && [ -z "$1" ] && [ $USER != 'root' ]; then echo "Running from SSH connection and no command arguments given" echo "Exiting" exit 1 fi # Init _tar_file=$_tmp_dir/$_tar_filename _user_home=$(eval echo "~$_rsync_user") _scp_remote=0 if test -n "$1" && [ $1 = '--scp-remote' ]; then debug "Remote SCP enabled, not uploading..." _scp_remote=1 # Determine if we need to run scp instead case "$SSH_ORIGINAL_COMMAND" in "scp -f $_tar_filename" | "scp -f $_tar_filename" | "scp -f $_tar_filename.sha256" | "scp -v -f $_tar_filename.sha256" ) cd $_user_home # Replace script with scp command eval "$SSH_ORIGINAL_COMMAND" exit 0 ;; esac fi cleanup mkdir -p $_staging_dir debug "Copying AppArmor profiles over to tmp dir..." read -r -d '' _profile_files <<- EOF || true /etc/apparmor.d /etc/apparmor.d/abstractions /etc/apparmor.d/abstractions/lxc /etc/apparmor.d/abstractions/lxc/container-base /etc/apparmor.d/abstractions/lxc/start-container /etc/apparmor.d/lxc /etc/apparmor.d/lxc/lxc-default /etc/apparmor.d/lxc/lxc-default-cgns /etc/apparmor.d/lxc/lxc-default-with-mounting /etc/apparmor.d/lxc/lxc-default-with-nesting /etc/apparmor.d/lxc-containers EOF # Read file list while read -r file; do if test -d $file; then _dest=$_staging_dir/.$file debug "Creating directory: $_dest" mkdir -p $_dest elif test -f $file then _src=$file _dest=$_staging_dir/.$file debug "Copying: $_src to $_dest" cp $_src $_dest fi done <<< "$_profile_files" debug "Changing directory to $_tmp_dir" cd $_staging_dir if [ $PWD != $_staging_dir ]; then echo "Failed to change directory!" exit 1 fi # Tar files tar $_tar_opts -czf $_tar_file . # Get file hash _file_hash=$(getfilehash $_tar_file) if [ $_scp_remote -ne 0 ]; then debug "Moving: $_tar_file to $_user_home" mv -f $_tar_file $_user_home/ echo $_file_hash > $_user_home/$_tar_filename.sha256 echo "200 OK" cleanup exit 0 elif test -n "$1"; then echo "ERROR: Invalid argument: $1" cleanup exit 1 fi # Get auth creds if test ! -f $auth_file; then echo "ERROR: Auth file '$auth_file' not found!" cleanup exit 1 fi source $auth_file _result=$(curl $_curl_opts -H 'X-AppArmor-State: ProcessUpload' -H "X-Tar-Hash: $_file_hash" -F "apparmor-profiles=@$_tmp_dir/$_tar_filename" --user "$username:$password" $_dl_server/$_dl_scriptname) if [[ $_results = '200 OK' ]]; then echo 'Successfully uploaded archive!' else echo "Something went wrong: $_result" fi ;; esac