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.
16 getent
="$srcdir/getent"
19 # find_std_utility should always come up with the full path to the standard
20 # version of the utility whose name is passed as "$1"
21 getconf
="/usr/bin/getconf"
22 [ -x "$getconf" ] || getconf
="/bin/getconf"
23 [ -x "$getconf" ] || getconf
="getconf"
24 stdpath
="$("unset" -f command; "command" "$getconf" "PATH
" 2>/dev/null)" ||
:
25 ":" "${stdpath:=/bin:/usr/bin}"
26 stdpath
="$stdpath:/sbin:/usr/sbin"
28 "unset" -f unalias command "$1" >/dev
/null
2>&1 ||
:
29 "unalias" -a >/dev
/null
2>&1 ||
:
30 PATH
="$stdpath" && "export" PATH ||
:
35 [ "$1" != "dbonly" ] || dbonly
=1
37 reserved_users
="root sshd _sshd mob git lock bundle nobody everyone $cfg_cgi_user $cfg_mirror_user"
39 # Require either sshd or _sshd user unless "dbonly"
41 if ! "$getent" passwd sshd
>/dev
/null
&& ! "$getent" passwd _sshd
>/dev
/null
; then
42 if [ -n "$dbonly" ]; then
43 if ! [ -s etc
/passwd
]; then
44 # Only complain on initial etc/passwd creation
45 echo "WARNING: no sshd or _sshd user, omitting entries from chroot etc/passwd"
49 echo "*** Error: You do not have required sshd or _sshd user in system." >&2
53 "$getent" passwd sshd
>/dev
/null || sshd_user
=_sshd
56 # Verify we have all we need
57 if ! "$getent" passwd
"$cfg_mirror_user" >/dev
/null
; then
58 echo "*** Error: You do not have \"$cfg_mirror_user\" user in system yet." >&2
61 if ! "$getent" passwd
"$cfg_cgi_user" >/dev
/null
; then
62 echo "*** Error: You do not have \"$cfg_cgi_user\" user in system yet." >&2
65 if [ -n "$dbonly" ] && [ -z "$cfg_owning_group" ]; then
66 cfg_owning_group
="$("$getent" passwd "$cfg_mirror_user" | cut -d : -f 4)"
67 elif ! "$getent" group
"$cfg_owning_group" >/dev
/null
; then
68 echo "*** Error: You do not have \"$cfg_owning_group\" group in system yet." >&2
72 # One last paranoid check before we go writing all over everything
73 if [ -z "$cfg_chroot" ] ||
[ "$cfg_chroot" = "/" ]; then
74 echo "*** Error: chroot location is not set or is invalid." >&2
75 echo "*** Error: perhaps you have an incorrect Config.pm?" >&2
80 mkdir
-p "$cfg_chroot"
82 chmod 755 "$cfg_chroot" ||
83 echo "WARNING: Cannot chmod $cfg_chroot"
86 chmod 0555 var
/empty ||
87 echo "WARNING: Cannot chmod a=rx $cfg_chroot/var/empty"
89 # Set up basic user/group configuration; if there isn't any already
91 [ -n "$cfg_mob" ] || mobpass
='x'
93 if ! [ -s etc
/passwd
]; then
95 root:x:0:0:system administrator:/var/empty:/bin/false
96 nobody:x:$("$getent" passwd nobody | cut -d : -f 3-4):unprivileged user:/var/empty:/bin/false
98 [ -z "$sshd_user" ] ||
cat >>etc
/passwd
<<EOT
99 sshd:x:$("$getent" passwd $sshd_user | cut -d : -f 3-4):privilege separation:/var/empty:/bin/false
100 _sshd:x:$("$getent" passwd $sshd_user | cut -d : -f 3-4):privilege separation:/var/empty:/bin/false
102 [ "$cfg_cgi_user" = "$cfg_mirror_user" ] ||
cat >>etc
/passwd
<<EOT
103 $cfg_cgi_user:x:$("$getent" passwd "$cfg_cgi_user" | cut -d : -f 3-5):/:/bin/true
105 cat >>etc
/passwd
<<EOT
106 $cfg_mirror_user:x:$("$getent" passwd "$cfg_mirror_user" | cut -d : -f 3-5):/:/bin/true
107 everyone:x:65537:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):every user:/:/bin/false
108 mob:$mobpass:65538:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):the mob:/:/bin/git-shell-verify
109 git::65539:$("$getent" passwd nobody | cut -d : -f 4):read-only access:/:/bin/git-shell-verify
111 elif [ -z "$dbonly" ]; then
112 # Make sure an sshd entry is present
113 if ! grep -q '^sshd:' etc
/passwd
; then
114 echo "*** Error: chroot etc/passwd exists but lacks sshd entry." >&2
119 if ! [ -s etc
/group
]; then
121 _repo:x:$("$getent" group "$cfg_owning_group" | cut -d : -f 3):$cfg_mirror_user
125 # Create backups area
128 # Set up basic default Git configuration
129 # Initialize one if none exists or update critical variables for an existing one
132 if [ -e etc
/girocco
/.gitconfig
] && ! [ -f etc
/girocco
/.gitconfig
]; then
133 echo "*** Error: chroot etc/girocco/.gitconfig exists but is not a file." >&2
136 if [ -f etc
/girocco
/.gitconfig
]; then
138 x
="$(git config --file etc/girocco/.gitconfig --get "no--such--section.no such subsection.no--such--key
")" || gcerr
=$?
139 if [ $gcerr -gt 1 ]; then
140 echo "*** Error: chroot etc/girocco/.gitconfig exists but is corrupt." >&2
141 echo "*** Error: either remove it or edit it to correct the problem." >&2
145 if ! [ -s etc
/girocco
/.gitconfig
]; then
146 chmod u
+w etc
/girocco
148 cat >etc
/girocco
/.gitconfig
<<EOT
149 # Any values set here will take effect whenever Girocco runs a git command
153 # $1 => name, $2 => value, $3 => overwrite_flag
154 # if $3 is "2" and $2 is "" value will be unset
155 update_config_item
() {
158 _oldval
="$(git config --file etc/girocco/.gitconfig --get "$1")" || _existsnot
=1
159 if [ -n "$_existsnot" ]; then
160 [ -n "$2" ] ||
[ "$3" != "2" ] ||
return 0
162 [ -n "$3" ] ||
return 0
163 [ "$_oldval" != "$2" ] ||
{ [ "$3" = "2" ] && [ -z "$2" ]; } ||
return 0
165 [ -n "$didchmod" ] ||
{ chmod u
+w etc
/girocco
; didchmod
=1; }
166 if [ "$3" = "2" ] && [ -z "$2" ]; then
167 git config
--file etc
/girocco
/.gitconfig
--unset "$1"
169 git config
--file etc
/girocco
/.gitconfig
"$1" "$2"
171 if [ -n "$_existsnot" ]; then
172 echo "chroot: etc/girocco/.gitconfig: config $1: (created) \"$2\""
173 elif [ "$3" = "2" ] && [ -z "$2" ]; then
174 echo "chroot: etc/girocco/.gitconfig: config $1: (removed)"
176 echo "chroot: etc/girocco/.gitconfig: config $1: \"$_oldval\" -> \"$2\""
179 if [ -n "$cfg_git_no_mmap" ]; then
180 update_config_item core.packedGitWindowSize
1m
1
182 update_config_item core.packedGitWindowSize
32m
1
184 update_config_item core.packedGitLimit
256m
1
185 if [ -n "$var_window_memory" ]; then
186 update_config_item pack.windowMemory
"$var_window_memory" 1
188 if [ -n "$cfg_jgit_compatible_bitmaps" ]; then
189 update_config_item pack.writeBitmapHashCache false
1
191 update_config_item pack.writeBitmapHashCache true
1
193 update_config_item core.pager
"cat" 1
194 update_config_item core.compression
5
195 update_config_item safe.directory
"*" 1
196 update_config_item
diff.renameLimit
250
197 update_config_item transfer.unpackLimit
1 1
198 update_config_item http.lowSpeedLimit
1
199 update_config_item http.lowSpeedTime
600
200 update_config_item receive.advertisePushOptions false
1
201 update_config_item receive.maxInputSize
"${cfg_max_receive_size:-0}" 1
202 update_config_item girocco.notifyHook
"${cfg_default_notifyhook}" 2
203 if [ -n "$defined_cfg_git_client_ua" ]; then
204 update_config_item http.userAgent
"$cfg_git_client_ua" 1
206 update_config_item http.userAgent
"" 2
209 # set up some default ssh client config just in case
210 if [ -e etc
/girocco
/.
ssh ] && ! [ -d etc
/girocco
/.
ssh ]; then
211 echo "*** Error: chroot etc/girocco/.ssh exists but is not a directory." >&2
214 if [ -e etc
/girocco
/.ssh
/config
] && ! [ -f etc
/girocco
/.ssh
/config
]; then
215 echo "*** Error: chroot etc/girocco/.ssh/config exists but is not a file." >&2
218 if ! [ -s etc
/girocco
/.ssh
/config
]; then
219 chmod u
+w etc
/girocco
221 [ -d etc
/girocco
/.
ssh ] || mkdir etc
/girocco
/.
ssh
222 cat >etc
/girocco
/.ssh
/config
<<EOT
223 # Any values set here will take effect whenever Girocco runs an ssh client command
225 StrictHostKeyChecking no
227 UserKnownHostsFile /dev/null
231 [ -z "$didchmod" ] ||
chmod a-w etc
/girocco
233 mkdir
-p etc
/sshkeys etc
/sshcerts etc
/sshactive
234 for ruser
in $reserved_users; do
235 touch etc
/sshkeys
/$ruser
237 chgrp
$cfg_owning_group etc etc
/sshkeys etc
/sshcerts etc
/sshactive ||
238 echo "WARNING: Cannot chgrp $cfg_owning_group the etc directories"
239 chgrp
$cfg_owning_group etc
/passwd ||
240 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/passwd"
241 chgrp
$cfg_owning_group etc
/group ||
242 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/group"
243 chgrp
$cfg_owning_group etc
/backups ||
244 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/backups"
245 chgrp
$cfg_owning_group etc
/girocco etc
/girocco
/.gitconfig ||
246 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/girocco"
247 chgrp
$cfg_owning_group etc
/girocco
/.
ssh etc
/girocco
/.ssh
/config ||
248 echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_chroot/etc/.ssh"
249 chmod g
+s etc etc
/sshkeys etc
/sshcerts etc
/sshactive ||
250 echo "WARNING: Cannot chmod g+s the etc directories"
251 chmod g
+w etc etc
/sshkeys etc
/sshcerts etc
/sshactive ||
252 echo "WARNING: Cannot chmod g+w the etc directories"
253 chmod g
+w etc
/passwd etc
/group ||
254 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
255 chmod go-w etc
/passwd etc
/girocco etc
/girocco
/.gitconfig ||
256 echo "WARNING: Cannot chmod go-w etc/girocco and/or etc/girocco/.gitconfig"
257 chmod go-w etc
/girocco
/.
ssh etc
/girocco
/.ssh
/config ||
258 echo "WARNING: Cannot chmod go-w etc/girocco/.ssh and/or etc/girocco/.ssh/config"
259 chmod go-rwx etc
/girocco
/.ssh
/config ||
260 echo "WARNING: Cannot chmod go-rwx etc/girocco/.ssh/config"
261 chmod a-w etc
/girocco
/.
ssh ||
262 echo "WARNING: Cannot chmod a-w etc/girocco/.ssh"
263 chmod a-w etc
/girocco ||
264 echo "WARNING: Cannot chmod a-w etc/girocco"
265 chmod -R g
+w etc
/sshkeys etc
/sshcerts etc
/sshactive
2>/dev
/null ||
266 echo "WARNING: Cannot chmod g+w the sshkeys, sshcerts and/or sshactive files"
268 # Note time of last install
269 >etc
/sshactive
/_install
271 [ -z "$dbonly" ] ||
exit 0
273 # Make sure the system type is supported for chroot
274 sysname
="$(uname -s | tr A-Z a-z)" ||
:
277 # These equivalents may need to be expanded at some point
291 chrootsetup
="$curdir/chrootsetup_$sysname.sh"
292 if ! [ -f "$chrootsetup" ] ||
! [ -r "$chrootsetup" ] ||
! [ -s "$chrootsetup" ]; then
293 echo "*** Error: $chrootsetup not found" >&2
294 echo "*** Error: creating a chroot for a $(uname -s) system is not supported" >&2
298 # validate reporoot, chroot, jailreporoot and sshd_bin before doing anything more
300 # validates the passed in dir if a second argument is not empty dir must NOT
301 # start with / otherwise it must. A trailing '/' is removed and any duplicated
302 # // are removed and a sole / or empty is disallowed.
304 _check
="$(echo "$1" | tr -s /)"
306 [ -n "$_check" ] && [ "$_check" != "/" ] ||
return 1
308 # must start with '/'
309 case "$_check" in /*) :;; *) return 1; esac
311 # must NOT start with '/'
312 case "$_check" in /*) return 1; esac
317 if ! reporoot
="$(make_valid_dir "$cfg_reporoot")"; then
318 echo "*** Error: invalid Config::reporoot: $cfg_reporoot" >&2
319 echo "*** Error: MUST start with '/' and MUST NOT be '/'" >&2
322 if ! chroot
="$(make_valid_dir "$cfg_chroot")"; then
323 echo "*** Error: invalid Config::chroot: $cfg_chroot" >&2
324 echo "*** Error: MUST start with '/' and MUST NOT be '/'" >&2
327 if ! jailreporoot
="$(make_valid_dir "$cfg_jailreporoot" 1)"; then
328 echo "*** Error: invalid Config::jailreporoot: $cfg_jailreporoot" >&2
329 echo "*** Error: MUST NOT start with '/' and MUST NOT be ''" >&2
333 # chroot MUST NOT be reporoot
334 if [ "$chroot" = "$reporoot" ]; then
335 echo "*** Error: invalid Config::reporoot: $cfg_reporoot" >&2
336 echo "*** Error: invalid Config::chroot: $cfg_chroot" >&2
337 echo "*** Error: reporoot and chroot MUST NOT be the same" >&2
341 # chroot MUST NOT be a subdirectory of reporoot
342 case "$chroot" in "$reporoot"/*)
343 echo "*** Error: invalid Config::reporoot: $cfg_reporoot" >&2
344 echo "*** Error: invalid Config::chroot: $cfg_chroot" >&2
345 echo "*** Error: chroot MUST NOT be a subdirectory of reporoot" >&2
349 # chroot/jailreporoot MUST NOT be a subdirectory of reporoot
350 case "$chroot/$jailreporoot" in "$reporoot"/*)
351 echo "*** Error: invalid Config::reporoot: $cfg_reporoot" >&2
352 echo "*** Error: invalid Config::chroot: $cfg_chroot" >&2
353 echo "*** Error: invalid Config::jailreporoot: $cfg_jailreporoot" >&2
354 echo "*** Error: chroot/jailreporoot MUST NOT be a subdirectory of reporoot" >&2
358 # reporoot MUST NOT be a subdirectory of chroot/jailreporoot
359 case "$reporoot" in "$chroot/$jailreporoot"/*)
360 echo "*** Error: invalid Config::reporoot: $cfg_reporoot" >&2
361 echo "*** Error: invalid Config::chroot: $cfg_chroot" >&2
362 echo "*** Error: invalid Config::jailreporoot: $cfg_jailreporoot" >&2
363 echo "*** Error: reporoot MUST NOT be a subdirectory of chroot/jailreporoot" >&2
367 # sshd_bin MUST be undef (or empty) or a full absolute path
369 case "$cfg_sshd_bin" in *"/../"*) sshd_bin_bad
=1;; ""|
/?
*) :;; *) sshd_bin_bad
=1;; esac
370 [ -z "$sshd_bin_bad" ] ||
{
371 echo "*** Error: invalid Config::sshd_bin $cfg_sshd_bin" >&2
372 echo "*** Error: if set, sshd_bin must be an absolute path" >&2
375 sshd_bin
="$cfg_sshd_bin"
376 [ -n "$sshd_bin" ] || sshd_bin
="$(find_std_utility "sshd
")" ||
{
377 echo "*** Error: Config::sshd_bin is not set and no sshd could be found" >&2
378 echo "*** Error: please set Config::sshd_bin to an absolute path to sshd" >&2
381 [ -x "$sshd_bin" ] && [ -r "$sshd_bin" ] && [ -f "$sshd_bin" ] ||
{
382 echo "*** Error: the selected sshd ('$sshd_bin') was not found, not readable or not executable" >&2
386 # Set the user and group on the top of the chroot before creating anything else
389 # When we create a fork, the alternates always have an absolute path.
390 # If reporoot is not --bind mounted at the same location in chroot we must
391 # create a suitable symlink so the absolute path alternates continue to work
392 # in the ssh chroot or else forks will be broken in there.
393 if [ "$reporoot" != "/$jailreporoot" ]; then
394 mkdirp
="$(dirname "${reporoot#/}")"
395 [ "$mkdirp" = "." ] && mkdirp
=
397 [ -z "$mkdirp" ] || lnback
="$(echo "$mkdirp/" | sed -e 's,[^/]*/,../,g')"
398 [ -z "$mkdirp" ] || mkdir
-p "$chroot/$mkdirp"
399 (umask 0; ln -s -f -n "$lnback$jailreporoot" "$chroot$reporoot")
400 [ $?
-eq 0 ] ||
exit 1
403 # First, setup basic platform-independent directory structure
404 mkdir
-p bin dev etc lib sbin var
/empty var
/run
"$jailreporoot"
411 # Now source the platform-specific script that is responsible for dev device
412 # setup, proc setup (if needed), lib64 setup (if needed) and basic library
413 # installation to make a chroot operational. Additionally it will define a
414 # pull_in_bin function that can be used to add executables and their library
415 # dependencies to the chroot and finally will install a suitable nc.openbsd
416 # compatible version of netcat that supports connections to unix sockets.
419 # Now, bring in sshd, sh etc.
420 # The $chrootsetup script should have already provided a suitable nc.openbsd
421 install -p "$cfg_basedir/bin/git-shell-verify" bin
/git-shell-verify.new
422 install -p "$cfg_basedir/bin/git-askpass-password" bin
/git-askpass-password.new
424 -e 'BEGIN {my @a; m|^(bin/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
425 -e 's|^#!.*|#!/bin/sh| if $. == 1;' \
426 -e 'close ARGV if eof;' \
427 bin
/git-shell-verify.new bin
/git-askpass-password.new
428 mv -f bin
/git-askpass-password.new bin
/git-askpass-password
429 mv -f bin
/git-shell-verify.new bin
/git-shell-verify
430 pull_in_bin
"$cfg_basedir/bin/can_user_push" bin
431 pull_in_bin
"$cfg_basedir/bin/list_packs" bin
432 pull_in_bin
"$cfg_basedir/bin/strftime" bin
433 pull_in_bin
"$cfg_basedir/bin/ulimit512" bin
434 pull_in_bin
"$var_sh_bin" bin
/sh
435 # be paranoid since these are going into the chroot and make sure
436 # that we get the "standard" versions of them (they are all standard "POSIX"
437 # utilities) not some wayward version picked up by a haphazard PATH
438 pull_in_bin
"$(find_std_utility cat )" bin
439 pull_in_bin
"$(find_std_utility chmod )" bin
440 pull_in_bin
"$(find_std_utility date )" bin
441 pull_in_bin
"$(find_std_utility find )" bin
442 pull_in_bin
"$(find_std_utility logger )" bin
443 pull_in_bin
"$(find_std_utility mkdir )" bin
444 pull_in_bin
"$(find_std_utility mv )" bin
445 pull_in_bin
"$(find_std_utility rm )" bin
446 pull_in_bin
"$(find_std_utility sleep )" bin
447 pull_in_bin
"$(find_std_utility sort )" bin
448 pull_in_bin
"$(find_std_utility touch )" bin
449 pull_in_bin
"$(find_std_utility tr )" bin
450 pull_in_bin
"$(find_std_utility wc )" bin
451 # this one's already been validated and might be in a non-standard location
452 pull_in_bin
"$sshd_bin" sbin
454 # ...and the bits of git we need,
455 # being sure to use the configured git and its --exec-path to find the pieces
456 for i
in git git-index-pack git-receive-pack git-shell git-update-server-info \
457 git-upload-archive git-upload-pack git-unpack-objects git-config \
458 git-for-each-ref git-rev-list git-rev-parse git-symbolic-ref
; do
459 pull_in_bin
"$var_git_exec_path/$i" bin git
462 # ...and any extras identified by install.sh
463 # these are also all standard "POSIX" utilities
464 # ones that a decent sh implementation would have built-in already...
465 if [ -n "$GIROCCO_CHROOT_EXTRA_INSTALLS" ]; then
466 for i
in $GIROCCO_CHROOT_EXTRA_INSTALLS; do
467 pull_in_bin
"$(find_std_utility "$
(basename "$i")")" bin
471 # Note time of last jailsetup
472 >etc
/sshactive
/_jailsetup
474 # Update permissions on the database files
475 chown
$cfg_cgi_user:$cfg_owning_group etc
/passwd etc
/group
476 chown
-R $cfg_cgi_user:$cfg_owning_group etc
/sshkeys etc
/sshcerts etc
/sshactive
477 chown
$cfg_mirror_user:$cfg_owning_group etc etc
/backups etc
/girocco etc
/girocco
/.gitconfig
478 chown
$cfg_mirror_user:$cfg_owning_group etc
/girocco
/.
ssh etc
/girocco
/.ssh
/config
480 # Set up basic sshd configuration:
481 if [ -n "$nosshdir" ]; then
484 ! [ -f /etc
/moduli
] ||
{ cp -p /etc
/moduli etc
/; chown
0:0 etc
/moduli
; }
486 ! [ -e etc
/ssh ] ||
[ -d etc
/ssh ] ||
rm -rf etc
/ssh
488 ! [ -f /etc
/ssh
/moduli
] ||
{ cp -p /etc
/ssh
/moduli etc
/ssh
/; chown
0:0 etc
/ssh
/moduli
; }
490 mkdir
-p var
/run
/sshd
491 if ! [ -s etc
/ssh
/sshd_config
]; then
492 cat >etc
/ssh
/sshd_config
<<EOT
494 Port $cfg_sshd_jail_port
497 AllowAgentForwarding no
498 AllowTcpForwarding no
500 IgnoreUserKnownHosts yes
505 UsePrivilegeSeparation yes
506 PubkeyAuthentication yes
507 ChallengeResponseAuthentication no
508 PasswordAuthentication no
509 PermitEmptyPasswords no
511 HostKey /etc/ssh/ssh_host_rsa_key
513 if [ -z "$cfg_disable_dsa" ]; then
514 cat >>etc
/ssh
/sshd_config
<<EOT
515 #PubkeyAcceptedKeyTypes +ssh-dss
516 HostKey /etc/ssh/ssh_host_dsa_key
519 cat >>etc
/ssh
/sshd_config
<<EOT
520 AuthorizedKeysFile /etc/sshkeys/%u
525 PasswordAuthentication yes
526 PermitEmptyPasswords yes
529 if ! [ -s etc
/ssh
/ssh_host_rsa_key
]; then
531 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev
/null
; then
532 bits
="$cfg_rsakeylength"
534 yes | ssh-keygen
-b "$bits" -t rsa
-N "" -C Girocco
-f etc
/ssh
/ssh_host_rsa_key
536 if [ -z "$cfg_disable_dsa" ] && ! [ -s etc
/ssh
/ssh_host_dsa_key
]; then
537 # ssh-keygen can only create 1024 bit DSA keys
538 yes | ssh-keygen
-b 1024 -t dsa
-N "" -C Girocco
-f etc
/ssh
/ssh_host_dsa_key
541 # Set the final permissions on the binaries and perform any final twiddling
542 chroot_update_permissions
544 # Change the owner of the sshd-related files
545 chown
0:0 etc
/ssh
/ssh_
* etc
/ssh
/sshd_
*
547 echo "--- Add to your boot scripts: mount --bind $reporoot $chroot/$jailreporoot"
548 echo "--- Add to your boot scripts: mount --bind /proc $chroot/proc"
549 echo "--- Add to your syslog configuration: listening on socket $chroot/dev/log"
550 echo "--- To restart a running jail's sshd: sudo kill -HUP \$(cat $chroot/var/run/sshd.pid)"