Merge pull request #78 from cedwards/template_work

template validation improvements
This commit is contained in:
Christer Edwards
2019-12-07 17:57:03 -07:00
committed by GitHub
4 changed files with 186 additions and 144 deletions

View File

@@ -1,9 +1,9 @@
Bastille: Automated Container Security
======================================
Bastille is an open-source system for automating deployment and management of
containerized applications on FreeBSD.
Bastille: Automate Container Security
=====================================
[Bastille](https://bastillebsd.org/) is an open-source system for automating
deployment and management of containerized applications on FreeBSD.
Looking for [Bastille Templates](https://gitlab.com/BastilleBSD-Templates)?
Looking for [Bastille Templates](https://gitlab.com/BastilleBSD-Templates/)?
Installation
@@ -557,9 +557,9 @@ To leverage a template hook, create an UPPERCASE file in the root of the
template directory named after the hook you want to execute. eg;
```shell
echo "install zsh vim-console git-lite htop" > /usr/local/bastille/templates/base/PKG
echo "/usr/bin/chsh -s /usr/local/bin/zsh" > /usr/local/bastille/templates/base/CMD
echo "etc\nroot\nusr" > /usr/local/bastille/templates/base/OVERLAY
echo "zsh vim-console git-lite htop" > /usr/local/bastille/templates/username/base/PKG
echo "/usr/bin/chsh -s /usr/local/bin/zsh" > /usr/local/bastille/templates/username/base/CMD
echo "usr" > /usr/local/bastille/templates/username/base/OVERLAY
```
Template hooks are executed in specific order and require specific syntax to

View File

@@ -360,74 +360,21 @@ bootstrap_template() {
_template=${bastille_templatesdir}/${_user}/${_repo}
## support for non-git
if [ ! -x /usr/local/bin/git ]; then
echo -e "${COLOR_RED}We're gonna have to use fetch. Strap in.${COLOR_RESET}"
echo -e "${COLOR_RED}Not yet implemented...${COLOR_RESET}"
if [ ! -x $(which git) ]; then
echo -e "${COLOR_RED}Git not found.${COLOR_RESET}"
echo -e "${COLOR_RED}Not yet implemented.${COLOR_RESET}"
exit 1
fi
## support for git
if [ -x /usr/local/bin/git ]; then
elif [ -x $(which git) ]; then
if [ ! -d "${_template}/.git" ]; then
/usr/local/bin/git clone "${_url}" "${_template}" ||\
$(which git) clone "${_url}" "${_template}" ||\
echo -e "${COLOR_RED}Clone unsuccessful.${COLOR_RESET}"
echo
elif [ -d "${_template}/.git" ]; then
cd ${_template} &&
/usr/local/bin/git pull ||\
cd ${_template} && $(which git) pull ||\
echo -e "${COLOR_RED}Template update unsuccessful.${COLOR_RESET}"
echo
fi
fi
## template validation
_hook_validate=0
for _hook in PRE FSTAB PF PKG SYSRC CMD; do
if [ -s ${_template}/${_hook} ]; then
_hook_validate=$((_hook_validate+1))
echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}"
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
cat "${_template}/${_hook}"
echo
fi
done
# template overlay
if [ -s ${_template}/OVERLAY ]; then
_hook_validate=$((_hook_validate+1))
echo -e "${COLOR_GREEN}Detected OVERLAY hook.${COLOR_RESET}"
while read _dir; do
echo -e "${COLOR_GREEN}[${_dir}]:${COLOR_RESET}"
if [ -x $(which tree) ]; then
tree -a ${_template}/${_dir}
fi
done < ${_template}/OVERLAY
echo
fi
if [ -s ${_template}/CONFIG ]; then
echo -e "${COLOR_GREEN}Detected CONFIG hook.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}CONFIG deprecated; rename to OVERLAY.${COLOR_RESET}"
while read _dir; do
echo -e "${COLOR_GREEN}[${_dir}]:${COLOR_RESET}"
if [ -x $(which tree) ]; then
tree -a ${_template}/${_dir}
fi
done < ${_template}/CONFIG
fi
## remove bad templates
if [ ${_hook_validate} -lt 1 ]; then
echo -e "${COLOR_GREEN}Template validation failed.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Deleting template.${COLOR_RESET}"
rm -rf ${_template}
exit 1
fi
## if validated; ready to use
if [ ${_hook_validate} -gt 0 ]; then
echo -e "${COLOR_GREEN}Template ready to use.${COLOR_RESET}"
echo
fi
bastille verify ${_user}/${_repo}
}
HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }')
@@ -486,8 +433,6 @@ http?://github.com/*/*|http?://gitlab.com/*/*)
BASTILLE_TEMPLATE_URL=${1}
BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }')
BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }')
echo -e "${COLOR_GREEN}Template: ${1}${COLOR_RESET}"
echo
bootstrap_template
;;
network)

View File

