4 Commits 7f6d2c3fef ... 66ab5cb3fe

Author SHA1 Message Date
  The MMGen Project 66ab5cb3fe armbian_rootenc_setup: add `-I` option (force use of ifupdown) 11 months ago
  The MMGen Project 2d420a20af armbian_rootenc_setup: support user/host specific `authorized_keys` configs 11 months ago
  The MMGen Project a299f6e606 copy_boot_loader(): count sectors instead of blocks 11 months ago
  The MMGen Project afa61eaf2d minor cleanups 11 months ago
1 changed files with 81 additions and 43 deletions
  1. 81 43
      scripts/armbian_rootenc_setup.sh

+ 81 - 43
scripts/armbian_rootenc_setup.sh

@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
 
 PATH="$PATH:/usr/sbin:/sbin"
 RED="\e[31;1m" GREEN="\e[32;1m" YELLOW="\e[33;1m" BLUE="\e[34;1m" PURPLE="\e[35;1m" RESET="\e[0m"
@@ -18,6 +18,7 @@ CONFIG_VARS='
 	USE_LOCAL_AUTHORIZED_KEYS
 	USB_GADGET
 	ETH_DEV
+	NETCFG_IFUPDOWN
 '
 STATES='
 	card_partitioned
@@ -44,6 +45,7 @@ USER_OPTS_INFO="
 	USB_GADGET                 -  enable disk unlocking via SSH over USB (g_ether)
 	ETH_DEV                    -  select the network device manually (default: auto)
 	VERBOSE                    -  produce verbose output
+	NETCFG_IFUPDOWN            -  force configuration of network interface using ifupdown
 "
 RSYNC_VERBOSITY='--info=progress2'
 
