-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmkchroot.sh
executable file
·236 lines (213 loc) · 5.53 KB
/
mkchroot.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/bin/sh
#
# build-rssh-chroot.sh - build complete rssh chroot cage
#
progname=`basename $0`
Usage() {
echo "$progname [ CHROOTDIR ]"
exit 1
}
if [ $# -gt 1 ]; then
Usage
elif [ -n "$1" ]; then
CHROOTDIR=$1
else
CHROOTDIR=/chroot/
fi
# Sanitize CHROOTDIR to prevent confusion
CHROOTDIR="`readlink --canonicalize "$CHROOTDIR"`"
case $CHROOTDIR in
'')
echo "Error: blank CHROOTDIR" >&2
exit 1
;;
/|*:*|*' '*)
echo "Error: unallowed CHROOTDIR \"$CHROOTDIR\"" >&2
exit 1
;;
/*)
;;
*)
echo "Error: unallowed CHROOTDIR \"$CHROOTDIR\"" >&2
exit 1
;;
esac
if [ ! -d "$CHROOTDIR" ]; then
echo "Error: non-existent \"$CHROOTDIR\"" >&2
exit 1
fi
findlibs() {
bin=$1
if [ -f $bin -a -x $bin -a ! -L $bin ]; then
ldd $bin | awk '{print $1"\n"$3}' | grep ^/
fi
}
rsynctarget() {
target=$1
if [ $# -ne 1 ]; then
echo "Error: Bad argument to rsynctarget, exiting" >&2
exit 1
elif [ ! -e "$target" ]; then
echo "Warning: rsynctarget skipping nonexistent $target" >&2
return 1
fi
#echo " rsynctarget: $target"
case $target in
/*../*)
echo "Warning: replacing '../' based $target" >&2
realname="`dirname "$target" | xargs readlink --canonicalize`"/"`basename "$target"`"
echo " Using $realname" >&2
rsynctarget "$realname"
return $?
;;
/*)
# Verify that target starts with /
;;
*)
echo "Error: no / at start of $target"
exit 1
esac
if [ -L "$target" ]; then
#echo "Replicating symlink: $target"
rsync -a --hard-links --relative "$target" $CHROOTDIR
link="`readlink "$target"`"
case "$link" in
/*)
;;
*)
echo -n " Unqualified symlink: $link, using "
link="`dirname "$target"`/$link"
echo -n "$link"
echo "$link"
;;
esac
rsynctarget "$link"
return $?
elif [ -d "$target" ]; then
# Use readlink to clean out symlinks
target="`readlink --canonicalize $target`"
case "$target" in
/*/)
# Replicate contents of directory
#echo "Replicating contents: $target"
rsync -a --hard-links --relative "$target" $CHROOTDIR
return $?
;;
/*)
# Replicate directory only
echo "Replicating directory: $target"
rsync -a --hard-links --relative --exclude=$target/* "$target" $CHROOTDIR
return $?
;;
*)
# How did we get here? this is wrong!!!
echo "Error: $target does not start with '/', exiting"
exit 1
esac
else
# Use readlink to clean out remaining links or '../' fun and games
target="`readlink --canonicalize $target`"
#echo "Replicating file: $target"
rsync -a --hard-links --relative "$target" "$CHROOTDIR" || return $?
return $?
fi
}
echo "$progname: Replicating bare directories"
LIBDIRS=''
LIBDIRS="$LIBDIRS /dev"
LIBDIRS="$LIBDIRS /etc"
LIBDIRS="$LIBDIRS /usr"
# All librari directories
LIBDIRS="$LIBDIRS /usr/bin"
LIBDIRS="$LIBDIRS /usr/lib"
LIBDIRS="$LIBDIRS /usr/lib64"
LIBDIRS="$LIBDIRS /usr/sbin"
# These are being replaced with symlinks in Fedora and RHEL 7
LIBDIRS="$LIBDIRS /bin"
LIBDIRS="$LIBDIRS /lib"
LIBDIRS="$LIBDIRS /lib64"
LIBDIRS="$LIBDIRS /sbin"
# Temporary for nss debugging
#LIBDIRS="$LIBDIRS /lib/"
#LIBDIRS="$LIBDIRS /lib64/"
#LIBDIRS="$LIBDIRS /usr/lib"
#LIBDIRS="$LIBDIRS /usr/lib64"
for libdir in $LIBDIRS; do
rsynctarget "$libdir"
done
# Get NSS libraries as needed
for nssdir in /lib/ /lib64/ /usr/lib64/ /usr/lib/; do
echo "Searching for libnss_files files: $nssdir"
find $nssdir -name libnss_files\* ! -type d | \
while read libnss; do
echo " Replicating libnss library: $libnss"
rsynctarget $libnss
done
done
DEVICES="$DEVICES /dev/null"
# Useful for enabling syslog or rsyslog
DEVICES="$DEVICES /dev/log"
# Potentially useful for ssh or scp as actual user in chroot cage
#DEVICES="$DEVICES /dev/urandom"
#DEVICES="$DEVICES /dev/random"
#DEVICES="$DEVICES /dev/zero"
for device in $DEVICES; do
rsynctarget "$device"
done
echo "$progname: Replicating files and populated directories"
FILES=''
FILES="$FILES /etc/ld.so.cache"
FILES="$FILES /etc/ld.so.cache.d/"
FILES="$FILES /etc/ld.so.conf"
FILES="$FILES /etc/nsswitch.conf"
FILES="$FILES /etc/hosts"
FILES="$FILES /etc/resolv.conf"
for file in $FILES; do
rsynctarget "$file"
done
echo "$progname: Replicating files and populated directories"
# Works around /bin symlinks in Fedora and RHEL 7
FILES=''
# rssh.conf activatable tools
FILES="$FILES /usr/bin/rssh"
FILES="$FILES /usr/bin/cvs"
FILES="$FILES /usr/bin/rdist"
FILES="$FILES /usr/bin/rsync"
FILES="$FILES /usr/bin/scp"
FILES="$FILES /usr/bin/sftp"
FILES="$FILES /usr/bin/ssh"
if [ -e /etc/redhat-release ]; then
FILES="$FILES /usr/libexec/openssh/sftp-server"
FILES="$FILES /usr/libexec/rssh_chroot_helper"
elif [ -e /etc/debian_version ]; then
FILES="$FILES /usr/lib/openssh/sftp-server"
FILES="$FILES /usr/lib/rssh_chroot_helper"
FILES="$FILES /usr/lib/sftp-server"
else
FILES="$FILES /usr/openssh/sftp-server"
echo Error: No idea where to find rssh_chroot_helper, exiting >&1
exit 1
fi
# Critical for file ownership management
FILES="$FILES /etc/nsswitch.conf"
# Possibly useful shells for debugging
#FILES="$FILES /bin/bash"
#FILES="$FILES /bin/sh"
# Useful for debugging tests inside chroot
#FILES="$FILES /bin/cat"
#FILES="$FILES /bin/su"
#FILES="$FILES /bin/pwd"
#FILES="$FILES /bin/ls"
#FILES="$FILES /usr/bin/ldd"
#FILES="$FILES /usr/bin/id"
#FILES="$FILES /usr/bin/getent"
#FILES="$FILES /usr/bin/groups"
#FILES="$FILES /usr/bin/whoami"
for file in $FILES; do
rsynctarget $file
# Get loadable libraries
findlibs $file | \
while read lib; do
rsynctarget $lib
done
done