]> git.proxmox.com Git - mirror_lxc.git/blobdiff - templates/lxc-busybox.in
Merge pull request #2055 from marcosps/cgfsng_debug
[mirror_lxc.git] / templates / lxc-busybox.in
index 90b995a0714a82a202fa3a16729f52b057760a75..fa7c78ff79a998942a8bfddca973868c2fc88a1b 100644 (file)
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-# Detect use under userns (unsupported)
-for arg in "$@"; do
-    [ "$arg" == "--" ] && break
-    if [ "$arg" == "--mapped-uid" -o "$arg" == "--mapped-gid" ]; then
-        echo "This template can't be used for unprivileged containers." 1>&2
-        echo "You may want to try the \"download\" template instead." 1>&2
-        exit 1
-    fi
-done
+LXC_MAPPED_UID=
+LXC_MAPPED_GID=
+SSH=
 
 # Make sure the usual locations are in PATH
 export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
@@ -44,6 +38,31 @@ am_in_userns() {
 in_userns=0
 [ $(am_in_userns) = "yes" ] && in_userns=1
 
+copy_binary()
+{
+    binary_path=`which $1`
+    if [ $? -ne 0 ]; then
+        echo "Unable to find $1 binary on the system"
+        return 1
+    fi
+
+    dir_path="${binary_path%/*}"
+    echo /{,usr/}{,s}bin | grep $dir_path >/dev/null 2>&1
+    if [ $? -ne 0 ]; then
+        echo "Binary $1 is located at $binary_path and will not be copied"
+        echo "($dir_path not supported)"
+        return 1
+    fi
+
+    cp $binary_path $rootfs/$binary_path
+    if [ $? -ne 0 ]; then
+        echo "Failed to copy $binary_path to rootfs"
+        return 1
+    fi
+
+    return 0
+}
+
 install_busybox()
 {
     rootfs=$1
@@ -80,9 +99,8 @@ $rootfs/usr/lib64"
 
     # minimal devices needed for busybox
     if [ $in_userns -eq 1 ]; then
-        for dev in tty console tty0 tty1 tty5 ram0 null urandom; do
-            touch $rootfs/dev/$dev
-            echo "/dev/$dev dev/$dev    none bind 0 0" >> $path/fstab
+        for dev in tty console tty0 tty1 ram0 null urandom; do
+            echo "lxc.mount.entry = /dev/$dev dev/$dev    none bind,optional,create=file 0 0" >> $path/config
         done
     else
         mknod -m 666 tty c 5 0       || res=1
@@ -118,14 +136,6 @@ EOF
     # executable
     chmod 744 $rootfs/etc/init.d/rcS || return 1
 
-    # mount points
-    cat <<EOF >> $rootfs/etc/fstab
-shm   /dev/shm   tmpfs   defaults     0      0
-EOF
-
-    # writable and readable for other
-    chmod 644 $rootfs/etc/fstab || return 1
-
     # launch rcS first then make a console available
     # and propose a shell on the tty, the last one is
     # not needed
@@ -176,6 +186,113 @@ EOF
     return $res
 }
 
+install_dropbear()
+{
+    # copy dropbear binary
+    copy_binary dropbear || return 1
+
+    # make symlinks to various ssh utilities
+    utils="\
+        $rootfs/usr/bin/dbclient \
+        $rootfs/usr/bin/scp \
+        $rootfs/usr/bin/ssh \
+        $rootfs/usr/sbin/dropbearkey \
+        $rootfs/usr/sbin/dropbearconvert \
+    "
+    echo $utils | xargs -n1 ln -s /usr/sbin/dropbear
+
+    # add necessary config files
+    mkdir $rootfs/etc/dropbear
+    dropbearkey -t rsa -f $rootfs/etc/dropbear/dropbear_rsa_host_key > /dev/null 2>&1
+    dropbearkey -t dss -f $rootfs/etc/dropbear/dropbear_dss_host_key > /dev/null 2>&1
+
+    echo "'dropbear' ssh utility installed"
+
+    return 0
+}
+
+install_openssh()
+{
+    # tools to be installed
+    server_utils="sshd"
+    client_utils="\
+        ssh \
+        scp \
+        "
+    client_optional_utils="\
+        sftp \
+        ssh-add \
+        ssh-agent \
+        ssh-keygen \
+        ssh-keyscan \
+        ssh-argv0 \
+        ssh-copy-id \
+        "
+
+    # new folders used by ssh
+    ssh_tree="\
+$rootfs/etc/ssh \
+$rootfs/var/empty/sshd \
+$rootfs/var/lib/empty/sshd \
+$rootfs/var/run/sshd \
+"
+
+    # create folder structure
+    mkdir -p $ssh_tree
+    if [ $? -ne 0 ]; then
+        return 1
+    fi
+
+    # copy binaries
+    for bin in $server_utils $client_utils; do
+        copy_binary $bin || return 1
+    done
+
+    for bin in $client_optional_utils; do
+        tool_path=`which $bin` && copy_binary $bin
+    done
+
+    # add user and group
+    cat <<EOF >> $rootfs/etc/passwd
+sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
+EOF
+
+    cat <<EOF >> $rootfs/etc/group
+sshd:x:74:
+EOF
+
+    # generate container keys
+    ssh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key >/dev/null 2>&1
+    ssh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key >/dev/null 2>&1
+
+    # by default setup root password with no password
+    cat <<EOF > $rootfs/etc/ssh/sshd_config
+Port 22
+Protocol 2
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+UsePrivilegeSeparation yes
+KeyRegenerationInterval 3600
+ServerKeyBits 768
+SyslogFacility AUTH
+LogLevel INFO
+LoginGraceTime 120
+PermitRootLogin yes
+StrictModes yes
+RSAAuthentication yes
+PubkeyAuthentication yes
+IgnoreRhosts yes
+RhostsRSAAuthentication no
+HostbasedAuthentication no
+PermitEmptyPasswords yes
+ChallengeResponseAuthentication no
+EOF
+
+    echo "'OpenSSH' utility installed"
+
+    return 0
+}
+
 configure_busybox()
 {
     rootfs=$1
@@ -187,13 +304,6 @@ configure_busybox()
         return 1
     fi
 
-    file $(which busybox) | grep -q "statically linked"
-    if [ $? -ne 0 ]; then
-        echo "warning : busybox is not statically linked."
-        echo "warning : The template script may not correctly"
-        echo "warning : setup the container environment."
-    fi
-
     # copy busybox in the rootfs
     cp $(which busybox) $rootfs/bin
     if [ $? -ne 0 ]; then
@@ -213,67 +323,13 @@ configure_busybox()
     # relink /sbin/init
     ln $rootfs/bin/busybox $rootfs/sbin/init
 
+    # /etc/fstab must exist for "mount -a"
+    touch $rootfs/etc/fstab
+
     # passwd exec must be setuid
     chmod +s $rootfs/bin/passwd
     touch $rootfs/etc/shadow
 
-    # setting passwd for root
-    CHPASSWD_FILE=$rootfs/root/chpasswd.sh
-
-    cat <<EOF >$CHPASSWD_FILE
-echo "setting root password to \"root\""
-
-mount -n --bind /lib $rootfs/lib
-if [ \$? -ne 0 ]; then
-    echo "Failed bind-mounting /lib at $rootfs/lib"
-    exit 1
-fi
-
-chroot $rootfs chpasswd <<EOFF 2>/dev/null
-root:root
-EOFF
-
-
-if [ \$? -ne 0 ]; then
-    echo "Failed to change root password"
-    exit 1
-fi
-
-umount $rootfs/lib
-
-EOF
-
-    lxc-unshare -s MOUNT -- /bin/sh < $CHPASSWD_FILE
-    rm $CHPASSWD_FILE
-
-    # add ssh functionality if dropbear package available on host
-    which dropbear >/dev/null 2>&1
-    if [ $? -eq 0 ]; then
-        # copy dropbear binary
-        cp $(which dropbear) $rootfs/usr/sbin
-        if [ $? -ne 0 ]; then
-            echo "Failed to copy dropbear in the rootfs"
-            return 1
-        fi
-
-        # make symlinks to various ssh utilities
-        utils="\
-            $rootfs/usr/bin/dbclient \
-            $rootfs/usr/bin/scp \
-            $rootfs/usr/bin/ssh \
-            $rootfs/usr/sbin/dropbearkey \
-            $rootfs/usr/sbin/dropbearconvert \
-        "
-        echo $utils | xargs -n1 ln -s /usr/sbin/dropbear
-
-        # add necessary config files
-        mkdir $rootfs/etc/dropbear
-        dropbearkey -t rsa -f $rootfs/etc/dropbear/dropbear_rsa_host_key > /dev/null 2>&1
-        dropbearkey -t dss -f $rootfs/etc/dropbear/dropbear_dss_host_key > /dev/null 2>&1
-
-        echo "'dropbear' ssh utility installed"
-    fi
-
     return 0
 }
 
@@ -283,16 +339,20 @@ copy_configuration()
     rootfs=$2
     name=$3
 
-grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
+grep -q "^lxc.rootfs.path" $path/config 2>/dev/null || echo "lxc.rootfs.path = $rootfs" >> $path/config
 cat <<EOF >> $path/config
-lxc.haltsignal = SIGUSR1
-lxc.utsname = $name
-lxc.tty = 1
-lxc.pts = 1
+lxc.signal.halt = SIGUSR1
+lxc.signal.reboot = SIGTERM
+lxc.uts.name = $name
+lxc.tty.max = 1
+lxc.pty.max = 1
 lxc.cap.drop = sys_module mac_admin mac_override sys_time
 
 # When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.aa_profile = unconfined
+#lxc.apparmor.profile = unconfined
+
+lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
+lxc.mount.entry = shm /dev/shm tmpfs defaults 0 0
 EOF
 
     libdirs="\
@@ -307,18 +367,32 @@ EOF
         fi
     done
     echo "lxc.mount.entry = /sys/kernel/security sys/kernel/security none ro,bind,optional 0 0" >>$path/config
-    echo "lxc.mount.auto = proc:mixed sys" >>$path/config
+}
+
+remap_userns()
+{
+    path=$1
+
+    if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
+        chown $LXC_MAPPED_UID $path/config >/dev/null 2>&1
+        chown -R root $path/rootfs >/dev/null 2>&1
+    fi
+
+    if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
+        chgrp $LXC_MAPPED_GID $path/config >/dev/null 2>&1
+        chgrp -R root $path/rootfs >/dev/null 2>&1
+    fi
 }
 
 usage()
 {
     cat <<EOF
-$1 -h|--help -p|--path=<path>
+$1 -h|--help -p|--path=<path> -s|--ssh={dropbear,openssh}
 EOF
     return 0
 }
 
