OpenWRT As a Virtual Router

Introduction

OpenWRT is GNU/Linux distribution for embedded devices. You can run OpenWRT on a dedicated hardware or you can have OpenWRT as virtual router which can be somewhere on cloud.

When we talk about the cloud image, we care about the size of the image which plays very important role in the space that the VM will occupy on disk and in the memory in addition to the time needed to spin a new virtual machine. Time to spin a virtual machine becomes more critical when you create a virtual machine depending on your consumption of your resources where you need to delete a virtual machine when it is not needed (e.g. low load) or when you need to create a new virtual machine quickly when you reach a threshold where you have high load and still you need to keep your service available.

In this article i will show you how simple is the creation of a small Linux image (OpenWRT) for cloud.

Clone the OpenWRT Repo from GitHub

  • Install the source:
    • # git clone git://git.openwrt.org/openwrt.git; cd openwrt
  • Open the file: feeds.conf.default  and comment the packages that you don’t want to be installed. For example if you have your own telephony then comment the telephony.git which includes installing Kamailio, OpenSIPS, Asterisk,….etc.
  • For cloud, we need the cloud-init for the early initialization of the virtual machine/instance (e.g. enable the SSH remote access). I am going to use another cloud-init which is rc.cloud and it is a set of shell scripts that implements part of the cloud-init. The aim is making the image small. The installation of rc.cloud will be as a custom feed:

Configuration & Compilation

# make menuconfig

Now we take an example so i will configure the target system as x86 and the subtarget as KVM guest so this image can work with Openstack cloud but not Amazon (xen based).

screenshot-from-2017-01-12-11-07-18

Then we configure the target image:

screenshot-from-2017-01-12-11-07-34

For example you can select ext4 file system, change the root file system partition size, root device name (for example /dev/vda2 for kvm). Check other options that you might be interested in.

Now you need to build so you type: # make V=99

After this and according to the above configuration we will have our compressed image in “bin/x86/openwrt-x86-kvm_guest-combined-ext4.img.gz”.

Image Configuration

  • Uncompress the compressed raw image file:
    • gzip -dc  bin/x86/openwrt-x86-kvm_guest-combined-ext4.img.gz   >  openwrt-x86-kvm_guest-combined-ext4.img
  • Mount the partions within the image file:
    • # sudo  kpartx  -av openwrt-x86-kvm_guest-combined-ext4.img
      [sudo] password for binan:
      add map loop0p1 (253:3): 0 8192 linear /dev/loop0 512
      add map loop0p2 (253:4): 0 241664 linear /dev/loop0 9216
  • Mount the image file as a block device (loop device):
    • # mkdir imgroot
    • # sudo mount -o  loop   /dev/mapper/loop0p2  imgroot

If using “kpartx” and then “mount” did not work then go further below and try that     “Mounting Your Image File as a  Loop Back Device”.

  • Copy the /bin/bash to imgroot/bin:
    • # sudo mkdir imgroot/bin
    • # sudo cp /bin/bash    imgroot/bin/
  • Change  the root directory for the current running process:
    • # sudo chroot imgroot

Now if you got this error message “chroot: failed to run command ‘/bin/bash’: No such file or directory” this means the /bin/bash or its dependencies are not exist in the new root so do these to fix this missing:

  • Check the /bin/bash dependencies in the old root:
    • $ ldd /bin/bash
      linux-vdso.so.1 (0x00007ffe69bee000)
      libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007fbc74ceb000)
      libdl.so.2 => /lib64/libdl.so.2 (0x00007fbc74ae7000)
      libc.so.6 => /lib64/libc.so.6 (0x00007fbc74725000)
      /lib64/ld-linux-x86-64.so.2 (0x000055be47e4b000)
    • Move the lib/* to lib64: # sudo mv imgroot/lib  imgroot/lib64
    • Copy the files from the old root to the new root:
      • One of the above (we must copy all above): # sudo  cp  /lib64/libc.so.6  imgroot/lib64
    • Ow we try again: # sudo chroot imgroot
      bash-4.3#     —–> success

Here is our tree:

bash-4.3#ls
bin         etc         lib64       mnt         proc        root        sys         usr         www
dev         lib         lost+found  overlay     rom         sbin        tmp         var
bash-4.3#

Now we can do our changes to the image files.

On cloud (openstack or amazon), you can define security groups to protect your virtual machines from the outside. So we should keep this in mind.

In addition to this the dropbear (the SSH compatible client and server) will not allow ssh without root password so we must set the root password (/etc/shadow):

You can open the file and edit the root password or using other Linux command like ‘sed’ to set/replace the password.

Then exist from chroot and umount the imgroot folder.

Mounting Your Image File as a Loop Back Device

Do the following:

# sudo fdisk -l  openwrt-x86-kvm_guest-combined-ext4.img
Disk openwrt-x86-kvm_guest-combined-ext4.img: 122.5 MiB, 128450560 bytes, 250880 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: 0x4ff362b1

Device                                                                         Boot Start    End Sectors  Size Id Type
openwrt-x86-kvm_guest-combined-ext4.img1 *      512   8703    8192    4M 83 Linux
openwrt-x86-kvm_guest-combined-ext4.img2       9216 250879  241664  118M 83 Linux

Then the offset will be 512 * 512 = 262144
Then we can mount the image:

the boot: [binan@dhcppc0 xen]$ sudo mount -o loop,rw,offset=262144 openwrt-x86-kvm_guest-combined-ext4.img  imgroot/

the rest: [binan@dhcppc0 xen]$ sudo mount -o loop,rw,offset=4718592 openwrt-x86-kvm_guest-combined-ext4.img  imgroot/

Now you can change the root.
chroot: $ sudo chroot imgroot/