Merge branch 'master' into rorcz
[girocco.git] / jailsetup.sh
blob241a40cb076d3146049b8d714941432c6917d5df
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 nobody everyone $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 nobody:x:$("$getent" passwd nobody | cut -d : -f 3-4):unprivileged user:/var/empty:/bin/false
78 EOT
79 [ -z "$sshd_user" ] || cat >>etc/passwd <<EOT
80 sshd:x:$("$getent" passwd $sshd_user | cut -d : -f 3-4):privilege separation:/var/empty:/bin/false
81 _sshd:x:$("$getent" passwd $sshd_user | cut -d : -f 3-4):privilege separation:/var/empty:/bin/false
82 EOT
83 cat >>etc/passwd <<EOT
84 $cfg_cgi_user:x:$("$getent" passwd "$cfg_cgi_user" | cut -d : -f 3-5):/:/bin/true
85 $cfg_mirror_user:x:$("$getent" passwd "$cfg_mirror_user" | cut -d : -f 3-5):/:/bin/true
86 everyone:x:65537:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):every user:/:/bin/false
87 mob:$mobpass:65538:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):the mob:/:/bin/git-shell-verify
88 EOT
89 elif [ -z "$dbonly" ]; then
90 # Make sure an sshd entry is present
91 if ! grep -q '^sshd:' etc/passwd; then
92 echo "*** Error: chroot etc/passwd exists but lacks sshd entry." >&2
93 exit 1
97 if [ ! -s etc/group ]; then
98 cat >etc/group <<EOT
99 _repo:x:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):$cfg_mirror_user
103 mkdir -p etc/sshkeys etc/sshcerts etc/sshactive
104 for ruser in $reserved_users; do
105 touch etc/sshkeys/$ruser
106 done
107 chgrp $cfg_owning_group etc etc/sshkeys etc/sshcerts etc/sshactive ||
108 echo "WARNING: Cannot chgrp $cfg_owning_group the etc directories"
109 chgrp $cfg_owning_group etc/passwd ||
110 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/passwd"
111 chgrp $cfg_owning_group etc/group ||
112 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/group"
113 chmod g+s etc etc/sshkeys etc/sshcerts etc/sshactive ||
114 echo "WARNING: Cannot chmod g+s the etc directories"
115 chmod g+w etc etc/sshkeys etc/sshcerts etc/sshactive ||
116 echo "WARNING: Cannot chmod g+w the etc directories"
117 chmod g+w etc/passwd etc/group ||
118 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
119 chmod -R g+w etc/sshkeys etc/sshcerts etc/sshactive 2>/dev/null ||
120 echo "WARNING: Cannot chmod g+w the sshkeys, sshcerts and/or sshactive files"
122 [ -z "$dbonly" ] || exit 0
124 # Make sure the system type is supported for chroot
125 sysname="$(uname -s | tr A-Z a-z || :)"
126 : ${sysname:=linux}
127 nosshdir=
128 # These equivalents may need to be expanded at some point
129 case "$sysname" in
130 *kfreebsd*)
131 sysname=linux;;
132 *darwin*)
133 sysname=darwin;;
134 *freebsd*)
135 sysname=freebsd;;
136 *linux*)
137 sysname=linux;;
138 esac
140 chrootsetup="$curdir/chrootsetup_$sysname.sh"
141 if ! [ -r "$chrootsetup" -a -s "$chrootsetup" ]; then
142 echo "*** Error: $chrootsetup not found"
143 echo "*** Error: creating a chroot for a `uname -s` system is not supported"
144 exit 1
147 # Set the user and group on the top of the chroot before creating anything else
148 chown 0:0 "$cfg_chroot"
150 # First, setup basic platform-independent directory structure
151 mkdir -p bin dev etc lib sbin var/empty var/run ${cfg_jailreporoot#/}
152 chmod 0444 var/empty
153 rm -rf usr
154 ln -s . usr
156 # Now source the platform-specific script that is responsible for dev device
157 # setup, proc setup (if needed), lib64 setup (if needed) and basic library
158 # installation to make a chroot operational. Additionally it will define a
159 # pull_in_bin function that can be used to add executables and their library
160 # dependencies to the chroot and finally will install a suitable nc.openbsd
161 # compatible version of netcat that supports connections to unix sockets.
162 . "$chrootsetup"
164 # Now, bring in sshd, sh etc.
165 # The $chrootsetup script should have already provided a suitable nc.openbsd
166 install -p "$cfg_basedir/bin/git-shell-verify" bin
167 pull_in_bin "$cfg_basedir/bin/can_user_push" bin
168 pull_in_bin /bin/sh bin
169 pull_in_bin /bin/date bin
170 pull_in_bin /bin/mv bin
171 pull_in_bin /bin/rm bin
172 pull_in_bin /usr/sbin/sshd sbin
174 # ...and the bits of git we need,
175 # being sure to use the configured git and its --exec-path to find the pieces
176 git_exec_path="$("$cfg_git_bin" --exec-path)"
177 for i in git git-index-pack git-receive-pack git-shell git-update-server-info git-upload-archive \
178 git-upload-pack git-unpack-objects git-show-ref git-config git-for-each-ref git-rev-list; do
179 pull_in_bin "$git_exec_path/$i" bin git
180 done
182 # Update permissions on the database files
183 chown $cfg_cgi_user:$cfg_owning_group etc etc/passwd etc/group
184 chown -R $cfg_cgi_user:$cfg_owning_group etc/sshkeys etc/sshcerts etc/sshactive
186 # Set up basic sshd configuration:
187 if [ -n "$nosshdir" ]; then
188 rm -rf etc/ssh
189 ln -s . etc/ssh
190 [ ! -f /etc/moduli ] || { cp -p /etc/moduli etc/; chown 0:0 etc/moduli; }
191 else
192 [ ! -e etc/ssh -o -d etc/ssh ] || rm -rf etc/ssh
193 mkdir -p etc/ssh
194 [ ! -f /etc/ssh/moduli ] || { cp -p /etc/ssh/moduli etc/ssh/; chown 0:0 etc/ssh/moduli; }
196 mkdir -p var/run/sshd
197 if [ ! -s etc/ssh/sshd_config ]; then
198 cat >etc/ssh/sshd_config <<EOT
199 Protocol 2
200 Port $cfg_sshd_jail_port
201 UsePAM no
202 X11Forwarding no
203 AllowAgentForwarding no
204 AllowTcpForwarding no
205 PermitTunnel no
206 IgnoreUserKnownHosts yes
207 PrintLastLog no
208 PrintMotd no
209 UseDNS no
210 PermitRootLogin no
211 UsePrivilegeSeparation yes
213 HostKey /etc/ssh/ssh_host_rsa_key
215 if [ -z "$cfg_disable_dsa" ]; then
216 cat >>etc/ssh/sshd_config <<EOT
217 HostKey /etc/ssh/ssh_host_dsa_key
220 cat >>etc/ssh/sshd_config <<EOT
221 AuthorizedKeysFile /etc/sshkeys/%u
222 StrictModes no
224 # mob user:
225 PermitEmptyPasswords yes
226 ChallengeResponseAuthentication no
227 PasswordAuthentication yes
230 if [ ! -s etc/ssh/ssh_host_rsa_key ]; then
231 bits=2048
232 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
233 bits="$cfg_rsakeylength"
235 yes | ssh-keygen -b "$bits" -t rsa -N "" -C Girocco -f etc/ssh/ssh_host_rsa_key
237 if [ -z "$cfg_disable_dsa" -a ! -s etc/ssh/ssh_host_dsa_key ]; then
238 # ssh-keygen can only create 1024 bit DSA keys
239 yes | ssh-keygen -b 1024 -t dsa -N "" -C Girocco -f etc/ssh/ssh_host_dsa_key
242 # Set the final permissions on the binaries and perform any final twiddling
243 chroot_update_permissions
245 # Change the owner of the sshd-related files
246 chown 0:0 etc/ssh/ssh_* etc/ssh/sshd_*
248 echo "--- Add to your boot scripts: mount --bind $cfg_reporoot $cfg_chroot/$cfg_jailreporoot"
249 echo "--- Add to your boot scripts: mount --bind /proc $cfg_chroot/proc"
250 echo "--- Add to your syslog configuration: listening on socket $cfg_chroot/dev/log"
251 echo "--- To restart a running jail's sshd: sudo kill -HUP \`cat $cfg_chroot/var/run/sshd.pid\`"