Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images
Using a Raspberry Pi or other single-board computers to create a “private cloud at home”.
https://linux.cn/article-12277-1.htmlAuthor: Chris CollinsTranslator: Zheng

Using a Raspberry Pi or other single-board computers to create a “private cloud at home”.

Building a home lab can be a fun way to learn new concepts and experiment with new technologies while also enjoying yourself. Thanks to the popularity of single-board computers (SBCs) led by the Raspberry Pi, it is now easy to build a multi-computer lab in the comfort of your own home. Creating a “private cloud at home” to experience cloud-native technologies at a lower cost compared to trying to set up the same configuration with mainstream cloud service providers is also a great approach.

This article explains how to modify the disk image of a Raspberry Pi or other single-board computer, pre-configure the host’s SSH, and disable the services that force interactive configuration on first boot. This is a great way to make your device “boot and run” instantly, similar to cloud instances. After that, you can use automated processes to connect via SSH for more professional and in-depth configurations.

Additionally, when adding more Raspberry Pis to your lab, modifying the disk image allows you to simply write that image to an SD card and insert it into the Raspberry Pi!

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Multiple Raspberry Pi computers, a switch, and a power bank

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Unpacking and Mounting the Image

For this project, you need to modify a server disk image. During testing, I used Fedora Server 31 ARM. After you download the disk image and verify its checksum, you need to unpack it and mount it to a location in the host’s file system so you can modify it as needed.

You can use the xz command with the --decompress parameter to unpack the Fedora server image:

xz --decompress Fedora-Server-armhfp-X-y.z-sda.raw.xz

This will leave you with an unpacked raw disk image (which will automatically replace the .xz compressed file). This raw disk image is exactly what it sounds like: a file containing all the data on a formatted installed disk. This includes partition information, boot partition, root partition, and other partitions. You need to mount the partition you intend to modify, but to do that, you need to know the starting positions and sector sizes of the partitions in the disk image so you can mount the file at the correct sector.

Fortunately, you can use the fdisk command on a disk image just as easily as you would on a real disk. Use the --list or -l parameter to view the list of partitions and their information:

# Use fdisk to list the partitions of the raw image file:
$ fdisk -l Fedora-Server-armhfp-31-1.9-sda.raw
Disk Fedora-Server-armhfp-X-y.z-sda.raw: 3.2 GiB, 3242196992 bytes, 6332416 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xdaad9f57

Device                               Boot   Start     End Sectors  Size Id Type
Fedora-Server-armhfp-X-y.z-sda.raw1         8192  163839  155648   76M  c W95 F
Fedora-Server-armhfp-X-y.z-sda.raw2 *     163840 1163263  999424  488M 83 Linux
Fedora-Server-armhfp-X-y.z-sda.raw3      1163264 6047743 4884480  2.3G 83 Linux

All the information you need can be found in the output above. The third line indicates the sector size (both logical and physical): 512 bytes / 512 bytes.

The device list shows the partitions in the raw disk image. The first, Fedora-Server-armhfp-X-y.z-sda.raw1, is undoubtedly the boot partition because it is the first one, small (only 76MB), and its type is identified as c, which is W95 FAT32 (LBA), a FAT32 partition that boots from the SD card.

The second partition is also not very large, only 488MB. This partition is a Linux native type partition (Id 83) and likely contains the Linux boot partition with the kernel and initramfs.

The third partition is likely what you need: it is 2.3GB in size, so it should contain the main part of the distribution, and it is also a Linux native partition type, which is expected. This partition should contain the partition and data you need to modify.

The third partition starts at sector 1163264 (shown in the fdisk output as the Start column), so your mount offset is 595591168, calculated by multiplying the sector size (512) by the starting sector (1163264) (i.e., 512 * 1163264). This means you need to mount the file with an offset of 595591168 to mount it to the correct location.

Equipped with this information, you can now mount the third partition to your home directory:

