Chrooting proxy services

From Gentoo Wiki
Jump to:navigation Jump to:search
Some of the information in this article may have drifted out of sync with current practices. Please help out by checking over the content (how to get started).
This article has been flagged for not conforming to the wiki guidelines (this article needs to clearly state it's intention and provide an overview of the process before "diving in" ; use of 2nd person pronouns). Please help Gentoo out by starting fixing things.

Today there are many process isolation techniques. Most of them are based on virtualization or containers. Some are focused on security, which is what we want for this.

Kernel options

We would like to use hardened chroot to isolate internet services, but since hardened-sources is no longer available and there is no replacement for most of us, therefore we will do without. We leave this section in for those that can still use it.

To create a hardened jail we need hardened-sources to be installed (it is wise to use one of hardened profiles). So emerge it:

root #emerge --ask sys-kernel/hardened-sources

Then set the necessary hardened chroot options:

KERNEL make menuconfig options
Security options --->
 Grsecurity --->
 [*] Grsecurity
 Customize Configuration --->
 Filesystem Protections --->
 [*] Chroot jail restrictions
 [*] Deny mounts
 [*] Deny double-chroots
 [*] Deny pivot_root in chroot
 [*] Enforce chdir("/") on all chroots
 [*] Deny (f)chmod +s
 [*] Deny fchdir and fhandle out of chroot
 [*] Deny mknod
 [*] Deny shmat() out of chroot
 [*] Deny access to abstract AF_UNIX sockets out of chroot
 [*] Protect outside processes
 [*] Restrict priority changes
 [*] Deny sysctl writes
 [*] Deny bad renames
 [*] Capability restrictions

Chroot

As an example, of building chroot services, lets take a look at home proxy server. A home proxy can look something like:

 +-------------------------------------------------------------+
 | Chrooted sockd or torsocks <-> Other Internet applications |
 | ^ |
 | | |
 | Chrooted HTTP* |
 +----------+ | Chrooted <-> Chrooted <-> HAVP <-> Internet |
 | Internet | <-> | <-> Tor Privoxy + applications |
 +----------+ | ^ libClamAV |
 | | |
 | |
 | Chrooted |
 | FreshClam |
 +-------------------------------------------------------------+

From a users perspective the best way would be to write an ebuild to build the chroot of the service!!! So generally for a chrooted tor service the Gentoo user wants to run:

root #emerge --config net-misc/tor

and that is all... Except developers don't want to support such a complicated ebuild. Therefore, here we will show examples of chrooted init scripts for all services shown above and examples of bash scripts to build the chroots (these should be hooked into the pkg_config() function of the respective ebuilds).

First build and install binary packages for the services ClamAV, tor, Dante, HAVP and privoxy:

root #emerge --ask -b app-antivirus/clamav net-vpn/tor net-proxy/torsocks net-proxy/dante net-proxy/havp net-proxy/privoxy

Then configure all of them, which is beyond the scope of this how-to, though. However, for this setup to work we need USE=clamav on HAVP.

The next scripts build chrooted services even when all file-systems with executables are mounted readonly and all writeable file-systems are mounted with noexec. Make sure you have write-access to the / and /usr partitions when you execute these!

You must manually run the chroot build scripts any time you update or reconfigure the service or update this library!

Chrooted FreshClamAV

FILE /etc/init.d/clamdchrooted freshclam
#!/sbin/openrc-run
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
CHROOT="/usr/chroot/clamav"
PIDCLAMD="/var/run/clamav/clamd.pid"
PIDFRESH="/var/run/clamav/freshclam.pid"
daemon_clamd="/usr/sbin/clamd"
daemon_freshclam="/usr/bin/freshclam"
daemon_milter="/usr/sbin/clamav-milter"
extra_commands="logfix"
depend(){
usenet
provideantivirus
}
get_config(){
clamconf|sed's/["=]//g'|\
awk"{
 if(\0ドル==\"Config file: 1ドル.conf\") S=1
 if(S==1&&\0ドル==\"\") {
 print \"3ドル\"
 exit
 }
 if(S==1&&\1ドル~\"^2ドル\$\") {
 print \2ドル!=\"disabled\"?\2ドル:\"3ドル\"
 exit
 }
 }"
}
checkconfig(){
checkpath--directory\
--owner"${CLAMAV_USER:-clamav}:${CLAMAV_GROUP:-clamav}"\
--mode0755--directory`dirname${CHROOT}${PIDCLAMD}`
if[!-c${CHROOT}/dev/null];then
mknod-m666${CHROOT}/dev/nullc13
mount-roremount${CHROOT}/dev
fi
}
start(){
# populate variables and fix log file permissions
logfix
if["${START_CLAMD}"="yes"];then
checkconfig||return1
if[-S"${CHROOT}${clamd_socket}"];then
rm-f${CHROOT}${clamd_socket}
fi
ebegin"Starting chrooted clamd"
start-stop-daemon--start--quiet\
--nicelevel${CLAMD_NICELEVEL:-0}\
--ionice${IONICE_LEVEL:-0}\
--pidfile"${CHROOT}${PIDCLAMD}"\
--execchroot${CHROOT}${daemon_clamd}
eend$?"Failed to start clamd"
fi
if["${START_FRESHCLAM}"="yes"];then
checkconfig||return1
ebegin"Starting chrooted freshclam"
start-stop-daemon--start--quiet\
--nicelevel${FRESHCLAM_NICELEVEL:-0}\
--ionice${IONICE_LEVEL:-0}\
--pidfile"${CHROOT}${PIDFRESH}"\
--execchroot${CHROOT}${daemon_freshclam}---d--pid"${PIDFRESH}"
retcode=$?
if[${retcode}=1];then
eend0
einfo"Virus databases are already up to date."
else
eend${retcode}"Failed to start freshclam"
fi
fi
if["${START_MILTER}"="yes"];then
if[-z"${MILTER_CONF_FILE}"];then
MILTER_CONF_FILE="/etc/clamav-milter.conf"
fi
ebegin"Starting clamav-milter"
start-stop-daemon--start--quiet\
--nicelevel${MILTER_NICELEVEL:-0}\
--ionice${IONICE_LEVEL:-0}\
--exec${daemon_milter}---c${MILTER_CONF_FILE}
eend$?"Failed to start clamav-milter"
fi
}
stop(){
if["${START_CLAMD}"="yes"];then
ebegin"Stopping chrooted clamd"
start-stop-daemon--stop--pidfile"${CHROOT}${PIDCLAMD}"--quiet--nameclamd
eend$?"Failed to stop clamd"
fi
if["${START_FRESHCLAM}"="yes"];then
ebegin"Stopping chrooted freshclam"
start-stop-daemon--stop--quiet\
--pidfile"${CHROOT}${PIDFRESH}"\
--namefreshclam\
--execchroot${CHROOT}${daemon_freshclam}---K--pid"${PIDFRESH}"
eend$?"Failed to stop freshclam"
fi
if["${START_MILTER}"="yes"];then
ebegin"Stopping clamav-milter"
start-stop-daemon--stop--quiet--nameclamav-milter
eend$?"Failed to stop clamav-milter"
fi
}
logfix(){
clamd_socket=$(get_configclamdLocalSocket/run/clamav/clamd.sock)
clamd_user=$(get_configclamdUserclamav)
freshclam_user=$(get_configfreshclamDatabaseOwnerclamav)
if["${START_CLAMD}"="yes"];then
# fix clamd log permissions
# (might be clobbered by logrotate or something)
locallogfile=$(get_configclamdLogFile)
if[-n"${CHROOT}${logfile}"];then
checkpath--quiet\
--owner"${clamd_user}":"${clamd_user}"\
--mode640\
--file${CHROOT}${logfile}
fi
fi
if["${START_FRESHCLAM}"="yes"];then
# fix freshclam log permissions
# (might be clobbered by logrotate or something)
locallogfile=$(get_configfreshclamUpdateLogFile)
if[-n"${CHROOT}${logfile}"];then
checkpath--quiet\
--owner"${freshclam_user}":"${freshclam_user}"\
--mode640\
--file${CHROOT}${logfile}
fi
fi
}
FILE clamav-chroot.shBuild chrooted freshclam
#!/bin/bash
# 20150922
# GPL-3
PKGDIR="/var/cache/binpkgs"
CATEGORY="app-antivirus"
PN="clamav"
CHROOT="/usr/chroot/${PN}"
WORKD=`pwd`
# Cleaning chroot directory.
umount"${CHROOT}"/var/lib/${PN}"${CHROOT}"/var/log/${PN}"${CHROOT}"/var/run"${CHROOT}"/var/tmp"${CHROOT}"/dev1>/dev/null2>&1
rm-rf"${CHROOT}"
# Make common directory and symlinks.
mkdir-p"${CHROOT}"/{dev,etc}
if[-d/lib64]
then
mkdir-p"${CHROOT}"/{lib64,usr/lib64}
cd"${CHROOT}"&&ln-slib64lib
cd"${CHROOT}/usr"&&ln-slib64lib
else
mkdir-p"${CHROOT}"/{lib,usr/lib}
fi
mkdir-p/var/log/${PN}"${CHROOT}"/var/log/${PN}"${CHROOT}"/var/run"${CHROOT}"/var/tmp
chown-R${PN}:${PN}/var/log/${PN}"${CHROOT}"/var/log/${PN}
chmod-Ro-rwx/var/log/${PN}"${CHROOT}"/var/log/${PN}
# Extract package.
tar-xjphf`ls${PKGDIR}/${CATEGORY}/${PN}-0*|tail-n1`-C"${CHROOT}"
# Copy necessary libraries.
cp-pRPd/lib/ld-*"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/bin/freshclam"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/bin/freshclam"|awk'{print 3ドル}'|grep"^/usr/lib"`"${CHROOT}/usr/lib"
# Copy user information and necessary libraries for it.
cp-pRPd/lib/libnss*/lib/libnsl*/lib/libresolv*"${CHROOT}/lib"
cp/usr/lib/libnss3.so"${CHROOT}/usr/lib"
grep"^${PN}""/etc/passwd">"${CHROOT}/etc/passwd"
grep"${PN}""/etc/group">"${CHROOT}/etc/group"
# fstab stuff.
if[[`grep"Clamav chroot stuff."/etc/fstab`=='']]
then
cat>>/etc/fstab<< EOF
# Clamav chroot stuff.
/var/lib/${PN} ${CHROOT}/var/lib/${PN} none bind,nodev,noexec,nosuid,rw 0 0
/var/log/${PN} ${CHROOT}/var/log/${PN} none bind,nodev,noexec,nosuid,rw 0 0
/var/tmp/havp ${CHROOT}/var/tmp none bind,nodev,noexec,nosuid,user=${PN},ro 0 0
none ${CHROOT}/var/run tmpfs rw,nodev,noexec,nosuid,relatime,size=1024k,mode=755 0 0
none ${CHROOT}/dev tmpfs rw,noexec,nosuid,relatime,size=1024k,nr_inodes=384443,mode=755 0 0
EOF
fi
mount-a
# Configuration.
cp-fp/etc/freshclam.conf${CHROOT}/etc/
cp-fp/etc/clamd.conf${CHROOT}/etc/
cd${WORKD}
cp-fclamd/etc/init.d/
cp-fclamd${CHROOT}/etc/init.d/
exit0

Chrooted Dante Sockd

FILE /etc/init.d/dante-sockdchrooted dante-sockd
#!/sbin/openrc-run
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$
CHROOT=/usr/chroot/dante
SOCKD_OPT=""
["${SOCKD_FORKDEPTH:-1}"-gt1]&&SOCKD_OPT="${SOCKD_OPT} -N ${SOCKD_FORKDEPTH}"
["${SOCKD_DEBUG:-0}"-eq1]&&SOCKD_OPT="${SOCKD_OPT} -d"
["${SOCKD_DISABLE_KEEPALIVE:-0}"-eq1]&&SOCKD_OPT="${SOCKD_OPT} -n"
PIDFILE=/var/run/dante/sockd.pid
SOCKDIR=/var/lock/dante-sockd/
depend(){
neednet
}
checkconfig(){
# first check that it exists
if[!-f${CHROOT}/etc/socks/sockd.conf];then
eerror"You need to setup /etc/socks/sockd.conf first"
eerror"Examples are in /usr/share/doc/dante[version]/example"
eerror"for more info, see: man sockd.conf"
return1
fi
/usr/sbin/sockd-V-f${CHROOT}/etc/socks/sockd.conf>/tmp/dante-sockd.checkconf2>&1
if[$?-ne0];then
cat/tmp/dante-sockd.checkconf
eerror"Something is wrong with your configuration file"
eerror"for more info, see: man sockd.conf"
return1
fi
rm/tmp/dante-sockd.checkconf
DAEMON_UID=`sed-e'/^[ \t]*user[.]notprivileged[ \t]*:/{s/.*:[ \t]*//;q};d'/etc/socks/sockd.conf`
if[-n"$DAEMON_UID"];then
checkpath--quiet--mode755--owner"${DAEMON_UID}":root--directory`dirname${CHROOT}${PIDFILE}`
checkpath--quiet--mode750--owner"${DAEMON_UID}":root--directory"${CHROOT}${SOCKDIR}"
else
checkpath--quiet--mode755--directory`dirname${CHROOT}${PIDFILE}`
checkpath--quiet--mode750--directory"${CHROOT}${SOCKDIR}"
fi
return0
}
start(){
checkconfig||return1
ebegin"Starting chrooted dante sockd"
start-stop-daemon--start--quiet\
--background--pidfile${CHROOT}$PIDFILE--make-pidfile--envTMPDIR=$SOCKDIR\
--execchroot${CHROOT}/usr/sbin/sockd--${SOCKD_OPT}>/dev/null2>&1
eend$?"Failed to start sockd"
}
stop(){
ebegin"Stopping chrooted dante sockd"
start-stop-daemon--stop--quiet--pidfile${CHROOT}$PIDFILE
eend$?"Failed to stop sockd"
}
FILE dante-chroot.shBuild chrooted dante-sockd
#!/bin/bash
# 20150922
# GPL-3
PKGDIR="/var/cache/binpkgs"
CATEGORY="net-proxy"
PN="dante"
CHROOT="/usr/chroot/${PN}"
USER="sockd"
WORKD=`pwd`
# Cleaning chroot directory.
umount"${CHROOT}"/var/lock/"${CHROOT}"/var/log/${PN}"${CHROOT}"/var/run"${CHROOT}"/dev"${CHROOT}"/tmp1>/dev/null2>&1
rm-rf"${CHROOT}"
# Make common directory and symlinks.
mkdir-p"${CHROOT}"/{dev,etc}
if[-d/lib64]
then
mkdir-p"${CHROOT}"/lib64
cd"${CHROOT}"&&ln-slib64lib
else
mkdir-p"${CHROOT}"/{lib}
fi
mkdir-p/var/log/${PN}/var/tmp/${PN}"${CHROOT}"/var/log/${PN}"${CHROOT}"/var/lock"${CHROOT}"/var/run"${CHROOT}"/tmp
chown-R${USER}:root/var/log/${PN}/var/tmp/${PN}"${CHROOT}"/var/log/${PN}
chmod-Ro-rwx/var/log/${PN}/var/tmp/${PN}"${CHROOT}"/var/log/${PN}
# Extract package.
tar-xjphf`ls${PKGDIR}/${CATEGORY}/${PN}*|tail-n1`-C"${CHROOT}"
# Copy necessary libraries.
cp-pRPd/lib/ld-*"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/sbin/${USER}"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
# Copy user information and necessary libraries for it.
cp-pRPd/lib/libnss*/lib/libnsl*/lib/libresolv*"${CHROOT}/lib"
cp/usr/lib/libnss3.so"${CHROOT}/usr/lib"
grep"^${USER}""/etc/passwd">"${CHROOT}/etc/passwd"
# fstab stuff.
if[[`grep"Dante chroot stuff."/etc/fstab`=='']]
then
cat>>/etc/fstab<< EOF
# Dante chroot stuff.
/var/log/${PN} ${CHROOT}/var/log/${PN} none bind,nodev,noexec,nosuid,rw 0 0
/var/tmp/${PN} ${CHROOT}/tmp none bind,nodev,noexec,nosuid,rw 0 0
none ${CHROOT}/var/lock tmpfs rw,nodev,noexec,nosuid,relatime,size=1024k,mode=755 0 0
none ${CHROOT}/var/run tmpfs rw,nodev,noexec,nosuid,relatime,size=1024k,mode=755 0 0
EOF
fi
mount-a
# Configuration.
cp-fp/etc/socks/*${CHROOT}/etc/socks/
cp-fp/etc/conf.d/${PN}-sockd${CHROOT}/etc/conf.d/
cd${WORKD}
cp-f${PN}-sockd/etc/init.d/
cp-f${PN}-sockd${CHROOT}/etc/init.d/
exit0

Chrooted HAVP + libClamAV

FILE /etc/init.d/havpchrooted havp
#!/sbin/openrc-run
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
CHROOT=/usr/chroot/${SVCNAME}
PIDFILE=/var/run/${SVCNAME}/${SVCNAME}.pid
depend(){
# need net
useclamd\
# squid apache2 bfilter mman junkbuster oops polipo privoxy tinyproxy tor wwwoffled
# #havp could be used in conjuction with any parent proxies enumerated above
}
get_havp_opt(){
evalHAVP_1ドル=`awk'/^[ \t]*'1ドル'[ \t]+/ { print 2ドル; }'</etc/${SVCNAME}/${SVCNAME}.config`
}
checkconfig(){
if[!-f${CHROOT}/etc/${SVCNAME}/${SVCNAME}.config];then
eerror"No ${CHROOT}/etc/${SVCNAME}/${SVCNAME}.config file exists!"
return1
fi
localHAVP_USER
get_havp_optUSER
if[-n"${HAVP_USER}"]&&!getentpasswd${HAVP_USER}>/dev/null;then
eerror"${HAVP_USER} user is missing!"
return1
fi
localHAVP_GROUP
get_havp_optGROUP
if[-n"${HAVP_GROUP}"]&&!getentgroup${HAVP_GROUP}>/dev/null;then
eerror"${HAVP_GROUP} group is missing!"
return1
fi
if[!-c${CHROOT}/dev/null];then
mknod-m666${CHROOT}/dev/nullc13
mount-roremount${CHROOT}/dev
fi
checkpath--directory\
--owner"${HAVP_USER:-havp}:${HAVP_GROUP:-havp}"--mode0755--directory`dirname${CHROOT}${PIDFILE}`
checkpath--directory\
--owner"${HAVP_USER:-havp}:${HAVP_GROUP:-havp}"--mode0700${CHROOT}/var/log/havp
checkpath--directory\
--owner"${HAVP_USER:-havp}:${HAVP_GROUP:-havp}"--mode0750"${CHROOT}/var/tmp/${SVCNAME}"
}
start(){
checkconfig||return1
/and/usrfilesystemwhenexecuteit!
ebegin"Starting chrooted HTTP AntiVirus Proxy"
start-stop-daemon--start--pidfile=${CHROOT}${PIDFILE}--execchroot${CHROOT}/usr/sbin/${SVCNAME}>/dev/null
eend$?
}
stop(){
localHAVP_PIDFILE
get_havp_optPIDFILE
ebegin"Stopping chrooted HTTP AntiVirus Proxy"
start-stop-daemon--stop--pidfile=${CHROOT}${PIDFILE}
eend$?
}
FILE havp-chroot.shBuild chrooted havp
#!/bin/bash
# 20150922 havp-chroot.sh
# GPL-3
PKGDIR="/var/cache/binpkgs"
CATEGORY="net-proxy"
PN="havp"
CHROOT="/usr/chroot/${PN}"
WORKD=`pwd`
# Cleaning chroot directory.
umount"${CHROOT}"/var/lib/clamav"${CHROOT}/var/log/${PN}""${CHROOT}"/var/run"${CHROOT}"/var/tmp"${CHROOT}"/dev1>/dev/null2>&1
rm-rf"${CHROOT}"
# Make common directory and symlinks.
mkdir-p"${CHROOT}"/{dev,etc}
if[-d/lib64]
then
mkdir-p"${CHROOT}"/{lib64,usr/lib64}
cd"${CHROOT}"&&ln-slib64lib
cd"${CHROOT}/usr"&&ln-slib64lib
else
mkdir-p"${CHROOT}"/{lib,usr/lib}
fi
mkdir-p/var/log/"${PN}""/var/tmp/${PN}""${CHROOT}"/var/lib/clamav"${CHROOT}/var/log/${PN}""${CHROOT}"/var/tmp/"${CHROOT}"/var/run
chown-R${PN}:${PN}/var/log/${PN}/var/tmp/${PN}"${CHROOT}/var/log/${PN}"
chmod-Ro-rwx/var/log/${PN}/var/tmp/${PN}"${CHROOT}/var/log/${PN}"
chmod-Rg-rwx/var/log/${PN}"${CHROOT}"/var/log/${PN}
# Extract package.
tar-xjphf`ls${PKGDIR}/${CATEGORY}/${PN}*|tail-n1`-C"${CHROOT}"
# Copy necessary libraries.
cp-pRPd/lib/ld-*"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/sbin/${PN}"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/sbin/${PN}"|awk'{print 3ドル}'|grep"^/usr/lib"`"${CHROOT}/usr/lib"
cp-pRPd/usr/lib/libclam*"${CHROOT}/usr/lib"
cp`ldd"${CHROOT}/usr/lib/libclamav.so"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/lib/libclamav.so"|awk'{print 3ドル}'|grep"^/usr/lib"`"${CHROOT}/usr/lib"
cp`ldd"${CHROOT}/usr/lib/libclamunrar_iface.so"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/lib/libclamunrar_iface.so"|awk'{print 3ドル}'|grep"^/usr/lib"`"${CHROOT}/usr/lib"
cp`ldd"${CHROOT}/usr/lib/libclamunrar.so"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
# Copy user information and necessary libraries for it.
cp-pRPd/lib/libnss*/lib/libnsl*/lib/libresolv*"${CHROOT}/lib"
cp/usr/lib/libnss3.so"${CHROOT}/usr/lib"
grep"^${PN}""/etc/passwd">"${CHROOT}/etc/passwd"
grep"^${PN}""/etc/group">"${CHROOT}/etc/group"
# fstab stuff.
if[[`grep"HAVP chroot stuff/ and /usr file system when execute it! ."/etc/fstab`=='']]
then
cat>>/etc/fstab<< EOF
# HAVP chroot stuff.
/var/lib/clamav ${CHROOT}/var/lib/clamav none bind,nodev,noexec,nosuid,rw 0 0
/var/log/${PN} ${CHROOT}/var/log/${PN} none bind,nodev,noexec,nosuid,rw 0 0
/var/tmp/${PN} ${CHROOT}/var/tmp none bind,nodev,noexec,nosuid,rw 0 0
none ${CHROOT}/var/run tmpfs rw,nodev,noexec,nosuid,relatime,size=1024k,mode=755 0 0
none ${CHROOT}/dev tmpfs rw,noexec,nosuid,relatime,size=1024k,nr_inodes=384443,mode=755 0 0
EOF
fi
mount-a
# Configuration.
cp-fpRPd/etc/${PN}/*${CHROOT}/etc/${PN}/
cd${WORKD}
cp-f${PN}/etc/init.d/
cp-f${PN}${CHROOT}/etc/init.d/
exit0

Chrooted Privoxy

FILE /etc/init.d/privoxychrooted privoxy
#!/sbin/openrc-run
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
CHROOT=/usr/chroot/${SVCNAME}
CONFFILE=/etc/${SVCNAME}/config
PIDFILE=/var/run/${SVCNAME}/${SVCNAME}.pid
depend(){
neednet
}
checkconfig(){
if[!-f"${CHROOT}/${CONFFILE}"];then
eerror"Configuration file ${CHROOT}/${CONFFILE} not found!"
return1
fi
checkpath--quiet--mode755\
--owner"${SVCNAME}":"${SVCNAME}"\
--directory`dirname${CHROOT}${PIDFILE}`
if[!-c${CHROOT}/dev/null];then
mknod-m666${CHROOT}/dev/nullc13
mount-roremount${CHROOT}/dev
fi
}
start(){
checkconfig||return1
ebegin"Starting chrooted privoxy"
start-stop-daemon--start--quiet\
--pidfile"${CHROOT}${PIDFILE}"\
--execchroot${CHROOT}/usr/sbin/privoxy\
----pidfile"${PIDFILE}"\
--userprivoxy.privoxy"${CONFFILE}"#2>/dev/null
eend$?
}
stop(){
ebegin"Stopping chrooted privoxy"
start-stop-daemon--stop--quiet--pidfile"${CHROOT}${PIDFILE}"
eend$?
}
FILE privoxy-chroot.shBuild chrooted privoxy
#!/bin/bash
# 20150922
# GPL-3
PKGDIR="/var/cache/binpkgs"
CATEGORY="net-proxy"
PN="privoxy"
CHROOT="/usr/chroot/${PN}"
WORKD=`pwd`
# Cleaning chroot directory.
umount"${CHROOT}"/var/log/${PN}"${CHROOT}"/var/run"${CHROOT}"/dev1>/dev/null2>&1
rm-rf"${CHROOT}"
# Make common directory and symlinks.
mkdir-p"${CHROOT}"/{dev,etc}
if[-d/lib64]
then
mkdir-p"${CHROOT}"/{lib64,usr/lib64}
cd"${CHROOT}"&&ln-slib64lib
cd"${CHROOT}/usr"&&ln-slib64lib
else
mkdir-p"${CHROOT}"/{lib,usr/lib}
fi
# Extract package.
tar-xjphf`ls${PKGDIR}/${CATEGORY}/${PN}*|tail-n1`-C"${CHROOT}"
# Copy necessary libraries.
cp-pRPd/lib/ld-*"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/sbin/${PN}"|awk'{print 3ドル}'|grep"^/lib"`"${CHROOT}/lib"
cp`ldd"${CHROOT}/usr/sbin/${PN}"|awk'{print 3ドル}'|grep"^/usr/lib"`"${CHROOT}/usr/lib"
# Copy user information and necessary libraries for it.
cp-pRPd/lib/libnss*/lib/libnsl*/lib/libresolv*"${CHROOT}/lib"
cp/usr/lib/libnss3.so"${CHROOT}/usr/lib"
grep"^${PN}""/etc/passwd">"${CHROOT}/etc/passwd"
grep"^${PN}""/etc/group">"${CHROOT}/etc/group"
# fstab stuff.
if[[`grep"Privoxy chroot stuff."/etc/fstab`=='']];
then
cat>>/etc/fstab<< EOF
# Privoxy chroot stuff.
/var/log/${PN} ${CHROOT}/var/log/${PN} none bind,nodev,noexec,nosuid,rw 0 0
none ${CHROOT}/var/run tmpfs rw,nodev,noexec,nosuid,relatime,size=1024k,mode=755 0 0
none ${CHROOT}/dev tmpfs rw,noexec,nosuid,relatime,size=1024k,nr_inodes=384443,mode=755 0 0
EOF
fi
mount-a
# Configuration.
cp-frp/etc/${PN}/*${CHROOT}/etc/${PN}/
cd${WORKD}
cp-f${PN}/etc/init.d/
cp-f${PN}${CHROOT}/etc/init.d/
exit0

Chrooted Tor

FILE /etc/init.d/torChrooted tor
#!/sbin/openrc-run
# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
CHROOT=/opt/torchroot
PIDFILE=/var/run/tor/tor.pid
CONFFILE=/etc/tor/torrc
SVCNAME=tor
GRACEFUL_TIMEOUT=${GRACEFUL_TIMEOUT:-60}
# See bug #523552, and https://trac.torproject.org/projects/tor/ticket/5525
# Graceful = wait 30 secs or so until all connections are properly closed.
extra_commands="checkconfig"
extra_started_commands="graceful gracefulstop reload"
description="Anonymizing overlay network for TCP"
description_checkconfig="Check for valid config file."
description_reload="Reload the configuration."
description_graceful="Gracefully restart."
description_gracefulstop="Gracefully stop."
depend(){
neednet
}
checkconfig(){
# first check that it exists
if[!-f${CHROOT}${CONFFILE}];then
eerror"You need to setup ${CHROOT}${CONFFILE} first"
eerror"Example is in ${CHROOT}${CONFFILE}.sample"
return1
fi
if[!-c${CHROOT}/dev/random];then
mknod-m666${CHROOT}/dev/nullc13
mknod-m644${CHROOT}/dev/randomc18
mknod-m644${CHROOT}/dev/urandomc19
mount-roremount${CHROOT}/dev
fi
#checkpath --quiet --mode 755 --owner "${SVCNAME}":"${SVCNAME}" --directory `dirname ${CHROOT}${PIDFILE}`
# now verify whether the configuration is valid
/usr/bin/${SVCNAME}--verify-config-f${CHROOT}${CONFFILE}>/dev/null2>&1
if[$?-eq0];then
einfo"Tor configuration (${CHROOT}${CONFFILE}) is valid."
return0
else
eerror"Tor configuration (${CHROOT}${CONFFILE}) not valid."
/usr/bin/${SVCNAME}--verify-config-f${CHROOT}${CONFFILE}
return1
fi
}
start(){
checkconfig||return1
ebegin"Starting chrooted Tor"
HOME=/var/lib/${SVCNAME}
start-stop-daemon--start--pidfile"${CHROOT}${PIDFILE}"--quiet--execchroot${CHROOT}/usr/bin/${SVCNAME}---f"${CONFFILE}"--runasdaemon1--PidFile"${PIDFILE}">/dev/null2>&1
eend$?
}
stop(){
ebegin"Stopping chrooted Tor"
start-stop-daemon--stop--pidfile"${CHROOT}${PIDFILE}"
eend$?
}
graceful(){
gracefulstop
start
eend$?
}
gracefulstop(){
localrc=0
ebegin"Gracefully stopping chrooted Tor"
ebegin"This can take up to ${GRACEFUL_TIMEOUT} seconds"
start-stop-daemon-P--stop--signalINT-R${GRACEFUL_TIMEOUT}--pidfile"${CHROOT}${PIDFILE}"
rc=$?
eend"done"
eend$rc
}
reload(){
if[!-f${CHROOT}${PIDFILE}];then
eerror"${SVCNAME} isn't running"
return1
fi
checkconfig||return1
ebegin"Reloading chrooted Tor configuration"
start-stop-daemon--signalHUP--pidfile${CHROOT}${PIDFILE}
eend$?
}
FILE tor-chroot.shBuild chrooted tor
#!/bin/bash
# 20170826
# CC0
# torchroot generation script
exportTORCHROOT=/opt/torchroot
mkdir-p$TORCHROOT
mkdir-p$TORCHROOT/etc/tor
mkdir-p$TORCHROOT/dev
mkdir-p$TORCHROOT/usr/bin
mkdir-p$TORCHROOT/usr/lib
mkdir-p$TORCHROOT/usr/share/tor
mkdir-p$TORCHROOT/var/lib
ln-s/usr/lib$TORCHROOT/lib
# Replace this line if you want to copy your own torrc instead of the default one.
cp/etc/tor/torrc$TORCHROOT/etc/tor/
cp/usr/bin/tor$TORCHROOT/usr/bin/
cp/usr/share/tor/geoip*$TORCHROOT/usr/share/tor/
cp/lib/ld-linux-*.so*$TORCHROOT/usr/lib/
cp/lib/libnss*/lib/libnsl*/lib/libresolv*$TORCHROOT/usr/lib/
cp$(ldd/usr/bin/tor|awk'{print 3ドル}'|grep--color=never"^/")$TORCHROOT/usr/lib/
cp-r/var/lib/tor$TORCHROOT/var/lib/
chown-Rtor:tor$TORCHROOT/var/lib/tor
sh-c"grep --color=never ^tor /etc/passwd > $TORCHROOT/etc/passwd"
sh-c"grep --color=never ^tor /etc/group > $TORCHROOT/etc/group"
mknod-m644$TORCHROOT/dev/randomc18
mknod-m644$TORCHROOT/dev/urandomc19
mknod-m666$TORCHROOT/dev/nullc13
if[["$(uname-m)"=="x86_64"]];then
cp/lib64/ld-linux-*.so*$TORCHROOT/usr/lib/
ln-s/usr/lib${TORCHROOT}/lib64
fi

Post install tasks

  • properly configure iptables, so only tor service can output packets to the internet;
  • properly setup proxy variables to all your internet applications and torify them;
  • install and properly configure some privacy addons to you browser.

See also

  • Tor — an onion routing Internet anonymity system.
  • Chroot Guide
  • Chroot — a Unix system utility used to change the apparent root directory to create a new environment logically separate from the main system's root directory.
  • Jail — how to use the jail tool to set up a chroot