-options=$(getopt -o hp:n: -l help,rootfs:,path:,name: -- "$@")
+options=$(getopt -o hp:n:s: -l help,rootfs:,path:,name:,mapped-uid:,mapped-gid:,ssh: -- "$@")
 if [ $? -ne 0 ]; then
     usage $(basename $0)
     exit 1
@@ -332,6 +406,9 @@ do
         -p|--path)      path=$2; shift 2;;
         --rootfs)       rootfs=$2; shift 2;;
         -n|--name)      name=$2; shift 2;;
+        --mapped-uid)   LXC_MAPPED_UID=$2; shift 2;;
+        --mapped-gid)   LXC_MAPPED_GID=$2; shift 2;;
+        -s|--ssh)       SSH=$2; shift 2;;
         --)             shift 1; break ;;
         *)              break ;;
     esac
@@ -350,8 +427,8 @@ fi
 # detect rootfs
 config="$path/config"
 if [ -z "$rootfs" ]; then
-    if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
-        rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
+    if grep -q '^lxc.rootfs.path' $config 2>/dev/null ; then
+        rootfs=$(awk -F= '/^lxc.rootfs.path =/{ print $2 }' $config)
     else
         rootfs=$path/rootfs
     fi
@@ -374,3 +451,34 @@ if [ $? -ne 0 ]; then
     echo "failed to write configuration file"
     exit 1
 fi
+
+remap_userns $path
+if [ $? -ne 0 ]; then
+    echo "failed to remap files to user"
+    exit 1
+fi
+
+if [ -n "$SSH" ]; then
+    case "$SSH" in
+        "dropbear")
+            install_dropbear
+            if [ $? -ne 0 ]; then
+                echo "Unable to install 'dropbear' ssh utility"
+                exit 1
+            fi ;;
+        "openssh")
+            install_openssh
+            if [ $? -ne 0 ]; then
+                echo "Unable to install 'OpenSSH' utility"
+                exit 1
+            fi ;;
+        *)
+            echo "$SSH: unrecognized ssh utility"
+            exit 1
+    esac
+else
+    which dropbear >/dev/null 2>&1
+    if [ $? -eq 0 ]; then
+        install_dropbear
+    fi
+fi