Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Install Mikrotik CHR on a Digital Ocean droplet (Ubuntu 16.04.6 tested working 31/08/2019)
#!/bin/bash
#
# Digital Ocean Ubuntu 16.04.6 Droplet
# Running:
# wget https://gist.githubusercontent.com/stroebs/54fc09734a3911e91eeeb43434f117df/raw/1ede2fb162d404171122db0c84a9eeea468a92cd/make-chr.sh
# chmod +x make-chr.sh
# ./make-chr.sh
#
wget http://download2.mikrotik.com/routeros/6.37/chr-6.37.img.zip -O chr.img.zip && \
gunzip -c chr.img.zip > chr.img && \
apt-get update && \
apt install -y qemu-utils pv && \
qemu-img convert chr.img -O qcow2 chr.qcow2 && \
qemu-img resize chr.qcow2 1073741824 && \
modprobe nbd && \
qemu-nbd -c /dev/nbd0 chr.qcow2 && \
echo "Give some time for qemu-nbd to be ready" && \
sleep 2 && \
partprobe /dev/nbd0 && \
sleep 5 && \
mount /dev/nbd0p2 /mnt && \
ADDRESS=`ip addr show eth0 | grep global | cut -d' ' -f 6 | head -n 1` && \
GATEWAY=`ip route list | grep default | cut -d' ' -f 3` && \
PASSWORD="CHANGEME" && \
echo "/ip address add address=$ADDRESS interface=[/interface ethernet find where name=ether1]
/ip route add gateway=$GATEWAY
/ip service disable telnet
/user set 0 name=root password=$PASSWORD
/ip dns set servers=1.1.1.1,1.0.0.1
/system package update install
" > /mnt/rw/autorun.scr && \
umount /mnt && \
echo "Magic constant is 65537 (second partition address). You can check it with fdisk before appliyng this" && \
echo "This scary sequence removes seconds partition on nbd0 and creates new, but bigger one" && \
echo -e 'd\n2\nn\np\n2\n65537\n\nw\n' | fdisk /dev/nbd0 && \
e2fsck -f -y /dev/nbd0p2 || true && \
resize2fs /dev/nbd0p2 && \
sleep 1 && \
echo "Compressing to gzip, this can take several minutes" && \
mount -t tmpfs tmpfs /mnt && \
pv /dev/nbd0 | gzip > /mnt/chr-extended.gz && \
sleep 1 && \
killall qemu-nbd && \
sleep 1 && \
echo u > /proc/sysrq-trigger && \
echo "Warming up sleep" && \
sleep 1 && \
echo "Writing raw image, this will take time" && \
zcat /mnt/chr-extended.gz | pv > /dev/vda && \
echo "Don't forget your password: $PASSWORD" && \
echo "Sleep 5 seconds (if lucky)" && \
sleep 5 || true && \
echo "sync disk" && \
echo s > /proc/sysrq-trigger && \
echo "Ok, reboot" && \
echo b > /proc/sysrq-trigger
@stroebs

This comment has been minimized.

Copy link
Owner Author

commented Oct 28, 2017

Can be used on a fresh Ubuntu 16.04 installation.
Kudos: https://www.digitalocean.com/community/questions/installing-mikrotik-routeros

@stroebs

This comment has been minimized.

Copy link
Owner Author

commented Nov 30, 2017

Updated to include a partx on line 11 - Script stopped at mount /dev/nbd0p2 /mnt with /dev/nbd0p2 missing

@stroebs

This comment has been minimized.

Copy link
Owner Author

commented Jan 24, 2018

Update: Your droplet is likely to run into Kernel Panic while the image is writing to disk.

You'll need to forcefully stop your droplet in the DO control panel and start it up again. After that it's good to go!

@electropolis

This comment has been minimized.

Copy link

commented Jan 27, 2018

Does work only in DO ? I tried that on Ubuntu on UpCloud provider and server restarted again to the same system what it was before .. Ubuntu

-bash: relocation error: -bash: symbol , version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference -bash: relocation error: -bash: symbol , version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference

Ok although it started somehow beside those error on servers from DO and UpCloud. You could also add eth1 for ether2 with private IP which is very important

@hklkf

This comment has been minimized.

Copy link

commented Feb 25, 2018

how to fix it?

2018-02-25 02:59:05 (4.87 MB/s) - ‘chr.img.zip’ saved [45164547/45164547]

