Initial commit
This commit is contained in:
		
							
								
								
									
										218
									
								
								chroot_base
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								chroot_base
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,218 @@ | ||||
| # -*- mode: sh; -*- | ||||
| # vim: ft=sh | ||||
| # This file is intended to be a wrapper to /etc/rc.d/rc.subr | ||||
| # that makes it easy to run software inside of chroot jails. | ||||
| # It handles the copying of programs by automatically detecting | ||||
| # and installing required shared libraries. | ||||
| # | ||||
| # NOTE: This file sources /etc/rc.d/rc.subr! DO NOT source it yourself. | ||||
| # | ||||
| # To use this file, simply include it as | ||||
| #     . /etc/rc.d/chroot_base | ||||
| # Then, use the provided functions in rc_pre and rc_post to | ||||
| # set up the chroot jail. | ||||
| # | ||||
| # The following variables MUST be defined BEFORE sourcing this file: | ||||
| #     chroot_exec - program to run inside chroot jail | ||||
| #     chroot_user - user to drop permissions to inside of chroot | ||||
| #     chroot_group - group to drop permissions to inside of chroot | ||||
| #     chroot_root - path of chroot jail. Should be owned by root:wheel | ||||
| #                   and writable only by root | ||||
| # | ||||
| # The following variables MAY be defined BEFORE sourcing this file: | ||||
| #     chroot_home - if set, the value of $HOME is set to this before the program is started | ||||
| #     chroot_bin - if set, programs will be coppied here instead of to /bin. See chroot_env_exec | ||||
| #                  for information about adding this to $PATH | ||||
| #     chroot_env_exec - if set, will be used as the path to the 'env' program in the chroot. You | ||||
| #                       must install and remove this program yourself. If this is set and chroot_bin | ||||
| #                       set, chroot bin will be added to PATH | ||||
| #     chroot_lib - if set, libraries will be coppied here instead of /usr/lib and it will be added | ||||
| #                  to $LD_LIBRARY_PATH | ||||
| #     chroot_no_ldso - if set to YES, this script will not touch ld.so in the jail | ||||
| #     chroot_no_vars - if set to YES, this script will not set any of the daemon* variables or pexp. | ||||
| #                      In addition, you may ignore all the variables except chroot_root | ||||
| # | ||||
| # The following function are defined by this script: | ||||
| #     chroot_install - copy files to the chroot | ||||
| #     chroot_install_program - copy a program and all of its libraries into the chroot | ||||
| #     chroot_rm - delete files from the chroot | ||||
| #     chroot_rm_program - delete a program from the chroot along with all of its libraries | ||||
| #     chroot_mkdev - create device files in the chroot's /dev | ||||
| #     chroot_mknull - create /dev/null in the chroot | ||||
|  | ||||
| # Internal variables used by functions | ||||
| _chroot_root_dir="${chroot_root%/}/" | ||||
| if [ -z "${chroot_home}" ]; then | ||||
| 	_chroot_user_home="$(grep "${chroot_user}" /etc/passwd | cut -d ":" -f6)" | ||||
| else | ||||
| 	_chroot_user_home="${chroot_home}" | ||||
| fi | ||||
| if [ -z "${chroot_bin}" ]; then | ||||
| 	_chroot_bin_dir="${_chroot_root_dir}bin/" | ||||
| 	_chroot_env_path="PATH='$(getconf PATH)'" | ||||
| else | ||||
| 	chroot_bin="${chroot_bin%/}" | ||||
| 	_chroot_bin_dir="${_chroot_root_dir}${chroot_bin#/}/" | ||||
| 	_chroot_env_path="PATH='${chroot_bin}:$(getconf PATH)'" | ||||
| fi | ||||
| if [ -z "${chroot_lib}" ]; then | ||||
| 	_chroot_lib_dir="${_chroot_root_dir}usr/lib/" | ||||
| else | ||||
| 	chroot_lib="${chroot_lib%/}" | ||||
| 	_chroot_lib_dir="${_chroot_root_dir}${chroot_lib#/}/" | ||||
| 	_chroot_env_ld="LD_LIBRARY_PATH='${chroot_lib}'" | ||||
| fi | ||||
| _chroot_chroot_cmd="/usr/sbin/chroot -u '${chroot_user}' -g '${chroot_user}' '${chroot_root}'" | ||||
|  | ||||
| # find our env command | ||||
| if [ -z "${chroot_env_exec}" ]; then | ||||
| 	# There is no env inside the chroot, therefore we run it before chroot | ||||
| 	# However, this means we cannon env PATH because the chroot resets it | ||||
| 	_chroot_env_cmd="/usr/bin/env HOME='${_chroot_user_home}' ${_chroot_env_ld}" | ||||
| else | ||||
| 	# The user has put env inside the chroot | ||||
| 	# Run it inside, allowing us to set path | ||||
| 	_chroot_inside_env_cmd="${chroot_env_exec} HOME='${_chroot_user_home}' ${_chroot_env_ld} ${_chroot_env_path}" | ||||
| fi | ||||
|  | ||||
| # Set normal rc.subr variables from chroot_* variables | ||||
| if [ "${chroot_no_vars}" != "YES" ]; then | ||||
| 	daemon_user="root" | ||||
| 	daemon="${_chroot_env_cmd} ${_chroot_chroot_cmd} ${_chroot_inside_env_cmd} ${chroot_exec}" | ||||
| fi | ||||
|  | ||||
| # Source rc.subr | ||||
| . /etc/rc.d/rc.subr | ||||
|  | ||||
| # Fix the pexp for the chroot | ||||
| if [ "${chroot_no_vars}" != "YES" ]; then | ||||
| 	pexp="$(eval echo ${chroot_exec}${daemon_flags:+ ${daemon_flags}})" | ||||
| fi | ||||
|  | ||||
| # usage: chroot_install [files ...] | ||||
| #     Copy files into the chroot. Permissions, owner, group, and flags are preserved. | ||||
| function chroot_install { | ||||
| 	for file in ${@}; do | ||||
| 		local rel_file | ||||
| 		if echo "${file}" | grep -E '^/' >/dev/null; then | ||||
| 			rel_file="$(echo "${file}" | cut -c '2-')" # remove leading / | ||||
| 		else | ||||
| 			rel_file="${file}" | ||||
| 		fi | ||||
| 		local dir="$(dirname "${rel_file}")" | ||||
| 		if ! [ -d "${_chroot_root_dir}${dir}" ]; then | ||||
| 			mkdir -p "${_chroot_root_dir}${dir}" | ||||
| 			echo "Created '${_chroot_root_dir}${dir}'" | ||||
| 		fi | ||||
| 		cp -Rp "${file}" "${_chroot_root_dir}${rel_file}" | ||||
| 		echo "Installed '${file}' to '${_chroot_root_dir}${rel_file}'" | ||||
| 	done | ||||
| } | ||||
|  | ||||
| # usage: chroot_install_program <file> [name] | ||||
| #     Install the program FILE and all of its shared library dependencies | ||||
| #     to the chroot. Dependencies are found with ldd. If NAME is provided, | ||||
| #     the program will be coppied as NAME. | ||||
| # | ||||
| # NOTE: By default, the program is installed to /bin in the chroot | ||||
| function chroot_install_program { | ||||
| 	echo "Installing dependencies for '${1}':" | ||||
| 	for dep in $(ldd "${1}" | tail -n '+4' | grep -Eo '/.+$'); do | ||||
| 		if [ "${dep}" == "/usr/libexec/ld.so" ]; then | ||||
| 			if [ "${chroot_no_ldso}" != "YES" ]; then | ||||
| 				if ! [ -d "${_chroot_root_dir}usr/libexec" ]; then | ||||
| 					mkdir -p "${_chroot_root_dir}usr/libexec" | ||||
| 					echo "  - Created '${_chroot_root_dir}usr/libexec'" | ||||
| 				fi | ||||
| 				install -o root -g bin -m 0444 "${dep}" "${_chroot_root_dir}usr/libexec/ld.so" | ||||
| 				echo "  - Installed '${dep}' to '${_chroot_root_dir}usr/libexec/ld.so'" | ||||
| 			fi | ||||
| 		else | ||||
| 			if ! [ -d "${_chroot_lib_dir}" ]; then | ||||
| 				mkdir -p "${_chroot_lib_dir}" | ||||
| 				echo "  - Created '${_chroot_lib_dir}'" | ||||
| 			fi | ||||
| 			local name="$(basename "${dep}")" | ||||
| 			install -o root -g bin -m 0444 "${dep}" "${_chroot_lib_dir}${name}" | ||||
| 			echo "  - Installed '${dep}' to '${_chroot_lib_dir}${name}'" | ||||
| 		fi | ||||
| 	done | ||||
| 	if ! [ -d "${_chroot_bin_dir}" ]; then | ||||
| 		mkdir -p "${_chroot_bin_dir}" | ||||
| 		echo "Created '${_chroot_bin_dir}'" | ||||
| 	fi | ||||
| 	local name | ||||
| 	if [ -z "${2}" ]; then | ||||
| 		name="$(basename "${1}")" | ||||
| 	else | ||||
| 		name="${2}" | ||||
| 	fi | ||||
| 	install -o root -g bin -m 0755 "${1}" "${_chroot_bin_dir}${name}" | ||||
| 	echo "Installed '${1}' to '${_chroot_bin_dir}${name}'" | ||||
| } | ||||
|  | ||||
| # usage: chroot_rm_program <file> | ||||
| #     Find all libraries of program with ldd and delete them. | ||||
| #     Then, delete the program FILE from /bin of the chroot. | ||||
| # | ||||
| # EXAMPLE: | ||||
| # The usage | ||||
| #     chroot_rm_program "/usr/local/bin/git" | ||||
| # would run ldd on /bin/git in the chroot and delete all the | ||||
| # resulting libraries. It would then remove /bin/git from the | ||||
| # chroot. | ||||
| function chroot_rm_program { | ||||
| 	local name="$(basename "${1}")" | ||||
| 	local path="${_chroot_bin_dir}${name}" | ||||
| 	echo "Deleting dependencies for '${1}'" | ||||
| 	for dep in $(ldd "${path}" | tail -n '+4' | grep -Eo '/.+$'); do | ||||
| 		if [ "${dep}" == "/usr/libexec/ld.so" ]; then | ||||
| 			if [ "${chroot_no_ldso}" != "YES" ]; then | ||||
| 				rm -f "${_chroot_root_dir}usr/libexec/ld.so" | ||||
| 				echo "  - Deleted '${_chroot_root_dir}usr/libexec/ld.so'" | ||||
| 			fi | ||||
| 		else | ||||
| 			local name="$(basename "${dep}")" | ||||
| 			rm -f "${_chroot_lib_dir}${name}" | ||||
| 			echo "  - Deleted '${_chroot_lib_dir}${name}'" | ||||
| 		fi | ||||
| 	done | ||||
| 	rm -f "${path}" | ||||
| 	echo "Deleted '${path}'" | ||||
| } | ||||
|  | ||||
| # usage: chroot_rm [files ...] | ||||
| #     Remove files from the chroot | ||||
| function chroot_rm { | ||||
| 	for file in ${@}; do | ||||
| 		if echo "${file}" | grep -E '^/' >/dev/null; then | ||||
| 			file="$(echo "${file}" | cut -c '2-')" # remove leading / | ||||
| 		fi | ||||
| 		rm -rf "${_chroot_root_dir}${file}" | ||||
| 		echo "Deleted '${_chroot_root_dir}${file}'" | ||||
| 	done | ||||
| } | ||||
|  | ||||
| # usage: chroot_mkdev [names ...] | ||||
| #     Runs /dev/MAKEDEV with NAMES as the argument in the chroot's | ||||
| #     /dev directory | ||||
| function chroot_mkdev { | ||||
| 	if ! [ -d "${_chroot_root_dir}dev" ]; then | ||||
| 		mkdir "${_chroot_root_dir}dev" | ||||
| 		echo "Created '${_chroot_root_dir}dev'" | ||||
| 	fi | ||||
| 	(cd "${_chroot_root_dir}dev" && /dev/MAKEDEV "$@") | ||||
| 	echo "Created device files for '$@' in '${_chroot_root_dir}dev'" | ||||
| } | ||||
|  | ||||
| # usage: chroot_mknull | ||||
| #     This is a convinience function that creates /dev/null in the | ||||
| #     chroot. | ||||
| function chroot_mknull { | ||||
| 	if ! [ -d "${_chroot_root_dir}dev" ]; then | ||||
| 		mkdir "${_chroot_root_dir}dev" | ||||
| 		echo "Created '${_chroot_root_dir}dev'" | ||||
| 	fi | ||||
| 	mknod -m 0666 "${_chroot_root_dir}dev/null" c 2 2 | ||||
| 	echo "Created /dev/null as '${_chroot_root_dir}dev/null'" | ||||
| } | ||||
		Reference in New Issue
	
	Block a user