Move image file to the script directory instead of build directory Add compression and filesystem type options Limit cpu usage
486 lines
16 KiB
Bash
Executable File
486 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
# This is the HardKernel ODROID XU3 Kali ARM build script - http://hardkernel.com/main/main.php
|
|
# A trusted Kali Linux image created by Offensive Security - http://www.offensive-security.com
|
|
|
|
# Uncomment to activate debug
|
|
# debug=true
|
|
|
|
if [ "$debug" = true ]; then
|
|
exec > >(tee -a -i "${0%.*}.log") 2>&1
|
|
set -x
|
|
fi
|
|
|
|
# Architecture
|
|
architecture=${architecture:-"armhf"}
|
|
# Generate a random machine name to be used.
|
|
machine=$(tr -cd 'A-Za-z0-9' < /dev/urandom | head -c16 ; echo)
|
|
# Custom hostname variable
|
|
hostname=${2:-kali}
|
|
# Custom image file name variable - MUST NOT include .img at the end.
|
|
imagename=${3:-kali-linux-$1-odroidxu3}
|
|
# Suite to use, valid options are:
|
|
# kali-rolling, kali-dev, kali-bleeding-edge, kali-dev-only, kali-experimental, kali-last-snapshot
|
|
suite=${suite:-"kali-rolling"}
|
|
# Free space rootfs in MiB
|
|
free_space="300"
|
|
# /boot partition in MiB
|
|
bootsize="128"
|
|
# Select compression, xz or none
|
|
compress="xz"
|
|
# Choose filesystem format to format ( ext3 or ext4 )
|
|
fstype="ext3"
|
|
# If you have your own preferred mirrors, set them here.
|
|
mirror=${4:-"http://http.kali.org/kali"}
|
|
# Gitlab url Kali repository
|
|
kaligit="https://gitlab.com/kalilinux"
|
|
# Github raw url
|
|
githubraw="https://raw.githubusercontent.com"
|
|
|
|
# Check EUID=0 you can run any binary as root.
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo "This script must be run as root"
|
|
exit 1
|
|
fi
|
|
|
|
# Pass version number
|
|
if [[ $# -eq 0 ]] ; then
|
|
echo "Please pass version number, e.g. $0 2.0, and (if you want) a hostname, default is kali"
|
|
exit 0
|
|
fi
|
|
|
|
# Check exist bsp directory.
|
|
if [ ! -e "bsp" ]; then
|
|
echo "Error: missing bsp directory structure"
|
|
echo "Please clone the full repository ${kaligit}/build-scripts/kali-arm"
|
|
exit 255
|
|
fi
|
|
|
|
# Current directory
|
|
current_dir="$(pwd)"
|
|
# Base directory
|
|
basedir=${current_dir}/odroidxu3-"$1"
|
|
# Working directory
|
|
work_dir="${basedir}/kali-${architecture}"
|
|
|
|
# Check directory build
|
|
if [ -e "${basedir}" ]; then
|
|
echo "${basedir} directory exists, will not continue"
|
|
exit 1
|
|
elif [[ ${current_dir} =~ [[:space:]] ]]; then
|
|
echo "The directory "\"${current_dir}"\" contains whitespace. Not supported."
|
|
exit 1
|
|
else
|
|
echo "The basedir thinks it is: ${basedir}"
|
|
mkdir -p ${basedir}
|
|
fi
|
|
|
|
components="main,contrib,non-free"
|
|
arm="kali-linux-arm ntpdate"
|
|
base="apt-transport-https apt-utils bash-completion console-setup dialog e2fsprogs ifupdown initramfs-tools inxi iw man-db mlocate netcat-traditional net-tools parted pciutils psmisc rfkill screen tmux unrar usbutls vim wget whiptail zerofree"
|
|
desktop="kali-desktop-xfce kali-root-login xserver-xorg-video-fbdev xfonts-terminus xinput"
|
|
tools="kali-linux-default"
|
|
services="apache2 atftpd"
|
|
extras="alsa-utils bc bison bluez bluez-firmware kali-linux-core libnss-systemd libssl-dev triggerhappy"
|
|
|
|
packages="${arm} ${base} ${services}"
|
|
|
|
# Automatic configuration to use an http proxy, such as apt-cacher-ng.
|
|
# You can turn off automatic settings by uncommenting apt_cacher=off.
|
|
# apt_cacher=off
|
|
# By default the proxy settings are local, but you can define an external proxy.
|
|
# proxy_url="http://external.intranet.local"
|
|
apt_cacher=${apt_cacher:-"$(lsof -i :3142|cut -d ' ' -f3 | uniq | sed '/^\s*$/d')"}
|
|
if [ -n "$proxy_url" ]; then
|
|
export http_proxy=$proxy_url
|
|
elif [ "$apt_cacher" = "apt-cacher-ng" ] ; then
|
|
if [ -z "$proxy_url" ]; then
|
|
proxy_url=${proxy_url:-"http://127.0.0.1:3142/"}
|
|
export http_proxy=$proxy_url
|
|
fi
|
|
fi
|
|
|
|
# create the rootfs - not much to modify here, except maybe throw in some more packages if you want.
|
|
debootstrap --foreign --keyring=/usr/share/keyrings/kali-archive-keyring.gpg --include=kali-archive-keyring \
|
|
--components=${components} --arch ${architecture} ${suite} ${work_dir} http://http.kali.org/kali
|
|
|
|
# systemd-nspawn enviroment
|
|
systemd-nspawn_exec(){
|
|
qemu_bin=/usr/bin/qemu-arm-static
|
|
LANG=C systemd-nspawn -q --bind-ro ${qemu_bin} -M ${machine} -D ${work_dir} "$@"
|
|
}
|
|
|
|
# debootstrap second stage
|
|
systemd-nspawn_exec /debootstrap/debootstrap --second-stage
|
|
|
|
cat << EOF > ${work_dir}/etc/apt/sources.list
|
|
deb ${mirror} ${suite} ${components//,/ }
|
|
#deb-src ${mirror} ${suite} ${components//,/ }
|
|
EOF
|
|
|
|
# Set hostname
|
|
echo "${hostname}" > ${work_dir}/etc/hostname
|
|
|
|
# So X doesn't complain, we add kali to hosts
|
|
cat << EOF > ${work_dir}/etc/hosts
|
|
127.0.0.1 ${hostname} localhost
|
|
::1 localhost ip6-localhost ip6-loopback
|
|
fe00::0 ip6-localnet
|
|
ff00::0 ip6-mcastprefix
|
|
ff02::1 ip6-allnodes
|
|
ff02::2 ip6-allrouters
|
|
EOF
|
|
|
|
# Disable IPv6
|
|
cat << EOF > ${work_dir}/etc/modprobe.d/ipv6.conf
|
|
# Don't load ipv6 by default
|
|
alias net-pf-10 off
|
|
EOF
|
|
|
|
cat << EOF > ${work_dir}/etc/network/interfaces
|
|
auto lo
|
|
iface lo inet loopback
|
|
|
|
auto eth0
|
|
allow-hotplug eth0
|
|
iface eth0 inet dhcp
|
|
EOF
|
|
|
|
# DNS server
|
|
echo "nameserver 8.8.8.8" > ${work_dir}/etc/resolv.conf
|
|
|
|
# Copy directory bsp into build dir.
|
|
cp -rp bsp ${work_dir}
|
|
|
|
export MALLOC_CHECK_=0 # workaround for LP: #520465
|
|
|
|
# Enable the use of http proxy in third-stage in case it is enabled.
|
|
if [ -n "$proxy_url" ]; then
|
|
echo "Acquire::http { Proxy \"$proxy_url\" };" > ${work_dir}/etc/apt/apt.conf.d/66proxy
|
|
fi
|
|
|
|
# Third stage
|
|
cat << EOF > ${work_dir}/third-stage
|
|
#!/bin/bash -e
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
export RUNLEVEL=1
|
|
ln -sf /bin/true /usr/sbin/invoke-rc.d
|
|
echo -e "#!/bin/sh\nexit 101" > /usr/sbin/policy-rc.d
|
|
chmod 755 /usr/sbin/policy-rc.d
|
|
|
|
apt-get update
|
|
|
|
apt-get -y install binutils ca-certificates console-common git initramfs-tools less locales nano u-boot-tools
|
|
|
|
# Create kali user with kali password... but first, we need to manually make some groups because they don't yet exist...
|
|
# This mirrors what we have on a pre-installed VM, until the script works properly to allow end users to set up their own... user.
|
|
# However we leave off floppy, because who a) still uses them, and b) attaches them to an SBC!?
|
|
# And since a lot of these have serial devices of some sort, dialout is added as well.
|
|
# scanner, lpadmin and bluetooth have to be added manually because they don't
|
|
# yet exist in /etc/group at this point.
|
|
groupadd -r -g 118 bluetooth
|
|
groupadd -r -g 113 lpadmin
|
|
groupadd -r -g 122 scanner
|
|
groupadd -g 1000 kali
|
|
|
|
useradd -m -u 1000 -g 1000 -G sudo,audio,bluetooth,cdrom,dialout,dip,lpadmin,netdev,plugdev,scanner,video,kali -s /bin/bash kali
|
|
echo "kali:kali" | chpasswd
|
|
|
|
aptops="--allow-change-held-packages -o dpkg::options::=--force-confnew"
|
|
|
|
# This looks weird, but we do it twice because every so often, there's a failure to download from the mirror
|
|
# So to workaround it, we attempt to install them twice.
|
|
apt-get install -y \$aptops ${packages} || apt-get --yes --fix-broken install
|
|
apt-get install -y \$aptops ${packages} || apt-get --yes --fix-broken install
|
|
apt-get install -y \$aptops ${desktop} ${extras} ${tools} || apt-get --yes --fix-broken install
|
|
apt-get install -y \$aptops ${desktop} ${extras} ${tools} || apt-get --yes --fix-broken install
|
|
apt-get install -y \$aptops --autoremove systemd-timesyncd || apt-get --yes --fix-broken install
|
|
apt-get dist-upgrade -y \$aptops
|
|
|
|
apt-get -y --allow-change-held-packages --purge autoremove
|
|
|
|
# Linux console/Keyboard configuration
|
|
echo 'console-common console-data/keymap/policy select Select keymap from full list' | debconf-set-selections
|
|
echo 'console-common console-data/keymap/full select en-latin1-nodeadkeys' | debconf-set-selections
|
|
|
|
# Copy all services
|
|
cp -p /bsp/services/all/*.service /etc/systemd/system/
|
|
|
|
# Regenerated the shared-mime-info database on the first boot
|
|
# since it fails to do so properly in a chroot.
|
|
systemctl enable smi-hack
|
|
|
|
# Generate SSH host keys on first run
|
|
systemctl enable regenerate_ssh_host_keys
|
|
# Enable sshd
|
|
systemctl enable ssh
|
|
|
|
cd /root
|
|
apt download -o APT::Sandbox::User=root ca-certificates 2>/dev/null
|
|
|
|
# Copy bashrc
|
|
cp /etc/skel/.bashrc /root/.bashrc
|
|
|
|
# Set a REGDOMAIN. This needs to be done or wireless doesn't work correctly on the RPi 3B+
|
|
sed -i -e 's/REGDOM.*/REGDOMAIN=00/g' /etc/default/crda
|
|
|
|
# Serial console settings.
|
|
# (Auto login on serial console)
|
|
#T1:12345:respawn:/sbin/agetty 115200 ttySAC2 vt100 >> /etc/inittab
|
|
# (No auto login)
|
|
#T1:12345:respawn:/bin/login -f root ttySAC2 /dev/ttySAC2 2>&1' >> /etc/inittab
|
|
# Make sure ttySACX is in root/etc/securetty so root can login on serial console below.
|
|
echo 'T1:12345:respawn:/bin/login -f root ttySAC2 /dev/ttySAC2 2>&1' >> /etc/inittab
|
|
|
|
# Try and make the console a bit nicer
|
|
# Set the terminus font for a bit nicer display.
|
|
sed -i -e 's/FONTFACE=.*/FONTFACE="Terminus"/' /etc/default/console-setup
|
|
sed -i -e 's/FONTSIZE=.*/FONTSIZE="6x12"/' /etc/default/console-setup
|
|
|
|
# Fix startup time from 5 minutes to 15 secs on raise interface wlan0
|
|
sed -i 's/^TimeoutStartSec=5min/TimeoutStartSec=15/g' "/usr/lib/systemd/system/networking.service"
|
|
|
|
rm -f /usr/sbin/policy-rc.d
|
|
unlink /usr/sbin/invoke-rc.d
|
|
EOF
|
|
|
|
# Run third stage
|
|
chmod 755 ${work_dir}/third-stage
|
|
systemd-nspawn_exec /third-stage
|
|
|
|
# Clean system
|
|
systemd-nspawn_exec << EOF
|
|
rm -f /0
|
|
rm -rf /bsp
|
|
fc-cache -frs
|
|
rm -rf /tmp/*
|
|
rm -rf /etc/*-
|
|
rm -rf /hs_err*
|
|
rm -rf /userland
|
|
rm -rf /opt/vc/src
|
|
rm -f /etc/ssh/ssh_host_*
|
|
rm -rf /var/lib/apt/lists/*
|
|
rm -rf /var/cache/apt/*.bin
|
|
rm -rf /var/cache/apt/archives/*
|
|
rm -rf /var/cache/debconf/*.data-old
|
|
history -c
|
|
EOF
|
|
#Clear all logs
|
|
for logs in `find $work_dir/var/log -type f`; do > $logs; done
|
|
|
|
# Disable the use of http proxy in case it is enabled.
|
|
if [ -n "$proxy_url" ]; then
|
|
unset http_proxy
|
|
rm -rf ${work_dir}/etc/apt/apt.conf.d/66proxy
|
|
fi
|
|
|
|
cat << EOF >> ${work_dir}/etc/udev/links.conf
|
|
M ttySAC2 c 5 1
|
|
EOF
|
|
|
|
cat << EOF >> ${work_dir}/etc/securetty
|
|
ttySAC0
|
|
ttySAC1
|
|
ttySAC2
|
|
EOF
|
|
|
|
# Mirror replacement
|
|
if [ ! -z "${@:5}" ]; then
|
|
mirror=${@:5}
|
|
fi
|
|
|
|
# Define sources.list
|
|
cat << EOF > ${work_dir}/etc/apt/sources.list
|
|
deb ${mirror} ${suite} ${components//,/ }
|
|
#deb-src ${mirror} ${suite} ${components//,/ }
|
|
EOF
|
|
|
|
# Kernel section. If you want to use a custom kernel, or configuration, replace
|
|
# them in this section.
|
|
git clone --depth 1 https://github.com/hardkernel/linux.git -b odroidxu4-4.14.y ${work_dir}/usr/src/kernel
|
|
cd ${work_dir}/usr/src/kernel
|
|
git rev-parse HEAD > ${work_dir}/usr/src/kernel-at-commit
|
|
patch -p1 --no-backup-if-mismatch < ${current_dir}/patches/kali-wifi-injection-4.14.patch
|
|
patch -p1 --no-backup-if-mismatch < ${current_dir}/patches/0001-wireless-carl9170-Enable-sniffer-mode-promisc-flag-t.patch
|
|
touch .scmversion
|
|
export ARCH=arm
|
|
export CROSS_COMPILE=arm-linux-gnueabihf-
|
|
make odroidxu4_defconfig
|
|
make -j $(grep -c processor /proc/cpuinfo)
|
|
make modules_install INSTALL_MOD_PATH=${work_dir}
|
|
cp arch/arm/boot/zImage ${work_dir}/boot
|
|
cp arch/arm/boot/dts/exynos5422-odroidxu3.dtb ${work_dir}/boot
|
|
cp arch/arm/boot/dts/exynos5422-odroidxu3-lite.dtb ${work_dir}/boot
|
|
cp arch/arm/boot/dts/exynos5422-odroidxu4.dtb ${work_dir}/boot
|
|
cp arch/arm/boot/dts/exynos5422-odroidxu4-kvm.dtb ${work_dir}/boot
|
|
make mrproper
|
|
make odroidxu4_defconfig
|
|
cd "${basedir}"
|
|
|
|
# Fix up the symlink for building external modules
|
|
# kernver is used so we don't need to keep track of what the current compiled
|
|
# version is
|
|
kernver=$(ls ${work_dir}/lib/modules/)
|
|
cd ${work_dir}/lib/modules/${kernver}
|
|
rm build
|
|
rm source
|
|
ln -s /usr/src/kernel build
|
|
ln -s /usr/src/kernel source
|
|
|
|
cat << EOF > ${work_dir}/boot/boot.ini
|
|
ODROIDXU-UBOOT-CONFIG
|
|
|
|
# U-Boot Parameters
|
|
setenv initrd_high "0xffffffff"
|
|
setenv fdt_high "0xffffffff"
|
|
|
|
# Mac address configuration
|
|
setenv macaddr "00:1e:06:61:7a:39"
|
|
|
|
#------------------------------------------------------------------------------------------------------
|
|
# Basic Ubuntu Setup. Don't touch unless you know what you are doing.
|
|
# --------------------------------
|
|
setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=/dev/mmcblk0p2 rootwait rootfstype=ext3 net.ifnames=0 rw"
|
|
|
|
# boot commands
|
|
# Uncomment the following if you use an initrd
|
|
#setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; fatload mmc 0:1 0x44000000 exynos5422-odroidxu3.dtb; bootz 0x40008000 0x42000000 0x44000000"
|
|
# Uncomment the following if you do NOT use an initrd
|
|
setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; fatload mmc 0:1 0x44000000 exynos5422-odroidxu3.dtb; bootz 0x40008000 - 0x44000000"
|
|
|
|
# --- Screen Configuration for HDMI --- #
|
|
# ---------------------------------------
|
|
# Uncomment only ONE line! Leave all commented for automatic selection.
|
|
# Uncomment only the setenv line!
|
|
# ---------------------------------------
|
|
# ODROID-VU forced resolution
|
|
# setenv videoconfig "video=HDMI-A-1:1280x800@60"
|
|
# -----------------------------------------------
|
|
# 1920x1080 (1080P) with monitor provided EDID information. (1080p-edid)
|
|
# setenv videoconfig "video=HDMI-A-1:1920x1080@60"
|
|
# -----------------------------------------------
|
|
# 1920x1080 (1080P) without monitor data using generic information (1080p-noedid)
|
|
# setenv videoconfig "drm_kms_helper.edid_firmware=edid/1920x1080.bin"
|
|
# -----------------------------------------------
|
|
# 1280x720 (720P) with monitor provided EDID information. (720p-edid)
|
|
# setenv videoconfig "video=HDMI-A-1:1280x720@60"
|
|
# -----------------------------------------------
|
|
# 1280x720 (720P) without monitor data using generic information (720p-noedid)
|
|
# setenv videoconfig "drm_kms_helper.edid_firmware=edid/1280x720.bin"
|
|
# -----------------------------------------------
|
|
# 1024x768 without monitor data using generic information
|
|
# setenv videoconfig "drm_kms_helper.edid_firmware=edid/1024x768.bin"
|
|
|
|
|
|
# final boot args
|
|
setenv bootargs "\${bootrootfs} \${videoconfig} smsc95xx.macaddr=\${macaddr}"
|
|
# drm.debug=0xff
|
|
# Boot the board
|
|
boot
|
|
EOF
|
|
|
|
|
|
# Calculate the space to create the image.
|
|
root_size=$(du -s -B1 ${work_dir} --exclude=${work_dir}/boot | cut -f1)
|
|
root_extra=$((${root_size}/1024/1000*5*1024/5))
|
|
raw_size=$(($((${free_space}*1024))+${root_extra}+$((${bootsize}*1024))+4096))
|
|
|
|
# Create the disk and partition it
|
|
echo "Creating image file ${imagename}.img"
|
|
fallocate -l $(echo ${raw_size}Ki | numfmt --from=iec-i --to=si) ${current_dir}/${imagename}.img
|
|
parted ${current_dir}/${imagename}.img --script -- mklabel msdos
|
|
parted ${current_dir}/${imagename}.img --script -- mkpart primary fat32 2MiB ${bootstart}KiB
|
|
parted ${current_dir}/${imagename}.img --script -- mkpart primary ext3 ${bootend}KiB 100%
|
|
|
|
# Set the partition variables
|
|
loopdevice=`losetup -f --show ${current_dir}/${imagename}.img`
|
|
device=`kpartx -va ${loopdevice} | sed 's/.*\(loop[0-9]\+\)p.*/\1/g' | head -1`
|
|
sleep 5
|
|
device="/dev/mapper/${device}"
|
|
bootp=${device}p1
|
|
rootp=${device}p2
|
|
|
|
# Create file systems
|
|
mkfs.vfat -n BOOT ${bootp}
|
|
if [[ $fstype == ext4 ]]; then
|
|
features="-O ^64bit,^metadata_csum"
|
|
elif [[ $fstype == ext3 ]]; then
|
|
features="-O ^64bit"
|
|
fi
|
|
mkfs $features -t $fstype -L ROOTFS ${rootp}
|
|
|
|
# Create the dirs for the partitions and mount them
|
|
mkdir -p "${basedir}"/root
|
|
mount ${rootp} "${basedir}"/root
|
|
mkdir -p "${basedir}"/root/boot
|
|
mount ${bootp} "${basedir}"/root/boot
|
|
|
|
# We do this down here to get rid of the build system's resolv.conf after running through the build.
|
|
cat << EOF > ${work_dir}/etc/resolv.conf
|
|
nameserver 8.8.8.8
|
|
EOF
|
|
|
|
# Create an fstab so that we don't mount / read-only.
|
|
UUID=$(blkid -s UUID -o value ${rootp})
|
|
echo "UUID=$UUID / ext3 errors=remount-ro 0 1" >> ${work_dir}/etc/fstab
|
|
|
|
echo "Rsyncing rootfs into image file"
|
|
rsync -HPavz -q ${work_dir}/ ${basedir}/root/
|
|
|
|
# Write the signed u-boot binary to the image so that it will boot.
|
|
cd "${basedir}"
|
|
git clone https://github.com/hardkernel/u-boot.git -b odroidxu4-v2017.05
|
|
cd "${basedir}"/u-boot
|
|
make odroid-xu4_defconfig
|
|
make
|
|
cd sd_fuse
|
|
sh sd_fusing.sh ${loopdevice}
|
|
cd "${basedir}"
|
|
|
|
# Unmount partitions
|
|
sync
|
|
umount ${bootp}
|
|
umount ${rootp}
|
|
kpartx -dv ${loopdevice}
|
|
|
|
losetup -d ${loopdevice}
|
|
|
|
# Limite use cpu function
|
|
limit_cpu (){
|
|
rand=$(tr -cd 'A-Za-z0-9' < /dev/urandom | head -c4 ; echo) # Randowm name group
|
|
cgcreate -g cpu:/cpulimit-${rand} # Name of group cpulimit
|
|
cgset -r cpu.shares=800 cpulimit-${rand} # Max 1024
|
|
cgset -r cpu.cfs_quota_us=80000 cpulimit-${rand} # Max 100000
|
|
# Retry command
|
|
local n=1; local max=5; local delay=2
|
|
while true; do
|
|
cgexec -g cpu:cpulimit-${rand} "$@" && break || {
|
|
if [[ $n -lt $max ]]; then
|
|
((n++))
|
|
echo -e "\e[31m Command failed. Attempt $n/$max \033[0m"
|
|
sleep $delay;
|
|
else
|
|
echo "The command has failed after $n attempts."
|
|
break
|
|
fi
|
|
}
|
|
done
|
|
}
|
|
|
|
if [ $compress = xz ]; then
|
|
if [ $(arch) == 'x86_64' ]; then
|
|
echo "Compressing ${imagename}.img"
|
|
limit_cpu pixz -p 2 ${current_dir}/${imagename}.img # -p Nº cpu cores use
|
|
chmod 644 ${current_dir}/${imagename}.img.xz
|
|
fi
|
|
else
|
|
chmod 644 ${current_dir}/${imagename}.img
|
|
fi
|
|
|
|
# Clean up all the temporary build stuff and remove the directories.
|
|
# Comment this out to keep things around if you want to see what may have gone
|
|
# wrong.
|
|
echo "Removing temporary build files"
|
|
rm -rf "${basedir}"
|