OpenWRT’s way

I’ve been using OpenWRT since 2012. For now I’ve been able to make it work under multiple environments, with or without native IPv6 support, bridged or NATed. By “work”, I mean both IPv4 and IPv6, with a reliable connection to the rest of the world.


Note that you may need to have some prerequisite knowledge to read the this article, including but not limited to Linux shell commands and computer networking basics.

Building the whole system on our own is no longer recommended. I used to build OpenWRT in my PC because I didn’t know how convenient the Image Generator and the SDK are. Basically, the Image Generator generates firmware image from pre-built binary packages, which eliminates us from downloading the source code and building them from scratch. The SDK is a complement for the Image Generator. You might find some of the packages are missing from the official mirror site and you would need to build them. The SDK is a pre-built toolchain, which keeps you from building the cross-compile toolchain from scratch (which takes quite some time!).

To use the Image Generator, choose your platform and download the correct version (yes I am using TUNA‘s mirror). Most common version is ar71xx/generic. Decompress the tarball and cd into it.

tar xvf OpenWrt-ImageBuilder-15.05.1-ar71xx-generic.Linux-x86_64.tar.bz2
cd OpenWrt-ImageBuilder-15.05.1-ar71xx-generic.Linux-x86_64

Now you can start building. First, make info to see and find your target profile.

make info
make image \
PROFILE=yourprofile \
PACKAGES="some space separated packages" \

The image target allows you to generate firmware. The PROFILE variable specifies which hardware you are generating firmware for.

The PACKAGES variable adds additional packages besides the defaults. I would suggest 6in4 bind-dig block-mount ddns-scripts firewall ip-bridge ip-full ipset iptables-mod-extra iputils-traceroute6 kernel kmod-ip6tables-extra kmod-ipt-geoip kmod-ipt-nat-extra kmod-ipt-extra kmod-ipt-nat6 kmod-iptunnel4 kmod-iptunnel6 kmod-l2tp kmod-macvlan kmod-nf-nat kmod-nf-nat6 kmod-sit kmod-tun luci luci-app-ddns luci-app-firewall luci-app-ntpc luci-app-qos luci-app-upnp luci-mod-admin-full luci-proto-ipv6 luci-proto-ppp luci-ssl luci-theme-bootstrap mtr uhttpd wget zoneinfo-core as a minimum installation. If you still have space in your router or whatever hardware, I would strongly recommend bird4 bird6 curl ca-certificates dnsmasq-full fastd htop iftop kmod-usb-core openconnect openvpn-polarssl netcat screen socat tcpdump-mini tinc as well.

The FILES variable allows you embed configurations in your generated firmware. The path should point to the decompressed root, usually obtained from decompressing the backup tarball from a previous installation.

mkdir -p /path/to/backup/folder
ssh root@openwrt.lan sysupgrade -b - |tar xvf - -C /path/to/backup/folder

Now you are able to integrate all officially built packages into your firmware. For custom packages, you will need the SDK. Download proper SDK tarball, decompress and cd into it.

tar xvf OpenWrt-SDK-15.05.1-ar71xx-generic_gcc-4.8-linaro_uClibc-
cd OpenWrt-SDK-15.05.1-ar71xx-generic_gcc-4.8-linaro_uClibc-

Use scripts/feeds update packagename1 packagename2 to acquire package repositories from the official feeds, or download the packages directory manually if you are building non-official package, shadowsocks-libev for example.

pushd package
git clone

Use scripts/feeds install -d m packagename1 packagesname2 to tell the SDK you are gonna build these packages. It will automatically solve dependencies.

Built the packages. Dependencies are handled automatically as well.

make package/packagename1/compile package/packagename2/compile package/shadowsocks-libev/openwrt/compile
make package/index

If errors pop up, do as it suggest.

make V=s package/packagename1/compile package/packagename2/compile package/shadowsocks-libev/openwrt/compile

Probably you are missing some tools like ccache or perl-xml-parser.

Once you have successfully built your custom packages, you should be able to seem the ipk files in some sub-sub-sub-folders of the bin directory. Make sure you have run make package/index successfully before going into the next step. Otherwise, the Image Generator would not be able recognize the repository correctly.

Let the Image Generator be aware of your recently built packages. To do this, add src chaos_calmer_base file:///path/to/sdk/root/bin/ar71xx/generic/packages/base and etc to the repositories.conf file in the Image Generator root. Then build as described above.



August 1st, 2016

P.S. The content below was originally written more than one year ago. Many ideas and practices are not quite mature.

How to install OpenWRT is pretty well documented and I shall not describe it in detail here. Basically you can either download a pre-built version, preferably from its official website, or build it your self. I prefer build it myself, as it make it possible to customize system models and packages. [Well, I’ll suggest use Image Generator(it was called Image Builder the first time I used it… ) as described in this article because it saves time and network traffic significantly. –updated March 24th, 2016]

First of all, choose a branch. Most recent ‘stable’ release is Barrier Breaker, and trunk branch is in Chaos Calmer. Follow the instructions here. Make sure you have enough disk space and an Internet connection.

Second, install packages to your source code repo. cd into root of your source code, and do scripts/feeds update -aandscripts/feeds install -a. This will make all officially available packages appear in the next step.

Third, make menuconfig. Choose your router type, and packages you would like to install. Do not choose too many packages, since OpenWRT would fail to generate a binary if it exceeds the router’s hardware limit. In order to maintain a flexible IPv6 connectivity, make sure you’ve selected ip 6in4 kmod-ip6tables and kmod-ipt-nat6. The first two are used to provide tunneled connection, and the last two are used to provide IPv6 NAT. I prefer using LuCI, so choose luci luci-ssl and luci-ipv6. If your router provides USB connection and you intend to use it, you’ll need kmod-fs-ext4 kmod-usb-core kmod-scsi-generic kmod-usb-ohci kmod-usb-storage kmod-usb-storage-extras and possibly luci-hd-idle.  Other packages I would install include nginx shadowsocks-libev(that you need to follow instructions on its github repo) privoxy tcpdump bind-dig wget curl luci-app-upnp iputils-traceroute6 .

Then, make. Multithreading could be enabled with -j $(#core+1) option, but it could be buggy. If error pops up, rebuild without -j option. If it is still there, rebuild with V=s option and read the detailed error message. You need to wait for a few hours if you’ve got a slow CPU or a slow Internet connection. On success, two binary file would appear in your bin/$arch directory, on noted with “factory” and another with “sysupgrade”, along with many other who-knows-what-for files. You’ll need the “factory” image if you are flushing OpenWRT on a router’s official ROM or the “sysupgrade” image to perform OpenWRT system upgrade.

Generally, if you have installed LuCI as I suggested, configuration should not be a big problem. Remember to set up a strong password for both root and WiFi.

Last but not least, here comes the tricky part. If you are using IPv6, you might fight yourself able to get valid IPv6 addresses but failed to transmit packets correctly from LAN. The router could be using IPv6 perfectly but LAN devices would faild. Even if you did NAT right. It might be cause by the faulty routing table configuration. OpenWRT failed to set a default gateway for LAN and you may need to set it up manually. According to this article, you need to find your gateway first, and add it as your default gateway:

route -A inet6 add default gw $GATEWAY

Note that $GATEWAY should be your IPv6 gateway, in other words, your first hop when performing traceroute. My OpenWRT starts to work perfectly when I found this tricky part.

So that’s it.




April 20th, 2015