FreeBSD tutorial :
Hosting shells in a jail environment.

Author: Clément Laforêt <sheepkiller at cultdeadsheep dot org> Version: 0.1
You can find the latest version of this document here : http://www.cultdeadsheep.org/sheepkiller/FreeBSD/tutorial-jails/

This tutorial aims to be a short tutorial to help you so set a shells hosting environment as secure as I can ;)

I would appreciate comments and improvment :)

I. Introduction :

You can use this tutorial with any FreeBSD version but, if you want to apply the big patch you should have at least FreeBSD 4.5-RELEASE. I tested it with FreeBSD 4.7-RELEASE. It seems to works great :)

The patch provided with this tutorial IS NOT written by me ! It's just a merge from this patches :

So please don't send me any mails about how they works. Thanks.

  1. First of all, update your sources to protects you from known security bugs pkg_add -r cvsup-without-gui wait few seconds to few minutes or cd /usr/ports/net/cvsup-without-gui wait few minutes to a lot ;)

Here my cvsup config file
*default host=goofy.cultdeadsheep.org/ # CHANGE THIS TO YOUR SETTINGS *default base=/usr
*default prefix=/usr
*default release=cvs tag=RELENG_4_7
*default delete use-rel-suffix
*default compress # I comment it ;) src-all

accounts# /usr/local/bin/cvsup cvsup.jail

let's go :)

Get Oliver home patch here :

accounts# cd /usr/
accounts# fetch http://www.cultdeadsheep.org/sheepkiller/FreeBSD/tutorial-jails/df-patch.diff Receiving df-patch.diff (8116 bytes): 100% 8116 bytes transferred in 0.0 seconds (12.25 MBps) accounts# patch -p0 < df-patch.diff

Hmm... Looks like a unified diff to me... (Patch is indented 1 space.)
The text leading up to this was:


| --- src/sys/kern/kern_jail.c.orig Mon Sep 3 10:17:12 2001 | +++ src/sys/kern/kern_jail.c Wed Feb 27 15:40:43 2002
Patching file src/sys/kern/kern_jail.c using Plan A... Hunk #1 succeeded at 69.
Hmm... The next patch looks like a unified diff to me... (Patch is indented 1 space.)
The text leading up to this was:
| --- src/sys/kern/vfs_syscalls.c.orig Mon Jan 7 21:47:34 2002 | +++ src/sys/kern/vfs_syscalls.c Wed Feb 27 13:21:06 2002
Patching file src/sys/kern/vfs_syscalls.c using Plan A... Hunk #1 succeeded at 59.
Hunk #2 succeeded at 73.
Hunk #3 succeeded at 375 (offset 15 lines). Hunk #4 succeeded at 629 (offset 14 lines). Hunk #5 succeeded at 734 (offset 15 lines). Hunk #6 succeeded at 745 (offset 14 lines). Hunk #7 succeeded at 786 (offset 15 lines). Hunk #8 succeeded at 795 (offset 14 lines). Hunk #9 succeeded at 837 (offset 15 lines). Hunk #10 succeeded at 865 (offset 14 lines). Hmm... The next patch looks like a unified diff to me... (Patch is indented 1 space.)
The text leading up to this was:
| --- src/sys/sys/jail.h.orig Wed Nov 1 18:58:06 2000 | +++ src/sys/sys/jail.h Wed Feb 27 15:40:17 2002
Patching file src/sys/sys/jail.h using Plan A... Hunk #1 succeeded at 30.
Hunk #2 succeeded at 50.
Hmm... Ignoring the trailing garbage.
done
accounts#

fetch http://www.trl.ibm.com/projects/security/ssp/freebsd44/protector4.4-1.patch

cd /usr/src
fetch http://www.cultdeadsheep.org/sheepkiller/FreeBSD/tutorial-jails/protector4.4-1.patch patch -p0 < protector4.4-1.patch/

<patch ouput>


|*** /dev/null Thu Nov 15 09:43:48 2001 |--- sys/libkern/stack_smash_handler.c Fri May 18 15:22:09 2001
(Creating file sys/libkern/stack_smash_handler.c...) Patching file sys/libkern/stack_smash_handler.c using Plan A... Hunk #1 succeeded at 1.
done