$ mkdir ~/mnt
$ sudo mount -o loop,offset=595591168 Fedora-Server-armhfp-X-y.z-sda.raw ~/mnt
$ ls ~/mnt

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Working Directly in the Disk Image

Once the disk image has been unpacked and mounted to a location on the host, you can modify the image to suit your needs. In my opinion, the easiest way to make changes to the image is to use chroot to change the root directory of your session to the working root directory of the mounted image. However, this can be a bit tricky.

Once you change the root directory, your session will use the binaries from the new root directory. Unless you are doing all this work on an ARM system, the architecture of the unpacked disk image will differ from that of the host system you are using. Even in a chroot environment, the host system cannot use binaries of a different architecture. At least, not natively.

Fortunately, there is a solution: qemu-user-static. Instructions from the Debian Wiki:

“[qemu-user-static] provides user-mode emulation binaries that are statically built. In this mode, QEMU can start a Linux process compiled for another CPU on one CPU… If the binfmt-support package is installed, the qemu-user-static package registers the binary formats that the emulator can handle so that it can directly run binaries of other architectures.”

This is exactly what you need to work in a non-native architecture in a chroot environment. If the host system is Fedora, use DNF to install the qemu-user-static package and restart the systemd-binfmt.service:

# Use DNF to enable non-native arch chroot environment, adding new binary format information
# Output image is trimmed
$ dnf install qemu-user-static
$ systemctl restart systemd-binfmt.service

Using this method, you can change the root directory to the mounted disk image and run the uname command to verify everything is working as expected:

sudo chroot ~/mnt/ /usr/bin/uname -a -r
Linux marvin 5.5.16-200.fc31.x86_64 #1 SMP Wed Apr 8 16:43:33 UTC 2020 armv7l armv7l armv7l GNU/Linux

Running uname in the chroot environment will show armv7l in the output, which is the architecture of the raw disk image, rather than the architecture of the host system. Everything is as expected, and you can continue modifying the image.

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Modifying the Disk Image

Now you can switch directly into this ARM-based disk image and work within that environment, making modifications to the image itself. You need to set up the image so that it can boot and be immediately accessible without any additional setup on the Raspberry Pi. To do this, you need to install and enable sshd (OpenSSH daemon) and add an authorized key for SSH access.

To make it behave more like a cloud environment, realizing the dream of establishing a private cloud at home, add a local user, grant that user sudo privileges, and (for heavy cloud users) allow that user to use sudo without a password.

So, what you will do is:

◈ Install and enable SSHD (SSHD is already installed and enabled in the Fedora ARM image, but you may need to do this manually for your distribution)
◈ Set up a local user
◈ Allow the local user to use sudo (no password, optional)
◈ Add authorized keys
◈ Allow root to use authorized keys for SSH (optional)

I used GitHub’s feature that allows you to upload your SSH public key, accessible at https://github.com/.keys. I found this to be a convenient way to distribute public keys, but I am naturally suspicious and always check that the downloaded key matches what I expect. If you don’t want to use this method, you can copy your public key from your host machine into the chroot environment, or you can host the public key on a web server you control to use the same workflow.

To start modifying the disk image, switch the root directory to the mounted disk image again, this time starting a shell so you can run multiple commands:

# Output of these commands omitted for brevity (if any)
$ sudo chroot ~/mnt /bin/bash

# Install openssh-server and enable it (already done on Fedora)
$ dnf install -y openssh-server
$ systemctl enable sshd.service

# Allow root to access SSH using authorized keys
$ mkdir /root/.ssh

# Download or otherwise add your authorized keys file, your public key
# Replace the URL with the path to your own public key
$ curl <https://github.com/clcollins.keys> -o /root/.ssh/authorized_keys
$ chmod 700 /root/.ssh
$ chmod 600 /root/.ssh/authorized_keys

# Add a local user and place them in the wheel group
# Change the group and user to whatever you want
useradd -g chris -G wheel -m -u 1000 chris

