Creating an OpenWrt image for Scaleway Instances
This tutorial shows how to build a custom image for Scaleway from scratch using the new export/import feature.
It introduces the basic needs and actions to create a custom image, but each operating system may have specifics that need to be troubleshooted individually.
To create a custom image, you need to build a QCOW2 image and create a snapshot from it.
The following steps are required to create the image:
- Download an OS disk image
- Convert it to QCOW2 (if not provided in this format)
- Edit the image to fit Scaleway's ecosystem
- Upload the image to Scaleway Object Storage
- Convert to Snapshot through import
- Test the image and troubleshoot via the Console
Before you start
To complete the actions presented below, you must have:
- A Scaleway account logged into the console
- Owner status or IAM permissions allowing you to perform actions in the intended Organization
- An SSH key
- An Object Storage bucket
The following commands are done on an Ubuntu 22.04.
Download the image
The needed image must be a full disk image, not an ISO image or only a rootfs.
In order to work on Scaleway Instances, the image must be using EFI (not just BIOS) to boot.
OpenWrt images are available here, we are going to use a stable release, for x86_64
architecture, with EFI.
Download the image we are going to use in this tutorial:
curl -sSLO https://downloads.openwrt.org/releases/24.10.1/targets/x86/64/openwrt-24.10.1-x86-64-generic-ext4-combined-efi.img.gz
gunzip openwrt-24.10.1-x86-64-generic-ext4-combined-efi.img.gz
Prepare the QCOW2 image
-
Install the needed QEMU tools:
apt-get install qemu-utils -y
-
Convert the image and resize the target disk size (minimum disk size at Scaleway = 1 GB):
qemu-img convert -f raw -O qcow2 openwrt-24.10.1-x86-64-generic-ext4-combined-efi.img openwrt-24.10.1-x86-64-generic-ext4-combined-efi.qcow2 qemu-img resize openwrt-24.10.1-x86-64-generic-ext4-combined-efi.qcow2 1G
-
Mount the QCOW2 image as a device
modprobe nbd qemu-nbd -c /dev/nbd0 openwrt-24.10.1-x86-64-generic-ext4-combined-efi.qcow2
-
Resize the main partition to fit the available space (partition number 2 in the example above):
growpart /dev/nbd0 2 resize2fs /dev/nbd0p2
Edit the image content
-
Mount the image:
mkdir -p /mount/temp mount /dev/nbd0p2 /mount/temp
OpenWrt needs two interfaces to work (WAN and LAN). But a default Instance only provides one interface. We are going to use the dummy module to add an interface.
-
Download the package.
curl -sSL -o /mount/temp/kmod-dummy_5.10.146-1_x86_64.ipk https://downloads.openwrt.org/releases/24.10.1/targets/x86/64/packages/kmod-dummy_5.10.146-1_x86_64.ipk
-
Chroot in the image.
chroot /mount/temp/ /bin/ash
-
Install the package.
mkdir -p /tmp/lock opkg install kmod-dummy_5.10.146-1_x86_64.ipk rm -rf /tmp/* kmod-dummy_5.10.146-1_x86_64.ipk
-
Set the root password, whilst in the chroot. In OpenWrt, it is used by the web interface for login.
passwd
-
Configure the web server ports and redirect
http
tohttps
using theuci
CLI of OpenWrt.uci del uhttpd.main.listen_http uci add_list uhttpd.main.listen_http='0.0.0.0:8080' uci del uhttpd.main.listen_https uci add_list uhttpd.main.listen_https='0.0.0.0:8443' uci set uhttpd.main.redirect_https=1 uci commit uhttpd
-
Disable password authentication in SSH.
uci set dropbear.@dropbear[0].PasswordAuth=off uci set dropbear.@dropbear[0].RootPasswordAuth=off uci commit dropbear
Configure SSH access
Since we have disabled password authentication in SSH, we need a way to load SSH keys when running.
In this tutorial, we do not set up cloud-init, but use the same magic IP mechanism to get the keys.
-
Create the
authorized_keys
file:touch /etc/dropbear/authorized_keys chmod 600 /etc/dropbear/authorized_keys
-
Create the fetch script:
cat <<EOF>/etc/init.d/fetch_ssh_keys #!/bin/sh /etc/rc.common START=97 start() { echo -e "\nFetching SSH keys from Scaleway Metadata" > /dev/console wget -qO- http://169.254.42.42/conf | egrep 'SSH_PUBLIC_KEYS_._KEY' | cut -d'=' -f2- | sed "s/'//g" > /etc/dropbear/authorized_keys } reload() { start } EOF chmod +x /etc/init.d/fetch_ssh_keys
-
Add the script to
rc.d
.ln -s /etc/init.d/fetch_ssh_keys /etc/rc.d/S97fetch_ssh_keys
-
Exit the chroot.
exit
Configure the network
-
Configure the network to be able to use the image on a Scaleway Instance:
cat <<EOF>/mount/temp/etc/config/network config interface 'loopback' option device 'lo' option proto 'static' option ipaddr '127.0.0.1' option netmask '255.0.0.0' config interface 'wan' option device 'eth0' option proto 'dhcp' config interface 'lan' option device 'dummy0' option proto 'static' option ipaddr '192.168.0.1' option netmask '255.255.255.0' EOF
-
Add firewall rules to redirect WAN ports to LAN ports. This is required, as accessing the UI and SSH in OpenWrt is normally only possible through the LAN interface.
cat <<EOF>>/mount/temp/etc/config/firewall # port redirect UI ACCESS and SSH config redirect option name HTTP-UI option src wan option src_dport 8080 option desti lan option dest_ip 192.168.0.1 option dest_port 8080 option proto tcp config redirect option name HTTPS-UI option src wan option src_dport 8443 option dest lan option dest_ip 192.168.0.1 option dest_port 8443 option proto tcp config redirect option name SSH option src wan option src_dport 22 option dest lan option dest_ip 192.168.0.1 option dest_port 22 option proto tcp EOF
-
Unmount the image container to finish editing its content.
umount /mount/temp qemu-nbd -d /dev/nbd0
Import the image
You can use the Scaleway console or your favorite Amazon S3-compatible CLI tool to upload objects into a bucket.
In this example, we use the AWS CLI.
-
Import the image into your bucket:
aws s3 cp openwrt-24.10.1-x86-64-generic-ext4-combined-efi.qcow2 s3://my-import-bucket/openwrt.qcow2
-
Trigger the import of the image as a snapshot in one of the regions where the bucket is located, using SCW CLI:
scw block snapshot create name=openwrt volume-type=b_ssd bucket=my-import-bucket key=openwrt.qcow2
-
Create the corresponding Instance image:
scw instance image create name=openwrt arch=x86_64 snapshot-id=$(scw instance snapshot list | grep -m1 openwrt | awk '{print $1}')
Testing and troubleshooting the image
-
Create an Instance using the snapshot image:
scw instance server create type=DEV1-S name=scw-openwrt ip=new image=$(scw instance image list | grep -m1 openwrt | awk '{print $1}')
-
Troubleshoot the boot behavior and configuration using the console of your Instance:
scw instance server console $(scw instance server list | grep -m1 scw-openwrt | awk '{print $1}')
-
Exit the console using
Ctrl+q
.
You can access the web console of OpenWrt using https://<public ip of instance>:8443
Visit our Help Center and find the answers to your most frequent questions.
Visit Help Center