build and install libgcc
cd /usr/src/gnu/lib/libgcc
make depend && make all install
build and install gcc
cd /usr/src/gnu/usr.bin/cc/cc_int
make depend && make libcc_int.a
cd ..
cd cc_fbsd/
make libcc_fbsd.a
make depend && make all install

ee /etc/make.conf
CFLAGS=" -O -pipe -fstack-protector"
COPTFLAGS=" -O -pipe -fstack-protector" Rebuild All your system.
http://freebsd.cultdeadsheep.org/doc/handbook/makeworld.html

4. edit your make.conf.jail/

accounts# cp make.conf make.conf.jail/
accounts# ee make.conf.jail/

here's mine :

CFLAGS=" -O -pipe -fstack-protector"
COPTFLAGS=" -O -pipe -fstack-protector" ENABLE_SUIDPERL="NO"
MAKE_IDEA="NO"
MAKE_KERBEROS4="NO"
MAKE_KERBEROS5="NO"
ENABLE_SUID_K5SU="NO"
NO_BIND="TRUE"
NO_FORTRAN="TRUE"
NO_CVS="TRUE"
NO_I4B="TRUE"
NO_IPFILTER="TRUE"
NO_LPR="TRUE" NO_MAILWRAPPER="TRUE"
NO_MAKEDEV="TRUE"
NO_OBJC="TRUE"
NO_SENDMAIL="TRUE"
NO_SHAREDOCS="TRUE"
NO_X ="TRUE"
NOGAMES="TRUE"
NOINFO="TRUE"
NOUUCP="TRUE"
PERL_THREADED="TRUE"
PPP_NOSUID="TRUE"

accounts#
rm -fr /usr/obj/
setenv JAIL_DIR /SERVICES/JAILS/accounts cd /usr/src
make clean
mkdir -p $JAIL_DIR
make world DESTDIR=$JAIL_DIR __MAKE_CONF="/etc/make.conf.jail" cd etc
make distribution DESTDIR=$JAIL_DIR -DNOMAKEDEV_RUN _MAKE_CONF="/etc/make.conf.jail" cd $JAIL_DIR/dev
cp /dev/MAKEDEV $JAIL_DIR/dev
sh MAKEDEV jail
cd $JAIL_DIR
ln -sf dev/null kernel
touch $JAIL_DIR/fstab
cp /etc/resolv.conf $JAIL_DIR/etc
setting time zone

You may want to know how jail is, isn't it ? chroot $JAIL_DIR/dev /bin/sh
# find / | wc -l

10929
we'll clean this
# exit
accounts#

7. Configuring host's environement

your rc.conf :)

defaultrouter="192.168.0.254"
hostname="accounts.cultdeadsheep.org/"
ifconfig_rl0="inet 192.168.0.10 netmask 255.255.255.0" ifconfig_rl0_alias0="inet 192.168.0.11 netmask 255.255.255.255" sshd_enable="YES"
usbd_enable="NO"
syslogd_flags="-ss -4 -b 192.168.0.10"
inetd_enable="NO" #if set to "YES" modofy inetd_flags ! inetd_program="/usr/sbin/inetd"
inetd_flags="-wW -a 192.168.0.10"
sendmail_enable="NONE" # please see /etc/defaults/rc.conf for more details


SSH
accounts# ee /etc/ssh/sshd_config
VersionAddendum shells server.

Port 22
#Protocol 2,1
ListenAddress 192.168.0.10

reboot to test :)
##############

accounts# ifconfig
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500

        inet 192.168.0.10 netmask 0xffffff00 broadcast 192.168.0.255
        inet6 fe80::260:67ff:fe76:fdef%rl0 prefixlen 64 scopeid 0x1 
        inet 192.168.0.11 netmask 0xffffffff broadcast 192.168.0.11
        ether 00:60:67:76:fd:ef
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active

lp0: flags=8810<POINTOPOINT,SIMPLEX,MULTICAST> mtu 1500 faith0: flags=8002<BROADCAST,MULTICAST> mtu 1500 lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384

        inet6 ::1 prefixlen 128 
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 
        inet 127.0.0.1 netmask 0xff000000 

ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500 sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552 accounts# netstat -l
Active Internet connections

Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0     48  accounts.ssh           satan.50139            ESTABLISHED
tcp4       0      0  accounts.ssh           *.*                    LISTEN
Active UNIX domain sockets
Address  Type   Recv-Q Send-Q    Inode     Conn     Refs  Nextref Addr
cec13e60 stream      0      0 cec44680        0        0        0 /tmp/ssh-RlIXKrwf/agent.94
cebeff00 dgram       0      0 cebea600        0        0        0 /var/run/log

