jailsetup.sh: verify $cfg_chroot is sane
[girocco.git] / jailsetup.sh
blobe3dc00cf1caacb3858e499f90446c38945661111
1 #!/bin/sh
2 # The Girocco jail setup script
4 # If the first parameter is "dbonly", setup the database only
6 # We are designed to set up the chroot based on the output of
7 # `uname -s` by sourcing a suitable system-specific script.
8 # Unrecognized systems will generate an error. When using
9 # "dbonly" the setup of the chroot binaries is skipped so the
10 # output of `uname -s` does not matter in that case.
12 set -e
14 curdir="`pwd`"
15 srcdir="$curdir/src"
16 getent="$srcdir/getent"
17 . ./shlib.sh
19 dbonly=''
20 [ "$1" != "dbonly" ] || dbonly=1
22 reserved_users="root sshd _sshd mob $cfg_cgi_user $cfg_mirror_user"
24 # Require either sshd or _sshd user unless "dbonly"
25 sshd_user=sshd
26 if ! "$getent" passwd sshd >/dev/null && ! "$getent" passwd _sshd >/dev/null; then
27 if [ -n "$dbonly" ]; then
28 if [ ! -s etc/passwd ]; then
29 # Only complain on initial etc/passwd creation
30 echo "WARNING: no sshd or _sshd user, omitting entries from chroot etc/passwd"
32 sshd_user=
33 else
34 echo "*** Error: You do not have required sshd or _sshd user in system." >&2
35 exit 1
37 else
38 "$getent" passwd sshd >/dev/null || sshd_user=_sshd
41 # Verify we have all we need
42 if ! "$getent" passwd "$cfg_mirror_user" >/dev/null; then
43 echo "*** Error: You do not have \"$cfg_mirror_user\" user in system yet." >&2
44 exit 1
46 if ! "$getent" passwd "$cfg_cgi_user" >/dev/null; then
47 echo "*** Error: You do not have \"$cfg_cgi_user\" user in system yet." >&2
48 exit 1
50 if [ -n "$dbonly" -a -z "$cfg_owning_group" ]; then
51 cfg_owning_group="$("$getent" passwd "$cfg_mirror_user" | cut -d : -f 4)"
52 elif ! "$getent" group "$cfg_owning_group" >/dev/null; then
53 echo "*** Error: You do not have \"$cfg_owning_group\" group in system yet." >&2
54 exit 1
57 # One last paranoid check before we go writing all over everything
58 if [ -z "$cfg_chroot" -o "$cfg_chroot" = "/" ]; then
59 echo "*** Error: chroot location is not set or is invalid." >&2
60 echo "*** Error: perhaps you have an incorrect Config.pm?" >&2
61 exit 1
64 umask 022
65 mkdir -p "$cfg_chroot"
66 cd "$cfg_chroot"
67 chmod 755 "$cfg_chroot" ||
68 echo "WARNING: Cannot chmod $cfg_chroot"
70 # Set up basic user/group configuration; if there isn't any already
71 mobpass=''
72 [ -n "$cfg_mob" ] || mobpass='x'
73 mkdir -p etc
74 if [ ! -s etc/passwd ]; then
75 cat >etc/passwd <<EOT
76 root:x:0:0:system administrator:/var/empty:/bin/false
77 EOT
78 [ -z "$sshd_user" ] || cat >>etc/passwd <<EOT
79 sshd:x:$("$getent" passwd $sshd_user | cut -d : -f 3-4):privilege separation:/var/empty:/bin/false
80 _sshd:x:$("$getent" passwd $sshd_user | cut -d : -f 3-4):privilege separation:/var/empty:/bin/false
81 EOT
82 cat >>etc/passwd <<EOT
83 $cfg_cgi_user:x:$("$getent" passwd "$cfg_cgi_user" | cut -d : -f 3-5):/:/bin/true
84 $cfg_mirror_user:x:$("$getent" passwd "$cfg_mirror_user" | cut -d : -f 3-5):/:/bin/true
85 mob:$mobpass:65538:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):the mob:/:/bin/git-shell-verify
86 EOT
87 elif [ -z "$dbonly" ]; then
88 # Make sure an sshd entry is present
89 if ! grep -q '^sshd:' etc/passwd; then
90 echo "*** Error: chroot etc/passwd exists but lacks sshd entry." >&2
91 exit 1
95 if [ ! -s etc/group ]; then
96 cat >etc/group <<EOT
97 _repo:x:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):$cfg_mirror_user
98 EOT
101 mkdir -p etc/sshkeys etc/sshcerts
102 for ruser in $reserved_users; do
103 touch etc/sshkeys/$ruser
104 done
105 chgrp $cfg_owning_group etc etc/sshkeys etc/sshcerts ||
106 echo "WARNING: Cannot chgrp $cfg_owning_group the etc directories"
107 chgrp $cfg_owning_group etc/passwd ||
108 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/passwd"
109 chgrp $cfg_owning_group etc/group ||
110 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/group"
111 chmod g+s etc etc/sshkeys etc/sshcerts ||
112 echo "WARNING: Cannot chmod g+s the etc directories"
113 chmod g+w etc etc/sshkeys etc/sshcerts ||
114 echo "WARNING: Cannot chmod g+w the etc directories"
115 chmod g+w etc/passwd etc/group ||
116 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
117 chmod -R g+w etc/sshkeys etc/sshcerts 2>/dev/null ||
118 echo "WARNING: Cannot chmod g+w the sshkeys and/or sshcerts files"
120 [ -z "$dbonly" ] || exit 0
122 # Make sure the system type is supported for chroot
123 sysname="$(uname -s | tr A-Z a-z || :)"
124 : ${sysname:=linux}
125 nosshdir=
126 # These equivalents may need to be expanded at some point
127 case "$sysname" in
128 *kfreebsd*)
129 sysname=linux;;
130 *darwin*)
131 sysname=darwin;;
132 *freebsd*)
133 sysname=freebsd;;
134 *linux*)
135 sysname=linux;;
136 esac
138 chrootsetup="$curdir/chrootsetup_$sysname.sh"
139 if ! [ -r "$chrootsetup" -a -s "$chrootsetup" ]; then
140 echo "*** Error: $chrootsetup not found"
141 echo "*** Error: creating a chroot for a `uname -s` system is not supported"
142 exit 1
145 # Set the user and group on the top of the chroot before creating anything else
146 chown 0:0 "$cfg_chroot"
148 # First, setup basic platform-independent directory structure
149 mkdir -p bin dev etc lib sbin var/empty var/run ${cfg_jailreporoot#/}
150 rm -rf usr
151 ln -s . usr
153 # Now source the platform-specific script that is responsible for dev device
154 # setup, proc setup (if needed), lib64 setup (if needed) and basic library
155 # installation to make a chroot operational. Additionally it will define a
156 # pull_in_bin function that can be used to add executables and their library
157 # dependencies to the chroot and finally will install a suitable nc.openbsd
158 # compatible version of netcat that supports connections to unix sockets.
159 . "$chrootsetup"
161 # Now, bring in sshd, sh etc.
162 # The $chrootsetup script should have already provided a suitable nc.openbsd
163 install -p "$cfg_basedir/bin/git-shell-verify" bin
164 pull_in_bin "$cfg_basedir/bin/can_user_push" bin
165 pull_in_bin /bin/sh bin
166 pull_in_bin /bin/date bin
167 pull_in_bin /bin/mv bin
168 pull_in_bin /bin/rm bin
169 # If /sbin/sshd is already running within the chroot, we get Text file busy
170 pull_in_bin /usr/sbin/sshd sbin || :
172 # ...and the bits of git we need,
173 # being sure to use the configured git and its --exec-path to find the pieces
174 git_exec_path="$("$cfg_git_bin" --exec-path)"
175 for i in git git-index-pack git-receive-pack git-shell git-update-server-info git-upload-archive \
176 git-upload-pack git-unpack-objects git-show-ref git-config git-for-each-ref; do
177 pull_in_bin "$git_exec_path/$i" bin
178 done
180 # Update permissions on the database files
181 chown $cfg_cgi_user:$cfg_owning_group etc etc/passwd etc/group
182 chown -R $cfg_cgi_user:$cfg_owning_group etc/sshkeys etc/sshcerts
184 # Set up basic sshd configuration:
185 if [ -n "$nosshdir" ]; then
186 rm -rf etc/ssh
187 ln -s . etc/ssh
188 [ ! -f /etc/moduli ] || { cp -p /etc/moduli etc/; chown 0:0 etc/moduli; }
189 else
190 [ ! -e etc/ssh -o -d etc/ssh ] || rm -rf etc/ssh
191 mkdir -p etc/ssh
192 [ ! -f /etc/ssh/moduli ] || { cp -p /etc/ssh/moduli etc/ssh/; chown 0:0 etc/ssh/moduli; }
194 mkdir -p var/run/sshd
195 if [ ! -s etc/ssh/sshd_config ]; then
196 cat >etc/ssh/sshd_config <<EOT
197 Protocol 2
198 Port 22
199 UsePAM no
200 X11Forwarding no
201 PermitRootLogin no
202 UsePrivilegeSeparation yes
204 AuthorizedKeysFile /etc/sshkeys/%u
205 StrictModes no
207 # mob user:
208 PermitEmptyPasswords yes
209 ChallengeResponseAuthentication no
210 PasswordAuthentication yes
213 if [ ! -s etc/ssh/ssh_host_dsa_key ]; then
214 yes | ssh-keygen -N "" -C Girocco -t dsa -f etc/ssh/ssh_host_dsa_key
216 if [ ! -s etc/ssh/ssh_host_rsa_key ]; then
217 yes | ssh-keygen -N "" -C Girocco -t rsa -f etc/ssh/ssh_host_rsa_key
220 # Set the final permissions on the binaries and perform any final twiddling
221 chroot_update_permissions
223 # Change the owner of the sshd-related files
224 chown 0:0 etc/ssh/ssh_* etc/ssh/sshd_*
226 echo "--- Add to your boot scripts: mount --bind $cfg_reporoot $cfg_chroot/$cfg_jailreporoot"
227 echo "--- Add to your boot scripts: mount --bind /proc $cfg_chroot/proc"
228 echo "--- Add to your syslog configuration: listening on socket $cfg_chroot/dev/log"