# Download and add your authorized keys
# Change home directory and URL as above
mkdir /home/chris/.ssh
curl <https://github.com/clcollins.keys> -o /home/chris/.ssh/authorized_keys
chmod 700 /home/chris/.ssh
chmod 600 /home/chris/.ssh/authorized_keys
chown -R chris.chris /home/chris/.ssh/

# Allow the wheel group (using your local user) to use sudo without a password
echo "%wheel ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/91-wheel-nopasswd

This is all the setup needed for SSH to be completed on first boot for the Raspberry Pi or other single-board computers. However, each distribution has its own quirks. For example, Raspbian already includes a local user: pi, and does not use the wheel group. So for Raspbian, it might be better to use the existing user or delete the pi user and replace it with another user.

In the case of Fedora ARM, the image prompts you to complete the setup on first boot. This defeats the purpose of the modifications you made above, especially since it will completely block the boot until the setup is complete. Your goal is to make the Raspberry Pi function like a part of the infrastructure of a private cloud, and this workflow includes configuring the host remotely via SSH at boot time. Disable the initialization setup, which is controlled by initial-setup.service:

# Disable initial-setup.service for multi-user and graphical targets
unlink /etc/systemd/system/multi-user.target.wants/initial-setup.service
unlink /etc/systemd/system/graphical.target.wants/initial-setup.service

While in the chroot environment, you can make any other changes you want to your system, or just leave it there to configure it via SSH after first boot, following the cloud-native workflow.

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Recompress and Install the Modified Image

Once you’ve completed these changes, all that’s left is to recompress the disk image and install it onto your Raspberry Pi’s SD card.

Make sure to exit the chroot environment and then unmount the disk image:

$ sudo umount ~/mnt/

Just like you unpacked the image initially, you can use the xz command again to compress the image. By using the --keep parameter, xz will keep the original image instead of cleaning it up. While this will take up more disk space, keeping the uncompressed image will allow you to make incremental changes to the image you are working on without having to unpack it every time. This is very helpful for saving time during testing and tweaking the image.

# Compress the disk image into a .xz file, but keep the original disk image
xz --compress Fedora-Server-armhfp-31-1.9-sda.raw --keep

The compression process will take some time, so take this time to stand up, stretch, and get your blood flowing again.

Once the compression is complete, you can copy the new, modified disk image to the SD card for use with the Raspberry Pi. The standard dd method of placing the image onto the SD card works well, but I prefer to use Fedora’s arm-image-installer because it provides some options when dealing with unedited images. It also works well with edited images and is a bit friendlier than the dd command.

Make sure to check which disk drive the SD card is on, and use it with the --media parameter:

# Use arm-image-installer to copy the modified disk image to the SD card
arm-image-installer --image=Fedora-Server-armhfp-X-y.z-sda.raw.xz --target=rpi3 --media=/dev/sdc --norootpass --resizefs -y

Now you have a new, modified Fedora Server ARM image ready to boot and SSH into your modified image. This method can also be used to make other modifications, and you can use the original disk images of other distributions if you prefer them over Fedora’s. This is a good foundation to start building a home lab private cloud. In future articles, I will guide you through using cloud technologies and automation to establish a home lab.

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Further Reading

To learn how to do the things in this article, I did a lot of research. Here are two resources I found to be the most helpful for learning how to customize disk images and work with non-native architectures. They helped me go from “not knowing what I’m doing” to “I can do it!”.

◈ How to Modify the Raw Disk Image of Your Custom Linux Distribution
◈ Using the DNF Wiki

via: https://opensource.com/article/20/5/disk-image-raspberry-pi

Author: Chris Collins Edited by: lujun9972 Translated by: robsean Proofread by: wxy

This article is produced by LCTT and honored by Linux China.

Creating a Raspberry Pi-based Home Lab by Modifying Disk Images

Leave a Comment

×