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.
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:
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>
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