8. configuring jails

we need only a well configured daemons :) and ports :)

account# mount goofy:/usr/ports /SERVICES/JAILS/accounts/usr/ports ee $JAIL_DIR/etc/rc.conf
like this

sshd_enable="YES"
syslogd_flags="-ss -4 -b 192.168.0.11"
inetd_enable="NO" #if set to "YES" modofy inetd_flags ! inetd_program="/usr/sbin/inetd"
inetd_flags="-wW -a 192.168.0.11"
sendmail_enable="NONE" # please see /etc/defaults/rc.conf for more details portmap_enable="NO"

setting root password
accounts# chroot /SERVICES/JAILS/accounts/ /bin/sh # passwd
Changing local password for root.
New password:
Please enter a password at least 6 characters in length. New password:
Retype new password:
passwd: updating the database...
passwd: done
#tzsetup

quit

Configuring SSH !
accounts# cp /etc/ssh/sshd_config /SERVICES/JAILS/accounts/etc/ssh/ accounts# ee /SERVICES/JAILS/accounts/etc/ssh/sshd_config

Now assuming your DNS and/or /etc/hosts is up to date... We can load our jail for the first time :) mount -t procfs proc $JAIL_DIR/proc
accounts# jail /SERVICES/JAILS/accounts/ shells.cultdeadsheep.org 192.168.0.11 /bin/sh /etc/rc

fstab: /etc/fstab:0: No such file or directory Skipping disk checks ...
fstab: /etc/fstab:0: No such file or directory adjkerntz[141]: sysctl(set_disrtcset): Operation not permitted Doing initial network setup:.
ifconfig: ioctl (SIOCDIFADDR): permission denied lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 Additional routing options: TCP keepalive=YESsysctl: net.inet.tcp.always/_keepalive: Operation not permitted .
Routing daemons:.
Additional daemons: syslogd.
Doing additional network setup:.
Starting final network daemons: creating ssh1 RSA host key Generating public/private rsa1 key pair. Your identification has been saved in /etc/ssh/ssh_host_key. Your public key has been saved in /etc/ssh/ssh_host_key.pub. The key fingerprint is:
fb:b1:59:76:c6:7f:a5:e1:57:40:be:85:e5:38:6c:b2 root@shells.cultdeadsheep.org creating ssh2 RSA host key
Generating public/private rsa key pair. Your identification has been saved in /etc/ssh/ssh_host_rsa_key. Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub. The key fingerprint is:
99:d3:ce:53:fa:20:fb:6e:eb:a3:72:c7:10:07:7a:82 root@shells.cultdeadsheep.org creating ssh2 DSA host key
Generating public/private dsa key pair. Your identification has been saved in /etc/ssh/ssh_host_dsa_key. Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub. The key fingerprint is:
f7:4f:ad:0b:de:0a:cb:eb:49:24:0f:6b:94:70:9c:ef root@shells.cultdeadsheep.org .
ELF ldconfig path: /usr/lib /usr/lib/compat a.out ldconfig path: /usr/lib/aout /usr/lib/compat/aout Starting standard daemons: cron sshd.
Initial rc.i386 initialization:.
Configuring syscons: blanktime/etc/rc.syscons: cannot open /dev/ttyv0: no such file .
Additional ABI support:.
Local package initialization:.
Additional TCP options:.

Sat Nov 30 02:55:09 CET 2002
accounts#

[root@goofy|(514)| root]# ssh root@shells The authenticity of host 'shells.cultdeadsheep.org/ (192.168.0.11)' can't be established. DSA key fingerprint is f7:4f:ad:0b:de:0a:cb:eb:49:24:0f:6b:94:70:9c:ef. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'shells.cultdeadsheep.org/' (DSA) to the list of known hosts. root@shells.cultdeadsheep.org's password: Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994

The Regents of the University of California. All rights reserved.

FreeBSD 4.7-RELEASE-p2 (GENERIC) #0: Sat Nov 30 00:02:25 GMT 2002

Welcome to FreeBSD!

