如何制作一个可启动的、无人值守的USB恢复盘?

我有一批14.04的亭台系统,在国家中部。这些都是糟糕的小型集成设备。我需要将它们全部升级到16.04以支持新的软件堆栈。do-release-upgrade一半的时间可以工作,另一半则会破坏安装。此外,CPU非常慢,有些站点的网络连接也相当糟糕。因此,即使它能正常工作,升级也需要很长时间。
所以,新计划。
我可以在Virtualbox、LXC或其他任何地方为每个亭台制作一个完全安装好的系统映像。
我需要一种方法将这些映像解包到系统上。 主要问题在于另一端几乎没有技术人员可用。而且我不想飞200英里去自己做这件事。我需要一些几乎完全自动化且不需要键盘的东西。
我想象一个场景:
  • 我为每个亭子制作一个系统镜像。
  • 我为每个亭子制作一个可启动的USB驱动器,并将亭子镜像复制到其中。
  • 我给它们贴上标签并张贴。
  • 在另一端,一个有物理接触USB端口的工作人员只需要插入正确的驱动器并重新启动。
  • 这个可启动元素会写入和扩展磁盘镜像。

我要找的就是这个“可启动元素”。我原本以为可能已经存在类似的东西(用于批量重新安装),但有可能是我进入了新领域。任何能够在没有人工干预的情况下(只需插入即可)安装我的镜像的东西都会得分。

据我所知,像Clonezilla这样的选项需要有人用键盘告诉它该做什么。我需要的是不需要键盘,能够自动完成任务的东西。


你认为他们能够使用一个定制的脚本,自动启动并从压缩的dd镜像中进行克隆吗? - sudodus
@sudodus 是的,基本上我也是这么想的。我想象中已经有类似的东西了,但一个能自己完成所有操作的脚本答案也是可以接受的。 - Oli
我不知道有这样一个完全自动化的系统,但是可以通过使用一个脚本在持久性的活动驱动器中自动启动来创建它,这应该是可行的。 - sudodus
一个全自动系统必须能够识别目标驱动器。你有没有想法如何做到这一点?将只有两个驱动器,即实时驱动器和目标驱动器吗?还是可能还有其他的驱动器? - sudodus
是的,默认情况下系统只有一个驱动器。 - Oli
2个回答

Shell脚本

我喜欢制作一个bash shell脚本,可以在安装的Ubuntu系统和持久化的live系统中自动执行,并且也适用于基于Debian Jessie的小型'9w'系统。我希望它对你以及将来的其他人有用。

该脚本假设应该有两个可写的驱动器(大容量存储设备),即live驱动器和目标驱动器。不要使用toram,它会破坏对live驱动器的识别。

这个shell脚本调用了dus-live,它是mkusb的一个执行部分。因此,它取代了交互式的shell脚本dus

dus-live可以管理以下类型的源文件:

  • file.iso
  • file.img
  • file.img.gz
  • file.img.xz
目标系统可以同时具有MSDOS和GUID分区表(当目标驱动器的大小大于图像中原始系统的大小时)。
我使用了名称autoclone
#!/bin/bash

# Date        Sign     Comment
# 2017-06-30  sudodus  Created
# 2017-07-01  sudodus  checking that there is 1 possible target drive

wait=30

read -t "$wait" -p "WARNING: After $wait seconds '$0' will CLONE AUTOMATICALLY;
from the file given as parameter to the first detected drive
(except the live drive), so it will be overwritten.
If this is not what you want or if you are not sure, PRESS {ctrl + C} NOW !
...
"

function power_off {
read -t "$wait" -p "WARNING: After $wait seconds '$0' will POWEROFF automatically;
If this is not what you want or if you are not sure, PRESS {ctrl + C} NOW !
...
"
sudo poweroff
}

user=$(whoami)
if [ "$user" != "root" ]
then
 echo "run $0 with sudo or as root"
 exit
fi
if [ "$1" == "" ] || ! test -s "$1"
then
 echo "Usage:   sudo $0 <with an iso file or image file as parameter>"
 echo "Example: sudo $0 \"file.iso\""
 echo "Example: sudo $0 \"file.img\""
 echo "Example: sudo $0 \"file.img.xz\""
 exit
fi

source="$1"

livedrive=$(lsblk -lo name,type,mountpoint | \
grep -m1 -e /$ -e /cdrom$ -e /lib/live/mount/medium -e /lib/live/mount/persistence)
#echo "$livedrive"
livedrive=${livedrive:0:3}
echo "livedrive=/dev/$livedrive"

number_of_targets=$(lsblk -ldo name,type|grep -v "$livedrive"|grep -v zram|grep disk|wc -l)
           target=$(lsblk -ldo name,type|grep -v "$livedrive"|grep -v zram|grep disk)

#echo "target=$target"
# echo "number_of_targets=$number_of_targets"
# sudo lsblk -o name,model,size,type,fstype,label,mountpoint | \
#  grep -v "$livedrive"|grep -v zram| grep -v loop|grep -v ' rom '
####

if [ $number_of_targets -ne 1 ]
then
 echo '--------------------------------------------------------'
 sudo lsblk -o name,model,size,type,fstype,label | \
  grep -v "$livedrive"|grep -v zram| grep -v loop|grep -v ' rom '
 echo "$number_of_targets possible target drives found, but
1 possible target drive should be found
for '$0' to work correctly."
 if [ $number_of_targets -gt 1 ]
 then
  echo "--------------------------------------------------------
