104 lines
2.6 KiB
Bash
Executable file
104 lines
2.6 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
chr=
|
|
bin=
|
|
user=
|
|
group=
|
|
devfs=0
|
|
listen=
|
|
out=
|
|
openfiles=
|
|
mem=
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
`basename ${0}` [options...] -c chroot_dir -x executable
|
|
|
|
-c - chroot directory
|
|
-x - executable binary
|
|
-u - user to run as
|
|
-g - group to run as (gets set to user if empty)
|
|
-d - dev fs
|
|
-l - listening port
|
|
-o - outgoing port
|
|
-f - max open files
|
|
-m - memory usage
|
|
-h - show this help
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
errx() { echo "${1}">&2;exit 1; }
|
|
|
|
while getopts hc:x:u:g:dl:o:f:m: arg; do
|
|
case ${arg} in
|
|
h) usage ;;
|
|
c) chr=${OPTARG} ;;
|
|
x) bin=${OPTARG} ;;
|
|
u) user=${OPTARG} ;;
|
|
g) group=${OPTARG} ;;
|
|
d) devfs=1 ;;
|
|
l) listen=${OPTARG} ;;
|
|
o) out=${OPTARG} ;;
|
|
f) openfiles=${OPTARG} ;;
|
|
m) mem=${OPTARG} ;;
|
|
*) errx "use -h for help" ;;
|
|
esac
|
|
done
|
|
shift $((${OPTIND}-1))
|
|
|
|
[ -z "${chr}" ] && errx "missing option: -c"
|
|
[ -z "${bin}" ] && errx "missing option: -x"
|
|
[ -z "${user}" ] && errx "missing option: -u"
|
|
[ ! -x "${bin}" ] && errx "${bin} is not an executable file"
|
|
[ "${user}" == "root" ] && errx "user root is not allowed"
|
|
[ -z "${group}" ] && group=${user}
|
|
|
|
[ -d "${chr}" ] && mkdir -p ${chr}/{bin,dev,etc}
|
|
[ ${devfs} -eq 1 ] && { cd ${chr}/dev; sh /dev/MAKEDEV std random; rm ${chr}/dev/{console,klog,kmem,ksyms,mem,tty,xf86}; }
|
|
cp /etc/{resolv.conf,hosts,localtime} ${chr}/etc/
|
|
chmod 0644 ${chr}/etc/{resolv.conf,hosts,localtime}
|
|
cp ${bin} ${chr}/bin
|
|
|
|
login_conf="/etc/login.conf"
|
|
echo "${user}:\\">>${login_conf}
|
|
[ -n "${mem}" ] && echo " :vmemoryuse-max=${mem}:\\">>${login_conf}
|
|
[ -n "${openfiles}" ] && cat <<EOF>>${login_conf}
|
|
:openfiles-max=${openfiles}:\\
|
|
:openfiles-cur=${openfiles}:\\
|
|
EOF
|
|
echo " :tc=daemon:">>${login_conf}
|
|
|
|
pf_dir="/etc/pf"
|
|
pf_conf="${pf_dir}/${user}.conf"
|
|
sed -i "1iinclude \"${pf_conf}\"" /etc/pf.conf
|
|
[ ! -d ${pf_dir} ] && mkdir ${pf_dir}
|
|
echo "block in quick on lo0 from user ${user}">>${pf_conf}
|
|
[ -n "${listen}" ] && echo "pass in quick on egress proto tcp from any to any port ${listen}">>${pf_conf}
|
|
[ -n "${out}" ] && echo "pass out quick on egress proto tcp to any port ${out}">>${pf_conf}
|
|
echo "block out quick on egress from user ${user}">>${pf_conf}
|
|
pfctl -f /etc/pf.conf
|
|
|
|
groupinfo ${group} || groupadd ${group}
|
|
userinfo ${user} || useradd -L ${user} -g ${user} -d /var/empty -s /sbin/nologin ${user}
|
|
|
|
rsync -aR $(ldd ${bin}|tail -n+4|awk '{print $7}') ${chr}
|
|
|
|
base=$(basename ${bin})
|
|
cat <<EOF> /etc/rc.d/${base}
|
|
#!/bin/sh
|
|
|
|
daemon="/usr/bin/env -i /usr/sbin/chroot -u ${user} -g ${group} ${chr}"
|
|
|
|
. /etc/rc.d/rc.subr
|
|
|
|
pexp="\${daemon_flags}"
|
|
|
|
rc_cmd \$1
|
|
EOF
|
|
|
|
chmod 0555 /etc/rc.d/${base}
|
|
|
|
rcctl enable ${base}
|
|
rcctl set ${base} flags "/bin/${base}"
|
|
rcctl start ${base}
|