@@ -55,6 +57,8 @@ print_help() {
              '-d'  Produce tons of debugging output
              '-f'  Force reconfiguration of target system
              '-F'  Force a complete rebuild of target system
+             '-I'  Force configuration of target system network interface using
+                   ifupdown (/etc/network/interfaces)
              '-m'  Add all currently loaded modules to the initramfs (may help
                    fix blank screen on bootup issues)
              '-o'  Add specified modules to the initramfs (comma-separated list)
@@ -382,14 +386,11 @@ _get_user_vars() {
 
 	if [ "$IP_ADDRESS" == 'none' ]; then
 		UNLOCKING_USERHOST=
-	elif [ -e 'authorized_keys' -a "$USE_LOCAL_AUTHORIZED_KEYS" ]; then
-		UNLOCKING_USERHOST=
 	else
 		_get_user_var 'UNLOCKING_USERHOST' 'USER@HOST' '' \
 			"Enter the user@host of the machine you'll be unlocking from:" \
 			'\S+@\S+' \
-			'malformed USER@HOST' \
-			'_test_unlocking_host_available'
+			'malformed USER@HOST'
 	fi
 
 	_get_user_var 'SERIAL_CONSOLE' 'serial console unlocking' '' \
@@ -437,15 +438,13 @@ _test_sdcard_mounted() {
 }
 
 get_authorized_keys() {
-	if [ -f 'authorized_keys' ]; then
-		rm -rf /tmp/armbian_rootenc_build-authorized_keys_file
-		mv 'authorized_keys' /tmp/armbian_rootenc_build-authorized_keys_file
-		mkdir 'authorized_keys'
-		mv /tmp/armbian_rootenc_build-authorized_keys_file 'authorized_keys'
-	fi
-	[ -e 'authorized_keys' -a "$USE_LOCAL_AUTHORIZED_KEYS" ] || {
-		mkdir -p 'authorized_keys'
-		rsync "$UNLOCKING_USERHOST:.ssh/id_*.pub" 'authorized_keys'
+	[ -f 'authorized_keys' ] && rm -rf 'authorized_keys' # remove legacy file if present
+	authorized_keys_dir="authorized_keys-$UNLOCKING_USERHOST"
+	[ -e $authorized_keys_dir -a "$USE_LOCAL_AUTHORIZED_KEYS" ] || {
+		_test_unlocking_host_available
+		mkdir -p $authorized_keys_dir
+		rsync "$UNLOCKING_USERHOST:.ssh/id_*.pub" $authorized_keys_dir
+		NEW_AUTHORIZED_KEYS='y'
 	}
 }
 
@@ -478,6 +477,7 @@ _print_pkgs_to_install() {
 					pkgs='cryptsetup-initramfs' pkgs_ssh='dropbear-initramfs'
 					warn "Warning: unrecognized target distribution '$target_distro'" ;;
 			esac
+			[ "$NETCFG_IFUPDOWN" == 'y' ] && pkgs+=" ifupdown"
 			[ "$IP_ADDRESS" != 'none' ] && pkgs+=" $pkgs_ssh" ;;
 	esac
 	for i in $pkgs; do
@@ -558,6 +558,20 @@ _preclean() {
 	remove_build_dir
 }
 
+_print_success_msg() {
+	gmsg "All done!"
+	imsg ""
+	imsg "  You may now shut down your board, switch removable media if applicable,"
+	imsg "  and restart."
+	if [ "$IP_ADDRESS" != "none" ]; then
+		imsg ""
+		imsg "  To unlock the disk on the target machine, execute the following from the"
+		imsg "  unlocking host:"
+		imsg ""
+		imsg "      ssh -p 2222 root@${IP_ADDRESS/dhcp/TARGET_IP}"
+	fi
+}
+
 _clean() {
 	pu_msg "Cleaning up, please wait..."
 	_show_output
@@ -566,8 +580,9 @@ _clean() {
 	umount_target
 	update_config_vars_file
 	_close_device_maps 'mounted_on_target'
-	[ -e 'authorized_keys' -a -z "$USE_LOCAL_AUTHORIZED_KEYS" ] && shred -u 'authorized_keys'
 	remove_build_dir
+	[ "$build_success" ] && _print_success_msg
+	true
 }
 
 get_armbian_image() {
@@ -607,7 +622,7 @@ _confirm_user_vars() {
 	[ "$NETMASK" ] && echo "  Target netmask:               $NETMASK"
 	echo "  Boot partition label:         $BOOTPART_LABEL"
 	echo "  Disk password:                $DISK_PASSWD"
-	[ "$UNLOCKING_USERHOST" ] && echo "  user@host of unlocking host:  $UNLOCKING_USERHOST"
+	[ "$UNLOCKING_USERHOST" ] && echo "  unlocking user@host:          $UNLOCKING_USERHOST"
 	echo "  Serial console unlocking:     ${SERIAL_CONSOLE:-no}"
 	echo "  SSH over USB unlocking:       ${USB_GADGET:-no}"
 	echo "  Ethernet device:              ${ETH_DEV:-auto}"
@@ -646,6 +661,9 @@ _update_state_from_config_vars() {
 	local saved_states cfgvar_changed
 	saved_states="$(_print_states)"
 	cfgvar_changed=
+
+	[ "$NEW_AUTHORIZED_KEYS" ] && cfgvar_changed+=' NEW_AUTHORIZED_KEYS' target_configured='n'
+
 	[ $cARMBIAN_IMAGE != $ARMBIAN_IMAGE ]    && cfgvar_changed+=' ARMBIAN_IMAGE' card_partitioned='n'
 	[ $cBOOTPART_LABEL != $BOOTPART_LABEL ]  && cfgvar_changed+=' BOOTPART_LABEL' bootpart_label_created='n'
 	[ $cROOTFS_NAME != $ROOTFS_NAME ]        && cfgvar_changed+=' ROOTFS_NAME' target_configured='n'
@@ -662,6 +680,7 @@ _update_state_from_config_vars() {
 	[ "$cADD_MODS" != "$ADD_MODS" ]          && cfgvar_changed+=' ADD_MODS' target_configured='n'
 	[ "$cUSB_GADGET" != "$USB_GADGET" ]      && cfgvar_changed+=' USB_GADGET' target_configured='n'
 	[ "$cETH_DEV" != "$ETH_DEV" ]            && cfgvar_changed+=' ETH_DEV' target_configured='n'
+	[ "$cNETCFG_IFUPDOWN" != "$NETCFG_IFUPDOWN" ] && cfgvar_changed+=' NETCFG_IFUPDOWN' target_configured='n'
 	[ "$IP_ADDRESS" -a "$cUSE_LOCAL_AUTHORIZED_KEYS" != "$USE_LOCAL_AUTHORIZED_KEYS" ] && {
 		cfgvar_changed+=' USE_LOCAL_AUTHORIZED_KEYS' target_configured='n'
 	}
@@ -804,12 +823,13 @@ create_partition_label() {
 }
 
 copy_boot_loader() {
-	local bs=4096 skip count
-	case $partition_table_type in 'dos') skip=0;; 'gpt') skip=8;; esac # LBA8 (0x8000): boot loader magic string
-	count=$((start_sector / 8 - $skip))
-	pu_msg "Copying boot loader ($count 4K blocks [$((count*8)) sectors], starting at $skip blocks [$((skip*8)) sectors]):"
+	local skip count
+	# GPT bootloader starts at LBA 8 (0x8000, sector 64):
+	case $partition_table_type in 'dos') skip=0;; 'gpt') skip=64;; esac
+	count=$((start_sector - skip))
+	pu_msg "Copying boot loader ($count sectors, starting at sector $skip [LBA $((skip / 8))]):"
 	_show_output
-	dd if=$ARMBIAN_IMAGE of="/dev/$SDCARD_DEVNAME" status='progress' bs=$bs count=$count skip=$skip seek=$skip
+	dd if=$ARMBIAN_IMAGE of="/dev/$SDCARD_DEVNAME" status='progress' bs=512 count=$count skip=$skip seek=$skip
 	_hide_output
 	do_partprobe
 }
@@ -907,7 +927,7 @@ copy_system_root() {
 
 		pu_msg "Copying system to encrypted root partition:"
 		_show_output
-		rsync $RSYNC_VERBOSITY --archive --exclude=boot $SRC_ROOT/* $TARGET_ROOT
+		rsync $RSYNC_VERBOSITY --archive --exclude='boot' --exclude='var/cache/apt/archives' $SRC_ROOT/* $TARGET_ROOT
 		_hide_output
 		sync
 
@@ -1163,7 +1183,7 @@ edit_initramfs_modules() {
 copy_authorized_keys() {
 	local dest="$TARGET_ROOT$dropbear_dir"
 	mkdir -p $dest
-	/bin/cat authorized_keys/* > "$dest/authorized_keys"
+	/bin/cat $authorized_keys_dir/* > "$dest/authorized_keys"
 	chmod 644 "$dest/authorized_keys"
 	_display_file "$dest/authorized_keys"
 }
@@ -1224,18 +1244,12 @@ ifupdown_config_usb0() {
 	local file bu_file text
 	file="$TARGET_ROOT/etc/network/interfaces"
 	bu_file="$file.rootenc.orig"
-	text="
-
-auto usb0
-iface usb0 inet static
-	address $IP_ADDRESS
-	netmask $NETMASK
-"
+	text="\nauto usb0\niface usb0 inet static\n\taddress $IP_ADDRESS\n\tnetmask $NETMASK"
 	if [ -e $file ]; then
 		if [ "$USB_GADGET" -a "$IP_ADDRESS" != 'dhcp' ]; then
 			grep -q '^auto usb0' $file || {
 				/bin/cp $file $bu_file
-				echo "$text" >> $file
+				echo -e "$text" >> $file
 			}
 			systemctl mask network-manager
 		else
@@ -1269,11 +1283,15 @@ exit 0'
 
 # begin chroot functions:
 
+_pkg_remove() {
+	dpkg -s $1 2>/dev/null | grep ^Status | grep -q installed && apt-get --yes purge $1 || :
+}
+
 apt_remove_target_pkgs() {
-	if [ "$IP_ADDRESS" == 'none' ]; then
-		apt --yes purge 'dropbear-initramfs' || :
-	fi
-	apt --yes purge 'bash-completion' 'command-not-found' || :
+	[ "$IP_ADDRESS" == 'none' ] && _pkg_remove 'dropbear-initramfs'
+	_pkg_remove 'bash-completion'
+	_pkg_remove 'command-not-found'
+	true
 }
 
 apt_install_target_pkgs() {
@@ -1300,6 +1318,29 @@ apt_install_target_pkgs() {
 	true
 }
 
+ifupdown_config_eth0() {
+	local dir file text
+	dir="/etc/network/interfaces.d"
+	mkdir -p $dir
+	file="$dir/$eth_dev"
+	rm -rf $file
+	if [ "$NETCFG_IFUPDOWN" == 'y' ]; then
+		if [ "$IP_ADDRESS" == 'dhcp' ]; then
+			text="auto $eth_dev\niface $eth_dev inet dhcp"
+		else
+			text="auto $eth_dev\niface $eth_dev inet static\n\taddress $IP_ADDRESS\n\tnetmask $NETMASK"
+		fi
+		systemctl -q is-enabled 'networking' || { systemctl unmask 'networking'; systemctl enable 'networking'; }
+		systemctl -q is-enabled 'networking' || die "fatal error: unable to enable networking service (ifupdown)"
+		echo -e "$text" > $file
+		_display_file $file
+	else
+		systemctl -q is-enabled 'networking' && systemctl mask 'networking'
+		systemctl -q is-enabled 'networking' && die "fatal error: unable to mask networking service"
+		true
+	fi
+}
+
 update_initramfs() {
 	[ "$ROOTENC_TESTING" ] && return 0
 	_show_output
@@ -1364,7 +1405,7 @@ configure_target() {
 
 	_show_output # this must be done before entering chroot
 	/bin/cp $0 $TARGET_ROOT
-	export 'ROOTFS_NAME' 'IP_ADDRESS' 'target_distro' 'ROOTENC_TESTING' 'ROOTENC_PAUSE' 'ROOTENC_IGNORE_APT_ERRORS' 'APT_UPGRADE'
+	export 'ROOTFS_NAME' 'IP_ADDRESS' 'target_distro' 'ROOTENC_TESTING' 'ROOTENC_PAUSE' 'ROOTENC_IGNORE_APT_ERRORS' 'APT_UPGRADE' 'eth_dev'
 
 	chroot $TARGET_ROOT "./$PROGNAME" $ORIG_OPTS 'in_target'
 
@@ -1398,13 +1439,14 @@ _mount_target_and_exit() {
 
 set -e
 
-while getopts hCfFmo:MUpRsudvz OPT
+while getopts hCfFImo:MUpRsudvz OPT
 do
 		case "$OPT" in
 			h)  print_help; exit ;;
 			C)  NO_CLEANUP='y' ;;
 			f)  FORCE_RECONFIGURE='y' ;;
 			F)  FORCE_REBUILD='y' ;;
+			I)  NETCFG_IFUPDOWN='y' ;;
 			m)  ADD_ALL_MODS='y' ;;
 			o)  ADD_MODS=$OPTARG ;;
 			M)  MOUNT_TARGET_ONLY='y' ;;
@@ -1454,6 +1496,7 @@ if [ "$ARG1" == 'in_target' ]; then
 	}
 	apt_remove_target_pkgs
 	apt_install_target_pkgs
+	ifupdown_config_eth0
 	[ "$initramfs_updated" ] || update_initramfs
 	gen_target_ssh_host_keys
 	check_initramfs
@@ -1504,10 +1547,5 @@ else
 	[ "$target_configured" == 'n' ]      && configure_target
 
 	sync
-	gmsg 'All done!'
-
-	if [ "$IP_ADDRESS" != 'none' ]; then
-		imsg "To unlock the target disk, execute the following from the unlocking host:"
-		imsg "    ssh -p 2222 root@${IP_ADDRESS/dhcp/TARGET_IP}"
-	fi
+	build_success=1
 fi