]> git.proxmox.com Git - mirror_lxc.git/blob - templates/lxc-sshd.in
Use consistent /proc, /sys and /sys/fs/cgroup (v2)
[mirror_lxc.git] / templates / lxc-sshd.in
1 #!/bin/bash
2
3 #
4 # lxc: linux Container library
5
6 # Authors:
7 # Daniel Lezcano <daniel.lezcano@free.fr>
8
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public
11 # License as published by the Free Software Foundation; either
12 # version 2.1 of the License, or (at your option) any later version.
13
14 # This library is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # Lesser General Public License for more details.
18
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with this library; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
23 # Detect use under userns (unsupported)
24 for arg in "$@"; do
25 [ "$arg" = "--" ] && break
26 if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
27 echo "This template can't be used for unprivileged containers." 1>&2
28 echo "You may want to try the \"download\" template instead." 1>&2
29 exit 1
30 fi
31 done
32
33 # Make sure the usual locations are in PATH
34 export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
35
36 install_sshd()
37 {
38 rootfs=$1
39
40 tree="\
41 $rootfs/var/run/sshd \
42 $rootfs/var/empty/sshd \
43 $rootfs/var/lib/empty/sshd \
44 $rootfs/etc/init.d \
45 $rootfs/etc/rc.d \
46 $rootfs/etc/ssh \
47 $rootfs/etc/sysconfig/network-scripts \
48 $rootfs/dev/shm \
49 $rootfs/run/shm \
50 $rootfs/proc \
51 $rootfs/sys \
52 $rootfs/bin \
53 $rootfs/sbin \
54 $rootfs/usr \
55 $rootfs/tmp \
56 $rootfs/home \
57 $rootfs/root \
58 $rootfs/lib \
59 $rootfs/lib64"
60
61 mkdir -p $tree
62 if [ $? -ne 0 ]; then
63 return 1
64 fi
65
66 return 0
67 }
68
69 configure_sshd()
70 {
71 rootfs=$1
72
73 cat <<EOF > $rootfs/etc/passwd
74 root:x:0:0:root:/root:/bin/bash
75 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
76 EOF
77
78 cat <<EOF > $rootfs/etc/group
79 root:x:0:root
80 sshd:x:74:
81 EOF
82
83 ssh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key
84 ssh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key
85
86 # by default setup root password with no password
87 cat <<EOF > $rootfs/etc/ssh/sshd_config
88 Port 22
89 Protocol 2
90 HostKey /etc/ssh/ssh_host_rsa_key
91 HostKey /etc/ssh/ssh_host_dsa_key
92 UsePrivilegeSeparation yes
93 KeyRegenerationInterval 3600
94 ServerKeyBits 768
95 SyslogFacility AUTH
96 LogLevel INFO
97 LoginGraceTime 120
98 PermitRootLogin yes
99 StrictModes yes
100 RSAAuthentication yes
101 PubkeyAuthentication yes
102 IgnoreRhosts yes
103 RhostsRSAAuthentication no
104 HostbasedAuthentication no
105 PermitEmptyPasswords yes
106 ChallengeResponseAuthentication no
107 EOF
108
109 if [ -n "$auth_key" -a -f "$auth_key" ]; then
110 u_path="/root/.ssh"
111 root_u_path="$rootfs/$u_path"
112 mkdir -p $root_u_path
113 cp $auth_key "$root_u_path/authorized_keys"
114 chown -R 0:0 "$rootfs/$u_path"
115 chmod 700 "$rootfs/$u_path"
116 echo "Inserted SSH public key from $auth_key into $rootfs/$u_path"
117 fi
118
119 return 0
120 }
121
122 copy_configuration()
123 {
124 path=$1
125 rootfs=$2
126 name=$3
127
128 grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
129 cat <<EOF >> $path/config
130 lxc.utsname = $name
131 lxc.pts = 1024
132 lxc.cap.drop = sys_module mac_admin mac_override sys_time
133
134 # When using LXC with apparmor, uncomment the next line to run unconfined:
135 #lxc.aa_profile = unconfined
136
137 lxc.mount.entry = /dev dev none ro,bind 0 0
138 lxc.mount.entry = /lib lib none ro,bind 0 0
139 lxc.mount.entry = /bin bin none ro,bind 0 0
140 lxc.mount.entry = /usr usr none ro,bind 0 0
141 lxc.mount.entry = /sbin sbin none ro,bind 0 0
142 lxc.mount.entry = tmpfs var/run/sshd tmpfs mode=0644 0 0
143 lxc.mount.entry = @LXCTEMPLATEDIR@/lxc-sshd sbin/init none ro,bind 0 0
144 lxc.mount.entry = /etc/init.d etc/init.d none ro,bind 0 0
145
146 lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
147 EOF
148
149 # Oracle Linux and Fedora need the following two bind mounted
150 if [ -d /etc/sysconfig/network-scripts ]; then
151 cat <<EOF >> $path/config
152 lxc.mount.entry = /etc/sysconfig/network-scripts etc/sysconfig/network-scripts none ro,bind 0 0
153 EOF
154 fi
155
156 if [ -d /etc/rc.d ]; then
157 cat <<EOF >> $path/config
158 lxc.mount.entry = /etc/rc.d etc/rc.d none ro,bind 0 0
159 EOF
160 fi
161
162 # if no .ipv4 section in config, then have the container run dhcp
163 grep -q "^lxc.network.ipv4" $path/config || touch $rootfs/run-dhcp
164
165 if [ "$(uname -m)" = "x86_64" ]; then
166 cat <<EOF >> $path/config
167 lxc.mount.entry = /lib64 lib64 none ro,bind 0 0
168 EOF
169 fi
170 }
171
172 usage()
173 {
174 cat <<EOF
175 $1 -h|--help -p|--path=<path> [--rootfs=<path>]
176 EOF
177 return 0
178 }
179
180 check_for_cmd()
181 {
182 cmd_path=`type $1`
183 if [ $? -ne 0 ]; then
184 echo "The command '$1' $cmd_path is not accessible on the system"
185 exit 1
186 fi
187 # we use cut instead of awk because awk is alternatives symlink on ubuntu
188 # and /etc/alternatives isn't bind mounted
189 cmd_path=`echo $cmd_path |cut -d ' ' -f 3`
190 }
191
192 options=$(getopt -o hp:n:S: -l help,rootfs:,path:,name:,auth-key: -- "$@")
193 if [ $? -ne 0 ]; then
194 usage $(basename $0)
195 exit 1
196 fi
197 eval set -- "$options"
198
199 while true
200 do
201 case "$1" in
202 -h|--help) usage $0 && exit 0;;
203 -p|--path) path=$2; shift 2;;
204 --rootfs) rootfs=$2; shift 2;;
205 -n|--name) name=$2; shift 2;;
206 -S|--auth-key) auth_key=$2; shift 2;;
207 --) shift 1; break ;;
208 *) break ;;
209 esac
210 done
211
212 if [ "$(id -u)" != "0" ]; then
213 echo "This script should be run as 'root'"
214 exit 1
215 fi
216
217 if [ $0 = "/sbin/init" ]; then
218
219 PATH="$PATH:/bin:/sbin:/usr/sbin"
220 check_for_cmd @SBINDIR@/init.lxc
221 check_for_cmd sshd
222 sshd_path=$cmd_path
223
224 # run dhcp?
225 if [ -f /run-dhcp ]; then
226 check_for_cmd dhclient
227 check_for_cmd ifconfig
228 touch /etc/fstab
229 rm -f /dhclient.conf
230 cat > /dhclient.conf << EOF
231 send host-name = gethostname();
232 EOF
233 ifconfig eth0 up
234 dhclient eth0 -cf /dhclient.conf
235 echo "Container IP address:"
236 ifconfig eth0 |grep inet
237 fi
238
239 exec @SBINDIR@/init.lxc -- $sshd_path
240 exit 1
241 fi
242
243 if [ -z "$path" ]; then
244 echo "'path' parameter is required"
245 exit 1
246 fi
247
248 # detect rootfs
249 config="$path/config"
250 if [ -z "$rootfs" ]; then
251 if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
252 rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
253 else
254 rootfs=$path/rootfs
255 fi
256 fi
257
258 install_sshd $rootfs
259 if [ $? -ne 0 ]; then
260 echo "failed to install sshd's rootfs"
261 exit 1
262 fi
263
264 configure_sshd $rootfs
265 if [ $? -ne 0 ]; then
266 echo "failed to configure sshd template"
267 exit 1
268 fi
269
270 copy_configuration $path $rootfs $name
271 if [ $? -ne 0 ]; then
272 echo "failed to write configuration file"
273 exit 1
274 fi