2018-01-28

Debian on ASUS Router

Asus makes pretty impressive hardware and I've been their fan for quite some time. Recently purchased router lives up to the task - their GT-AC5300 variant features a quad core CPU and 1GB of on-board RAM. Toss in a small SD card and you've got yourself a pretty neat server.

It turns out the firmware on this router is pretty custom even by Asus standards. The features and the look of UI is full of not entirely important stuff for an average user. This means Merlin firmware does support these routers - nobody has time for that.

Luckily, the router's impressive specs are good enough to start a debian chroot. Here's a post explaining how to land Debian on GT-AC5300 or other Asus routers that don't run a custom firmware for whatever reason.

Set up SSH access

Create SSH key

If you don't have an SSH key, open terminal window on your OS X or Linux box and type in:

ssh-keygen

This will start SSH key generation process, which will, at the end, create two files:

  • ~/.ssh/id_rsa - this is your private key. You don't want to share this key with anyone. Works as a physical door key,
  • ~/.ssh/id_rsa.pub - this is your public key. Works as a physical door lock: systems that list this key as authorized_key will accept your private key as a login credential.

Add your SSH key to router's authorized keys

Open your Asus' web UI (most of the routers running recent firmware will respond to http://router.asus.com) and scroll down to Administration. Click the System tab and paste in your public ssh key to a field named Authorized keys.

Set up SD card

Now that your ssh is authorized, it's time to initialize your SD card. You do want to make sure that:
  • you have a decently fast SD card (cards marked U3 with speeds ~60-100MBps should be perfect)
  • you have a USB3.0 SD card reader. While sd card readers for USB 2.0 will work, too, they won't be anywhere that fast.
SSH to your router and initialize your SD card:

ssh admin@192.168.1.1
umount /dev/sda1
mkfs.ext3 /dev/sda1
mount /dev/sda1 /tmp/mnt/sda1

Install software

Get Optware / ipkg

That part is fairly simple and depends solely on software supplied by Asus. Simply navigate to USB Application, scroll down to Download Master and hit Install. This process will take a short while, but once it's complete, the next time you ssh to your router, a new command will be accessible: ipkg.

ssh admin@192.168.1.1
ipkg

Get basic debian image

There is a good instruction on https://www.hqt.ro/how-to-install-debian-jessie-arm/ explaining how to install Debian Jessie on Arm. It's good for the most part, but lacks a few important steps, so i dared put my updates here:

ssh admin@192.168.1.1
ipkg install nano findutils
cd /opt
wget --no-check-certificate -c https://files.hqt.ro/debian/arm/debian_jessie8.9-arm_clean.tgz
tar -xvzf ./debian_jessie8.9-arm_clean.tgz

Next, create the debian script:

cat > /opt/etc/init.d/S99debian << 'EOF'
#!/bin/sh
PATH=/opt/bin:/opt/sbin:/sbin:/bin:/usr/sbin:/usr/bin
CHROOT_DIR=/opt/debian
EXT_DIR=/mnt/sda1/ws

CHROOT_SERVICES_LIST=/opt/etc/chroot-services.list
if [ ! -e "$CHROOT_SERVICES_LIST" ]; then
echo "Please, define Debian services to start in $CHROOT_SERVICES_LIST first!"
echo "One service per line. Hint: this is a script names from Debian's /etc/init.d/"
exit 1
fi

MountedDirCount="$(mount | grep $CHROOT_DIR | wc -l)"

start() {
if [ $MountedDirCount -gt 0 ]; then
echo "Chroot'ed services seems to be already started,
exiting..."
exit 1
fi

echo "Starting chroot'ed Debian services..."
for dir in dev dev/pts proc sys; do
mount -o bind /$dir $CHROOT_DIR/$dir
done

[ -d "$EXT_DIR" ] && mount -o bind $EXT_DIR $CHROOT_DIR/mnt
for item in $(cat $CHROOT_SERVICES_LIST); do
chroot $CHROOT_DIR /etc/init.d/$item start
done
}

stop() {
if [ $MountedDirCount -eq 0 ]; then
echo "Chroot'ed services seems to be already stopped,
exiting..."
exit 1
fi
echo "Stopping chroot'ed Debian services..."
for item in $(cat $CHROOT_SERVICES_LIST); do
chroot $CHROOT_DIR /etc/init.d/$item stop
sleep 2
done

for dir in sys proc dev/pts dev; do
umount $CHROOT_DIR/$dir
done
[ -d "$EXT_DIR" ] && umount $CHROOT_DIR/mnt
}

restart() {
if [ $MountedDirCount -eq 0 ]; then
start
else
stop
MountedDirCount=0
start
fi
}

enter() {
if [ $MountedDirCount -eq 0 ]; then
echo "Not started."
else
chroot /opt/debian /bin/bash
fi
}

status() {
if [ $MountedDirCount -gt 0 ]; then
echo "Chroot'ed services running..."
else
echo "Chroot'ed services not running!"
fi
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
enter)
enter
;;
status)
status
;;
*)
echo "Usage: (start|stop|restart|enter|status)"
exit 1
;;
esac
echo Done.
exit 0
EOF
chmod 755 /opt/etc/init.d/S99debian

Create a control file telling Asus to start debian for you upon each reboot:

cat > /opt/lib/ipkg/info/debian.control <
Package: debian
Architecture: arm
Priority: optional
Section: misc
Version: 8.0.0
Maintainer: debian
Source: debian.org
Description: Debian chroot
Depends:
Suggests: 
Conflicts: 
Enabled: yes
EOF

The most important part up there is to make sure that 'Enabled: yes' is present. This is how Asus' optware decides what is to be started at boot.

touch /opt/etc/chroot-services.list
ln -s /opt/etc/init.d/S99debian /opt/bin/debian
ln -s /opt/debian/usr/sbin/chroot /opt/bin/chroot

This step will ensure you have a 'debian' script and 'chroot' commands available. Finally, you probably want to execute:

debian start
debian enter

and edit the /etc/apt/sources.list file, replacing all references to jessie with buster, which will put you on current (as of the time of writing this post) debian testing head. At the end, simply execute:

apt-get update
apt-get dist-upgrade

and reboot your router. The moment it comes up, it should be running debian chroot already, so after you ssh in to your router, type in debian enter