scripts/tar.lxc-apparmor-profiles

299 lines
7.0 KiB
Bash
Executable File

#!/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