mirror of
https://github.com/hackacad/bastille.git
synced 2025-12-23 18:50:46 +01:00
Initial support for clone jails
This commit is contained in:
@@ -57,5 +57,6 @@ bastille_network_gateway6="" ## default
|
|||||||
bastille_template_base="default/base" ## default: "default/base"
|
bastille_template_base="default/base" ## default: "default/base"
|
||||||
bastille_template_empty="" ## default: "default/empty"
|
bastille_template_empty="" ## default: "default/empty"
|
||||||
bastille_template_thick="default/thick" ## default: "default/thick"
|
bastille_template_thick="default/thick" ## default: "default/thick"
|
||||||
|
bastille_template_clone="default/clone" ## default: "default/clone"
|
||||||
bastille_template_thin="default/thin" ## default: "default/thin"
|
bastille_template_thin="default/thin" ## default: "default/thin"
|
||||||
bastille_template_vnet="default/vnet" ## default: "default/vnet"
|
bastille_template_vnet="default/vnet" ## default: "default/vnet"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
|
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,6 +43,7 @@ usage() {
|
|||||||
-L | --linux -- This option is intended for testing with Linux jails, this is considered experimental.
|
-L | --linux -- This option is intended for testing with Linux jails, this is considered experimental.
|
||||||
-T | --thick -- Creates a thick container, they consume more space as they are self contained and independent.
|
-T | --thick -- Creates a thick container, they consume more space as they are self contained and independent.
|
||||||
-V | --vnet -- Enables VNET, VNET containers are attached to a virtual bridge interface for connectivity.
|
-V | --vnet -- Enables VNET, VNET containers are attached to a virtual bridge interface for connectivity.
|
||||||
|
-C | --clone -- Creates a clone container, they are duplicates of the base release, consume low space and preserves changing data.
|
||||||
-B | --bridge -- Enables VNET, VNET containers are attached to a specified, already existing external bridge.
|
-B | --bridge -- Enables VNET, VNET containers are attached to a specified, already existing external bridge.
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@@ -205,6 +206,43 @@ ${NETBLOCK}
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
post_create_jail() {
|
||||||
|
# Common config checks and settings.
|
||||||
|
|
||||||
|
# Using relative paths here.
|
||||||
|
# MAKE SURE WE'RE IN THE RIGHT PLACE.
|
||||||
|
cd "${bastille_jail_path}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ ! -f "${bastille_jail_conf}" ]; then
|
||||||
|
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
|
||||||
|
local bastille_jail_conf_interface=${bastille_network_shared}
|
||||||
|
fi
|
||||||
|
if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then
|
||||||
|
local bastille_jail_conf_interface=${bastille_network_loopback}
|
||||||
|
fi
|
||||||
|
if [ -n "${INTERFACE}" ]; then
|
||||||
|
local bastille_jail_conf_interface=${INTERFACE}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${bastille_jail_fstab}" ]; then
|
||||||
|
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||||
|
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
|
||||||
|
else
|
||||||
|
touch "${bastille_jail_fstab}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate the jail configuration file.
|
||||||
|
if [ -n "${VNET_JAIL}" ]; then
|
||||||
|
generate_vnet_jail_conf
|
||||||
|
else
|
||||||
|
generate_jail_conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
create_jail() {
|
create_jail() {
|
||||||
bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir
|
bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir
|
||||||
bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir
|
bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir
|
||||||
@@ -219,8 +257,10 @@ create_jail() {
|
|||||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||||
## create required zfs datasets, mountpoint inherited from system
|
## create required zfs datasets, mountpoint inherited from system
|
||||||
|
if [ -z "${CLONE_JAIL}" ]; then
|
||||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}"
|
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}"
|
||||||
if [ -z "${THICK_JAIL}" ]; then
|
fi
|
||||||
|
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
|
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -228,8 +268,10 @@ create_jail() {
|
|||||||
mkdir -p "${bastille_jailsdir}/${NAME}/root"
|
mkdir -p "${bastille_jailsdir}/${NAME}/root"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## PoC for Linux jails @hackacad
|
## PoC for Linux jails @hackacad
|
||||||
if [ -n "${LINUX_JAIL}" ]; then
|
if [ -n "${LINUX_JAIL}" ]; then
|
||||||
|
info "\nCreating a linuxjail. This may take a while...\n"
|
||||||
if [ ! -d "${bastille_jail_base}" ]; then
|
if [ ! -d "${bastille_jail_base}" ]; then
|
||||||
mkdir -p "${bastille_jail_base}"
|
mkdir -p "${bastille_jail_base}"
|
||||||
fi
|
fi
|
||||||
@@ -273,55 +315,29 @@ create_jail() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then
|
if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then
|
||||||
|
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||||
if [ ! -d "${bastille_jail_base}" ]; then
|
if [ ! -d "${bastille_jail_base}" ]; then
|
||||||
mkdir -p "${bastille_jail_base}"
|
mkdir -p "${bastille_jail_base}"
|
||||||
fi
|
fi
|
||||||
|
if [ ! -d "${bastille_jail_template}" ]; then
|
||||||
|
mkdir -p "${bastille_jail_template}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -d "${bastille_jail_path}/usr/local" ]; then
|
if [ ! -d "${bastille_jail_path}/usr/local" ]; then
|
||||||
mkdir -p "${bastille_jail_path}/usr/local"
|
mkdir -p "${bastille_jail_path}/usr/local"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "${bastille_jail_template}" ]; then
|
# Check and apply required settings.
|
||||||
mkdir -p "${bastille_jail_template}"
|
post_create_jail
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${bastille_jail_fstab}" ]; then
|
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||||
if [ -z "${THICK_JAIL}" ]; then
|
|
||||||
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
|
|
||||||
else
|
|
||||||
touch "${bastille_jail_fstab}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "${bastille_jail_conf}" ]; then
|
|
||||||
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
|
|
||||||
local bastille_jail_conf_interface=${bastille_network_shared}
|
|
||||||
fi
|
|
||||||
if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then
|
|
||||||
local bastille_jail_conf_interface=${bastille_network_loopback}
|
|
||||||
fi
|
|
||||||
if [ -n "${INTERFACE}" ]; then
|
|
||||||
local bastille_jail_conf_interface=${INTERFACE}
|
|
||||||
fi
|
|
||||||
|
|
||||||
## generate the jail configuration file
|
|
||||||
if [ -n "${VNET_JAIL}" ]; then
|
|
||||||
generate_vnet_jail_conf
|
|
||||||
else
|
|
||||||
generate_jail_conf
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
## using relative paths here
|
|
||||||
## MAKE SURE WE'RE IN THE RIGHT PLACE
|
|
||||||
cd "${bastille_jail_path}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [ -z "${THICK_JAIL}" ]; then
|
|
||||||
LINK_LIST="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src"
|
LINK_LIST="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src"
|
||||||
|
info "Creating a thinjail...\n"
|
||||||
for _link in ${LINK_LIST}; do
|
for _link in ${LINK_LIST}; do
|
||||||
ln -sf /.bastille/${_link} ${_link}
|
ln -sf /.bastille/${_link} ${_link}
|
||||||
done
|
done
|
||||||
|
|
||||||
# Properly link shared ports on thin jails in read-write.
|
# Properly link shared ports on thin jails in read-write.
|
||||||
if [ -d "${bastille_releasesdir}/${RELEASE}/usr/ports" ]; then
|
if [ -d "${bastille_releasesdir}/${RELEASE}/usr/ports" ]; then
|
||||||
if [ ! -d "${bastille_jail_path}/usr/ports" ]; then
|
if [ ! -d "${bastille_jail_path}/usr/ports" ]; then
|
||||||
@@ -331,7 +347,7 @@ create_jail() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${THICK_JAIL}" ]; then
|
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||||
## rw
|
## rw
|
||||||
## copy only required files for thin jails
|
## copy only required files for thin jails
|
||||||
FILE_LIST=".cshrc .profile COPYRIGHT dev etc media mnt net proc root tmp var usr/obj usr/tests"
|
FILE_LIST=".cshrc .profile COPYRIGHT dev etc media mnt net proc root tmp var usr/obj usr/tests"
|
||||||
@@ -345,9 +361,21 @@ create_jail() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
info "Creating a thickjail. This may take a while..."
|
|
||||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||||
|
if [ -n "${CLONE_JAIL}" ]; then
|
||||||
|
info "Creating a clonejail...\n"
|
||||||
|
## clone the release base to the new basejail
|
||||||
|
SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)"
|
||||||
|
zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
|
||||||
|
|
||||||
|
zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \
|
||||||
|
"${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
|
||||||
|
|
||||||
|
# Check and apply required settings.
|
||||||
|
post_create_jail
|
||||||
|
elif [ -n "${THICK_JAIL}" ]; then
|
||||||
|
info "Creating a thickjail. This may take a while...\n"
|
||||||
## perform release base replication
|
## perform release base replication
|
||||||
|
|
||||||
## sane bastille zfs options
|
## sane bastille zfs options
|
||||||
@@ -366,6 +394,7 @@ create_jail() {
|
|||||||
## cleanup temp snapshots initially
|
## cleanup temp snapshots initially
|
||||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
|
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
|
||||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}"
|
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$?" -ne 0 ]; then
|
if [ "$?" -ne 0 ]; then
|
||||||
## notify and clean stale files/directories
|
## notify and clean stale files/directories
|
||||||
@@ -474,6 +503,10 @@ create_jail() {
|
|||||||
if [ -n "${bastille_template_thick}" ]; then
|
if [ -n "${bastille_template_thick}" ]; then
|
||||||
bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||||
fi
|
fi
|
||||||
|
elif [ -n "${CLONE_JAIL}" ]; then
|
||||||
|
if [ -n "${bastille_template_clone}" ]; then
|
||||||
|
bastille template "${NAME}" ${bastille_template_clone} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||||
|
fi
|
||||||
elif [ -n "${EMPTY_JAIL}" ]; then
|
elif [ -n "${EMPTY_JAIL}" ]; then
|
||||||
if [ -n "${bastille_template_empty}" ]; then
|
if [ -n "${bastille_template_empty}" ]; then
|
||||||
bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||||
@@ -519,6 +552,7 @@ fi
|
|||||||
## reset this options
|
## reset this options
|
||||||
EMPTY_JAIL=""
|
EMPTY_JAIL=""
|
||||||
THICK_JAIL=""
|
THICK_JAIL=""
|
||||||
|
CLONE_JAIL=""
|
||||||
VNET_JAIL=""
|
VNET_JAIL=""
|
||||||
LINUX_JAIL=""
|
LINUX_JAIL=""
|
||||||
|
|
||||||
@@ -546,6 +580,10 @@ while [ $# -gt 0 ]; do
|
|||||||
VNET_JAIL_BRIDGE="1"
|
VNET_JAIL_BRIDGE="1"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
-C|--clone|clone)
|
||||||
|
CLONE_JAIL="1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-*|--*)
|
-*|--*)
|
||||||
error_notify "Unknown Option."
|
error_notify "Unknown Option."
|
||||||
usage
|
usage
|
||||||
@@ -558,13 +596,15 @@ done
|
|||||||
|
|
||||||
## validate for combined options
|
## validate for combined options
|
||||||
if [ -n "${EMPTY_JAIL}" ]; then
|
if [ -n "${EMPTY_JAIL}" ]; then
|
||||||
if [ -n "${THICK_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${LINUX_JAIL}" ]; then
|
if [ -n "${CLONE_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${LINUX_JAIL}" ]; then
|
||||||
error_exit "Error: Empty jail option can't be used with other options."
|
error_exit "Error: Empty jail option can't be used with other options."
|
||||||
fi
|
fi
|
||||||
elif [ -n "${LINUX_JAIL}" ]; then
|
elif [ -n "${LINUX_JAIL}" ]; then
|
||||||
if [ -n "${EMPTY_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${THICK_JAIL}" ]; then
|
if [ -n "${EMPTY_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${CLONE_JAIL}" ]; then
|
||||||
error_exit "Error: Linux jail option can't be used with other options."
|
error_exit "Error: Linux jail option can't be used with other options."
|
||||||
fi
|
fi
|
||||||
|
elif [ -n "${CLONE_JAIL}" ] && [ -n "${THICK_JAIL}" ]; then
|
||||||
|
error_exit "Error: Clonejail and Thickjail can't be used together."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
NAME="$1"
|
NAME="$1"
|
||||||
@@ -748,6 +788,9 @@ fi
|
|||||||
if [ -z ${bastille_template_thick+x} ]; then
|
if [ -z ${bastille_template_thick+x} ]; then
|
||||||
bastille_template_thick='default/thick'
|
bastille_template_thick='default/thick'
|
||||||
fi
|
fi
|
||||||
|
if [ -z ${bastille_template_clone+x} ]; then
|
||||||
|
bastille_template_clone='default/clone'
|
||||||
|
fi
|
||||||
if [ -z ${bastille_template_thin+x} ]; then
|
if [ -z ${bastille_template_thin+x} ]; then
|
||||||
bastille_template_thin='default/thin'
|
bastille_template_thin='default/thin'
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
|
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@@ -118,6 +118,23 @@ destroy_rel() {
|
|||||||
if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
|
if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
|
||||||
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
|
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
|
||||||
BASE_HASCHILD="1"
|
BASE_HASCHILD="1"
|
||||||
|
elif [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||||
|
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||||
|
## check if this release have child clones
|
||||||
|
if zfs list -H -t snapshot -r "${bastille_rel_base}" > /dev/null 2>&1; then
|
||||||
|
SNAP_CLONE=$(zfs list -H -t snapshot -r "${bastille_rel_base}" 2> /dev/null | awk '{print $1}')
|
||||||
|
for _snap_clone in ${SNAP_CLONE}; do
|
||||||
|
if zfs list -H -o clones "${_snap_clone}" > /dev/null 2>&1; then
|
||||||
|
CLONE_JAIL=$(zfs list -H -o clones "${_snap_clone}" | tr ',' '\n')
|
||||||
|
CLONE_CHECK="${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}/root"
|
||||||
|
if echo "${CLONE_JAIL}" | grep -qw "${CLONE_CHECK}"; then
|
||||||
|
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
|
||||||
|
BASE_HASCHILD="1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
ARG BASE_TEMPLATE=default/base
|
||||||
|
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||||
|
|
||||||
|
INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||||
Reference in New Issue
Block a user