This post is a WIP - please let me know if I’ve got something wrong here, as I’m most likely still working on it.
I got a Zyxel NAS 540 for cheap on eBay, and then ran across $50 used WD SATA II RAID drives, and bought four of those. There’s a bit of prep to do here though.
Testing the Drives
Apparently this is what you do when SpinRite craps out:
dd if=/dev/zero of=/dev/<your drive> bs=1M status=progress
This will write zeros to all sectors on that disk forcing the bad sector to reallocate. After you do this, run the following to perform a full read check of the entire disk to make sure there are no other bad sectors.
smartctl -t long /dev/<your drive>
Installing Debian onto the Zyxel
First, since the process involves me exploiting a telnet backdoor in the NAS, I have to get it registered with the DHCP server which only happened once I did a long factory reset. Once I did that, it popped up as
NAS540. All good and well.
Getting root wasn’t bad. Following the backdoor instructions for firmware version 4.70, I was able to own the box with root privileges via the user
NsaRescueAngel over telnet. The webpage to visit never fully loads, it just stays open while the telnet connection is made. However, it can be closed once the login is complete.
Building bareboxenv from source
I downloaded the latest version of the barebox source. I needed to specify the architecture and the cross-compilation prefix for the compilation and then run the compiler.
# yaourt arm-linux-gnueabihf-gcc # pacman -S lzop # wget https://br.unchti.me/config -O barebox-YYYY.MM.0/arch/arm/configs/freescale-1024a_defconfig # ARCH=arm make freescale-1024a_defconfig # ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make
Since I’m running Arch right now, it’s going to be somewhat roundabout getting the bootstrapped system onto the SD card. However, wiping it and partitioning it is easy enough.
# dd if=/dev/zero of=/dev/mmcblk0 bs=1M status=progress # parted --script --align optimal /dev/mmcblk0 mklabel gpt mkpart primary ext4 0% 100% # mkfs.ext4 /dev/mmcblk0p1
Luckily enough, Arch does have
debootstrap available for install, however, I need a bit more than that.
# pacman -S debootstrap qemu-arch-extra # yaourt binfmt-qemu-static # yaourt qemu-user-static # yaourt binfmt-support
I’m not sure that all of these packages are required, but they are the ones that I installed to get this working.
There were a couple steps to install this as opposed to the clean way that was in the
# mount /dev/mmcblk0p1 /mnt # debootstrap --no-check-gpg --arch=armhf --foreign testing /mnt "https://mirrors.kernel.org/debian"
This got the first half of the install working - it downloaded the files in the
armhf architecture. Next, I had to enable arm emulation, place the emulation binary into the chroot filesystem, and chroot in to finish the debootstrap.
# update-binfmts --enable qemu-arm # cp /usr/bin/qemu-arm-static /mnt/usr/bin
If the files are put into
/mnt/bin, no further commands will work, but putting it in
/mnt/usr/bin allows everything to work just fine. This might be able to be fixed with a debootstrap argument
# DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /mnt /debootstrap/debootstrap --second-stage # DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /mnt dpkg --configure -a
Upon repeating this after the initial test setup, I had to chroot into the build itself with
chroot /mnt /bin/bash -l in order to run it, as I was getting a
command not found for
cat. It’s certainly there. God knows what happened.
After that, the base system is installed, and the rest of the setup tasks can be performed in a proper chroot.
# chroot /mnt /bin/bash -l # mount -t proc proc /proc # mount -t sysfs sysfs /sys # cat > /etc/apt/sources.list << EOF deb https://deb.debian.org/debian testing main contrib non-free deb-src https://deb.debian.org/debian testing main contrib non-free EOF # apt update && apt upgrade && apt install openssh-server mtd-utils vim ranger tmux xz-utils
And now for a little housekeeping.
# echo <my-hostname> > /etc/hostname # passwd # cat > /etc/network/interfaces.d/eth0 << EOF auto eth0 iface eth0 inet dhcp EOF
I got a lot of locale errors, so I’ll probably have to fix that. Next up, I need to find the partition UUID to identify the root partition. This is done outside of the chroot, and then it is put into the
/etc/fstab file inside of the chroot.
(host) # ls -l /dev/disk/by-partuuid (chroot) # cat > /etc/fstab << EOF PARTUUID = <part-uuid> / ext4 defaults 0 1 EOF
The prebuilt binaries provided at
l.unchti.me allow for the box to boot.
# cd / # wget https://br.unchti.me/uImage # wget https://br.unchti.me/modules.tar.xz # tar xf modules.tar.xz
bareboxenv binary is no longer located at
br.unchti.me, but is installed already under
/firmware on the box.
After that, I followed the configuration to create a barebox config and a set a couple other parameters. The instructions at l.unchti.me uses
$PARTUUID to denote the places that the actual
PARTUUID needs to go. Also, the scripts and the
bareboxenv executable need to be executable in order to run. After that, the SD card is ready to be placed into the NAS and setup.
Now for the tricky bit
After logging back in via telnet, I ran a
cat /proc/mtd and saw that there were two additional entries. Those were
ubi_config. I hope that’s not bad. To find out which
/dev/sdX to mount, I had to run
blkid and match the
PARTUUID to what I had used earlier.
When I went to use
flash_eraseall, I found that there was no such command, however, there was a
flash_erase. From my further research, they seem to do similar things. Simply specifying 0 for the block count (as show with
flash_erase --help) erased the entirety of the device as was intended.
# flash_erase <mtd-device> 0 0
Then I installed the bb.env and the uImage kernel
# flashcp bb.env /dev/mtd2 # flashcp /mnt/uImage /dev/mtd6
The uImage kernel gave an error after it flashed, but I zeroed out the device with
dd, and it was fine. The
flashcp command also only gave an invalid argument only after flashing the entirety of the kernel onto the device and returning an ‘OK’. Unfortunately, the device fell into a boot loop after rebooting, and I’ll have to utilize a serial connection to debug it.
This is the first time I’m using a serial connection, so apologies if I ramble on here. I initially figured I had to use a TTL to a RS232 connection, but that seems to not be the case. There’s an Adafruit USB-to-TTL converter, and I should just be able to plug it into the usb port and play. Of course, it’s not quite that simple, but following that everything is a file, I can use a terminal emulator program. It has to deal with bauds and stuff. Anyways, it should create a virtual terminal at
/dev/ttyUSBX that I can connect to with that program, provided my user is in the group uucp. At least, that’s what the arch wiki says.
After plugging in the USB end of the cable into my machine, I was able to see that it registered itself when it was plugged in.
# dmesg | grep tty usb 2-1: cp210x converter now attached to ttyUSB0
Unfortunately, there is no output, and I am forced to put this project aside for awhile.
- Building a NAS using a HP Microserver, FreeNAS and ZFS
- Cheap, Low Power NAS solution?
- What is a SAN?
- NAS-Central - Zyxel NAS540
- Zyxel NAS540 running Debian 8 off USB stick or SD card
- Debian on the Zyxel NAS540
- What happens when SpinRite Craps Out
- Zyxel Telnet Backdoor
- Debian Wiki - Cross-installing Debian using debootstrap
- Debian Wiki - Qemu User Emulation
- Ubuntu Wiki - Qemu Debootstrap
- Barebox Documentation - Compiling Barebox
- Cross-Compiling Barebox