- Please remove every other possible target drive!
- Or are you running in the wrong computer?"
 fi
 echo "--------------------------------------------------------"
 wait=60
 power_off
 exit
fi
target=/dev/${target:0:3}

echo "target=$target"

umount "$target"?*

paramfromfile=$(mktemp)

echo "$source
$target" > "$paramfromfile"

# do it with dus-live, which comes with mkusb version 12-

echo "calling 'dus-live' ..."
dus-live pff:"$paramfromfile"

power_off

在持久化的实时系统中进行测试

我在两个持久化的实时系统中进行了测试,这些系统可以从压缩的镜像文件中安装。

请点击此链接查看更多关于该方法的详细信息。

自动启动

当在Lubuntu中通过以下命令将以下行追加到自动启动时,此脚本可以自动启动:

echo 'xterm -fa default -fs 12 -title autoclone -e sudo /home/lubuntu/autoclone dd_no-biggie-68MB.img.xz' >> ~/.config/lxsession/Lubuntu/autostart

修改它以匹配实际的 'dd' 图像 /path/name 和 shell 脚本的实际位置。
在 9w 中对应的命令是:
echo '@xterm -fa default -fs 12 -title autoclone -e sudo /root/autoclone /root/dd_no-biggie-68MB.img.xz' >> ./.config/lxsession/LXDE/autostart

您自己的定制系统

您可能想要或必须创建您自己的定制系统(实时、持久性实时或安装在USB驱动器或存储卡中)。如果您要安装的系统使用MSDOS分区表,您可以使用简单的dd命令行来替换dus-live

免责声明

这个shell脚本是我比较快地制作的,经过我的测试是有效的,但还有很多未经测试的情况,可能会发生意外情况。因此,请在没有重要数据的驱动器上进行测试,以免被覆盖。

屏幕截图

Lubuntu的三张屏幕截图

在前30秒内,您可以使用热键组合ctrl + C停止自动克隆。

enter image description here

控制台输出:当前阶段系统正在同步(将缓冲区刷新到目标驱动器)。

enter image description here

在30秒内,您可以使用热键组合Ctrl + C来避免关机(如果您希望保持在Lubuntu桌面会话中)。

enter image description here

9w的相应截图

enter image description here


你有没有考虑使用来自Hak5的USB橡皮鸭https://hakshop.com/collections/usb-rubber-ducky以双鸭模式工作?我用它们在7台机器上安装了Ubuntu。对于每台机器,我只需将橡皮鸭插入USB端口后重新启动系统,因为我的系统始终优先从USB引导,所以这很简单。但你也可以使用两个橡皮鸭,一个用于调整BIOS首选项并从USB启动,另一个则用作Live Boot闪存驱动器和键盘,用于导航由unetbootin启动安装菜单生成的设置闪屏。稍加耐心和试错,你就可以做到。而且由于不需要现场技术人员,你可以将准备好的橡皮鸭邮寄给那些与系统有物理接近性和访问权限的人。
当处于双鸭模式时,橡皮鸭既充当HID(在我们的情况下是键盘),又作为USB大容量存储设备。因此,您只需要将unetbootin制作成可引导的闪存盘,并将其放入橡皮鸭的USB大容量存储中,然后使用HID(键盘)自动化-按键注入-功能来自动执行安装操作系统所需的导航(按键)。您甚至可以在无头系统上进行此操作。

这些对黑客友好的橡皮鸭设备是否足够安全,适合用于这个任务? - karel
@karel,我知道它们看起来有些可疑,但是对于在许多类似系统上进行大量重复操作 - 尤其是那些没有可靠网络连接的系统,我真的认为没有比这更好的解决方案了。此外,在正确使用的情况下,它们对于任何有能力的系统管理员来说都是很好的辅助工具。 - endrias
我想,如果“橡皮鸭”(Rubber Ducky)的源代码是可用的,那么就有可能将其复制到自己选择的设备上,而不是使用一个看起来像鸭子的黄色USB设备。 - karel
你不需要任何源代码。Hak5网站将为您展示您所需了解的一切。而且按键脚本语言 - ducky script - 是如此简单易学,您可以在不到一分钟的时间内学会它,真的。 - endrias
我对USB设备安全也很感兴趣,比如这个回答:https://superuser.com/questions/1206321/how-do-i-safely-investigate-a-usb-stick-found-in-the-parking-lot-at-work/1206324#1206324 - karel
我的主要问题是它太贵了!900美元一次性的费用——我不指望工作人员会照顾这些或者归还它们——这比我自己飞过去并DIY(自己动手做)的费用还要高。对于一个单一的主持人来说,这可能是一个可行的选择。 - Oli
如果你担心员工不归还这些小鸭子,你应该告诉他们这些是诊断工具,必须归还。同时,给他们发送一份看起来很正式的文件,附上一些法律条文,明确规定他们的责任。每个人都害怕法律文件。如果这些文件足够有说服力,你可以用不超过300块钱升级所有的机器——一点社会工程学从未伤害过任何人。 - endrias
再说,这真的是次要的,相比于900美元的支出(用于20个亭子)。这还需要额外的设置时间。为了背景,飞行费用为100英镑,并且给我提供了长达9小时的现场时间。我可以带上几个普通的Live USB存储设备,在每个系统上手动安装时无聊地玩弄我的大拇指。橡皮鸭子是一个有趣的想法,但在这里并不经济。 - Oli