Linksys AC Series Router Configuration Tips for OpenWRT
Most of this article is focused on the OpenWRT Firmware / OS (Operating System) and the WRT1900ACS and WRT3200ACM routers. The WRT32X is essentially the same as the WRT3200ACM and is not mentioned specifically in this article. The WRT1900AC series is older and because the price difference between it and the WRT1900ACS is negligible, along with better hardware specification for the WRT1900ACS, it is recommended to purchase the ACS, thus the AC model is not fully covered here. The information below does work for the most part on the WRT1900AC and WRT32X.
These devices are also known as the WRT1900 and WRT3200.
See WRT1900AC, WRT1900ACS, and WRT3200ACM Routers, SoS (CPU), and Hardware for information about hardware specifics.
QuickD
- Upgrade Firmware
- Partition and Configure OpenWRT to use the USB Flash Drive (as Overlay, alternate boot, storage, swap, etc.)
Hardware
WRT1900AC
There are two hardware versions of the WRT1900AC (v1 and v2, v1 will not appear on the label, it is used here to differentiate between v1 and v2) so check the label on the bottom of the router and get the right firmware.
WRT1900ACS
There are two hardware versions of the WRT1900ACS (v1 and v2, v1 will not appear on the label, it is used here to differentiate between v1 and v2), but unlike the WRT1900AC, both versions of the router use the same firmware.
WRT3200ACM
As of the writing of this article on 7.2020, there is only one version of the WRT3200ACM
Storage (AKA Disk Drive) and File System
Another subject that OpenWRT is a bit opaque about is how information is stored on a router. It's not really their job, so let's go over it here.
A router is essentially a computer. It has all of the components of a computer, CPU, RAM, Network Adapter, Storage, etc. Unlike a computer, in a classic sense a router does not have a Disk Drive (unless one is attached via a USB or eSATA port), but it does have a way to store information which is Flash Memory. IE Flash Memory equals a Disk Drive (mechanical). In a more modern sense, it does have a disk drive in that modern disk drives in computers are SSD (Solid State Drives), which use a type of Flash Memory.
How OpenWRT handles that "Disk Drive" is much different than computers. Their explanation is here: https://openwrt.org/docs/techref/filesystems#squashfs
The part that OpenWRT doesn't explain very well is their "Overlay". Their Overlay is an abstraction layer that exposes a single interface to a user which is very similar to how a computer would present storage space to a user. On the other side is the Flash Memory which is broken down into two sections, firmware (equivalent to an Operating System) and storage space (equivalent to storage space on a disk drive or SSD for a computer). The firmware section is controlled by SquashFS and the storage space is controlled by JFFS/JFFS2
UBI = Unsorted Block Image, as in UBIFS (Unsorted Block Image File System)
Ethernet Switch
The Ethernet Switch typically transfers data at a sustained 90 MB/S for a Gigabyte Network Adapter.
Firmware
REMEMBER: The AC Series of routers has dual boot partitions, so if you're installing firmware it will flash it to the non-active flash partition. The same occurs if upgrading existing OpenWRT firmware. So if one happens to be running OpenWRT on one partition and DD-WRT or the stock Linksys firmware on the other partition, if installing from the OpenWRT / LUCI GUI, it will overwrite the other partition.
Dual Booting
This allows for rebooting to the alternate partition;
- opkg update
- Advanced Boot: opkg install luci-app-advanced-reboot
Switching Boot Partitions
Commands for OpenWRT
- To determine which boot partition is active: /usr/sbin/fw_printenv -n boot_part
- To change which boot partition is active: /usr/sbin/fw_setenv boot_part 1 OR /usr/sbin/fw_setenv boot_part 2
Commands for DD-WRT
- To determine which boot partition is active:ubootenv get boot_part
- To change which boot partition is active: ubootenv set boot_part 1
Power Switch
Per this site: https://community.linksys.com/t5/Wireless-Routers/WRT1900AC-May-have-bricked-it/td-p/811096
- Reset the router by holding the reset button in until the PWR light starts to flash, appx. 15 seconds.
- Once the power light stops flashing, you can power off the router with the power switch.
- Turn the power back on and the PWR light will light. As soon as any other light turns on, power off the router with the power switch.
- Turn the power back on and the PWR light will light. As soon as any other light turns on, power off the router with the power switch.
- Turn the power back on and the PWR light will light. As soon as any other light turns on, power off the router with the power switch.
- Turn the power back on and the PWR light will light. This time just let the router power all the way up. It should now be on the alternate
Per this site: https://forum.archive.openwrt.org/viewtopic.php?id=70202
- Start with the power switch off, then switch on. Watch the power LED:
- Power LED: on (a few seconds)
- Power LED: off (a second or two)
- Power LED: on (immediately when the power light turns on, flip the power switch off)
- That is 1 cycle of the 3 required to revert to the other partition. Repeat the above procedure two more times, making sure to flip the switch off as soon as the power LED comes on the second time.
- The fourth time you turn the power switch on you can let the device boot and it should boot into the other partition.
Remember: When attempting to utilize this within the LUCI GUI (if already logged in and connected), refresh the browser windows (CTRL Key plus Refresh Button in Firefox).
So how does one upgrade OpenWRT firmware on the current / active boot partition when the process upgrades the other inactive partition? What about changing the boot partition to the inactive one and then upgrade the firmware (See the Switching Boot Partitions section of this article for the commands to view or change the boot partition)? After several attempts, this trick didn't work. Documentation exists that says this trick works with DD-WRT (https://forum.dd-wrt.com/phpBB2/viewtopic.php?t=311117). It seems the flashing of the NVRAM is left up to the Marvell SoS / CPU and there is no way around it via OpenWRT. Alternative?
The solution is to upgrade from the other partition. IE, if Partition 1 needs to be upgraded, boot to Partition 2 and perform an upgrade, which will then upgrade Partition 1. This will obviously work if OpenWRT is installed on both partitions. But how can one install DD-WRT on the other partition from OpenWRT?
Solution: Use the command line. IE, it won't work from the OpenWRT LUCI GUI.
- Download the DD-WRT Factory Firmware (factory-to-ddwrt.bin) to the /tmp Directory
- For WGET to work, this may be needed: opkg install libustream-mbedtls
- Type the following command: sysupgrade -n -v -F /tmp/factory-to-ddwrt.bin (-n = do NOT keep current settings, -v = verbose, -F = Force)
The firmware will be installed on the other partition.
Only Upgrade versions of OpenWRT can be flashed via the GUI. Factory firmware will result in an error.
, but not sure if it is possible to "cross update" between DD-WRT and OpenWRT.
Use the OpenWRT Install / Factory image in this instance.
Upgrading the "Other Partition" from OpenWRT (be it another OpenWRT installation, Linksys firmware, DD-WRT, etc.)
Using LuCI to upgrade firmware, as of about 19.07.3, the upgrade process in the GUI has changed slightly and states: "Upload a sysupgrade-compatible image here to replace the running firmware." That might lead one to believe that the "running firmware", IE the currently booted and running version of OpenWRT will be upgraded. That is NOT the case. The LuCI GUI upgrade will upgrade the firmware on the other partition and then boot from the other partition. The OpenWRT message is probably related to the fact most routers do not have the special dual boot flash partitions that the AC Series has.
Using the command line to upgrade the firmware will upgrade the other partition, the subsequent boot will be to the current partition (IE, the one it was flashed from): sysupgrade -n -v -F /tmp/factory-to-ddwrt.bin (-n = do NOT keep current settings, -v = verbose, -F = Force)
OpenWRT System Logging
In /etc/config/system, add the following lines;
- option log_file '/var/log/messages'
- option log_remote '0'
For additional information see: https://openwrt.org/docs/guide-user/base-system/log.essentials and https://openwrt.org/docs/guide-user/base-system/system_configuration
Storage: Internal NAND Flash Memory, USB Flash Drives, and eSATA Drives
Believe it or not, the stock installation of OpenWRT does not come with the capability to access USB or eSATA devices. Considering how prevalent a USB port is on routers these days, that's a bit baffling. Plus it's really frustrating for so many web sites that refer to the LuCI, System, Mount Point menu that doesn't exist unless the previously mentioned items are installed. Big woof on this one.
Recommended Hardware Devices
The best recommendation for a USB Flash Drive is the SanDisk Ultra Fit USB 3.1 Flash Drive Series. And the recommendation is NOT because it is the fastest. They brag speeds up to 130 MB/S. Maybe downhill in a tornado, but under normal systems, that speed is a joke for this piece of hardware. So why recommend it? Well as it turns out, the fastest drive, USB, eSATA, or otherwise that has been tested on the AC Series is about 70 MB/S (this has been confirmed for eSATA) and around 45 MB/S for USB 3.0 (using a Patriot SuperSonic Rage Elite USB 3.1 Flash Drive that has been verified multiple times at over 200 MB/S sustained). Based on that and the below reviews it seems the Ethernet Switch may be topping out at about 70 MB/S, which is quite respectable.
Some reviews have the USB 3.0 speeds and eSATA speeds about the same at around 70 MB/S: https://www.eteknix.com/linksys-wrt3200acm-router-review/10/
Others have the USB 3.0 speeds measured considerably slower at about 20 MB/S: https://www.kitguru.net/peripherals/james-morris/linksys-wrt3200acm-ac3200-wireless-router-review/4/
Anyway, the above mentioned SanDisk device tops out at about 70 MB/S on every system that the above mentioned Patriot device tops out at over 200 MB/S. Notice that 70 MB/S speed mentioned twice? Once for the SanDisk device and once for the AC Series. The next item to consider is price. The SanDisk is not the cheapest, but it is fairly low. When price and performance are both considered, it turns out the SanDisk device beats everyone. And since the AC series router and SanDisk USB Flash Drive both top out at around 70 MB/S, that makes it the perfect match.
If one is considering using the USB Flash Drive for other purposes, go with the Patriot USB Flash Drive. If using the USB flash drive as a dedicated device for an AC series routers then go with the SanDisk USB flash drive. Plus it's also much smaller and has a lower profile than the patriot device. Both drives claim speeds about double what they can deliver. The final joke is that the Patriot device is USB 3.0 and the SanDisk is a USB 3.1 device.
Software Needed for USB Flash Drives to Connect, Partition, Format, etc., with Other Configuration Tools and the LuCI GUI Interface
- opkg update
- opkg install block-mount e2fsprogs kmod-fs-ext4 kmod-usb-storage kmod-usb2 kmod-usb3 ntfs-3g usbutils gdisk cfdisk tune2fs kmod-fs-exfat dosfstools kmod-fs-vfat f2fs-tools kmod-fs-f2fs lsblk ntfs-3g-utils fdisk sfdisk wipefs
Among other things the above command(s) install the following items and can perform the following tasks;
- e2fsprogs: mkfs.ext2, mkfs.ext3, mkfs.ext4, etc.
- kmod-fs-ext4: Includes ext2, ext3, and ext4
- tune2fs: Changes a volume label
- block-mount: Displays a volume label
- df: Displays general partition information
- cfdisk: A text GUI equivalent for gdisk or fdisk
- lsblk: Shows the type of formatting
- parted: A Linux utility that does not seem to be available with OpenWRT
Configuration with LuCI GUI Interface is located here: System, Mount Points
Partition Table, Partitioning, Formatting, and Performance Tuning a USB Flash Drive
A recommended method with the AC Series of routers is to create two EXT4 Partitions (one for each boot partition), an NTFS Partition (for compatibility with Windows), and a SWAP Partition. Also remember there is a difference between the MBR and GPT numbering of Partition types (IE, Linux Swap in MBR is 82 and 19 in GPT).
To switch from GPT to MBR without losing existing partitions, see this web site: https://sites.google.com/site/aleksanderbrain/ubuntu-server/disk-management/convert-from-gpt-to-mbr-partition-table
Utilities to Display Information about Drives / Disks
- df (Displays information about mounted file systems)
- block info (Displays additional information about mounted file systems)
- lsblk -l (Displays information about ALL available Drives / Disks)
Partition Table
For small USB 3.0 Flash Drives, use the MBR Partition Table. The following command will start things off with a clean slate. There are instances where a Flash Drive may have been previously configure to use a GPT Partition Table which can cause issues with GDISK and other partitioning Software;
- wipefs -a /dev/sdX
Partitioning
CFDISK is one of the easier utilities to use because of its "text GUI" style interface. I also aligns partitions on solid state devices correctly, as does most modern partitioning software. Don't forget to set the partition type too (7=NTFS, 83=Linux, 82=Linux Swap, etc.). The interface is fairly self explanatory, but in order to commit changes remember to select Write and confirm by typing "yes";
- cfdisk /dev/sdX (Example cfdisk /dev/sda)
If the Partition Table does not exist, CFDISK will prompt for one to be selected. Choose DOS, which equates to MBR in "Linux Speak".
To check proper partition alignment (if it starts on a boundary divisible by 1024, then it is properly aligned, newer partition software generally does this properly for flash based devices);
- sfdisk -d /dev/sdX
- fdisk -l -u /dev/sdX
Formatting
Formatting an EXT4 Partition (remember to unmount before formatting if a drive is being used);
- mkfs.ext4 -L WhatEverName -v /dev/sdaX (-L = Label, -v = Verbose)
Format an NTFS Partition;
- mkntfs -f -L NTFS -v /dev/sdaX
Change a Volume Label;
- tune2fs -L WhatEverName /dev/sdaX
Performance Tuning for ExtX
The below commands can be used to enhance performance for the ExtX File Systems, but are negligable according to this site: https://cromwell-intl.com/open-source/performance-tuning/file-systems.html
- tune2fs -o journal_data_writeback /dev/sdaX
- tune2fs -O ^has_journal /dev/sdaX
Performance Tuning for NTFS
For NTFS volumes enabling "big_writes" makes a HUGE difference in performance. Some Linux systems claim this setting is deprecated, but for OpenWRT it works and makes a big performance difference. Real world file copy performance was measured at sustained 60 MB/S for a USB 3.0 Flash Drive and almost 90 MB/S for an eSATA HDD.
- In the LUCI GUI, Mount Points, Mount Points, Edit, Advanced Settings, Mount Options add: big_writes
- If compression is also desired, add this in the above noted location: big_writes,compression
Clone a Partition
It is recommended to make sure the destination partition is the same size or larger of course. Be prepared to wait a while, even on a USB 3.0 port.
- dd if=/dev/sda1 of=/dev/sda2 (if = source, of = destination)
Note: After cloning, to save confusion and sanity, remove the source drive. It also may be necessary to reboot the router or dismount and mount the drive if it was already mounted to see the "cloned" directories and files. All of this is necessary because everything is cloned and OpenWRT may display two /dev/sdX devices that are exactly the same (IE sdb1 and sdb1 as two distinct, but duplicate device partitions).
Use a USB Flash Drive instead of internal Flash Memory using Overlay
In the LuCI GUI interface;
- System, Mount Points, Mount Points, Add, General Settings (select the USB Flash Drive Partition)
- Add by one of several methods, UUID displays device too (IE, /dev/sda1)
- Use as external overlay (/overlay)
- ...Advanced Settings
- File System: EXT4, NTFS, etc.
- Mount Options
- EXT4: barrier=0,data=writeback
- NTFS: big_writes,compression
REMEMBER: The system will then reboot and if viewed in the LuCI GUI interface the "Enable Mount" will not be checked, but it will be mounted (it can be checked for "comfort" purposes without any ill effects).
Access and Use an External USB Flash Drive
Install the drivers and LuCI interface as noted above, then in the LuCI GUI Interface;
- System, Mount Points, Mount Points, Add, General Settings (select the USB Flash Drive Partition)
- Add by one of several methods, UUID displays device too (IE, /dev/sda1)
- Mount Point (type it manually): /mnt/WhatEverName (Match it to the device name, IE /dev/sda1 will be mounted as /mnt/sda1)
- ...Advanced Settings
- File System: EXT4, NTFS, etc.
- Mount Options
- EXT4: barrier=0,data=writeback
- NTFS: big_writes,compression
REMEMBER;
- If using a the USB 3.0 by itself (IE, nothing plugged into the eSATA / USB 2.0 port), the flash drive will be referred to as device SDA (with partitions SDA1, SDA2, etc.)
- If the eSATA port / USB 2.0 port is used by itself, the same naming convention applies.
- If both ports are used, but only the USB 3.0 device is mounted it will still be referred to as SDA (etc.)
- BUT, and this is a tricky thing
- If both ports are used, but only the USB 3.0 device is mounted, as soon as an eSATA / USB 2.0 port device is mounted it will be seen as SDB (etc.)
- BUT, big BUT here, when the system is rebooted, the eSATA / USB 2.0 device can sometimes be mounted first, so SDA and SDB are reversed. WOOF!
Swap Partition or Swap File
A Swap Partition or Swap File can be used.
Most references to Swap Partitions or Files indicate performance is quite poor. There is considerable ancient / old /archived information about Swap Files and OpenWRT. But this may have been written during the USB 2.0 period and doesn't reflect the performance of USB3 or eSATA devices in 2020. That said, "Virtual RAM" is slow. Is it slower than RAM? Yes. Does one sometimes need more RAM than is physically available? Yes, sometimes. So for all the people that discourage the use of a Swap File, fine. But sometimes one needs it. Unlike other routers, the AC Series comes with an astounding amount of RAM (512 MB), so it may not be an issue. But here's how to do it...
Make sure there is an available empty partition for usage of a Swap File, then;
- mkswap -L SWAP /dev/sdaX
- Use the LuCI GUI interface
OR
- mkswap -L SWAP /dev/sdaX
- swapon /dev/sdaX
It is recommended to use the GUI to be able to monitor it later. Check functionality with: HTOP
Inactive Internal Flash Memory Partitions and Linksys Reserved NVRAM / Flash Memory Partition Mounting and Information
Internal Flash Memory Partitions (mtd6 (rootfs1 UBI), mtd7 (rootfs2 UBI), and mtd9 (syscfg UBI), etc.) can also be mounted and accessed. For more information on the WRT3200ACM Flash Memory Layout, click here (other AC models are similar, but different sizes). Other mtdX Flash Memory sections can also probably be accessed, but are not addressed here.
One use for this would be to manually edit settings from the active partition to the inactive partition to fix some type of issue.
Viewing Available Internal Partitions and Information
Various commands to "see" the available partitions;
- A directory listing of UBI devices: ls -la /dev/ ub*
- A list of the various MTD (Memory Technology Device) Partitions: cat /proc/mtd
How the various memory sections are categorized (Note, the below UBI numbers assume one is booting from the first bootable partition (mtd6) and the mtd9 / syscfg partition has been automatically mounted by OpenWRT;
- mtd6 (the first bootable flash memory partition)
- Referred to as ubi with cat /proc/mtd
- Referred to as: rootfs1 in OpenWRT Documentation
- Referred to mtdblock6 in the LuCI GUI UUID drop down menu
- Referred to as ubi0 in /sys/devices/virtual/ubi, which in turn includes ubi0_0 (kernel* image) and ubi0_1 (usable flash storage)
- mtd8 (the second bootable flash memory partition)
- Referred to as rootfs2 with cat /proc/mtd
- Referred to as: rootfs2 in OpenWRT Documentation
- Referred to mtdblock8 in the LuCI GUI UUID drop down menu
- Referred to as ubi2 in /sys/devices/virtual/ubi, which in turn includes ubi2_0 (kernel* image) and ubi2_1 (usable flash storage)
- mtd9 (a flash memory partition used as a temporary storage location when new images are flashed)
- Referred to as syscfg with cat /proc/mtd and the OpenWRT Documentation
- Referred to mtdblock9 in the LuCI GUI UUID drop down menu
- Referred to as ubi2 in /sys/devices/virtual/ubi, which in turn includes ubi1_0 and ubi1_1
Remember: The flash memory layout of the AC Series was created by Linksys, not Marvell. And as noted by some, it seems a bit wasteful in how it was utilized.
* Funny Trivia: I originally spelled KERNEL as KERNAL. Can you guess which brand of computer I grew up using?
Mounting Internal Partitions at Boot
The LuCI GUI cannot attach internal Flash Memory Partitions via the Mount Points MTDBLOCKx method, nor can the block mount /dev/ubiblockX command. Editing the /etc/config/fstab file is the only method that works (Note, not the /etc/fstab file) if the system is rebooted.
The below example of /etc/config/fstab file (which can be created manually or within the LuCI GUI) to mount the mt8 / rootfs2 partition does not work as OpenWRT will not mount it (The block mount command mounts the various items in the /etc/config/fstab file);
The below /etc/config/fstab Entry will NOT work;
config mount
option device '/dev/ubi2_0'
option target '/tmp/MTD8'
option fstype 'squashfs'
option enabled '1'
Instead, edit the /etc/rc.local file to to mount an the mtb8 / rootfs2 internal flash memory partition;
The following will mount the second flash memory partition (mtb8 / rootfs2);
ubiattach -m 8
mkdir /tmp/MTD8
mount -t ubifs /dev/ubi2_1 /tmp/MTD8
The following will mount the mtb9 / syscfg partition (if it isn't already mounted)
ubiattach -m 9
mkdir /tmp/MTD9
mount -t ubifs /dev/ubi1_0 /tmp/MTD9
Some Additional Commands to Attach Internal Partitions
- To attach a UBI Partition: ubiattach -m 6 OR ubiattach -m 8 OR ubiattach -m 9 (an error will occur if a partition is already mounted)
- To mount the second bootable partition;
- mkdir /tmp/MTD8 (this follows the OpenWRT convention in terms of the location to mount it, instead of using the /mnt directory)
- mount -t ubifs /dev/ubi2_1 /tmp/ubi2_1 (or MTDBLOCK8, etc)
- An alternative method from here to mount the second bootable partition has a slightly different method which didn't seem to work quite right with the final command;
- ubiattach -m 8
- ubiblock --create /dev/ubi2_0
- mount -t squashfs -o ro /dev/ubiblock2_0 mnt
To mount the syscfg partition (mtd9), if it isn't already mounted under /tmp/syscfg;
- mkdir /tmp/MTD9 (this follows the OpenWRT convention in terms of the location to mount it, instead of using the /mnt directory)
- mount -t ubifs /dev/ubi1_0 /tmp/MTD9
NOTE: The mounting of the mtb9 (syscfg UBI) for various models of the AC Series seems to be erratic, in that some automatically mount it and others don't. Even in ones where it is mounted, it isn't listed in the /etc/config/fstab file.
NOTE: The directory structure of the mtd8 / rootfs2 partition will not be the same as if it were the active partition. Look in the directory named "upper" for the /etc, /sbin, etc. directories.
WRT3200ACM UBI Layout
On a WRT3200ACM with both the mtd6 (rootfs1), mtd8 (rootfs2), and mtd9 (syscfg) partitions attached, ls -la /dev/ub* or cat /proc/mtd will show the following devices;
UBI Devices Attached
/dev/ubi0_0
/dev/ubi0_1
/dev/ubi1
/dev/ubi1_0
/dev/ubi2
/dev/ubi2_0
/dev/ubi2_1
/dev/ubi_ctrl
/dev/ubiblock0_0
ubi0_0: The read only kernel / firmware image for mtd6 (under mtd5)
ubi0_1 (mtd6 / rootfs1): The squashfs / ubifs read / write partition
ubi1_0 (mtd9 / syscfg): The flash memory partition used as a temporary storage location for new firmware
ubi2_0: The read only kernel / firmware image for mtd8 (under mtd7)
ubi2_1 (mtd8 / rootfs1): The squashfs / ubifs read / write partition
See the OpenWRT documentation for the memory layout of the WRT3200ACM here.
Additional Information
/sys/devices/virtual/ubi/ubi0/mtd_num is a file that indicates the current / active partition, which is 6 (for mtd6) or 8 (for mtd8)
/sys/devices/virtual/ubi/ubi1/mtd_num is the file that indicates the mtd9 / syscfg partition, which is 9
Performance Thoughts
Performance Testing
In order to determine "end user speed", the below rates were measured using Windows Explorer between an M.2 SSD on a Windows 2016 Server and the below routers using Samba 4 (FD = Flash Drive and HDD = Hard Disk Drive). CPU, Flash Drive, HDD, Gigabit Switch connecting devices, etc. were all tested on other systems at faster speeds, so they are not the limiting factor. IE, the below tests reliably measure the bus speeds of the router(s);
Router Model -->
MB/S Read - Write Port Connected to |
WRT1900ACS | WRT3200ACM with Flash Drive | WRT3200ACM with eSATA in USB Enclosure |
---|---|---|---|
eSATA HDD NTFS | 60 - 85 | ||
USB 3 FD ext2 | 50 - 70 | - 14 | |
USB 3 FD ext3 | 40ish - 40ish | ||
USB 3 FD ext4 | 50 - 50 | 33 - 20 | 90 - 50 |
USB 3 FD NTFS | 30 - 70 | 30 - 24 | 90 - 50 |
exFAT | Forget It | Didn't try | |
FSFS | same as ext2 | ||
FAT32 | 4 GB size limit |
It is worth noting the above Read - Write speeds are not reversed. Counter to what is normally experienced, Read speeds are regularly slower than Write.
Compatibility and Recommendations
For compatibility with Windows choose NTFS (and accept the speed hit on OpenWRT).
For OpenWRT Native Overlay use EXT4.
F2FS supposedly has issues, even though OpenWRT recommends it, so do NOT use it.
vFAT or any FAT is a joke and either doesn't work, performs like a dog, or has space limitations.
Cloning a USB Flash Drive
Cloning an OpenWRT USB Flash Drive with Acronis
Don't do it. Acronis will successfully clone a USB flash drive, but there is no guarantee it will put the partitions back in the same order
Cloning an OpenWRT USB Flash Drive with EaseUS (or another equivalent utility)
It works, but... It is dog slow, even for partitions and file systems that contained no data, files, or directories. The process took almost half an hour with two identical USB 3.0 Flash Drives. No detailed logs were available, but the odds are it went sector by sector. So that means a completely full USB Flash Drive would take just as long to copy as one that was partitioned and formatted, but contained no data.
Alternative Cloning Methods
OpenWRT doesn't have much in the way of backup or cloning software. There is no cloning software. The one piece of backup software, RESTIC, is a very functional piece of software, but it doesn't facilitate backing up from USB Flash Drive to another. The lack of OpenWRT software for cloning and backing up is probably because most hardware devices do not have multiple USB Ports. Additionally, most routers are probably not configured to boot from a USB Flash Drive using the Overlay functionality in OpenWRT, IE, they just boot from their internal non-volatile Flash Memory.
Clonezilla is a viable alternative, but requires booting a computer from a "Live CD" as it is not a Windows program.
Networking
The OpenWRT article on Basic Networking, Aliases, etc. includes a lot of information. But they don't explain in a simple manner, what is occuring in some instances. Below are a few examples;
- BR Term: The "br" part of br-lan name (seen in the LuCI GUI or when using the ifconfig command) is automatically assigned to a network interface if it's type is set to "bridge". OpenWRT refers to this as a pseudo interface. IE, if an interface defined in the /etc/config/network file is option type 'bridge' then "br" with a hyphen ( br- ) is prepended to the name of the interface ( interface 'lan' ) in the /etc/config/network file
- Firewall Tip: Make sure each new "Interface" is include in the firewall setting (LuCI GUI: Interface, Firewall Settings, Assign Firewall Zone OR File: /etc/config/firewall, config zone (lan), option network, add the name of the interface)
- Syntax Item: OpenWRT examples tend to vacillate between one of two different syntax in their examples, for instance;
- option 'type' 'bridge' OR option type 'bridge' (the latter seems to reflect how the actual configuration files are done)
- Alias or Second IP Address Tip: The option ifname item in the Alias or Secondary IP Address Network Configuration should be set to the above mentioned br-lan ( or if the default name has been changed from lan to lan1, then br-lan1 ). Do NOT set it to the option ifname 'eth0.1' (default name) or lan if the type is set to bridge as some examples give and don't emphasize the "in this example the interface is not configured as a bridge" note. The br-lan interface name doesn't exist in the /etc/config/network file, but it is if the IFCONFIG command is typed it does show the br-lan interface, and in LuCI it shows both (/etc/config/network name in large letters at the top and the IFCONFIG command name smaller on the bottom). How is one supposed to know? Well, as mentioned in the BR Term bullet point above, this information was discovered after a bit of experimenting. Thus the initial comment about the OpenWRT documentation leaving out a key detail to actually making things function.
Notes;
- Items in the above bullet points noted in italic represent configuration statements in a file.
- Items below and above are referred to as Adapter(s) (NIC, Network Interface Card, etc.) and Interface(s) interchangabely, even though using the term Adapter is usually in reference to a piece of hardware and Interface usually refers to the Adapter as it is seen from an OS.
Default Network IDs, Labels, Configuration
Port # (as labeled on back of router) | Port # (from OpenWRT perspective) | /etc/config/network Name | ifconfig | VLAN | Assigned an IP Address |
---|---|---|---|---|---|
LAN 1 | 3 | LAN | br-lan (eth0.1 set to bridge mode) | 1 | Yes, and is assigned to br-lan |
LAN 2 | 2 | LAN | br-lan (eth0.1 set to bridge mode) | 1 | Yes, and is assigned to br-lan |
LAN 3 | 1 | LAN | br-lan (eth0.1 set to bridge mode) | 1 | Yes, and is assigned to br-lan |
LAN 4 | 0 | LAN | br-lan (eth0.1 set to bridge mode) | 1 | Yes, and is assigned to br-lan |
WAN | 4 | WAN | eth1.2 | 2 | Yes, depends on setting |
N/A | 5 / 5t (CPU for LAN) | N/A | eth0 | 1 | No |
N/A | 6 / 6t (CPU for WAN) | N/A | eth1 | 2 | No |
Notes;
- The br-lan (a pseudo interface) is what OpenWRT adds to the LAN / eth0.1 interface if it is configured to option type 'bridge' in /etc/config/network
- If the LAN / eth0.1 interface is not set to option type 'bridge', then the IP Address is assigned to eth0.1
- The setting of eth0.1 to bridge or not bridge (OpenWRT documentation indicates the only option type is bridge) does not affect connectivity to the switch. It does affect connectivity to the wireless ethernet adapter(s) (see the next note)
- Wireless Ethernet Adapters / Interfaces in OpenWRT are not assigned an IP Address. Instead they are "bridged" to eth0 and the switch via a "pseudo" bridge.
- The eth0.1 and eth1.2 are named for the sake of the VLAN they belong to. In OpenWRT, the .1, .2, or whatever .Number following a standard ethernet interface name like eth0, eth1, eth2, etc. factor into how VLANs operate. A VLAN labeled as 1 will send traffic to ethX.1, a label of 8 would send it to ethX.8, etc.
- The eth0.1 Interface when configured as a bridge becomes br-lan
- lo is the loopback interface, 127.0.0.1
Conceptual View of OpenWRT and the AC Series of Routers "Network System"
The AC Series of routers has 2 "Wired" Ethernet Adapters (built into the SoC (System on a Chip)), 3 Wireless Ethernet Adapters (discrete components from the SoS), and 1 Switch (connected to the 5 Ethernet Ports on the rear of the unit). Both the eth0 and eth1 Ethernet Adapters are connected to the switch at a TCP/IP level. The VLAN capability of the switch is used to separate / isolate the WAN port from the LAN ports. Wireless Adapters are connected to LAN / br-lan and eth0 via a "pseudo" bridge and are not assigned a discrete IP Address, instead using the IP Address of the LAN / br-lan interface.
Multiple IP Addresses assigned to a Single (AKA Alias or Aliases in OpenWRT)
In the /etc/config/network File example below two IP Addresses are assigned to the LAN Bridge / eth0.1 Interface, where A.B.C.D and W.X.Y.Z are place holders for an IP Address
# When using IFCONFIG, this interface will be displayed as br-lan1 and eth0.1 will not
# have an IP Address
config interface 'lan1'
option type 'bridge'
option ifname 'eth0.1'
option proto 'static'
option netmask '255.255.255.0'
option ip6assign '60'
option ipaddr 'A.B.C.D'
config interface 'lan2'
option proto 'static'
option ipaddr 'W.X.Y.Z'
option netmask '255.255.255.0'
# The ifname needs to be set to the br-lan1 name, not eth0.1
option ifname 'br-lan1'
...and don't forget;
- Edit, Firewall Settings, Assign firewall zone, ...LAN
- Save and Apply
- service network reload.
VLANs
For the AC Series, the ports as "seen" from OpenWRT*;
LAN Ports: Port 0, 1, 2, 3
WAN Port: Port 4
CPU Ethernet for LAN: Port 5 / 5t
CPU Ethernet for WAN: Port 6 / 6t
* NOTE: The above port numbers are how OpenWRT "sees" the ports. The physical labeling of the ports as numbered on the back of the router are reversed. IE, OpenWRT Port 3 is labeled as LAN 1 on the router label. This is possibly due to how Marvell numbers their switches and manufacturers like Linksys wishing to have the ports numbered left to right.
VLAN Related Commands
- To show the bridge name: brctl show (use the OpenWRT GUI to configure)
- To show the available switches: swconfig list (usually returns: switch0)
- To show the current configuration: swconfig dev switch0 show
- To show what can be configured: swconfig dev switch0 help (again, use the OpenWRT GUI to configure)
- To show what is currently configured on router: ls -l /sys/class/net
More information from OpenWRT is available here.
Configuration File
/etc/config/network
LuCI GUI
Network, Switch
Configuring Individual Physical Ports with Unique IP Addresses on Separate VLANs
- Configure an additional VLAN with LuCI GUI
- Edit the /etc/config/network File as follows (VLAN number 9 was randomly chosen, and could be any number, but they need to match in all instances of the below example, IE, wherever there is a 9, use 5 or 4 in all the same places if using a different number);
Do NOT use any special characters in the "config interface 'WhatEverName'" field like a dot ( . ), dash ( - ), etc.
config device
option type '8021q'
option ifname 'eth0'
option vid '9'
option name 'LAN9'
config interface 'LAN9'
option ifname 'eth0.9'
option proto 'static'
option ipaddr 'A.B.C.D'
option netmask '255.255.255.0'
- In the LuCI GUI, Network Interfaces, WhatEverNewName, Edit, Firewall Settings Tab, add it to the LAN Zone
- Save and Apply in the LuCI GUI
- Type: service network restart (as the Save and Apply apparently doesn't do that step) OR Restart Button in the LuCI GUI
Forwarding between VLANs
https://forum.openwrt.org/t/solved-routing-between-2-vlans/8847
Use the Network, Firewall LuCI GUI
Multiple WAN Ports with MWAN3
Installing
Install MWAN3: opkg install mwan3 luci-app-mwan3 (The luci-app-mwan3 is under Network, Load Balancing)
Optional: opkg install kmod-macvlan (A utility that allows a single port to function as two ports with two IP Addresses and different MAC Addresses. IE, the WAN port could be configured with two IP Addresses)
Configuring
First, make sure there are two functional WAN Ports with distinct IP Addresses. This can be configured with the below /etc/config/network example.
In LuCI, Load Balancing, Interfaces Tab, WhatEverNameOfInterface, MWAN Interface Configuration sub-tab, set the following (as a minium);
- Enabled: Checked
- Initial State: Online
- Tracking Host Name IP Address: -.-.-.- (This is an IP Address to Ping to test whether the interface is up / working)
Members sub-tab is not really important in the below example.
Policy sub-tab;
- The granular details of this sub-tab have to be configured in the /etc/config/mwan3 file as LuCI doesn't allow detailed configuration, just selecting existing policies
- Set up two that represent each WAN Port
Rules sub-tab can be used to explicitly configure a client machine behind the router use a specific interface;
- Source Address: Whatever device should use this interface
- Destination address: 0.0.0.0/0 (if not configured it won't work properly)
- Policy assigned: Whatever Policy that says use "interface X"
- Sticky "suggests" that subsequent connections should use the same interface (in the below example it doesn't affect anything, but in some circumstances could affect secure connections to bank web sites as they are very picky about stuff, as it should be.)
Example
In the below example (/etc/config/mwan3) there are two physical WAN Ports (the WAN Port and Port 4 has been removed from the LAN VLAN and assigned to its own WAN VLAN and the WAN Firewall Zone in the /etc/config/network after the mwan3 example). It is a very simple example that has two WAN Ports. No load balancing or failover is configured. The example would be useful in a case where all client computers utilized one WAN for internet access and web servers could use the other WAN, so either WANs usage would not affect the other.;
config rule 'https'
option sticky '1'
option dest_port '443'
option proto 'tcp'
option use_policy 'balanced'
config rule 'Win8_Test'
option src_ip '192.168.2.50'
option proto 'all'
option dest_ip '0.0.0.0/0'
option use_policy 'WAN2_only'
option sticky '0'
config rule 'default_rule_v4'
option dest_ip '0.0.0.0/0'
option use_policy 'balanced'
option family 'ipv4'
config globals 'globals'
option local_source 'LAN1'
option mmx_mask '0x3F00'
option rtmon_interval '5'
config member 'WAN1_m1_w1'
option interface 'WAN1'
option metric '1'
option weight '1'
config member 'WAN2_m2_w2'
option interface 'WAN2'
option weight '2'
option metric '2'
config policy 'WAN1_only'
list use_member 'WAN1_m1_w1'
option last_resort 'unreachable'
config policy 'WAN2_only'
list use_member 'WAN2_m2_w2'
option last_resort 'unreachable'
config policy 'balanced'
list use_member 'WAN1_m1_w1'
list use_member 'WAN2_m2_w2'
option last_resort 'unreachable'
config policy 'WAN1_WAN2'
list use_member 'WAN1_m1_w1'
list use_member 'WAN2_m2_w2'
option last_resort 'unreachable'
config policy 'WAN2_WAN1'
list use_member 'WAN1_m1_w1'
list use_member 'WAN2_m2_w2'
option last_resort 'unreachable'
config interface 'WAN1'
option initial_state 'online'
option family 'ipv4'
option track_method 'ping'
option reliability '1'
option count '1'
option size '56'
option max_ttl '60'
option check_quality '0'
option timeout '2'
option failure_interval '5'
option down '3'
option up '3'
list track_ip '96.77.203.198'
option recovery_interval '60'
option interval '60'
option enabled '1'
list flush_conntrack 'connected'
config interface 'WAN2'
option initial_state 'online'
option family 'ipv4'
option track_method 'ping'
option reliability '1'
option count '1'
option size '56'
option max_ttl '60'
option check_quality '0'
option timeout '2'
option failure_interval '5'
option recovery_interval '5'
option down '3'
option up '3'
list track_ip '76.212.87.54'
option interval '60'
option enabled '1'
In the below /etc/config/network example, all of the other LAN, etc. configuration is not included. The -.-.-.- indicates one's own IP Address, subnet mask, etc. information be used. The below example uses Port 4 (as labeled on the back of the router, but is Port 0 from OpenWRT's "perspective") for the second WAN / WAN2 port. VLAN numbers can be anything, as long as when they are changed, they match in a similar manner to what is below and do not interfere with existing LAN VLANs. The metric for WAN1 is set lower so it is always favored for clients behind the router as long as it is functional.
config device
option type '8021q'
option ifname 'eth1'
option vid '11'
option name 'WAN1'
config interface 'WAN1'
option ifname 'eth1.11'
option proto 'static'
option ipaddr '-.-.-.-'
option netmask '-.-.-.-'
option gateway '-.-.-.-'
list dns '-.-.-.-'
list dns '-.-.-.-'
option metric '10'
config device
option type '8021q'
option ifname 'eth1'
option vid '12'
option name 'WAN2'
config interface 'WAN2'
option ifname 'eth1.12'
option proto 'static'
option ipaddr '-.-.-.-'
option netmask '-.-.-.-'
option gateway '-.-.-.-'
list dns '-.-.-.-'
list dns '-.-.-.-'
option metric '20'
config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'
config switch_vlan
option device 'switch0'
option vlan '11'
option ports '4 6t'
option vid '11'
config switch_vlan
option device 'switch0'
option vlan '12'
option ports '0 6t'
option vid '12'
Additional Information
https://openwrt.org/docs/guide-user/network/wan/multiwan/mwan3
DNS - BIND - NAMED
Uninstall DNSMASQ or set the port to Port 0 to disable DNS
opkg install bind-server bind-tools (bind-tools includes: bind-rndc bind-check, plus dependencies)
Configure via text files in /etc/bind/... (see example file below)
Enable and start the service;
- service named enable (the OpenWRT documentation contains information that applies to older versions and states: enable /etc/init.d/named)
- service named start
Check to see if the service is running: pidof named
If using Slave Zones, make sure permissions are set correctly for the Directory;
- chown bind /etc/bind/slaves
- chgrp bind /etc/bind/slaves
This is the command line OpenWRT uses (CHROOT is not employed): /usr/sbin/named -u bind -f -c /etc/bind/named.conf (-u = User, -f = Run in the Foreground not as a Daemon, -c = Configuration File)
- To disable IPv6, add the following to the command line: -4
Logging: see section on OpenWRT System Logging
For additional information: https://openwrt.org/docs/guide-user/services/dns/bind (Note: The OpenWRT documentation makes references to /etc/named.conf, but the files are in /etc/bind/...)
For command line information: https://linux.die.net/man/8/named
For logging information: https://kb.isc.org/docs/aa-01526 and https://docstore.mik.ua/orelly/networking_2ndEd/dns/ch07_05.htm
Example Configuration;
options {
directory "/tmp";
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
// forwarders {
// 0.0.0.0;
// };
auth-nxdomain no; # conform to RFC1035
allow-recursion {
W.X.Y.Z/24;
};
allow-transfer {
A.B.C.D;
};
listen-on port 53 {
A.B.C.D;
};
querylog yes;
};
// Use with the following rndc.conf in named.conf, adjusting the allow list as needed:
//
// Generate with this command: rndc-confgen
//
key "rndc-key" {
algorithm hmac-sha256;
secret "zrb7APg1fyNhfwr/c1Fy8slvbd7BkIAzw9U8gUoJE90=";
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { "rndc-key"; };
};
// These Items are in the Default OpenWRT named.conf File
//
// be authoritative for the localhost forward and reverse zones, and for broadcast zones as per RFC 1912
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
//////////
zone "150.168.192.in-addr.arpa" {
type slave;
masters {
A.B.C.D;
};
file "/etc/bind/slaves/A.B.C.D.rev";
allow-query {
A.B.C.D;
};
};
zone "WhatEverZone" {
type slave;
masters {
A.B.C.D;
};
file "/etc/bind/slaves/WhatEverZone.hosts";
allow-query {
W.X.Y.Z/24;
};
};
zone "WhatEverZone" {
type slave;
masters port 53 {
A.B.C.D;
};
file "/etc/bind/slaves/WhatEverZone.hosts";
};
logging {
channel default_log {
file "/var/log/named/default" versions 3 size 20m;
print-time yes;
print-category yes;
print-severity yes;
severity info;
};
channel zone_transfers_log {
file "/tmp/log/named/zone_transfers" versions 3 size 20m;
print-time yes;
print-category yes;
print-severity yes;
severity dynamic;
};
category notify { zone_transfers_log; };
category xfer-in { zone_transfers_log; };
category xfer-out { zone_transfers_log; };
};
Software, Utilities, Drivers, & System Configuration, etc.
Package Installation with OPKG
opkg is the package management utility on OpenWRT.
Useful Utilities & Features
General Utilities
opkg update
A nice text editor: opkg install nano
An enhanced version of TOP (AKA Task Viewer): opkg install htop
The web server for LuCI is uHTTPd, to configure in the LuCI GUI: opkg install uci-app-uhttpd
WGET is installed by default but does not support HTTPS
- Solution: opkg install libustream-mbedtls20150806 (or whatever current package name, or alterntively: opkg install libustream-mbedtls*, NOTE: the SSL version will not work)
For proper time zone detection by PHP and other scripts be sure to install whatever local time zone module is appropriate in addition to the core (zoneinfo-core): zoneinfo-northamerica (for example)
Network Tools for Diagnostics
A tool to see what ports a router is listening on: opkg install lsof
- lsof -i -P -n | grep LISTEN
SCP
Copy files between Linux machines using SCP, which in turn uses the SSH protocol (IE, nothing has to be installed on the client)
To copy from one router to another: scp -r /local/directory UserName@RemoteIPAddress:/remote/
LAMP - Apache (Nginx, LighttpD, and uHTTPd) MariaDB (MySQL), and PHP plus PHPmyAdmin, FastCGI, Parsoid
OpenWRT has no less than four different web servers available for installation. Each of them have their own advantages and disadvantages, relative to what is availabe in OpenWRT, usage, etc. Because routers tend to be more limited in terms of resources, OpenWRT seems to favor Lighttpd as the preferred web server. It is a full featured web server in terms of the number of modules available. The modules it offers are also smaller in size than Apache and Nginx, which again makes sense for a device that has less storage available than a computer. uHTTPd is the most basic of the four and is also used for the LuCI GUI. Apache has the advantage of being the most mature and familiar in terms of configuration, but it has a disadvantage in that FastCGI, among other things, is not available.
Apache
In OpenWRT CGI, but FastCGI is not available, even though the PHP 7 package for FastCGI is available (opkg install php7-fastcgi) and PHP-FPM (opkg install php7-fpm) are available. Althought the PHP-FPM package only includes instructions to enable the PHP-FPM service. And since it relies on FastCGI, it is essentially pointless. Additionally in the /usr/bin directory, if php7-fastcgi is installed installed as php-cgi and the php-fcgi binary redirects to the php-cgi binary (IE, the php7-fcgi binary handles both FastCGI and CGI, type php-cgi -v). In reality the php7-cgi package has the binary for both CGI and FastCGI.
opkg update
opkg install apache apache-utils apache-mod-ssl (in many installations it is referred to as HTTPD)
There is no LuCI GUI interface, so use text configuration files and / or Webmin
- Initilization Script: /etc/init.d/apache2
- Configuration: /etc/apache2/apache2.conf
- Default Server Root: /usr
- Default Document Root: /usr/share/apache2/htdocs
- Executables / Binaries: /usr/lib/apache2
- User / Group (/etc/group): apache / apache
- To test Apache configuration file: apachectl configtest
- To check and make sure whatever port one wants Apache to run on is clear: netstat -lnp | grep WhatEverPortNumber
Apache2 default directories can be copied, moved, reconfigured to reflect other typical HTTPD configurations as used in CentOS and other RedHat derivatives.
Make sure the following lines exist in the apache2.conf file for the sake of CGI functionality;
- LoadModule cgi_module lib/apache2/mod_cgi.so
For CGI scripts, add the following to /etc/apache2/apache2.conf;
ScriptAlias /cgi-bin /usr/share/apache2/cgi-bin
<Directory /cgi-bin>
AllowOverride None
Options None
Require all granted
</Directory>
Set permissions for the root directory
chown -R apache:apache /usr/share/apache2
find /usr/share/apache2 -type d -exec chmod 755 {} \;
find /usr/share/apache2 -type f -exec chmod 644 {} \;
The below items do NOT work or are NOT available in OpenWRT for Apache, so do NOT attempt to enable them in /etc/apache2/apache2.conf
- LoadModule proxy_fcgi_module lib/apache2/mod_proxy_fcgi.so (Module does NOT exist for OpenWRT)
- LoadModule proxy_scgi_module lib/apache2/mod_proxy_scgi.so (Module does NOT exist for OpenWRT)
- LoadModule cgid_module lib/apache2/mod_cgid.so (does NOT seem to work, even when setting the ScriptSock Directive)
Lighttpd
Lighttpd has built-in CGI capability and a FastCGI module available (opkg install lighttpd-fastcgi) in OpenWRT that allows it to use the PHP FastCGI capability (php7-fastcgi). OpenWRT has PHP 7 packages for CGI and FastCGI (opkg install php7-fastcgi) available to make use of the Lighttpd capabilities, plus the PHP-FPM (opkg install php7-fpm) module.
To see the various modules compiled within the Lighttpd binary: lighttpd -V (that's a CAPITAL "V")
opkg update
opkg install lighttpd lighttpd-mod-cgi lighthttpd-mod-fastcgi
The biggest thing to watch out for is that by default, the directory Lighttpd is configured to use (/www) is also used by uHTTPd (the web server for the OpenWRT GUI). So change that in the /etc/lighttpd/lighttpd.conf configuration file. The port number is set to 81 by default, so as to not interfere with uHTTPd and LuCI. A new user (http in /etc/passwd) and a new group (www-data in /etc/group) are configured, so be sure to change the permissions and owner appropriately for a new root directory for Lighttpd;
chown -R http:www-data /usr/share/lighttpd
find /usr/share/lighttpd -type d -exec chmod 755 {} \;
find /usr/share/lighttpd -type f -exec chmod 644 {} \;
The /usr/share/lighttpd Directory was chosen in order to conform to the same folder convention OpenWRT uses for Apache. To allow directory browsing;
dir-listing.activate = "enable"
dir-listing.encoding = "utf-8"
CGI and FastCGI
See the below PHP section for Lighttpd
php-cgi -b 127.0.0.1:9123
PHP
The mod_php module is not available for Apache, nor does there seem to be a separate module for Lighttpd. The php-cgi (opkg install php7-cgi) package is available from OpenWRT and is necessary to make PHP function. The guide at: https://openwrt.org/docs/guide-user/services/webserver/http.apache leaves out a LOT of Apache configuration that is necessary to have PHP function correctly. Additionally, it adds some items that do not seem necessary. Of course this could be due to changes in the settings for the Apache package over the years or differences between router platforms, so the previous comments are not a criticism of OpenWRT.
opkg update
opkg install php7 php7-cgi php7-cli php7-fastcgi php7-fpm (php7-cgi is necessary because the Apache mod_php module is not included with OpenWRT and Lighttpd doesn't have a dedicated module for PHP, php-cli is the command line program for PHP and is useful for troubleshooting. Note: Most examples use just php as the command for executing PHP scripts, so it maybe useful to create a symbolic link, php, to php-cli (ln -s /usr/bin/php-cli /usr/bin/php), php7-fastcgi subtitutes for the Apache mod_php (Lighttpd doesn't have a FastCGI module for PHP, instead relying on the php7-fastcgi module) and allows for FastCGI functionality for PHP with both Apache and Lighttpd (it is worth noting that there is not an additional binary in this package, just settings to utilize the FastCGI capability that exists within the php-cgi binary package from OpenWRT), php7-fpm is an alternative to php7-fastcgi (but since Apache doesn't have a FastCGI module, this won't work, but Lighttpd does).
For enhanced performancd: opkg install php7-fpm php7-fastcgi (Remember, php7-fastcgi and php7-fpm are only useful for Lighttpd as Apache has no available FastCGI module available in OpenWRT)
/etc/php.ini Settings
Comment out or change the line in /etc/php.ini to: doc_root =
The guide at: https://openwrt.org/docs/guide-user/services/webserver/http.apache states the following should be put in the php.ini file, but was found to be unnecessary: extension=gd.so However, if opkg install php7-mod-gd is installed, then the gd.so extension may be useful. It appears to be for graphics. The line should be extension=/usr/lib/php/gd.so And it isn't even necessary to add, because when the package is added, the php7-mod-gd package also adds the /etc/php7/ directory with a file named 20_gd.ini that is included in the PHP binary / executable to scan the /etc/php7 directory for additional configuration items (-config-file-scan-dir=/etc/php7', visible in a PHP test file that includes the <?php phpinfo(); ?> script line).
PHP FastCGI
The php7-mod-fastcgi is configured as a service named php7-fastcgi and configured in /etc/config/php7-fastcgi
PHP for Apache with CGI: /etc/apache2/apache2.conf Settings
- /etc/apache2/apache2.conf file has the settings to make PHP function properly (see above Apache section). This is done manually as no additional "PHP.conf" file for Apache is included with any OpenWRT package.
LoadModule cgi_module lib/apache2/mod_cgi.so
LoadModule actions_module lib/apache2/mod_actions.so
ScriptAlias /php /usr/bin
AddHandler application/x-httpd-php .php
OR
AddType application/x-httpd-php .php
Action application/x-httpd-php /php/php-cgi
The cgi_module is necessary for for Apache to utilize the PHP binary / executable php-cgi file (the program that makes PHP function). Either the AddHandler or AddType Directive can be used to configure what Apache does with files that end with the .php extension. The ScriptAlias Directive is used to designate the binary / executable file used to handle PHP as CGI related. The AddHandler Directive, the "application/x-httpd-php" name is a lablel that is used in the Action Directive to associated it with a binary. Some examples use a trailing slash ( / ) and quotes ( " ), but after experimentation, the trailing / isn't necessary and as long as spaces aren't used in a path, quotes aren't needed either. The guide at: https://openwrt.org/docs/guide-user/services/webserver/http.apache states the following should be put in the apache2.conf file, but was found to be unnecessary;
<Directory "/usr/bin">
AllowOverride None
Options none
Order allow,deny
Allow from all
</Directory>
Make sure Apache permissions and ownership for directories and files is set correctly.
Make sure this line is set to nothing in /etc/php.ini (original setting: doc_root = "/www"): doc_root =
Make sure this is NOT commented out in the /etc/apache2/apache2.conf File: LoadModule cgi_module lib/apache2/mod_cgi.so
Test PHP at the command line by directing its configuration output into an HTML File: php-cgi /var/www/html/php.php > /var/www/html/php.html (Note: The php.php file should contain a single line of code: <?php phpinfo(); ?> )
Create a PHP file (test.php) in a working Apache directory with this code and then test from a web browser: <?php phpinfo(); ?>
OpenWRT named the interactive command line interface for PHP php-cli. Most sites give examples that use just "php", so to make it easier, add a symbolic link to the rc.local file for OpenWRT via the LuCI GUI, System, Startup, Local Startup: ln -s /usr/bin/php-cli /usr/bin/php
And remember, OpenWRT does not include the Apache packages needed for Apache to utilize FastCGI or PHP-FPM.
PHP for Lighttpd: /etc/lighttpd/conf.d/30-cgi.conf (NOT the /etc/lighttpd/lighttpd.conf) Settings
PHP with Lightttpd CGI
Add the following line to /etc/lighttpd/conf.d/30-cgi.conf (NOT the /etc/lighttpd/lighttpd.conf file): ".php" => "/usr/bin/php-cgi", see example below;
cgi.assign = ( ".pl" => "/usr/bin/perl",
".cgi" => "/usr/bin/perl",
".rb" => "/usr/bin/ruby",
".erb" => "/usr/bin/eruby",
".php" => "/usr/bin/php-cgi",
".py" => "/usr/bin/python" )
Unlike the instructions at: https://openwrt.org/docs/guide-user/services/webserver/lamp#lighttpd1 indicate,the above line is added to the /etc/lighttpd/conf.d/30-cgi.conf file. It is possible the instructions are old or written for a different router platform and at some point after it was written, the CGI configuration was separated and put into a different file (all files in the /conf.d directory are "added" into the lighttpd.conf file at run time with an include statement). If it is put in the lighttpd.conf file it will cause a "Validation failed" error when starting the Lighttpd service because of two cgi.assign statements.
PHP with Lighttpd FastCGI
Make sure the lighttpd-mod-fastcgi module is installed as noted in the Lighttpd section. And remember, OpenWRT uses the same binary / executable (php-cgi) for CGI and FastCGI. There also does not seem to be a way to verify if the FastCGI is handling things, other than disabling the 30-cgi.conf file for Lighttpd or stopping the php-fastcgi service or looking at log files.
Check the following items in the /etc/lighttpd/conf.d/30-fastcgi.conf file (this is just following the OpenWRT convention for Lighttpd, instead of adding it to the lighttpd.conf file as most example give) and remove the comment hash tag (#) to enable them;
fastcgi.server = ( ".php" =>
((
"host" => "127.0.0.1" ,
"port" => "1026" ,
#"socket" => <string>, # either socket or host+port
#"bin-path" => "/usr/lib/lighttpd/mod_fastcgi.so", # optional
#"bin-environment" => <array>, # optional
#"bin-copy-environment" => <array>, # optional
#"mode" => <string>, # optional
#"docroot" => <string> , # optional if "mode" is not "authorizer"
#"check-local" => <string>, # optional
#"max-procs" => <integer>, # optional - when omitted, default is 4
#"broken-scriptfilename" => <boolean>, # optional
#"fix-root-scriptname" => <boolean>, # optional, since 1.4.23 (option didn't work before 1.4.23)
#"disable-time" => <integer>, # optional
#"allow-x-send-file" => <boolean>, # optional, (deprecated since 1.4.40)
#"x-sendfile" => <boolean>, # optional, since 1.4.40
#"x-sendfile-docroot" => <array>, # optional, since 1.4.40
#"kill-signal" => <integer>, # optional, default is SIGTERM(15) (v1.4.14+)
#3"tcp-fin-propagate" => <boolean> # optional, propagate TCP FIN to backend (since 1.4.50) (default: disabled)
))
)
An explanation of the above settings can be found here: https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI If file extensions other than .php are used, add the following to /etc/lighttpd/conf.d/30-fastcgi.conf
fastcgi.map-extensions = ( ".php3" => ".php",
".php4" => ".php",
".php5" => ".php",
".phps" => ".php",
".phtml" => ".php" )
PHP with Lighttpd FastCGI and PHP-FPM
opkg install php7-mod-fpm spawn-fcgi
/etc/php7-fpm.conf
/etc/php7-fpm.d
Change the lines in /etc/lighttpd/conf.d/30-fastcgi.conf from the above FastCGI example as follows;
#"host" => "127.0.0.1" ,
#"port" => "1026" ,
"socket" => "/var/run/php7-fpm.sock", # either socket or host+port
Also, in the /etc/php7-fpm.d directory, modify the www.conf (which is an arbitrary name, all .conf files in the directory are used as configuration by the php-fpm service) as follows;
listen.owner = http
listen.group = www-data
listen.mode = 0666
If the above items aren't modified is won't work, and a "Permission denied socket" error will be recorded in the /var/log/lighttpd/error.log file (if enabled)
Looking at a PHP output file (a file containing this PHP script: <?php phpinfo(); ?>), it does verify that the FPM service is being used.
SPECIAL NOTE: If CGI (not FastCGI) is left enabled and everything is left in the default configuration order that OpenWRT suppliec, the CGI interface will intercept the PHP files. So, disable CGI (not really desireable) or change the order in the /etc/lighttpd/conf.d file by changing the name of the file from "30-cgi.conf" to "31-cgi.conf" so the settings in the "30-fastcgi.conf" file will take precidence.
MariaDB Server
- opkg update
- opkg install mariadb-server mariadb-client libaprutil-dbd-mysql mariadb-server-extra mariadb-client-extra (dependencies are automatically installed)
- Change the "option enabled '0'" to a '1' to enable in the /etc/config/mysqld file
- To create the default database: mysql_install_db --force --basedir=/usr
- Start the service: service mysqldb start
- To create a password for the current user (blank if not configured): /usr/bin/mysqladmin -u root password 'new-password'
- Log into the command line for the database: mysql -u root -p
Default database location: /mnt/data/mysql/
Memory footprint..., Aria see https://coderwall.com/p/lz0qsa/convert-all-myisam-tables-to-aria, https://mariadb.com/kb/en/aria-storage-engine/, and the MariaDB Cookbook
Storage engines: innodb is the default, MyISAM is older, but has the smallest footprint, Aria seems to be the middle road (https://mariadb.com/kb/en/choosing-the-right-storage-engine/)
Show available storage engines: SHOW ENGINES\G or show engines;
phpMyAdmin
- opkg update
- opkg install php7-mod-mbstring php7-mod-json php7-mod-hash php7-mod-ctype php7-mod-zip php7-mod-gd php7-mod-mysqli php7-mod-session php7-mod-snmp zoneinfo-northamerica (if one is in North America, if not, choose another zone and remember, phpMyAdmin will display a blank page with no error if a zoneinfo-WhatEverZone is not installed in addition to the zoneinfo-core package, see additional information below, dependencies will also be installed automatically).
The following item is VERY important, hence it's typeface in BOLD CAPITAL letters. If the appropirate additional time zone module is not installed it can cause a completely invisible error (IE, no error in Apache, Lighttpd, or PHP logs). IE, it only displays a blank page. Even using a command line instance of PHP will not reveal the error. This line in the /phpMyAdmin/libraries/classes/Core.php file: date_default_timezone_set(@date_default_timezone_get()); is the source of the issue (Note, this is not the fault of phyMyAdmin, but it would be nice if they wrote a bit of code to address this situation). The error message that can be coaxed out of Lighttpd by taking that line of code and placing it in a file by itself is: Timezone database is corrupt – this should never happen! (thanks to this site for a key bit of information on that issue: https://e3fi389.wordpress.com/2014/12/07/timezone-database-is-corrupt-date-error-in-openwrt/)
- ALSO MAKE SURE TO INSTALL THE APPROPRIATE TIME ZONE MODULE, IN ADDITION TO THE DEFAULT zoneinfo-core: opkg install zoneinfo-northamerica (for example)
- To install all of the php7-mod packages if desired, but not necessary:opkg list | grep php7-mod-| awk '{print $1}' | xargs opkg install
- wget https://files.phpmyadmin.net/phpMyAdmin/4.9.5/phpMyAdmin-4.9.5-english.tar.gz (or whatever the latest version is)
- If not installed, wget needs: opkg install libustream-mbedtls20150806 (or whatever other version, type opkg list libustream* to see available packages)
- tar -xzvf phpMyAdmin-4.9.5-english.tar.gz
- mv WhatEverUnTarredDirectory /usr/share/apache/htdocs OR WhatEverLighttpd Directory
- Change the permissions to what they should be, see CHOWN, etc. in the above Lighttpd section
- Browse to: http://WhatEverURL/phpMyAdmin/setup/index.php, or use the below configuration file (/WhatEverPath/config.inc.php)
<?php
/* Servers configuration */
$i = 0;
/* Server: WRT3200ACM [1] */
$i++;
$cfg['Servers'][$i]['verbose'] = 'WRT3200ACM';
$cfg['Servers'][$i]['host'] = '127.0.0.1';
$cfg['Servers'][$i]['port'] = '3306';
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'WhatEverPassword';
$cfg['Servers'][$i]['MemoryLimit'] = '-1';
/* End of servers configuration */
$cfg['blowfish_secret'] = '\'ci.NDxXw@1QB^Y!x(`QY0<&e!|)XG`?';
$cfg['DefaultLang'] = 'en';
$cfg['ServerDefault'] = 1;
$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';
?>
- The config.inc.php file permissions have to be set to whatever the web server is: chown apache:apache OR http:www-data config.inc.php (for Apache OR Lighttpd) and chmod 644 config.inc.php
- REMEMBER: If using Lighttpd with PHP-FPM, restart the php7-fpm service as it does not automatically restart when Lighttpd is restarted (unless configured)
- Also to remember to configure proper security for the phpMyAdmin within Apache or Lighttpd to restrict access to say only local IP Addresses.
- It will also prompt to set up a phpMyAdmin table within the database, just click on the links and it will automatically create the database
- Configure a TEMP folder for phpMyAdmin to use in the config.inc.php file: $cfg['TempDir'] = '/tmp/phpMyAdmin'; (as an example, make sure chmod 777 /tmp/phpMyAdmin, and to create the directory and set permissions when the router is rebooted in the rc.local file as everything in the /tmp directory will be deleted after a reboot of a router)
- Also consider increasing php.ini settings for memory, upload, etc.
- memory_limit = 100M
- file_uploads = On
- upload_max_filesize = 128M
- post_max_size = 128M
- max_file_uploads = 20
- To diagnose any issues when attempting to access the phpMyAdmin setup this will display the error message (look for the line that says WarnMissingExtension to spot missing modules): php-cli /usr/share/apache2/htdocs/phpMyAdmin/setup/index.php
LetsEncrypt / ACME
opkg update
opkg install acme luci-app-acme
Additional Reading for OpenWRT and LAMP
A nice summary and comparison of CGI, FastCGI, and PHP-FPM: https://www.basezap.com/difference-php-cgi-php-fpm/
Samba Server and File Sharing
There are two versions of Samba Server available, 3.6.25 and 4.x.
- opkg update
- opkg install samba36-server OR opkg install samba4-server samba4-utils
- opkg luci-app-samba OR opkg install luci-app-samba4
- smbpasswd -a root (or whatever user is desired)
The stock OpenWRT Samba Server Configuration (in LuCI) can be replaced with something similar to below (LUCI GUI, Service, Network Shares, Edit Template Tab);
[global]
netbios name = OpenWRT
server string = Samba on OpenWRT
workgroup = ESTUARY-A
guest account = nobody
security = user
map to guest = Bad User
guest ok = yes
guest only = no
timestamp logs = no
preserve case = yes
short preserve case = yes
socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
log level = 0
syslog = 0
passdb backend = smbpasswd
smb encrypt = disabled
smb passwd file = /etc/samba/smbpasswd
Below is the default OpenWRT configuration for Samba Server 3
[global]
netbios name = |NAME|
display charset = |CHARSET|
interfaces = |INTERFACES|
server string = |DESCRIPTION|
unix charset = |CHARSET|
workgroup = |WORKGROUP|
bind interfaces only = yes
deadtime = 30
enable core files = no
invalid users = root
local master = no
map to guest = Bad User
max protocol = SMB2
min receivefile size = 16384
null passwords = yes
passdb backend = smbpasswd
security = user
smb passwd file = /etc/samba/smbpasswd
use sendfile = yes
A key to getting Samba 4 to work properly with Windows 10 is this: map to guest = Never The below is an actual functional smb.conf file for Samba 4 that works with Windows 10. Thanks to https://www.nodeum.io/howto/guest-access-in-smb2-disabled-by-default-in-windows-10 for the key piece of information. Click here for the default OpenWRT configuration for Samba 4.
[global]
netbios name = |NAME|
interfaces = |INTERFACES|
server string = |DESCRIPTION|
unix charset = |CHARSET|
workgroup = |WORKGROUP|
security = user
timestamp logs = no
preserve case = yes
short preserve case = yes
socket options = TCP_NODELAY SO_KEEPALIVE IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
log level = 0
syslog = 0
passdb backend = smbpasswd
smb passwd file = /etc/samba/smbpasswd
# Below is the key to getting Samba Server to work with Windows 10
map to guest = Never
There are so many different sources that babble about solving the Samba / Windows 10 issues that include ntlm = true, server min protocol = SMB3, min protocol = SMB3, blah, blah, blah. Nothing works. All of these items seem to be set correctly with default values as of a version of Samba sometime after 2019, so they do not fix the issue. For the "You can't access this shared folder because your organization's security policies block unauthenticated guest..." Error Message, the above noted map to guest = Never solves the issue
Then dd a Network Share: In LUCI GUI, Service, Network Shares, General Settings or Edit Template Tab, enter a Name and a Path, the other defaults are fine.
If any attempts are made to edit the /etc/samba/smb.conf file directly, it will be overwritten each time by OpenWRT as that's the way it functions in OpenWRT. It can be prevented, but it is recommended not to do that in order to preserve the standard functionality of OpenWRT.
And lastly, remember if one attempts to share the "Root Directory" ( / ), none of the sub directories will open, because of the way the OpenWRT file system works.
DNS (BIND), DHCP (DHCPD), and DNSMASQ
If installing BIND or DHCPD, first uninstall DNSMASQ
- service stop dnsmasq
- opkg remove dnsmasq
- ...or use the LuCI GUI to uninstall
BIND
opkg update
opkg install bind-server
opkg install bind-rndc (some administration tools) OR opkg install bind-tools (all administration tools)
DHCPD
There are two versions of DHCPD, ISC and KEA. ISC is the older server and KEA is the newer. For simple or small networks, ISC is the choice. Read here for more information: https://www.isc.org/kea/
opkg update
opkg install isc-dhcp-server-ipv4
POPTOP / PPTPD
opkg install pptpd (dependencies will automatically be installed)
Configuration File: /etc/config/pptpd
There is no LuCI GUI available
Additional Information: https://openwrt.org/docs/guide-user/services/vpn/pptp/basic
OpenVPN
For some reason if one installs OpenVPN via opkg install openvpn, the mbedTLS version is installed as opposed to the OpenSSL. Hint: Use the OpenSSL. Why?
To install OpenVPN with OpenSSL and the LUCI GUI for it (under VPN)
- opkg update
- opkg install openvpn-openssl openvpn-easy-rsa luci-app-openvpn luci-ssl-openssl (openssl-util and other dependencies will automatically install)
- OpenVPN will be available under LuCI GUI, VPN, OpenVPN (Remember to refresh the web browser window to display the new category (Firefox: CTRL + Refresh) or log out and log back into the LuCI GUI)
Telnet
TelnetD is supported (and works) on DD-WRT, but OpenWRT has essentially discontinued use of telnet in the name of security. It is possible to build a custom version of the OpenWRT firmware that supports telnetd (and telnet the client), but they've effectively made it very difficult (sad, but probably as it should be). The below section of the source configuration file for OpenWRT says it all;
bool "telnetd"
default BUSYBOX_DEFAULT_TELNETD
select BUSYBOX_CONFIG_FEATURE_SYSLOG
help
A daemon for the TELNET protocol, allowing you to log onto the host
running the daemon. Please keep in mind that the TELNET protocol
sends passwords in plain text. If you can't afford the space for an
SSH daemon and you trust your network, you may say 'y' here. As a
more secure alternative, you should seriously consider installing the
very small Dropbear SSH daemon instead:
http://matt.ucc.asn.au/dropbear/dropbear.html
Note that for busybox telnetd to work you need several things:
First of all, your kernel needs:
CONFIG_UNIX98_PTYS=y
Next, you need a /dev/pts directory on your root filesystem:
$ ls -ld /dev/pts
drwxr-xr-x 2 root root 0 Sep 23 13:21 /dev/pts/
Next you need the pseudo terminal master multiplexer /dev/ptmx:
$ ls -la /dev/ptmx
crw-rw-rw- 1 root tty 5, 2 Sep 23 13:55 /dev/ptmx
Any /dev/ttyp[0-9]* files you may have can be removed.
Next, you need to mount the devpts filesystem on /dev/pts using:
mount -t devpts devpts /dev/pts
You need to be sure that busybox has LOGIN and
FEATURE_SUID enabled. And finally, you should make
certain that Busybox has been installed setuid root:
chown root.root /bin/busybox
chmod 4755 /bin/busybox
with all that done, telnetd _should_ work....
Finding a version of BusyBox that includes TelnetD will not suffice as there are additional items that need to be configured for it to work. However, a telnet client program seems appropriate. See the "signoff" on TELNET here: https://github.com/openwrt/openwrt/commit/a35a7afc9f15b4c084c996ab0dbcd833b45f30d5 But there is an alternative (see the next section)
NETCAT or NC
opkg update
opkg install netcat
Use as a Telnet Client: nc -T -v W.X.Y.Z (-T = Answer using telnet negotiation, -v = Verbose)
Instead of simply pressing the Enter Key in NETCAT, one must instead using the following key commands: CTRL+V, CTRL+M, ENTER (That equates to pressing the ENTER Key. OpenWRT's version of NETCAT in BusyBox does not include the -C switch which allows for easy "carriage returns")
Statistics
CollectD
Task Scheduling with Cron
Additional Information: https://openwrt.org/docs/guide-user/base-system/cron
BackUps
opkg install restic
To create a backup repository: restic init --repo "WhatEverRepositoryPath"
To make a backup: restic -r "WhatEverRepositoryPath" --verbose backup /WhatEverPathToBackUp
- Example: restic -r "/mnt/sdb2/RESTIC/WRT3200ACM/" --verbose --tag "What Ever Note" backup /overlay
To view backups: restic -r "WhatEverRepositoryPath" snapshots
- Example: restic -r "/mnt/sdb2/RESTIC/WRT3200ACM/" snapshots
To restore a backup: restic -r "WhatEverRepositoryPath" restore ID --target /WhatEverPathToRestoreTo (the ID can be obtained from the above "snapshots" command, the target does not have to be the original source, --verbose doesn't work)
Additional Information: https://restic.readthedocs.io/en/stable/ (Note: In some of their examples a tilde ( ~ ) is used, which is a user's home directory)
Webmin
Webmin can be successfully installed on OpenWRT, AND IT IS USEFUL. The end of the previous sentence is in all CAPS and BOLD because of the large number websites and posts that do nothing more than question why anyone would want to install Webmin on OpenWRT instead of just answering the original question of how to install it. Sometimes it is just nice to have a GUI. The editor for config files alone is worth it.
There is however a word of caution to address: Do NOT use Webmin for any OpenWRT services that have an associated LuCI GUI or /etc/config/WhatEverConfigurationFile because modifications made by Webmin will be wiped out by changes made via LuCI or the /etc/config/Files... There are many, many services such as BIND / NAMED, Apache / HTTPD, ProFTPD, OpenSSL for OpenVPN Certificate generation that have no LuCI GUI, nor are they "controlled" or configured via the /etc/config/ Files. That means these services are safe to configure via text or by GUI.
Installing Webmin
Download the Webmin ...tar.gz file: wget https://prdownloads.sourceforge.net/webadmin/webmin-1.953.tar.gz
Unzip and UnTAR the file;
- The location chosen when unzipping and untarring Webmin will be the installation directory where the program runs
- Possible location: /overlay/webmin (don't use the /tmp directory or it will be gone when the router reboots)
- CentOS typical location: /usr/libexec/webmin
- gunzip webmin-1.953.tar.gz
- tar xf webmin-1.953.tar (be patient, there are a LOT of files, even on a fast USB 3.0 flash drive it takes a couple of minutes.
Before running the setup program;
- Add the bin Group to /etc/group using this: bin:x:10000:
Run the setup and configuration questions during setup (Note: OpenWRT does not provide the NET::SSLeay Perl Module, so SSL will not be available for Webmin);
- Detailed instructions to install "The Old Fashion Way..." can be found here: https://doxfer.webmin.com/Webmin/Installation_-_the_old_fashioned_way
- In the new /overlay/webmin directory: ./setup.sh
- When prompted, configure the ETC Directory as: /etc/webmin (suggested)
- Configure the LOG Directory as: /overlay/webmin/log (suggested)
- Configure OS as: 110 - Generic Linux
Configuring Webmin
- Verify the /etc/webmin/config file contains the following settings;
os_type=generic-linux
os_version=4
real_os_type=OpenWRT
real_os_version=19.07.03
- Modify the /overlay/webmin/proc/module.info File as follows (It disables the Webmin Processor Module because that module does not run correctly on OpenWRT for the AC Series of routers);
Original Line: os_support=solaris generic-linux hpux freebsd osf1 irix unixware openserver macos aix netbsd openbsd windows
Modified Line: os_support=solaris hpux freebsd osf1 irix unixware openserver macos aix netbsd openbsd windows
For safety considerations, it is also worth disabling additional modules (Samba, etc.) that have a LuCI GUI or are configured via /etc/config using the above method.
Alternative Method of Configuring Webmin
The /etc/webmin/config file can be set as follows
os_type=linux
os_version=4
real_os_type=OpenWRT
real_os_version=19.07.03
...however, this necessitates that any Webmin modules that require certain operating systems (apache, bind, etc.) need to have their module.info files modified to include the os_type of linux. The below script modifies all of the module.info files in the /overlay/webmin directory.
find /overlay/webmin -type f -name module.info -exec sed -i 's/*-linux/linux *-linux/g' {} +
And again, the /overlay/webmin/proc/module.info will need to be modified as above.
Adding and Configuring Modules
Before any modules are moved from the Unused-Modules Category, they must be properly configured for Webmin to detect.
Users and Groups
System, Users and Groups, Settings;
Password File (User & Password File): /etc/passwd (/etc/passwd- seems to be the OpenWRT template file for passwd)
Group file: /etc/group
Apache / Apache2 / HTTPD Module (/etc/webmin/apache/config)
allow_virtualmin=0
apply_cmd=/etc/init.d/apache2 restart
test_apachectl=1
pid_file=/var/run/apache2/httpd.pid
httpd_path=/usr/sbin/apache2
test_manual=0
apachectl_path=/usr/sbin/apachectl
auto_mods=1
httpd_dir=/etc/apache2
test_config=1
stop_cmd=/etc/init.d/apache2 stop
max_servers=100
mime_types=/etc/apache2/mime.types
start_cmd=/etc/init.d/apache2 start
graceful_cmd=/etc/init.d/apache2 reload
httpd_version=2.4.43
httpd_conf=/etc/apache2/apache2.conf
BIND / BIND8 / NAMED (/etc/webmin/bind8/config);
The below Code Block contains the settings to customize the Webmin interface for BIND / NAMED
Expand / Collapse the Code Block
rndc_conf=/etc/bind/rndc.conf
force_random=0
keygen=/usr/sbin/dnssec-keygen
rev_def=0
tmpl_dnssec_dt=1
spf_record=0
by_view=0
other_slaves=1
updserial_def=0
soa_start=0
rndc_cmd=/usr/sbin/rndc
whois_cmd=
allow_wild=1
updserial_man=1
records_order=0
checkzone=/usr/sbin/named-checkzone
updserial_on=1
dnssec_period=21
ndc_cmd=
allow_long=0
tmpl_dnssec=0
allow_underscore=1
rev_must=0
master_ttl=1
confirm_zone=1
restart_cmd=/etc/init.d/named reload
short_names=0
max_zones=999
no_chroot=1
soa_style=0
master_dir=/etc/bind/masters
confirm_rec=1
reversezonefilename_format=ZONE.rev
support_aaaa=1
start_cmd=/etc/init.d/named start
stop_cmd=/etc/init.d/named stop
largezones=0
dnssectools_rollmgr_pidfile=
dnssectools_conf=
signzone=/usr/sbin/dnssec-signzone
no_pid_chroot=0
relative_paths=0
ipv6_mode=1
checkconf=/usr/sbin/named-checkconf
named_conf=/etc/bind/named.conf
dnssectools_rollrec=
slave_dir=/etc/bind/masters
dnssectools_keydir=
rndcconf_cmd=/usr/sbin/rndc-confgen
show_list=1
pid_file=/tmp/run/named/named.pid
named_path=/usr/sbin/named
forwardzonefilename_format=ZONE.hosts
allow_comments=0
extra_forward=
file_owner=bind:bind
default_view=
this_ip=
keys_dir=
extra_reverse=
slave_file_perms=
named_group=
default_master=
named_user=
extra_slaves=
auto_chroot=
chroot=
free_nets=
default_prins=
file_perms=
zones_file=
Sadly, for the BIND / NAMED module, it didn't seem that OpenWRT included the named-compilezone command. However, after some quick research with a major hint (from here: http://www.linuxfromscratch.org/blfs/view/svn/server/bind.html) which included a notation that the named-compilezone command was a symbolic link, then a quick check on a CentOS system which showed the /usr/sbin/named-compilezone pointing to /usr/sbin/named-checkzone, which confirmed the utility as a standalone file does NOT exist, but is simply a softlink to another file. The solution is to add this line to the rc.local file: ln /usr/sbin/named-checkzone /usr/sbin/named-compilezone That way the command is available to Webmin.
Third Party Modules (OpenVPN Certificate Authority, not OpenVPN itself as that is configured via LuCI or /etc/config, etc)
Install via the Webmin GUI and remember to configure the module.info file if necessary and settings
OpenVPN (/etc/webmin/openvpn/config);
status_cmd=systemctl status openvpn@%s
openvpn_servers_subdir=servers
start_cmd=/etc/init.d/openvpn start
openvpn_home=/etc/openvpn
br_end_cmd=/usr/share/webmin/openvpn/br_scripts/bridge_end
openvpn_keys_subdir=keys
stop_cmd=/etc/init.d/openvpn stop openvpn@%s
down_root_plugin=/usr/share/webmin/openvpn/ovpn_plugin/openvpn-plugin-down-root.so
openvpn_pid_path=/var/run
openvpn_version=2.4.7
openvpn_path=/usr/sbin/openvpn
zip_cmd=/usr/bin/gzip
br_start_cmd=/usr/share/webmin/openvpn/br_scripts/bridge_start
log_lines=200
openvpn_clients_subdir=clients
openvpn_pid_prefix=openvpn/
openssl_home=/etc/openvpn/openvpn-ssl.cnf
openssl_path=/usr/bin/openssl
openssl_version=1.1.1g
Starting and Stopping Webmin
Start: /etc/webmin/start
Stop: /etc/webmin/stop
Additonally, /etc/webmin/start can be added to the /etc/rc.local file to automatically start Webmin at boot.
Webmin Performance
To decrease the Webmin CPU load on the OpenWRT router;
- Disable Real-Time Monitoring: Webmin, Webmin Configuration, Themes, Real-time monitoring options, Enable real-time monitoring, NO
- Reduce Real-Time Monitoring Refresh: Interval for performing update, 10000 (Increasing the default value of 1000 (ms) will also cause delays in information in certain categories, such as Network I/O to be displayed slowly)
Special Notes for Webmin
Some modules, such as NAMED / BIND, may not accurately show the Stop / Start status after a stop or start until after a screen refresh, which is possibly related to the Monitoring Refresh time mentioned above, if increased.
Sources
https://forum.openwrt.org/t/script-mount-alternate-nand-firmware-linksys/33588
https://forum.openwrt.org/t/solved-how-to-mount-ubifs-in-openwrt-kirkwood/32443/4
Startup Scripts
/etc/rc.local
LuCI, System, Startup, Local Startup