#!/bin/bash set -e # Variables set through command-line arguments # the assigned values are used as defaults if no matching argument is provided FORCE=0 MIRROR="" HOSTNAME="pi" TIMEZONE="UTC" WPA_ESSID="" WPA_PSK="" ROOT_PASSWORD="toor" SSH_KEY="$HOME/.ssh/id_rsa.pub" # Paths for installation DEVICE=/dev/nonexisting PARTITION1="$DEVICE"p1 PARTITION2="$DEVICE"p2 ROOTFS=/mnt/pi print_usage() { cat 1>&2 < Use a debian mirror, such as "fr" or "ch" --hostname=<$HOSTNAME> Use a given hostname for the device. --timezone=<$TIMEZONE> Set timezone data as listed in /usr/share/zoneinfo --wpa-essid=<$WPA_ESSID> Use a given wireless ESSID. Sets up wireless networking. --wpa-psk=<$WPA_PSK> Use a given WPA pre-shared key. --password=<$ROOT_PASWORD> Set the given root password. --ssh-key=<$SSH_KEY> Add the given SSH key to root's authorized_keys file. If invalid, password login will be enabled. --root-fs=<$ROOTFS> Use given directory as mount point during installation. EOF } # Process options while [ $# -gt 1 ] do case "$1" in -f|--force) FORCE=1 ;; --mirror=*) MIRROR=."${1#*=}" ;; --hostname=*) HOSTNAME="${1#*=}" ;; --timezone=*) TIMEZONE="${1#*=}" ;; --wpa-essid=*) WPA_ESSID="${1#*=}" ;; --wpa-psk=*) WPA_PSK="${1#*=}" ;; --password=*) ROOT_PASSWORD="${1#*=}" ;; --ssh-key=*) SSH_KEY="${1#*=}" ;; --root-fs=*) ROOTFS="${1#*=}" ;; *) echo "Unknown argument: $1" 1>&2 exit 1 esac shift done # Process last argument, the device to use if [ -z "$1" ] || [ "$1" = -h ] || [ "$1" = --help ]; then print_usage exit 1 fi if [ ! -e "$1" ]; then echo "Device not found: $1" 1>&2 exit 1 fi if [ ! -b "$1" ]; then echo "Specified device is not a block device: $1" 1>&2 exit 1 fi DEVICE="$1" PARTITION1="$DEVICE"p1 PARTITION2="$DEVICE"p2 # Check environment if [ "$EUID" != 0 ]; then echo "This script must be run as root." 1>&2 exit 1 fi # Argument processing and enivronment check are done at this point # Start with actual script # Setup partitions on SD card partition() { parted "$DEVICE" --script mklabel msdos && parted "$DEVICE" --script mkpart primary fat32 1M 200M && parted "$DEVICE" --script mkpart primary ext4 200M 100% && mkfs.vfat -F 32 "$PARTITION1" && mkfs.ext4 "$PARTITION2" } mountrootfs() { mkdir "$ROOTFS" && mount "$PARTITION2" "$ROOTFS" && mkdir "$ROOTFS"/boot && mount "$PARTITION1" "$ROOTFS"/boot } mkrootfs() { # Create initial debian filesystem qemu-debootstrap --arch=armhf \ --include=ssh,sudo,ntpdate,fake-hwclock,openssl,ca-certificates,vim,nano,cryptsetup,lvm2,locales,less,cpufrequtils,wireless-tools,wpasupplicant \ jessie \ "$ROOTFS" \ "http://ftp${MIRROR}.debian.org/debian/" # Set package configuration to use raspberrypi.org archive for kernel package cat > "$ROOTFS"/etc/apt/sources.list < "$ROOTFS"/etc/apt/preferences.d/raspberrypi < "$ROOTFS"/boot/config.txt < "$ROOTFS"/etc/network/interfaces.d/wlan0 < "$ROOTFS"/etc/network/interfaces.d/eth0 < "$ROOTFS"/etc/fstab < "$ROOTFS"/etc/timezone ln -sf /usr/share/zoneinfo/"$TIMEZONE" "$ROOTFS"/etc/localtime # Set host configuration echo "$HOSTNAME" > "$ROOTFS"/etc/hostname sed -i "/^127.0.0.1/ s/\$/ $HOSTNAME/" "$ROOTFS"/etc/hosts sed -i "/^::1/ s/\$/ $HOSTNAME/" > "$ROOTFS"/etc/hosts # Login options chroot "$ROOTFS" /bin/sh -c "echo root:$ROOT_PASSWORD | chpasswd" if [ -e "$SSH_KEY" ]; then mkdir "$ROOTFS"/root/.ssh chmod 600 "$ROOTFS"/root/.ssh cat "$SSH_KEY" >> "$ROOTFS"/root/.ssh/authorized_keys chmod 600 "$ROOTFS"/root/.ssh/authorized_keys sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' "$ROOTFS"/etc/ssh/sshd_config echo "Success: SSH password login was disabled! Use the key in $SSH_KEY to login." 1>&2 else sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/g' "$ROOTFS"/etc/ssh/sshd_config echo "Warning: no SSH key found, SSH password login has been enabled for root! Please enable key-login only as soon as possible." 1>&2 fi } umountrootfs() { rm -f "$ROOTFS"/usr/bin/qemu-arm-static umount "$ROOTFS"/boot umount "$ROOTFS" rm -r "$ROOTFS" } if [ "$FORCE" != 1 ]; then echo "WARNING: The following operations may have destructive consequences." 1>&2 echo "Partition device $DEVICE and create bootable root file system on $ROOTFS" 1>&2 read -p "Continue? [Y,n] " yn if [ "$yn" != "Y" ] && [ "$yn" != "y" ]; then echo "Aborting." 1>&2 exit 1 fi fi partition && mountrootfs && mkrootfs && umountrootfs