123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #!/usr/bin/env bash
- function print_help {
- echo '''
- Light Hardened Container / a super light hardened container using alpine and runc
- v1.0
- Usage: lhc <containername> <containerpath> <datapath>
- '''
- exit -1
- }
- get_arch() {
- ORIG_ARCH=`arch`
- case $ORIG_ARCH in
- aarch64)
- echo "arm64"
- ;;
- *)
- echo $ORIG_ARCH
- ;;
- esac
- }
- # print message to console
- # if there's not second parameter this is an info
- print_msg() {
- CONTENT=$1
- TYPE=${2:+"[\e[91mError\e[0m]"}
- TYPE=${msgType:-"[\e[92mInfo\e[0m]"}
- echo -e $TYPE $CONTENT
- }
- export ARCH=$(get_arch)
- print_msg "Arch: $ARCH"
- ## check if container's name is passed
- ## TODO, has to check if is not '--help' or '-h'
- if [ $# -lt 3 ]
- then
- print_help
- fi
- export CONTAINER_NAME=$1
- export FULL_CONTAINER_PATH=`readlink -f $2`/$CONTAINER_NAME
- export FULL_DATA_PATH=`readlink -f $3`/$CONTAINER_NAME
- print_msg "Container Name: '$CONTAINER_NAME'"
- print_msg "Creating directory '$FULL_CONTAINER_PATH'"
- mkdir $FULL_DATA_PATH
- mkdir $FULL_CONTAINER_PATH
- print_msg "Decompress alpine rootfs into '$FULL_CONTAINER_PATH'"
- sudo tar xf rootfs/alpine-minirootfs-3.5.1-$ARCH.tar.gz -C $FULL_CONTAINER_PATH
- chmod 0755 $FULL_CONTAINER_PATH
- ## set dns
- echo "nameserver 84.200.70.40" >> $FULL_CONTAINER_PATH/etc/resolv.conf
- echo "nameserver 4.2.2.2" >> $FULL_CONTAINER_PATH/etc/resolv.conf
- ## create user
- print_msg "Create user $CONTAINER_NAME"
- useradd $CONTAINER_NAME --no-create-home -p=''
- export CONTAINER_UID=`id $CONTAINER_NAME -u`
- export CONTAINER_GID=`id $CONTAINER_NAME -g`
- print_msg "uid: $CONTAINER_UID gid: $CONTAINER_GID"
- print_msg "Create container $CONTAINER_NAME"
- #export CAPABILITIES=', "CAP_SYS_ADMIN", "CAP_CHOWN", "CAP_FOWNER", "CAP_NET_RAW", "CAP_SETGID", "CAP_SETUID", "CAP_SYS_CHROOT"'
- export CAPABILITIES=""
- ./runc.template > config.json
- ## mount with loggedfs container root
- loggedfs -l files_$CONTAINER_NAME.log -c config.xml -p $FULL_CONTAINER_PATH
- ## run chroot
- print_msg "
- \n\n
- I'm running chroot now, all opened files will be logged in $CONTAINER_NAME.log\n
- \n
- - Install and setup your stuff, if you need some package use 'apk update' and 'apk search'\n
- - Configure your process to use /data as storage path (/ will be read-only)\n
- - Clean $CONTAINER_NAME.log from host machine: 'echo "" > $CONTAINER_NAME.log'\n
- - Start your process and try to activate funtionality, exit on done!\n\n
- "
- mount -t proc proc $FULL_CONTAINER_PATH/proc/
- mount -t sysfs sys $FULL_CONTAINER_PATH/sys/
- mount -o bind /dev $FULL_CONTAINER_PATH/dev/
- chroot $FULL_CONTAINER_PATH sh
- ## let's copy all used files/symlink in a new shiny dir
- escaped_path=$(echo $FULL_CONTAINER_PATH | sed -e 's/\//\\\//g')
- mkdir $FULL_CONTAINER_PATH.tmp
- files=`sed -rn "s/.* open (readwrite |writeonly )?$escaped_path\/?(.*) \{.*/\2/p" < files_$CONTAINER_NAME.log | sort | uniq`
- links=`sed -rn "s/.* readlink $escaped_path\/?(.*) \{.*/\1/p" < files_$CONTAINER_NAME.log | sort | uniq`
- cd $FULL_CONTAINER_PATH
- for f in $files; do
- echo $f
- cp --parents $f $FULL_CONTAINER_PATH.tmp/
- done
- for l in $links; do
- to=$(ls -la $l | sed -rn "s/.*-> (.*)/\1/p")
- echo "$l -> $to"
- ln -s $to $FULL_CONTAINER_PATH.tmp/$l
- done
- cd -
- umount $FULL_CONTAINER_PATH/proc
- umount $FULL_CONTAINER_PATH/dev
- umount $FULL_CONTAINER_PATH/sys
- umount $FULL_CONTAINER_PATH
- ORIG_SIZE=`du -hs $FULL_CONTAINER_PATH`
- LHC_SIZE=`du -hs $FULL_CONTAINER_PATH.tmp`
- print_msg "ORIGINAL CONTAINER SIZE: `du -hs $FULL_CONTAINER_PATH` // N_FILES: `find $FULL_CONTAINER_PATH | wc -l`"
- print_msg "LHC CONTAINER SIZE: `du -hs $FULL_CONTAINER_PATH.tmp` // N_FILES: `find $FULL_CONTAINER_PATH.tmp | wc -l`"
- mv $FULL_CONTAINER_PATH $FULL_CONTAINER_PATH.orig
- mv $FULL_CONTAINER_PATH.tmp $FULL_CONTAINER_PATH
- print_msg "Place specify your init command in config.json and try to run 'runc run $CONTAINER_NAME'$"
- cp config.json runc.config/$CONTAINER_NAME.json
- ###### CHECK #####
|