Before seeking technical support, please use the following resources:

If you still have a question or problem, please take the output of `uname -a', along with any relevant error messages, and email it as a question to the questions@FreeBSD.org mailing list. If you are unfamiliar with FreeBSD's directory layout, please refer to the hier(7) man page. If you are not familiar with man pages, type `man man'.

You may also use /stand/sysinstall to re-enter the installation and configuration utility. Edit /etc/motd to change this login announcement.

shells#

accounts# ps aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 208 0.0 0.1 416 216 p0 R+ 1:56AM 0:00.00 ps aux

root     1  0.0  0.1   556  308  ??  ILs   1:36AM   0:00.01 /sbin/init --
root     2  0.0  0.0     0    0  ??  DL    1:36AM   0:00.00  (pagedaemon)
root     3  0.0  0.0     0    0  ??  DL    1:36AM   0:00.00  (vmdaemon)
root     4  0.0  0.0     0    0  ??  DL    1:36AM   0:00.01  (bufdaemon)
root     5  0.0  0.0     0    0  ??  DL    1:36AM   0:00.01  (vnlru)
root     6  0.0  0.0     0    0  ??  DL    1:36AM   0:00.15  (syncer)

root 62 0.0 0.2 960 620 ?? Ss 1:36AM 0:00.16 /usr/sbin/syslogd -ss -4 -b 192.168.0.10 root 69 0.0 0.3 1044 756 ?? Ss 1:36AM 0:00.01 /usr/sbin/cron root 71 0.0 0.6 2380 1816 ?? Is 1:36AM 0:00.16 /usr/sbin/sshd root 86 0.0 0.2 968 664 v0 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv0 root 87 0.0 0.2 968 664 v1 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv1 root 88 0.0 0.2 968 664 v2 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv2 root 89 0.0 0.2 968 664 v3 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv3 root 90 0.0 0.2 968 664 v4 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv4 root 91 0.0 0.2 968 664 v5 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv5 root 92 0.0 0.2 968 664 v6 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv6 root 93 0.0 0.2 968 664 v7 Is+ 1:36AM 0:00.00 /usr/libexec/getty Pc ttyv7 root 94 0.0 0.7 2532 2068 ?? S 1:36AM 0:00.33 sshd: root@ttyp0 (sshd) root 96 0.0 0.4 1344 1012 p0 Ss 1:36AM 0:00.10 -csh (csh) root 175 0.0 0.2 960 632 ?? SsJ 1:55AM 0:00.00 /usr/sbin/syslogd -ss -4 -b 192.168.0.11 root 185 0.0 0.3 1020 744 ?? SsJ 1:55AM 0:00.00 /usr/sbin/cron root 187 0.0 0.8 2912 2180 ?? SsJ 1:55AM 0:00.28 /usr/sbin/sshd root 204 0.0 0.8 3064 2428 ?? SJ 1:55AM 0:00.16 sshd: root@ttyp1 (sshd) root 205 0.0 0.3 1276 904 p1 Ss+J 1:55AM 0:00.02 -csh (csh) root 0 0.0 0.0 0 0 ?? DLs 1:36AM 0:00.00 (swapper)

accounts# accounts# ps aux | awk '$8 ~ /.*J/;' root 175 0.0 0.2 960 632 ?? SsJ 1:55AM 0:00.00 /usr/sbin/syslogd -ss -4 -b 192.168.0.11 root 185 0.0 0.3 1020 744 ?? IsJ 1:55AM 0:00.00 /usr/sbin/cron root 187 0.0 0.8 2912 2180 ?? IsJ 1:55AM 0:00.28 /usr/sbin/sshd root 204 0.0 0.8 3064 2428 ?? IJ 1:55AM 0:00.16 sshd: root@ttyp1 (sshd) root 205 0.0 0.3 1276 904 p1 Is+J 1:55AM 0:00.02 -csh (csh)

to see process in the jail :)

Filesystem 1K-blocks Used Avail Capacity Mounted on goofy:/usr/ports 34971108 24545329 7628091 76% /usr/ports procfs 4 4 0 100% /proc

A little bit buggy ;)

So now I say backup :)

Ok... that's great I've my jails !

9. test !
playing with the jails :)