make-chr.sh: line 3: apt-get: command not found

@fyrstyk

This comment has been minimized.

Copy link

commented Mar 7, 2018

DO have updated to ubuntu 16.04.4, and it looks like the script no longer works when writing to /dev/vda :(

Any ideas?

Thanks in advance.

@happy201807

This comment has been minimized.

Copy link

commented Aug 31, 2018

If the ip addr NIC is ens3 instead of eth0, I can't connect to vps after installation. What do I need to change?

@devstudios

This comment has been minimized.

Copy link

commented Apr 25, 2019

script fails at line 11,
partx: stat of /dev/nbd0p2 failed: No such file or directory

@devstudios

This comment has been minimized.

Copy link

commented Apr 25, 2019

partx fails to add a partition, what could be the solution?

ubuntu@ip-172-31-37-159:~$ sudo partx --add /dev/nbd0
partx: /dev/nbd0: error adding partition 1
ubuntu@ip-172-31-37-159:~$
@devstudios

This comment has been minimized.

Copy link

commented Apr 25, 2019

script working with ubuntu 16.04 but not 18.04.

@lzcykevin

This comment has been minimized.

Copy link

commented Jun 15, 2019

Debian 9.6
Give some time for qemu-nbd to be ready

partx: /dev/nbd0: error adding partition 1
resize2fs 1.43.4 (31-Jan-2017)
open: No such file or directory while opening /dev/nbd0p2

@stroebs

This comment has been minimized.

Copy link
Owner Author

commented Jun 18, 2019

I've noticed that this script only works in certain situations, very temperamental. I will look into the issues mentioned here at some stage in the next few weeks... Travelling is a killer

@vfedyay

This comment has been minimized.

Copy link

commented Jul 22, 2019

Yes, after partx -a /dev/nbd0 we have only /dev/nbd0p1 on device
so resizing with "echo -e 'd\n2\nn\np\n2\n65537\n\nw\n' | fdisk /dev/nbd0" doesn't work.
I've tried to delete manualy p1 partition and create new one (bigger) and meet another problem.
p1 starts at sector 1, but fdisk allows to create primary partition only from 2048 starting.

All this made on droplet with Ubuntu 16.04.6 x64 and router OS chr-6.45.2.img.zip (RAW image download).
Will try on latest Ubuntu available for droplet.

@nick1543

This comment has been minimized.

Copy link

commented Aug 28, 2019

All this made on droplet with Ubuntu 16.04.6 x64 and router OS chr-6.45.2.img.zip (RAW image download).
Will try on latest Ubuntu available for droplet.

Any success with the latest Ubuntu version?

I've just tried this script (a bit modified) on Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-159-generic x86_64).
No success, but I understand where the problem is:

echo "Magic constant is 65537 (second partition address). You can check it with fdisk before appliyng this" && \
echo "This scary sequence removes seconds partition on vda and creates new, but bigger one" && \
echo -e 'd\n2\nn\np\n2\n227328\n\nw\n' | fdisk /dev/vda && \

I changed 65537 to 227328, but in fact that wasn't correct.

Could anyone advise me, how to modify the script correctly?

Here is my fdisk -l result

Disk /dev/vda: 25 GiB, 26843545600 bytes, 52428800 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: gpt
Disk identifier: 68AB7630-F3A6-4BD2-B264-F6121E676127

Device      Start      End  Sectors  Size Type
/dev/vda1  **227328** 52428766 52201439 24.9G Linux filesystem
/dev/vda14   2048    10239     8192    4M BIOS boot
/dev/vda15  10240   227327   217088  106M Microsoft basic data

And here is the modified script by me (but still not correct at all)

wget https://download.mikrotik.com/routeros/6.44.5/chr-6.44.5.img.zip -O chr.img.zip && \
gunzip -c chr.img.zip > chr.img && \
apt-get update && \
apt install -y qemu-utils pv && \
qemu-img convert chr.img -O qcow2 chr.qcow2 && \
qemu-img resize chr.qcow2 `fdisk /dev/vda -l | head -n 1 | cut -d',' -f 2 | cut -d' ' -f 2` && \
modprobe nbd && \
qemu-nbd -c /dev/vda chr.qcow2 && \
echo "Give some time for qemu-nbd to be ready" && \
sleep 2 && \
partx -a /dev/vda && \
mount /dev/vda1 /mnt && \
ADDRESS=`ip addr show eth0 | grep global | cut -d' ' -f 6 | head -n 1` && \
GATEWAY=`ip route list | grep default | cut -d' ' -f 3` && \
echo "/ip address add address=$ADDRESS interface=[/interface ethernet find where name=ether1]
/ip route add gateway=$GATEWAY
/ip service disable telnet
/user set 0 name=XXXXXXXX password=XXXXXXXX
 " > /mnt/rw/autorun.scr && \
umount /mnt && \
echo "Magic constant is 65537 (second partition address). You can check it with fdisk before appliyng this" && \
echo "This scary sequence removes seconds partition on vda and creates new, but bigger one" && \
echo -e 'd\n2\nn\np\n2\n227328\n\nw\n' | fdisk /dev/vda && \
e2fsck -f -y /dev/vda1 || true && \
resize2fs /dev/vda1 && \
sleep 1 && \
echo "Compressing to gzip, this can take several minutes" && \
mount -t tmpfs tmpfs /mnt && \
pv /dev/vda | gzip > /mnt/chr-extended.gz && \
sleep 1 && \
killall qemu-nbd && \
sleep 1 && \
echo u > /proc/sysrq-trigger && \
echo "Warming up sleep" && \
sleep 1 && \
echo "Writing raw image, this will take time" && \
zcat /mnt/chr-extended.gz | pv > /dev/vda && \
echo "Sleep 5 seconds (if lucky)" && \
sleep 5 || true && \
echo "sync disk" && \
echo s > /proc/sysrq-trigger && \
echo "Ok, reboot" && \
echo b > /proc/sysrq-trigger

And here is the end of stdout after starting the script:

...
Setting up qemu-utils (1:2.11+dfsg-1ubuntu7.17) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Image resized.
Failed to set NBD socket
resize2fs 1.44.1 (24-Mar-2018)
The filesystem is already 6525179 (4k) blocks long.  Nothing to do!

Compressing to gzip, this can take several minutes
1.63GiB 0:01:24 [18.9MiB/s] [======>                                                                                                                              ]  6% ETA 0:20:05
gzip: stdout: No space left on device
1.64GiB 0:01:24 [19.8MiB/s] [======>                                                                                                                              ]  6%
sync disk
Ok, reboot

@stroebs

This comment has been minimized.

Copy link
Owner Author

commented Aug 31, 2019

@nick1543 @vfedyay @lzcykevin @devstudios @fyrstyk @hklkf

FYI this script has been updated and confirmed working 100% with an Ubuntu 16.04.6 droplet on DigitalOcean.
CAVEAT: The disk is only 1GB - You can change this by changing the number "1073741824" and test for yourself.
There were some issues, which I've found, researched about and fixed.

  • Newer ROS images do not have two partitions, so I've gone back to 6.37
  • Trying to use autorun.scr on newer images no longer works, so I've gone back to 6.37
  • Partition syncing on DO droplets causes a kernel panic while the image is being written to disk, so the disk had to be shrunk to a reasonable size to be written, so reduced image size to 1GB (1073741824). I don't know why this happens but this method works and having a MikroTik with more than 1GB disk is a rare edge case.
  • DNS servers set to Cloudflare (1.1.1.1, 1.0.0.1) by default
  • Added an upgrade to the latest stable ROS on startup

Mileage may vary - I simply copied the script and pasted it into a terminal and executed it. The droplet reboots just fine, takes a few seconds to download the latest ROS, reboots and it's good to go!

@imperio2k

This comment has been minimized.

Copy link

commented Sep 1, 2019

I ran the scrip ./make-chr.sh on my VPS Ubuntu 16.04.6 x84_64 and it gets stuck in the next part:

Warming up sleep
Writing raw image, this will take time
744MiB 0:00:06 [ 142MiB/s] [=> ] 2% ETA 0:03:20

In the VPS screen connection this shows me.

image

What could be happening? What other code can I try?

Thank you in advance for your reply.

@stroebs

This comment has been minimized.

Copy link
Owner Author

commented Sep 1, 2019

@imperio2k Try it a second time. It looks like there’s some disk synchronization that occurs which causes a kernel panic when the image is being written to disk, before the image can be completely written. I’ve tried this many times using Ubuntu 16.04 and 18.04 and I can assure you that it does work if you are not unlucky enough to get a Kernel panic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.