--- layout: wiki title: FreeBSDJail updated: 2010-12-19 15:10 author: rick default: false --- This document will describe the setup of jail(8) and how-to configure all applications to work properly within a jail(8). It has the following design criteria/assumptions: - file:/usr/ports is shared throughout all installations (so are all the configuration for the ports then) and every system build all ports himself. - The sample jail is called `pzwet` and is located in file:/usr/jail/pzwet and has IP `178.63.108.109` assigned to it. - All services dependencies are within their own jail, so I can start and stop jails without affecting the others. - My sendmail setup has spam filtering --powered by file:mail/spamass-milter-- support for *incoming* email only. - I do not list all the dependencies to be installed, but only the 'meta' port services I like to have running on the system. - Keep the list of installed packages as small as possible. As least X11 as possible. Important: Your jail server should not run *any* public facing services which does 'wildcard' binding to IP addresses, else it will 'claim' the service before your jail can take it, causing weird behaviour. To check for potential errors: `sockstat -46l | grep '*:[0-9]'` ### Install Jail First make sure to install the jail using the [method in the handbook](http://www.freebsd.org/doc/handbook/jails-build.html): ```sh master# mkdir -p /usr/jail/pzwet master# cd /usr/src master# make buildworld master# make installworld DESTDIR=/usr/jail/pzwet master# make distribution DESTDIR=/usr/jail/pzwet ``` Ensure your jail if configured (use your own IP of course): ```sh master# cat <> /etc/rc.conf jail_pzwet_rootdir="/usr/jail/pzwet" jail_pzwet_interface="re0" jail_pzwet_hostname="pzwet.vanderzwet.net" jail_pzwet_ip="178.63.108.109" jail_pzwet_devfs_enable="YES" jail_pzwet_devfs_ruleset="devfsrules_jail" jail_pzwet_mount_enable="YES" EOF ``` Mirror the file:/usr/ports within the jail using nullfs(5): ```sh master# mkdir /usr/jail/pzwet/usr/ports ``` ```sh master# cat < /etc/fstab.pzwet /usr/ports /usr/jail/pzwet/usr/ports nullfs rw 0 0 EOF ``` Make it do DNS resolving: ```sh master# cp /etc/resolv.conf //usr/jail/pzwet/etc/resolv.conf ``` Start the jail and login to it: ```sh master# /etc/rc.d/jail start pzwet ``` Tip: The **JID is different** every time the jail restarts (increment) and starts over when the machine is rebooted. There are tools around in ports which provides wrappers around them, like ez-jails. But I prefer to stick to *base* setup only. ```sh master# jls ``` ``` JID IP Address Hostname Path 27 178.63.108.109 pzwet.vanderzwet.net /usr/jail/pzwet ``` ```sh master# jexec 27 csh ``` ### Configure Jail Tip: Jails does **NOT** have a local loopback device, so you will need to use UNIX sockets on places you would normally use the loopback address. ```sh pzwet# cat <> /etc/rc.conf # # Base Services sshd_enable="YES" syslogd_flags="-ss" sendmail_enable="YES" # saving entropy bits is not useful within jails, as your host will do handle this. entropy_dir="NO" # Get some jitter in your cron runs to make sure the does not all run at time same time. # Do NOT use if you rely on having your process to start at 'exact' that time. cron_flags="-J10" # # Port Services spamass_milter_enable="YES" spamass_milter_localflags="-i 178.63.108.109,0.0.0.0 -r -1 -- -U /var/run/spamd.sock" spamd_enable="YES" spamd_flags="--socketpath=/var/run/spamd.sock --nouser-config --username=nobody" mysql_enable="YES" mysql_args="--skip-networking" apache22_enable="YES" EOF ``` Bit more user friendly default csh shell. Include the hostname: ```sh pzwet# echo 'set prompt="\`hostname -s\`% "' >> /etc/csh.cshrc ``` Tip: Make sure your port directory is clean before start. Run `find /usr/ports/ -mindepth 3 -maxdepth 3 -type d -name work | rev | cut -c 5- | rev | xargs -n 1 -I % make -C % clean` if you are not sure. Install the ports: ```sh pzwet# make -C /usr/ports/security/sudo WITH_INSULTS=yes BATCH=yes install clean pzwet# make -C /usr/ports/devel/subversion WITH_MOD_DAV_SVN=yes APACHE_VERSION=22 BATCH=yes install clean pzwet# make -C /usr/ports/ports-mgmt/portaudit BATCH=yes install clean; /usr/local/sbin/portaudit -Fda pzwet# make -C /usr/ports/ports-mgmt/portupgrade BATCH=yes install clean pzwet# make -C /usr/ports/editors/vim-lite BATCH=yes install clean pzwet# make -C /usr/ports/mail/spamass-milter BATCH=yes install clean pzwet# make -C /usr/ports/sysutils/screen BATCH=yes install clean pzwet# make -C /usr/ports/databases/mysql51-server BATCH=yes install clean pzwet# make -C /usr/ports/databases/php52-mysql BATCH=yes install clean pzwet# make -C /usr/ports/textproc/php52-ctype BATCH=yes install clean pzwet# make -C /usr/ports/www/drupal6 WITHOUT_X11=yes APACHE_VERSION=22 WITH_APACHE=yes BATCH=yes install clean pzwet# make -C /usr/ports/mail/mailman WITH_SENDMAIL=yes BATCH=yes install clean pzwet# make -C /usr/ports/www/trac BATCH=yes install clean pzwet# make -C /usr/ports/www/mod_wsgi3 BATCH=yes install clean ``` Create a User Accounts and set Passwords, please replace with your own detail of course: ```sh pzwet# passwd root pzwet# pw user add -m -w random -G wheel -s /bin/csh -c 'Rick van der Zwet' -n rvdzwet ``` All all members of group will to do sudo powers: ```sh pzwet# sed -i '' 's+# %wheel ALL=(ALL) ALL+%wheel ALL=(ALL) ALL+' /usr/local/etc/sudoers; visudo -c ``` Update port INDEX tree and report on pending upgrades every Saturday: ```sh pzwet# echo '0 3 \* \* sat root /usr/sbin/portsnap -I cron update && /usr/sbin/pkg_version -vIL=' >> /etc/crontab ``` #### Highly experimental HACK to automatically execute all commands in this page ```sh ( awk '/<