shells# ping goofy
ping: socket: Operation not permitted
shells# traceroute linuxfr.org
traceroute: icmp socket: Operation not permitted shells#

10. managing jail

removing useless software
First of all :
suid/sgid program

shells# find . -type f -a \( -perm -2000 -o -perm -4000 \) -print ./bin/rcp
./sbin/ccdconfig
./sbin/ping
./sbin/ping6
./sbin/route
./sbin/shutdown
./usr/bin/man
./usr/bin/k5su
./usr/bin/at
./usr/bin/atq
./usr/bin/atrm
./usr/bin/batch
./usr/bin/chpass
./usr/bin/chfn
./usr/bin/chsh
./usr/bin/ypchpass
./usr/bin/ypchfn
./usr/bin/ypchsh
./usr/bin/fstat
./usr/bin/ipcs
./usr/bin/keyinfo
./usr/bin/keyinit
./usr/bin/lock
./usr/bin/login
./usr/bin/netstat
./usr/bin/opieinfo
./usr/bin/opiepasswd
./usr/bin/passwd
./usr/bin/yppasswd
./usr/bin/quota
./usr/bin/rlogin
./usr/bin/rsh
./usr/bin/su
./usr/bin/systat
./usr/bin/top
./usr/bin/vmstat
./usr/bin/wall
./usr/bin/write
./usr/bin/crontab
./usr/sbin/iostat
./usr/sbin/mrinfo
./usr/sbin/mtrace
./usr/sbin/pppd
./usr/sbin/pstat
./usr/sbin/swapinfo
./usr/sbin/sliplogin
./usr/sbin/timedc
./usr/sbin/traceroute
./usr/sbin/traceroute6
./usr/sbin/trpt

shells# rm /bin/rcp /sbin/ccdconfig ./sbin/ping ./sbin/ping6 ./sbin/route ./sbin/shutdown ./usr/bin/k5su ./usr/bin/yppasswd ./usr/bin/quota ./usr/bin/rlogin ./usr/bin/rsh ./usr/sbin/pppd ./usr/sbin/sliplogin ./usr/sbin/timedc ./usr/sbin/mrinfo ./usr/sbin/mtrace override r-sr-xr-x root/wheel schg for /bin/rcp? y rm: /bin/rcp: Operation not permitted
override r-sr-xr-x root/wheel schg for ./usr/bin/k5su? y rm: ./usr/bin/k5su: Operation not permitted override r-sr-xr-x root/wheel schg for ./usr/bin/yppasswd? y rm: ./usr/bin/yppasswd: Operation not permitted override r-sr-xr-x root/wheel schg for ./usr/bin/rlogin? y rm: ./usr/bin/rlogin: Operation not permitted override r-sr-xr-x root/wheel schg for ./usr/bin/rsh? y rm: ./usr/bin/rsh: Operation not permitted override r-sr-x--- root/network schg for ./usr/sbin/sliplogin? y rm: ./usr/sbin/sliplogin: Operation not permitted

shells# chflags noschg ./usr/sbin/sliplogin chflags: ./usr/sbin/sliplogin: Operation not permitted shells#

Great isn't it ? :)

accounts# chflags noschg .//bin/rcp ./usr/bin/k5su ./usr/bin/yppasswd ./usr/bin/rlogin ./usr/bin/rsh ./usr/sbin/sliplogin accounts# rm .//bin/rcp ./usr/bin/k5su ./usr/bin/yppasswd ./usr/bin/rlogin ./usr/bin/rsh ./usr/sbin/sliplogin

As I don't use yp opie and co :
accounts# chflags noschg ./usr/bin/opie* ./usr/bin/yp* accounts# rm ./usr/bin/opie* ./usr/bin/yp*

Restricting access to software
shells# sh
# for i in $(find . -type f -a \( -perm -2000 -o -perm -4000 \) -print); do chmod 750 $i ; done chmod: ./usr/bin/man: Operation not permitted chmod: ./usr/bin/login: Operation not permitted chmod: ./usr/bin/su: Operation not permitted chmod: ./usr/bin/crontab: Operation not permitted # exit
shells#

just what we need :)

kern.ps_showallprocs: 1 -> 0


Copyright 2000-2003 The Cult Of The Dead Sheep
Dessins et images : © Clément Laforêt 2000-2002
Logo : © JOJOProd' 2002 - All Rights Reserved