lxc-sshd.in revision b78b2e23a17cdf59d057201508c1f0a90afb7e9e
2582N/A#!/bin/bash
2582N/A
4006N/A#
4459N/A# lxc: linux Container library
2582N/A
2582N/A# Authors:
2582N/A# Daniel Lezcano <daniel.lezcano@free.fr>
7161N/A
7161N/A# This library is free software; you can redistribute it and/or
2582N/A# modify it under the terms of the GNU Lesser General Public
2582N/A# License as published by the Free Software Foundation; either
2582N/A# version 2.1 of the License, or (at your option) any later version.
2582N/A
2582N/A# This library is distributed in the hope that it will be useful,
2582N/A# but WITHOUT ANY WARRANTY; without even the implied warranty of
2582N/A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4006N/A# Lesser General Public License for more details.
4006N/A
4006N/A# You should have received a copy of the GNU Lesser General Public
4006N/A# License along with this library; if not, write to the Free Software
2582N/A# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2582N/A
4006N/A# Detect use under userns (unsupported)
4006N/Afor arg in "$@"; do
4006N/A [ "$arg" = "--" ] && break
4006N/A if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
4459N/A echo "This template can't be used for unprivileged containers." 1>&2
4459N/A echo "You may want to try the \"download\" template instead." 1>&2
4459N/A exit 1
4459N/A fi
4459N/Adone
4459N/A
4459N/A# Make sure the usual locations are in PATH
4459N/Aexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
4459N/A
4459N/Ainstall_sshd()
7161N/A{
4459N/A rootfs=$1
4459N/A
4459N/A tree="\
4459N/A$rootfs/var/run/sshd \
4459N/A$rootfs/var/empty/sshd \
4459N/A$rootfs/var/lib/empty/sshd \
4459N/A$rootfs/etc/init.d \
4459N/A$rootfs/etc/rc.d \
4459N/A$rootfs/etc/ssh \
4459N/A$rootfs/etc/sysconfig/network-scripts \
4459N/A$rootfs/dev/shm \
7161N/A$rootfs/run/shm \
4459N/A$rootfs/proc \
4459N/A$rootfs/sys \
4459N/A$rootfs/bin \
4459N/A$rootfs/sbin \
4459N/A$rootfs/usr \
4459N/A$rootfs/tmp \
4459N/A$rootfs/home \
4459N/A$rootfs/root \
4459N/A$rootfs/lib \
4459N/A$rootfs/lib64"
4459N/A
7161N/A mkdir -p $tree
4459N/A if [ $? -ne 0 ]; then
7161N/A return 1
4006N/A fi
4006N/A
7161N/A return 0
2582N/A}
2582N/A
2582N/Aconfigure_sshd()
2582N/A{
2582N/A rootfs=$1
2582N/A
4459N/A cat <<EOF > $rootfs/etc/passwd
4459N/Aroot:x:0:0:root:/root:/bin/bash
7161N/Asshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
4459N/AEOF
7161N/A
4459N/A cat <<EOF > $rootfs/etc/group
4459N/Aroot:x:0:root
4459N/Asshd:x:74:
4459N/AEOF
4459N/A
4459N/Assh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key
4459N/Assh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key
4459N/A
4459N/A # by default setup root password with no password
4459N/A cat <<EOF > $rootfs/etc/ssh/sshd_config
4459N/APort 22
4459N/AProtocol 2
4459N/AHostKey /etc/ssh/ssh_host_rsa_key
4459N/AHostKey /etc/ssh/ssh_host_dsa_key
4459N/AUsePrivilegeSeparation yes
4459N/AKeyRegenerationInterval 3600
4459N/AServerKeyBits 768
4459N/ASyslogFacility AUTH
7161N/ALogLevel INFO
4459N/ALoginGraceTime 120
4459N/APermitRootLogin yes
4459N/AStrictModes yes
4459N/ARSAAuthentication yes
4459N/APubkeyAuthentication yes
4459N/AIgnoreRhosts yes
4459N/ARhostsRSAAuthentication no
4459N/AHostbasedAuthentication no
4459N/APermitEmptyPasswords yes
4459N/AChallengeResponseAuthentication no
4459N/AEOF
4459N/A
4459N/A if [ -n "$auth_key" -a -f "$auth_key" ]; then
4459N/A u_path="/root/.ssh"
4459N/A root_u_path="$rootfs/$u_path"
4459N/A mkdir -p $root_u_path
4459N/A cp $auth_key "$root_u_path/authorized_keys"
4459N/A chown -R 0:0 "$rootfs/$u_path"
4459N/A chmod 700 "$rootfs/$u_path"
4459N/A echo "Inserted SSH public key from $auth_key into $rootfs/$u_path"
4459N/A fi
4459N/A
4459N/A return 0
4459N/A}
4459N/A
7161N/Acopy_configuration()
4459N/A{
2582N/A path=$1
2582N/A rootfs=$2
7161N/A name=$3
7161N/A
7161N/A grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
7161N/Acat <<EOF >> $path/config
7161N/Alxc.utsname = $name
7161N/Alxc.pts = 1024
7161N/Alxc.kmsg = 0
7161N/Alxc.cap.drop = sys_module mac_admin mac_override sys_time
7161N/A
7161N/A# When using LXC with apparmor, uncomment the next line to run unconfined:
4459N/A#lxc.aa_profile = unconfined
7161N/A
7161N/Alxc.mount.entry = /dev dev none ro,bind 0 0
7161N/Alxc.mount.entry = /lib lib none ro,bind 0 0
7161N/Alxc.mount.entry = /bin bin none ro,bind 0 0
7161N/Alxc.mount.entry = /usr usr none ro,bind 0 0
7161N/Alxc.mount.entry = /sbin sbin none ro,bind 0 0
7161N/Alxc.mount.entry = tmpfs var/run/sshd tmpfs mode=0644 0 0
7161N/Alxc.mount.entry = @LXCTEMPLATEDIR@/lxc-sshd sbin/init none ro,bind 0 0
7161N/Alxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
7161N/Alxc.mount.entry = sysfs sys sysfs ro 0 0
4459N/Alxc.mount.entry = /etc/init.d etc/init.d none ro,bind 0 0
2582N/AEOF
2582N/A
7161N/A # Oracle Linux and Fedora need the following two bind mounted
7161N/A if [ -d /etc/sysconfig/network-scripts ]; then
2582N/A cat <<EOF >> $path/config
7161N/Alxc.mount.entry = /etc/sysconfig/network-scripts etc/sysconfig/network-scripts none ro,bind 0 0
7161N/AEOF
4459N/A fi
4459N/A
2582N/A if [ -d /etc/rc.d ]; then
4459N/A cat <<EOF >> $path/config
4459N/Alxc.mount.entry = /etc/rc.d etc/rc.d none ro,bind 0 0
4459N/AEOF
4459N/A fi
4459N/A
4459N/A # if no .ipv4 section in config, then have the container run dhcp
4459N/A grep -q "^lxc.network.ipv4" $path/config || touch $rootfs/run-dhcp
4459N/A
4459N/A if [ "$(uname -m)" = "x86_64" ]; then
4459N/A cat <<EOF >> $path/config
7161N/Alxc.mount.entry = /lib64 lib64 none ro,bind 0 0
7161N/AEOF
4459N/A fi
2582N/A}
7161N/A
4459N/Ausage()
7161N/A{
4459N/A cat <<EOF
4459N/A$1 -h|--help -p|--path=<path> [--rootfs=<path>]
4459N/AEOF
4459N/A return 0
4459N/A}
7161N/A
7161N/Acheck_for_cmd()
7161N/A{
4459N/A cmd_path=`type $1`
7161N/A if [ $? -ne 0 ]; then
7161N/A echo "The command '$1' $cmd_path is not accessible on the system"
2582N/A exit 1
2582N/A fi
4006N/A # we use cut instead of awk because awk is alternatives symlink on ubuntu
4006N/A # and /etc/alternatives isn't bind mounted
4006N/A cmd_path=`echo $cmd_path |cut -d ' ' -f 3`
7161N/A}
4006N/A
4006N/Aoptions=$(getopt -o hp:n:S: -l help,rootfs:,path:,name:,auth-key: -- "$@")
4006N/Aif [ $? -ne 0 ]; then
4006N/A usage $(basename $0)
2582N/A exit 1
4459N/Afi
4459N/Aeval set -- "$options"
4459N/A
4459N/Awhile true
4006N/Ado
2582N/A case "$1" in
4006N/A -h|--help) usage $0 && exit 0;;
7161N/A -p|--path) path=$2; shift 2;;
4459N/A --rootfs) rootfs=$2; shift 2;;
4459N/A -n|--name) name=$2; shift 2;;
4459N/A -S|--auth-key) auth_key=$2; shift 2;;
4459N/A --) shift 1; break ;;
4459N/A *) break ;;
4459N/A esac
4459N/Adone
4459N/A
4459N/Aif [ "$(id -u)" != "0" ]; then
4459N/A echo "This script should be run as 'root'"
4459N/A exit 1
4459N/Afi
4459N/A
7161N/Aif [ $0 = "/sbin/init" ]; then
4459N/A
4459N/A PATH="$PATH:/bin:/sbin:/usr/sbin"
4459N/A check_for_cmd @SBINDIR@/init.lxc
4459N/A check_for_cmd sshd
4459N/A sshd_path=$cmd_path
4459N/A
4459N/A # run dhcp?
4459N/A if [ -f /run-dhcp ]; then
4459N/A check_for_cmd dhclient
4459N/A check_for_cmd ifconfig
4459N/A touch /etc/fstab
2582N/A rm -f /dhclient.conf
2582N/A cat > /dhclient.conf << EOF
2582N/Asend host-name = gethostname();
2582N/AEOF
2582N/A ifconfig eth0 up
2582N/A dhclient eth0 -cf /dhclient.conf
2582N/A echo "Container IP address:"
2582N/A ifconfig eth0 |grep inet
2582N/A fi
2582N/A
2582N/A exec @SBINDIR@/init.lxc -- $sshd_path
2582N/A exit 1
2582N/Afi
7161N/A
7161N/Aif [ -z "$path" ]; then
2582N/A echo "'path' parameter is required"
2582N/A exit 1
2582N/Afi
2582N/A
2582N/A# detect rootfs
2582N/Aconfig="$path/config"
2582N/Aif [ -z "$rootfs" ]; then
2582N/A if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
2582N/A rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
2582N/A else
2582N/A rootfs=$path/rootfs
2582N/A fi
2582N/Afi
2582N/A
2582N/Ainstall_sshd $rootfs
2582N/Aif [ $? -ne 0 ]; then
2582N/A echo "failed to install sshd's rootfs"
2582N/A exit 1
2582N/Afi
2582N/A
2582N/Aconfigure_sshd $rootfs
7161N/Aif [ $? -ne 0 ]; then
2582N/A echo "failed to configure sshd template"
7161N/A exit 1
2582N/Afi
2582N/A
2582N/Acopy_configuration $path $rootfs $name
2582N/Aif [ $? -ne 0 ]; then
7161N/A echo "failed to write configuration file"
7161N/A exit 1
7161N/Afi
7161N/A