OpenWRT
Installation
Refer to OpenWRT's list of hardware and firmware downloads at:
Intel based Hardware or as a VM
Navigate to the 'x86' target of the latest release. Use the '64' release for 64-bit capable processors or 'Generic' for 32-bit. For example, OpenWRT 19.0.7 for Intel based 64bit processors can be found at https://downloads.openwrt.org/releases/19.07.3/targets/x86/64/.
Use either the read-only squashfs image (which limits you to 230MB available for packages) or the ext4 image (which can be expanded and the entire filesystem is writable but without a factory reset feature).
Download the combined ext4 disk image, decompress the image, then dd
the image to your hard drive or flash media. For ext4 images, use fdisk to expand the second partition to the full size of the storage device and then run resize2fs /dev/sdx2
.
Raspberry Pi 1 Model B
For all other Raspberry Pis, the installation information can be found at https://openwrt.org/toh/raspberry_pi_foundation/raspberry_pi
The installation process involves dd
'ing the image to the SD card. You may wish to resize the SD card after the image has been written. To do so, resize the data partition and then run e2fsck -f /dev/mmcblk0p2
and resize2fs /dev/mmcblk0p2
. More info at https://elinux.org/RPi_Resize_Flash_Partitions#Manually_resizing_the_SD_card_on_Linux.
# dd if=openwrt-brcm2708-bcm270{8,9}-sdcard-vfat-ext4.img of=/dev/sdX bs=2M conv=fsync status=progress
## Optionally resize the data partition
# e2fsck -f /dev/sdX2
# resize2fs /dev/sdX2
Serial is enabled and is available via GPIO pins 8 and 10 for TX and RX respectively.
Default IP is 192.168.1.1/24.
Raspberry Pi 2 Model B v1.2
Update: It appears there is an official image. I have not tried this yet and the information below may be inaccurate or unnecessary. See https://openwrt.org/toh/raspberry_pi_foundation/raspberry_pi for more information.
OpenWRT does not list an official image for the Raspberry Pi 2 v1.2 board. Neither the Pi 3 or Pi 2 image works. This is because the Raspberry Pi 2 v1.2 board uses the bcm2710 SOC (same as the Pi 3) but both images don't properly handle the Pi 2 v1.2 board and as such, both versions fail to boot.
To get OpenWRT to work on this board, image the SD card with the bcm2710 image (the Pi 3 version) and then:
- Mount
/boot
- Copy
bcm2710-rpi-3-b.dtb
tobcm2709-rpi-2-b.dtb
A copy can be found at https://github.com/raspberrypi/firmware/raw/master/boot/bcm2710-rpi-3-b.dtb to bcm2709-rpi-2-b.dtb
.
Buffalo WZR-600HP
See: WZR-600DHP
Linksys E8450
See: Linksys E8450
Linksys MR8300
See: Linksys MR8300
Package Development
Guide on building packages for OpenWRT: http://dvblog.soabit.com/building-custom-openwrt-packages-an-hopefully-complete-guide/
Tasks
Change LAN IP Address
By default, OpenWRT will assign itself 192.168.1.1. You can change this default IP address to something else by editing /etc/config/network
or using the Unified Configuration Interface (uci) configuration tool.
The first method requires editing /etc/config/network
and changing the option ipaddr
value within the 'lan' interface section.
## The 'lan' section in /etc/config/network
config interface 'lan'
option type 'bridge'
option ifname 'eth0'
option proto 'static'
option ipaddr '192.168.1.1' <-- change this
option netmask '255.255.255.0'
option ip6assign '60'
Apply the changes by running service network reload
, or /etc/init.d/network reload
.
Alternatively, use uci
by setting the network.lan.ipaddr
with the desired IP address.
# uci set network.lan.ipaddr 10.1.0.10
## Optionally set other values as well:
# uci set network.lan.gateway 10.1.1.1
# uci set network.lan.dns 10.1.1.1
# uci set network.lan.ifname eth0
## Apply changes, and reload network
# uci commit network
# /etc/init.d/network reload
See Also: https://openwrt.org/docs/guide-user/base-system/basic-networking
Add an IP Alias
To add an additional IP address to the LAN interface, create a new interface with the ifname set to @lan
.
# uci set network.lan2=interface
# uci set network.lan2.ifname='@lan'
# uci set network.lan2.proto=static
# uci set network.lan2.ipaddr=192.168.35.10
# uci set network.lan2.netmask=255.255.255.0
# uci commit network
# /etc/init.d/network reload
Running a PHP Application
I want to run a PHP application on a separate IP address. I will use the built-in uHTTPd web server and have the PHP application served from a secondary IP address.
## Install PHP and dependencies
# opkg install php7 php7-cgi php7-cli php7-mod-mbstring php7-mod-json php7-mod-pdo-sqlite php7-mod-sqlite3
## Set the primary IP LAN address for luci only
# uci set uhttpd.main.listen_http=`uci get network.lan.ipaddr`:80
# uci set uhttpd.main.listen_https=`uci get network.lan.ipaddr`:443
# uci commit uhttpd
## Create a second listener for 'app' listening on second IP address
## served from /srv/www
# uci set uhttpd.app=uhttpd
# uci set uhttpd.app.listen_http=`uci get network.lan2.ipaddr`:80
# uci set uhttpd.app.home=/srv/www
## Enable PHP interpreter and index files
## Unset doc_root in php.ini so script can be found in /srv/www
# uci add_list uhttpd.app.interpreter=".php=/usr/bin/php-cgi"
# uci set uhttpd.app.index_page="index.html index.php"
# sed -i 's,doc_root.*,doc_root = "",g' /etc/php.ini
## Apply and restart uhttpd
# uci commit uhttpd
# /etc/init.d/uhttpd restart
This will start an instance of uhttpd serving /srv/www on the second IP address on port 80. From a security point of view however, this is far from ideal since uhttpd is spawned as root and your PHP script will also execute with root privileges.
To make this second instance of uhttpd run as a non-root user, we will need to make a few changes to /etc/init.d/uhttpd so that procd is told what user to run uhttpd as. However, we will also need to change the listen port from 80 to something above 1024 because uhttpd is no longer running as a privileged user. We can still make it this instance appear on port 80 by configuring the firewall to redirect port 80 to our new listen port number.
# Set listen port to 8000 and run as a non-root user
# uci set uhttpd.app.listen_http=`uci get network.lan2.ipaddr`:8000
# uci set uhttpd.app.user=httpd
## Ensure that a user 'httpd' is created.
# useradd ...
## Configure the firewall
# uci set firewall.@redirect[0]=redirect
# uci set firewall.@redirect[0].proto='tcp'
# uci set firewall.@redirect[0].dest_ip='192.168.35.10'
# uci set firewall.@redirect[0].src='lan'
# uci set firewall.@redirect[0].name='8000to80'
# uci set firewall.@redirect[0].src_dip='192.168.35.10'
# uci set firewall.@redirect[0].dest='lan'
# uci set firewall.@redirect[0].target='DNAT'
# uci set firewall.@redirect[0].dest_port='8000'
# uci set firewall.@redirect[0].reflection='0'
# uci set firewall.@redirect[0].src_dport='80'
The /etc/init.d/uhttp
d script must have the following lines added in start_instance()
:
config_get user "$cfg" user
procd_set_param user "$user"
Setup Adblock
You can make the DNS server block advertisement servers using blacklists that are available online. This is similar to how Pi-hole blocks ads with a modified version of dnsmasq.
To set up adblock on OpenWRT, install the following packages:
- adblock
- luci-app-adblock
Update block lists in the luci adblock page.
Mouting a USB drive
To mount storage on OpenWRT, you will need to install the block-mount package and then define the fstab configs in uci
.
See:
- https://openwrt.org/docs/guide-user/storage/fstab
- https://openwrt.org/docs/guide-user/storage/usb-drives
To get started, install the necessary packages:
# opkg update
# opkg install block-mount
## USB storage also needs:
# opkg install kmod-usb-storage
## Filesystem specific packages. Install as required:
# opkg install e2fsprogs kmod-fs-ext4
# opkg install kmod-fs-exfat
# opkg install ntfs-3g
# opkg install f2fs-tools kmod-fs-f2fs
You should now be able to see the block devices using block detect
:
root@linksys:/# block detect
config 'global'
option anon_swap '0'
option anon_mount '0'
option auto_swap '1'
option auto_mount '1'
option delay_root '5'
option check_fs '0'
config 'mount'
option target '/mnt/sda'
option uuid 'dd464c3f-bdcc-4ecf-b452-52416de97015'
option enabled '0'
Then, configure the mount with uci
by defining the following key/values:
## For each line, run 'uci set ....'
fstab.@global[0]=global
fstab.@global[0].anon_swap='0'
fstab.@global[0].anon_mount='0'
fstab.@global[0].auto_swap='1'
fstab.@global[0].auto_mount='1'
fstab.@global[0].delay_root='5'
fstab.@global[0].check_fs='1'
fstab.@mount[0]=mount
fstab.@mount[0].target='/mnt/sda'
fstab.@mount[0].uuid='dd464c3f-bdcc-4ecf-b452-52416de97015'
fstab.@mount[0].enabled='1'
Verify with uci show fstab
.
Mount by restarting the fstab service: service fstab boot
Enabling tftp
Just enable tftp
on dnsmasq
like so:
dhcp.@dnsmasq[0].enable_tftp='1'
dhcp.@dnsmasq[0].tftp_root='/mnt/sda/tftpboot'
Backup configuration
Run uci export
to dump all configs. Useful for generating a periodic config backup.
$ ssh root@openwrt "uci export" > config
Logging DNS Queries
For troubleshooting, you may wish to enable DNS logging in dnsmasq. Do so by editing two files:
/etc/dnsmasq.conf
:
log-queries
log-facility=/tmp/dnsmasq.log
/etc/config/dhcp
:
config dnsmasq
...
option logdhcp '1'
option logqueries '1'
option logfacility '/tmp/dnsmasq.log'
When done, comment out log-queries
and restart dnsmasq with /etc/init.d/dnsmasq restart
.
Recursive DNS
I did not get this working.
OpenWRT by default uses dnsmasq which will forward non-local DNS lookups to another server (typically your actual router or ISP retrieved from WAN DHCP). You could configure dnsmasq to use a local resolver such as Unbound.
See: https://kevinlocke.name/bits/2017/03/09/unbound-with-dnsmasq-on-openwrt/
Managing wireless clients
iw dev wlanN station dump
will dump all associated clients including all client details such as signal strength.
# iw dev wlan0 station dump
To disassociate a client by their MAC address:
# ubus call hostapd.wlanN del_client "{'addr':'$MAC', 'reason':5, 'deauth':false, 'ban_time':0}"
Disable IPv6
See: https://superuser.com/questions/1104484/disable-ipv6-with-openwrt
# uci set 'network.lan.ipv6=0'
# uci set 'network.wan.ipv6=0'
# uci set 'dhcp.lan.dhcpv6=disabled'
# uci -q delete dhcp.lan.dhcpv6
# uci -q delete dhcp.lan.ra
# uci set network.lan.delegate="0"
# uci -q delete network.globals.ula_prefix
# uci commit dhcp
# uci commit network
# /etc/init.d/odhcpd disable
# /etc/init.d/odhcpd stop
# /etc/init.d/network restart
Setup p910nd
Install p910nd: opkg install p910nd luci-app-p910nd kmod-usb-printer
Refresh the luci web interface and navigate to Services -> "p910nd - Print Server". Enable the service for /dev/usb/lp0
on port 9100.
Setup NTP server
Install the ntpd
package and then:
- Edit
/etc/config/system
. Find the 'ntp' section and setenable_server
to1
. Save the file and quit. - Restart the NTP service using the command
/etc/init.d/sysntpd restart
Troubleshooting
your adblock config seems to be too old, please update your config with the '--force-maintainer' opkg option
Recreate the configs from the package by reinstalling the package:
# opkg --force-maintainer --force-reinstall install adblock
TP-Link USB WiFi Support
The TP-Link dual antenna USB adapter that I have has a RTL8192 chip. Install these packages:
- rtl8192cu-firmware
- kmod-rtl8192cu
- kmod-rtl8192
- cu-common
wget: Invalid SSL certificate
opkg fails and wget is unable to download from https sites.
root@OpenWrt:~# opkg update
Downloading https://downloads.openwrt.org/releases/22.03.5/targets/ipq40xx/generic/packages/Packages.gz
*** Failed to download the package list from https://downloads.openwrt.org/releases/22.03.5/targets/ipq40xx/generic/packages/Packages.gz
root@OpenWrt:~# wget https://downloads.openwrt.org/releases/22.03.5/packages/arm_cortex-a7_neon-vfpv4/telephony/Packages.gz
Downloading 'https://downloads.openwrt.org/releases/22.03.5/packages/arm_cortex-a7_neon-vfpv4/telephony/Packages.gz'
Connecting to 168.119.138.211:443
Connection error: Invalid SSL certificate
Make sure your system time is synced.
ntpd -p pool.ntp.org
Firewall rules aren't applying
If you've made changes to the firewall such as to port forwardings, you may need to clear the nf_conntrack table for changes to apply properly:
echo f >/proc/net/nf_conntrack
Symptoms of this could be reject messages like this from tcpdump: ICMP X.X.X.X udp port 5555 unreachable, length 68