@@ -31,7 +31,7 @@
. /usr/local/share/bastille/colors.pre.sh
. /usr/local/etc/bastille/bastille.conf
usage() {
bastille_usage() {
echo -e "${COLOR_RED}Usage: bastille template TARGET project/template.${COLOR_RESET}"
exit 1
}
@@ -39,12 +39,12 @@ usage() {
# Handle special-case commands first.
case "$1" in
help|-h|--help)
usage
bastille_usage
;;
esac
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
usage
bastille_usage
fi
TARGET="${1}"
@@ -60,24 +60,13 @@ fi
TEMPLATE="${1}"
shift
if [ ! -d "${bastille_templatesdir}"/"${TEMPLATE}" ]; then
if [ ! -d "${bastille_templatesdir}/${TEMPLATE}" ]; then
echo -e "${COLOR_RED}${TEMPLATE} not found.${COLOR_RESET}"
exit 1
fi
## global variables
bastille_template=${bastille_templatesdir}/${TEMPLATE}
bastille_template_TARGET=${bastille_template}/TARGET
bastille_template_INCLUDE=${bastille_template}/INCLUDE
bastille_template_PRE=${bastille_template}/PRE
bastille_template_OVERLAY=${bastille_template}/OVERLAY
bastille_template_FSTAB=${bastille_template}/FSTAB
bastille_template_PF=${bastille_template}/PF
bastille_template_PKG=${bastille_template}/PKG
bastille_template_SYSRC=${bastille_template}/SYSRC
bastille_template_SERVICE=${bastille_template}/SERVICE
bastille_template_CMD=${bastille_template}/CMD
for _jail in ${JAILS}; do
## jail-specific variables.
bastille_jail_path=$(jls -j "${_jail}" path)
@@ -85,52 +74,86 @@ for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
## TARGET
if [ -s "${bastille_template_TARGET}" ]; then
if [ $(grep -w "${_jail}" ${bastille_template_TARGET}) ]; then
if [ -s "${bastille_template}/TARGET" ]; then
if [ $(grep -w "${_jail}" ${bastille_template}/TARGET) ]; then
echo -e "${COLOR_GREEN}TARGET: !${_jail}.${COLOR_RESET}"
echo
echo
continue
fi
if [ ! $(grep -E "(^|\b)(${_jail}|ALL)($|\b)" ${bastille_template_TARGET}) ]; then
if [ ! $(grep -E "(^|\b)(${_jail}|ALL)($|\b)" ${bastille_template}/TARGET) ]; then
echo -e "${COLOR_GREEN}TARGET: ?${_jail}.${COLOR_RESET}"
echo
echo
continue
fi
fi
## INCLUDE
if [ -s "${bastille_template_INCLUDE}" ]; then
if [ -s "${bastille_template}/INCLUDE" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- START${COLOR_RESET}"
while read _include; do
echo
echo -e "${COLOR_GREEN}INCLUDE: ${_include}${COLOR_RESET}"
echo -e "${COLOR_GREEN}Bootstrapping ${_include}...${COLOR_RESET}"
bastille bootstrap ${_include}
case ${_include} in
http?://github.com/*/*|http?://gitlab.com/*/*)
bastille bootstrap ${_include}
;;
*/*)
BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }')
bastille template ${_jail} ${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}
;;
*)
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
exit 1
;;
esac
echo
echo -e "${COLOR_GREEN}Applying ${_include}...${COLOR_RESET}"
BASTILLE_TEMPLATE_PROJECT=$(echo "${_include}" | awk -F / '{ print $4}')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $5}')
bastille template ${_jail} ${BASTILLE_TEMPLATE_PROJECT}/${BASTILLE_TEMPLATE_REPO}
done < "${bastille_template_INCLUDE}"
done < "${bastille_template}/INCLUDE"
echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- END${COLOR_RESET}"
echo
fi
## PRE
if [ -s "${bastille_template_PRE}" ]; then
if [ -s "${bastille_template}/PRE" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:PRE -- START${COLOR_RESET}"
jexec -l ${_jail} /bin/sh < "${bastille_template_PRE}" || exit 1
jexec -l ${_jail} /bin/sh < "${bastille_template}/PRE" || exit 1
echo -e "${COLOR_GREEN}[${_jail}]:PRE -- END${COLOR_RESET}"
echo
fi
## FSTAB
if [ -s "${bastille_template}/FSTAB" ]; then
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
fi
## PF
if [ -s "${bastille_template}/PF" ]; then
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
fi
## PKG (bootstrap + pkg)
if [ -s "${bastille_template}/PKG" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- START${COLOR_RESET}"
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg bootstrap || exit 1
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install $(cat ${bastille_template}/PKG) || exit 1
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg audit -F
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- END${COLOR_RESET}"
echo
fi
## CONFIG / OVERLAY
if [ -s "${bastille_template_OVERLAY}" ]; then
if [ -s "${bastille_template}/OVERLAY" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- START${COLOR_RESET}"
while read _dir; do
cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1
done < ${bastille_template_OVERLAY}
done < ${bastille_template}/OVERLAY
echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- END${COLOR_RESET}"
echo
fi
@@ -144,54 +167,30 @@ for _jail in ${JAILS}; do
echo
fi
## FSTAB
if [ -s "${bastille_template_FSTAB}" ]; then
bastille_templatefstab=$(cat "${bastille_template_FSTAB}")
echo -e "${COLOR_GREEN}Updating fstab.${COLOR_RESET}"
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
fi
## PF
if [ -s "${bastille_template_PF}" ]; then
bastille_templatepf=$(cat "${bastille_template_PF}")
echo -e "${COLOR_GREEN}Generating PF profile.${COLOR_RESET}"
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
fi
## PKG (bootstrap + pkg)
if [ -s "${bastille_template_PKG}" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- START${COLOR_RESET}"
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg bootstrap || exit 1
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg audit -F
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install $(cat ${bastille_template_PKG}) || exit 1
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- END${COLOR_RESET}"
echo
fi
## SYSRC
if [ -s "${bastille_template_SYSRC}" ]; then
if [ -s "${bastille_template}/SYSRC" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- START${COLOR_RESET}"
while read _sysrc; do
jexec -l ${_jail} /usr/sbin/sysrc "${_sysrc}" || exit 1
done < "${bastille_template_SYSRC}"
done < "${bastille_template}/SYSRC"
echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- END${COLOR_RESET}"
echo
fi
## SERVICE
if [ -s "${bastille_template_SERVICE}" ]; then
if [ -s "${bastille_template}/SERVICE" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- START${COLOR_RESET}"
while read _service; do
jexec -l ${_jail} /usr/sbin/service ${_service} || exit 1
done < "${bastille_template_SERVICE}"
done < "${bastille_template}/SERVICE"
echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- END${COLOR_RESET}"
echo
fi
## CMD
if [ -s "${bastille_template_CMD}" ]; then
if [ -s "${bastille_template}/CMD" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:CMD -- START${COLOR_RESET}"
jexec -l ${_jail} /bin/sh < "${bastille_template_CMD}" || exit 1
jexec -l ${_jail} /bin/sh < "${bastille_template}/CMD" || exit 1
echo -e "${COLOR_GREEN}[${_jail}]:CMD -- END${COLOR_RESET}"
echo
fi

View File

@@ -31,32 +31,130 @@
. /usr/local/share/bastille/colors.pre.sh
. /usr/local/etc/bastille/bastille.conf
usage() {
echo -e "${COLOR_RED}Usage: bastille verify release.${COLOR_RESET}"
bastille_usage() {
echo -e "${COLOR_RED}Usage: bastille verify [release|template].${COLOR_RESET}"
exit 1
}
verify_release() {
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1
fi
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" --currently-running ${RELEASE} IDS
else
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
exit 1
fi
}
verify_template() {
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
_hook_validate=0
for _hook in TARGET INCLUDE PRE OVERLAY FSTAB PF PKG SYSRC SERVICE CMD; do
_path=${_template_path}/${_hook}
if [ -s ${_path} ]; then
_hook_validate=$((_hook_validate+1))
echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}"
## line count must match newline count
if [ $(wc -l ${_path} | awk '{print $1}') -ne $(grep -c $'\n' ${_path}) ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
echo -e "${COLOR_RED}${BASTILLE_TEMPLATE}:${_hook} [failed].${COLOR_RESET}"
echo -e "${COLOR_RED}Line numbers don't match line breaks.${COLOR_RESET}"
echo
echo -e "${COLOR_RED}Template validation failed.${COLOR_RESET}"
exit 1
## if INCLUDE; recursive verify
elif [ ${_hook} = 'INCLUDE' ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
cat "${_path}"
echo
while read _include; do
echo -e "${COLOR_GREEN}[${_hook}]:[${_include}]:${COLOR_RESET}"
case ${_include} in
http?://github.com/*/*|http?://gitlab.com/*/*)
bastille bootstrap ${_include}
;;
*/*)
BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }')
bastille verify ${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}
;;
*)
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
exit 1
;;
esac
done < ${_path}
## if tree; tree -a bastille_template/_dir
elif [ ${_hook} = 'OVERLAY' ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
cat "${_path}"
echo
while read _dir; do
if [ -x /usr/local/bin/tree ]; then
echo -e "${COLOR_GREEN}[${_hook}]:[${_dir}]:${COLOR_RESET}"
tree -a ${_template_path}/${_dir}
echo
fi
done < ${_path}
else
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
cat "${_path}"
echo
fi
fi
done
## remove bad templates
if [ ${_hook_validate} -lt 1 ]; then
echo -e "${COLOR_RED}No valid template hooks found.${COLOR_RESET}"
echo -e "${COLOR_RED}Template discarded.${COLOR_RESET}"
rm -rf ${bastille_template}
exit 1
fi
## if validated; ready to use
if [ ${_hook_validate} -gt 0 ]; then
echo -e "${COLOR_GREEN}Template ready to use.${COLOR_RESET}"
fi
}
# Handle special-case commands first.
case "$1" in
help|-h|--help)
usage
bastille_usage
;;
esac
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
usage
bastille_usage
fi
RELEASE=$1
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1
fi
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" IDS
else
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
exit 1
fi
case "$1" in
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
RELEASE=$1
verify_release
;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
RELEASE=$1
verify_release
;;
http?*)
bastille_usage
;;
*/*)
BASTILLE_TEMPLATE=$1
verify_template
;;
*)
bastille_usage
;;
esac