Linksys AC Series Router Configuration Tips for OpenWRT: Difference between revisions
mNo edit summary |
m →Overlay |
||
Line 13: | Line 13: | ||
*Upgrade Firmware from Linksys to OpenWRT | *Upgrade Firmware from Linksys to OpenWRT | ||
*Install a several basic software packages that add very useful utilities and access to USB and eSATA storage | *Install a several basic software packages that add very useful utilities and access to USB and eSATA storage device (Flash Drive, HDD enclosures, and even mSATA and M.2 NGFF & NVMe SSDs in USB 3.0 enclosures). This includes backup software too. | ||
*Partition and Configure OpenWRT to use external storage drives, not just for storage, but also as a replacement / addition to the internal non-volitile storage | *Partition and Configure OpenWRT to use external storage drives, not just for storage, but also as a replacement / addition to the internal non-volitile storage | ||
Line 136: | Line 136: | ||
[[File:USB 3.0 Extension.jpg|alt=USB 3.0 Extension|none|thumb|120x120px|USB 3.0 Extension]] | [[File:USB 3.0 Extension.jpg|alt=USB 3.0 Extension|none|thumb|120x120px|USB 3.0 Extension]] | ||
But there is a solution... A USB 3.0 A Male to A Female Adapter (Part # 1206-N, UPC 848076012233) from a company named CMPLE. It is available from several places: [https://www.walmart.com/ip/Cmple-USB-3-0-A-Male-to-A-Female-Adapter/172246645 Wal-Mart], [https://www.ebay.com/itm/NEW-USB-3-0-A-MALE-TO-A-FEMALE-M-F-ADAPTER-CONNECTOR-NEW-/362695174727 eBAy], and from the company that appears to have it manufactured (in China), [https://www.cmple.com/ProductsBySKU/1206-N CMPLE]. Even at about $3.00 it is a bit more expensive than other similar products (and there are only a few). But it has one advantage in that the orientation of the male and female part of the connector are arranged such that the above noted 3 Port USB 3.0 hub from Sabrent can connect and be in the "up" position. All other similar items found require that the hub be rotated to the left, right, or down. Down isn't a choice unless one's router is on the edge of a table. Left and right are good as the adapter provides enough clearance for the hub so it doesn't contact the power cord or the Ethernet cable on the WAN port. | But there is a solution... A USB 3.0 A Male to A Female Adapter (Part # 1206-N, UPC 848076012233) from a company named CMPLE. It is available from several places: [https://www.walmart.com/ip/Cmple-USB-3-0-A-Male-to-A-Female-Adapter/172246645 Wal-Mart], [https://www.ebay.com/itm/NEW-USB-3-0-A-MALE-TO-A-FEMALE-M-F-ADAPTER-CONNECTOR-NEW-/362695174727 eBAy], and from the company that appears to have it manufactured (in China), [https://www.cmple.com/ProductsBySKU/1206-N CMPLE]. Even at about $3.00 it is a bit more expensive than other similar products (and there are only a few). But it has one advantage in that the orientation of the male and female part of the connector are arranged such that the above noted 3 Port USB 3.0 hub from Sabrent can connect and be in the "up" position. All other similar items found require that the hub be rotated to the left, right, or down. Down isn't a choice unless one's router is on the edge of a table. Left and right are good as the adapter provides enough clearance for the hub so it doesn't contact the power cord or the Ethernet cable on the WAN port. | ||
===Overlay=== | |||
Before getting into the "how" with an external storage device, it is worth pointing out one of the more useful features available in OpenWRT. | |||
Whatever external storage device is chosen, be it an old USB 2.0 Flash Drive that's been sitting in a drawer to an 8 TB or more HDD in an eSATA enclosure, it can be used in the capacity of just a storage device. However, there is a nice feature that allows for additional software that acts in conjunction with the basic firmware of the router to be stored on an external storage device. To put it in terms of a computer, the router can be a computer that has two storage devices. One for the Operating System (Firmware in the case of a router) and the other for file storage. But what if the Operating System (AKA firmware) could also reside on an external storage device. With OpenWRT it can. | |||
There are two choice to make in regards to relocating the OS of a router. The first choice, referred to as "Overlay", has part of the OS continuing to reside on the internal Flash Storage with the rest on an external storage device. The second choice, mounting the extenal storage device as the "root filesystem" can move almost all of the OS to the external storage device. | |||
Details on the OpenWRT booting process, overlay, file systems, etc. can be read about at the below links. Don't do any of it yet, just read it for the technical background information; | |||
* File Systems & Summary of Boot Process: https://openwrt.org/docs/techref/filesystems | |||
* Detailed Boot Process: https://openwrt.org/docs/techref/preinit_mount | |||
* Details on Overlay are discussed here ): https://openwrt.org/docs/guide-user/additional-software/extroot_configuration | |||
Both choice offer almost unlimited expansion of the OS, limited only by the size of the storage device(s) connected, with neither offering a performance advantage over the other. The "Overlay" choice is the safer of the two if the external storage device malfunctions. If a malfunction does occur, the router will essentially revert to a "newly flashed" state. This allows for a new external flash drive to be connected and hopefully a backup restoration. The second choice is more dangerous in that any malfunction of the external storage device will result in the router being unresponsive to normal access methods. | |||
Even with the huge (compared to other routers) amount of non-volatile Flash Storage space available on the AC Series of routers, sometimes it isn't enough. There's a total of 128 MB for the AC and ACS, and a whopping (relative to routers) 256 MB available on the WRT3200ACM. But... There's always a "but". Even with the ACM, typically only a single 80 MB partition is readily available. And of that, only about 70 MB is available as free space (half that for the AC and ACS series). | |||
It is possible to access all of the internal Flash Storage space, as described below. But be careful when using it as it could make the router malfunction, be overwritten, etc. The available Flash Memory Storage could certainly have been utilized more efficiently. And don't blame OpenWRT for that. It is Linksys that designed the Flash Memory Storage design into the hardware. | |||
Anyway, there is a nice solution to overcome the storage limitations of the router using a feature called "Overlay". In short, a USB Flash Drive or eSATA drive or mSATA drive (in a USB 3.0 enclosure) can be used instead. | |||
===Software Needed for USB Flash Drives to Connect, Partition, Format, etc., with Other Configuration Tools and the LuCI GUI Interface=== | ===Software Needed for USB Flash Drives to Connect, Partition, Format, etc., with Other Configuration Tools and the LuCI GUI Interface=== | ||
Line 257: | Line 277: | ||
**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.) | **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! | **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=== | ===Swap Partition or Swap File=== |
Revision as of 23:14, 20 August 2020
This subject(s) of this article are the AC Series of routers manufactured by Linksys and the OpenWRT Firmware designed for them. The Linksys AC Routers include the WRT1200AC, WRT1900AC v1, WRT1900AC v2, WRT1900ACS v2, WR1900ACS v2, WRT3200ACM, and WRT32X. The WRT1900AC v2 is essentially a WRT1900ACS v1 and the WRT3200ACM and WRT32X are duplicate hardware models with different firmware (from Linksys) and the former blue / black and the latter black /gray. The models are sometimes referred to with out the suffix letters as WRT1200, WRT1900, WRT3200.
Information covered in this article was written for and tested on both the WRT1900ACS v1, WRT1900ACS v2, and WRT3200ACM. However the information applies to the other models as well.
All models are available on eBay and the ACS, ACM, and 32X series are available new as of the writing of this article in 2020. The most powerful and expensive models are the WRT3200ACM and the WRT32X. The best bargain used in terms of cost and "horsepower" is the ACS series. Occasionally it is possible to find a less than observant vendor on eBay selling an ACS model that is advertised as an AC model. Those are the best deals.
Details on each model are very nicely summarized on the OpenWRT website here: https://openwrt.org/toh/linksys/wrt_ac_series?s%5B%5D=wrt1200ac
As it started out, this article was intended to be a quick how to on a couple of items, but then grew to enormous proportions. There was some consideration on breaking it into smaller sections, but the Mediawiki interface with its table of contents mitigates that need to an acceptable level.
Quick C (as in Quick Configuration)
Because this article contains a lot of information in addition to "How to..." tutorials, this sections summarizes and provides links to the major "How to..." sections below.
- Upgrade Firmware from Linksys to OpenWRT
- Install a several basic software packages that add very useful utilities and access to USB and eSATA storage device (Flash Drive, HDD enclosures, and even mSATA and M.2 NGFF & NVMe SSDs in USB 3.0 enclosures). This includes backup software too.
- Partition and Configure OpenWRT to use external storage drives, not just for storage, but also as a replacement / addition to the internal non-volitile storage
Hardware
WRT1900AC
There are two hardware versions of the WRT1900AC, the v1 (version 1) and v2 (version 2). "v1" does not appear on the label, but is instead commonly used to differentiate between the original WRT1900AC and the version 2 model. Make sure to check the label on the bottom of the router and get the correct firmware.
WRT1900ACS
There are two versions of the WRT1900ACS. As with the WRT1900AC, the term "v1" is only used to differentiate with the version 2 model and does not appear on the model sticker. Unlike the WRT1900AC, both versions of the ACS router use the same firmware.
WRT3200ACM
As of the writing of this article on 7.2020, there is only one hardware version of the WRT3200ACM. The same is true for the WRT32X.
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
Log out and log back in to see the new LuCI feature (System, Advanced Reboot) OR Refresh browser windows (in Firefox Shift+RefreshButton)
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.
Another nice item, which isn't necessary, but makes nice neat way to connect several USB flash drives to a router is a Sabrent USB 3.0 Hub (model HB-RBM3). From Wal-Mart, only about $12. There are other similar device, but this one is much higher quality. Sadly, even with its ability to rotate, it won't plug into the router without blocking several of the Ethernet ports (including the WAN port) or the power connector. Thanks to the overhang on the rear of the AC Series router, it can't be rotated up.


But there is a solution... A USB 3.0 A Male to A Female Adapter (Part # 1206-N, UPC 848076012233) from a company named CMPLE. It is available from several places: Wal-Mart, eBAy, and from the company that appears to have it manufactured (in China), CMPLE. Even at about $3.00 it is a bit more expensive than other similar products (and there are only a few). But it has one advantage in that the orientation of the male and female part of the connector are arranged such that the above noted 3 Port USB 3.0 hub from Sabrent can connect and be in the "up" position. All other similar items found require that the hub be rotated to the left, right, or down. Down isn't a choice unless one's router is on the edge of a table. Left and right are good as the adapter provides enough clearance for the hub so it doesn't contact the power cord or the Ethernet cable on the WAN port.
Overlay
Before getting into the "how" with an external storage device, it is worth pointing out one of the more useful features available in OpenWRT.
Whatever external storage device is chosen, be it an old USB 2.0 Flash Drive that's been sitting in a drawer to an 8 TB or more HDD in an eSATA enclosure, it can be used in the capacity of just a storage device. However, there is a nice feature that allows for additional software that acts in conjunction with the basic firmware of the router to be stored on an external storage device. To put it in terms of a computer, the router can be a computer that has two storage devices. One for the Operating System (Firmware in the case of a router) and the other for file storage. But what if the Operating System (AKA firmware) could also reside on an external storage device. With OpenWRT it can.
There are two choice to make in regards to relocating the OS of a router. The first choice, referred to as "Overlay", has part of the OS continuing to reside on the internal Flash Storage with the rest on an external storage device. The second choice, mounting the extenal storage device as the "root filesystem" can move almost all of the OS to the external storage device.
Details on the OpenWRT booting process, overlay, file systems, etc. can be read about at the below links. Don't do any of it yet, just read it for the technical background information;
- File Systems & Summary of Boot Process: https://openwrt.org/docs/techref/filesystems
- Detailed Boot Process: https://openwrt.org/docs/techref/preinit_mount
- Details on Overlay are discussed here ): https://openwrt.org/docs/guide-user/additional-software/extroot_configuration
Both choice offer almost unlimited expansion of the OS, limited only by the size of the storage device(s) connected, with neither offering a performance advantage over the other. The "Overlay" choice is the safer of the two if the external storage device malfunctions. If a malfunction does occur, the router will essentially revert to a "newly flashed" state. This allows for a new external flash drive to be connected and hopefully a backup restoration. The second choice is more dangerous in that any malfunction of the external storage device will result in the router being unresponsive to normal access methods.
Even with the huge (compared to other routers) amount of non-volatile Flash Storage space available on the AC Series of routers, sometimes it isn't enough. There's a total of 128 MB for the AC and ACS, and a whopping (relative to routers) 256 MB available on the WRT3200ACM. But... There's always a "but". Even with the ACM, typically only a single 80 MB partition is readily available. And of that, only about 70 MB is available as free space (half that for the AC and ACS series).
It is possible to access all of the internal Flash Storage space, as described below. But be careful when using it as it could make the router malfunction, be overwritten, etc. The available Flash Memory Storage could certainly have been utilized more efficiently. And don't blame OpenWRT for that. It is Linksys that designed the Flash Memory Storage design into the hardware.
Anyway, there is a nice solution to overcome the storage limitations of the router using a feature called "Overlay". In short, a USB Flash Drive or eSATA drive or mSATA drive (in a USB 3.0 enclosure) can be used instead.
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
Reboot after installing all of the above software.
The above installed sofware provides many new commmands for "disk drives" (Flash Drive, SSD, HDD, etc.), including;
- 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
For a USB Flash Drive or eSATA drive on a router, MBR is absolutely fine. Several programs such as CGDISK (not CFDISK), GDISK, etc., insist on creating a GPT disk without giving the end user a choice. They demand it be done their way. If one is comfortable with being pushed around and forced to do something like that, fine. If not, choose a utility like CFDISK. Is a GPT partitioned drive better? Well, define better. It is newer, has more options, etc., but guess what? It's still a router with a Flash Drive or eSATA drive and MBR is fine. Is GDISK a better program? Well, it is way more powerful and has far more capabilities than CFDISK, so in that respect, yes. But in respect to giving the end user the final choice in what is done? Not so much.
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)
- The items shown as "mtdblockX" are different the different "partitions" for the routers internal Flash Drive (equivalent to a computer's disk drive, OpenWRT refers to it as NAND (Not AND) Flash Memory). These partitions are dictated by the hardware as Linksys designed and layed it out.
- Anything starting with sd (sda, sdb, sdc, etc.) are the USB or eSATA devices connected to the router.
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 (If it isn't installed, use this command: opkg install wipefs
When starting CFDISK, if prompted to "Select label type", it means the Flash Drive or SSD has been initilized back to its most basic state. Choose DOS, which equates to MBR.
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". One oddity after partitioning with CFDISK is that if the same device is viewed in GDISK, that program will complain that a partition table overlaps another one. This is not an issue with the partitioning at all. This is the GDISK program whining that it wasn't left space at the end of the SSD to create room to make the drive a GPT, and then trick other software and computers into thinking it is an MBR disk. That's deceptive and misleading. Use CFDISK, make an MBR based drive, good to go. Done.
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 an External Drive (USB Flash Drive, USB to mSATA) 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 internal non-volatile flash memory (equivalent to a disk drive in the router) is arranged (Note: The WRT1900ACS and WRT3200ACM have slightly different numbering noted below as WRT1900ACS Name and Number / WRT3200ACM Name and Number;
- mtd5 / mtd6 (the first bootable flash memory partition)
- Referred to as ubi with cat /proc/mtd
- Referred to as: rootfs1 in OpenWRT Documentation
- Referred to mtdblock5 / 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)
- mtd7 / mtd8 (the second bootable flash memory partition)
- Referred to as rootfs2 with cat /proc/mtd
- Referred to as: rootfs2 in OpenWRT Documentation
- Referred to mtdblock7 /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)
- mtd8 / 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 mtdblock8 / 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
The WRT3200ACM has an extra partition, mtd4, labeled as sysdiag.
The full memory layout can be found here;
- WRT1900AC: https://openwrt.org/toh/linksys/linksys_wrt1900ac
- WRT1900ACS: https://openwrt.org/toh/linksys/linksys_wrt1900acs
- WRT3200ACM: https://openwrt.org/toh/linksys/linksys_wrt3200acm
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.
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) for a WRT3200ACM, adjust as noted above for the AC or ACS. Also remember that if one of the mtd partitions is already attached an error will occur with the ubiattach command, so just go to the next command;
ubiattach -m 8
mkdir /mnt/mtd8
mount -t ubifs /dev/ubi2_1 /mnt/mtd8
The following will mount the mtb9 / syscfg partition (if it isn't already mounted)
ubiattach -m 9
mkdir /mnt/mtd9
mount -t ubifs /dev/ubi1_0 /mnt/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; };
};
PPTP (Point to Point Tunneling Protocol) for Clients
OpenWRT defines the use of PPTP Clients on the LAN side of a router that wish to connect to a PPTP server via the internet as NAT traversal for PPTP. Default installations of OpenWRT do not have the capability to facilitate PPTP connections by clients. The following software package must be installed;
- opkg update
- opkg install kmod-nf-nathelper-extra
The instructions on enabling the capability is a bit lacking on the OpenWRT site, so below is an improved explanation. After installing the above package, do the following;
- Create a file named 20-nf-conntrack-helper.conf in /etc/sysctl.d: nano /etc/sysctl.d/20n-nf-conntrack-helper.conf
- Add a single line of code in the 20-nf-conntrack-helper.conf file to enable the program: net.netfilter.nf_conntrack_helper = 1
- Save the file: CTRL + O, then exit nano: CTRL + X
- Restart the sysctl service: service sysctl restart
PPTP should now work for clients wishing to use PPTP connections.
As has been mentioned and will continue to be mentioned, it is understandable that the OpenWRT documentation may be lacking in some ways. Creating and writing good documentation is difficult and time consuming. The nice people responsible for OpenWRT spend most of their time making things work, improving functionality, adding new firmware for new routers, etc.. This leaves little time for good documentation. So for all the nice people that work so hard on OpenWRT, thank you. And no offense meant. The rather cryptic several lines written by the author of the below noted article for more information very likely uses that "shortcut" to create files or may have thought it was helpful to present it in that way. And it may work for some people. But it was decided to present it here slightly differently as done above.
More information on enabling the feature can be found here: https://openwrt.org/docs/guide-user/services/vpn/pptp/nat_traversal
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 all the ports a router is listening on: lsof -i -P -n | grep LISTEN (install the package with this command: opkg install lsof)
To see services listening on specific ports: netstat -lnp | grep WhatEverPortNumber
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 - Web Server (Apache, LighttpD, Nginx, and / or uHTTPd) MariaDB (MySQL), and PHP
OpenWRT has four different web server platforms available. Apache, LighttpD, and Nginx are all full featured, whereas uHTTPd is more limited in its functionality. uHTTPd also serves as the web server for the LuCI GUI interface for OpenWRT. Apache does not have CGI or FastCGI built into the binary executable, but both Lighttpd and Nginx have CGI and FastCGI capability built in, making addon modules unecessary.
Apache
The Apache package in OpenWRT appears to only have CGI capability as the FastCGI module is not available. However, there are additional proxy modules included with Apache in OpenWRT that allow for PHP-FPM functionality with FastCGI.
Installation for Apache
opkg update
opkg install apache apache-utils apache-mod-ssl
Configuration for Apache
There is no LuCI GUI interface, so use text configuration files and / or Webmin (see below section on Webmin)
- Initilization Script: /etc/init.d/apache2
- Configuration File: /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
Below is working configuration file for Apache with CGI capability;
ServerRoot "/usr"
Listen 192.168.2.66:80
Listen 192.168.15.66:80
Listen 192.168.22.66:80
Listen 96.77.203.196:80
Listen 76.212.87.51:80
TimeOut 3600
#LoadModule mpm_event_module lib/apache2/mod_mpm_event.so
LoadModule mpm_prefork_module lib/apache2/mod_mpm_prefork.so
#LoadModule mpm_worker_module lib/apache2/mod_mpm_worker.so
LoadModule authn_file_module lib/apache2/mod_authn_file.so
#LoadModule authn_dbm_module lib/apache2/mod_authn_dbm.so
#LoadModule authn_anon_module lib/apache2/mod_authn_anon.so
LoadModule authn_dbd_module lib/apache2/mod_authn_dbd.so
#LoadModule authn_socache_module lib/apache2/mod_authn_socache.so
LoadModule authn_core_module lib/apache2/mod_authn_core.so
LoadModule authz_host_module lib/apache2/mod_authz_host.so
LoadModule authz_groupfile_module lib/apache2/mod_authz_groupfile.so
LoadModule authz_user_module lib/apache2/mod_authz_user.so
#LoadModule authz_dbm_module lib/apache2/mod_authz_dbm.so
#LoadModule authz_owner_module lib/apache2/mod_authz_owner.so
#LoadModule authz_dbd_module lib/apache2/mod_authz_dbd.so
LoadModule authz_core_module lib/apache2/mod_authz_core.so
#LoadModule authnz_ldap_module lib/apache2/mod_authnz_ldap.so
LoadModule access_compat_module lib/apache2/mod_access_compat.so
LoadModule auth_basic_module lib/apache2/mod_auth_basic.so
#LoadModule auth_form_module lib/apache2/mod_auth_form.so
#LoadModule auth_digest_module lib/apache2/mod_auth_digest.so
#LoadModule allowmethods_module lib/apache2/mod_allowmethods.so
#LoadModule file_cache_module lib/apache2/mod_file_cache.so
#LoadModule cache_module lib/apache2/mod_cache.so
#LoadModule cache_disk_module lib/apache2/mod_cache_disk.so
#LoadModule cache_socache_module lib/apache2/mod_cache_socache.so
#LoadModule socache_shmcb_module lib/apache2/mod_socache_shmcb.so
#LoadModule socache_dbm_module lib/apache2/mod_socache_dbm.so
#LoadModule socache_memcache_module lib/apache2/mod_socache_memcache.so
#LoadModule socache_redis_module lib/apache2/mod_socache_redis.so
#LoadModule watchdog_module lib/apache2/mod_watchdog.so
#LoadModule macro_module lib/apache2/mod_macro.so
#LoadModule dbd_module lib/apache2/mod_dbd.so
#LoadModule dumpio_module lib/apache2/mod_dumpio.so
#LoadModule echo_module lib/apache2/mod_echo.so
#LoadModule buffer_module lib/apache2/mod_buffer.so
#LoadModule data_module lib/apache2/mod_data.so
#LoadModule ratelimit_module lib/apache2/mod_ratelimit.so
LoadModule reqtimeout_module lib/apache2/mod_reqtimeout.so
#LoadModule ext_filter_module lib/apache2/mod_ext_filter.so
#LoadModule request_module lib/apache2/mod_request.so
#LoadModule include_module lib/apache2/mod_include.so
LoadModule filter_module lib/apache2/mod_filter.so
#LoadModule reflector_module lib/apache2/mod_reflector.so
#LoadModule substitute_module lib/apache2/mod_substitute.so
#LoadModule sed_module lib/apache2/mod_sed.so
#LoadModule charset_lite_module lib/apache2/mod_charset_lite.so
#LoadModule deflate_module lib/apache2/mod_deflate.so
LoadModule xml2enc_module lib/apache2/mod_xml2enc.so
LoadModule proxy_html_module lib/apache2/mod_proxy_html.so
LoadModule mime_module lib/apache2/mod_mime.so
#LoadModule ldap_module lib/apache2/mod_ldap.so
LoadModule log_config_module lib/apache2/mod_log_config.so
#LoadModule log_debug_module lib/apache2/mod_log_debug.so
#LoadModule log_forensic_module lib/apache2/mod_log_forensic.so
#LoadModule logio_module lib/apache2/mod_logio.so
#LoadModule lua_module lib/apache2/mod_lua.so
LoadModule env_module lib/apache2/mod_env.so
LoadModule mime_magic_module lib/apache2/mod_mime_magic.so
#LoadModule expires_module lib/apache2/mod_expires.so
LoadModule headers_module lib/apache2/mod_headers.so
#LoadModule usertrack_module lib/apache2/mod_usertrack.so
#LoadModule unique_id_module lib/apache2/mod_unique_id.so
LoadModule setenvif_module lib/apache2/mod_setenvif.so
LoadModule version_module lib/apache2/mod_version.so
#LoadModule remoteip_module lib/apache2/mod_remoteip.so
#LoadModule proxy_module lib/apache2/mod_proxy.so
#LoadModule proxy_connect_module lib/apache2/mod_proxy_connect.so
#LoadModule proxy_ftp_module lib/apache2/mod_proxy_ftp.so
#LoadModule proxy_http_module lib/apache2/mod_proxy_http.so
#LoadModule proxy_fcgi_module lib/apache2/mod_proxy_fcgi.so
#LoadModule proxy_scgi_module lib/apache2/mod_proxy_scgi.so
#LoadModule proxy_uwsgi_module lib/apache2/mod_proxy_uwsgi.so
#LoadModule proxy_fdpass_module lib/apache2/mod_proxy_fdpass.so
#LoadModule proxy_wstunnel_module lib/apache2/mod_proxy_wstunnel.so
#LoadModule proxy_ajp_module lib/apache2/mod_proxy_ajp.so
#LoadModule proxy_balancer_module lib/apache2/mod_proxy_balancer.so
#LoadModule proxy_express_module lib/apache2/mod_proxy_express.so
#LoadModule proxy_hcheck_module lib/apache2/mod_proxy_hcheck.so
#LoadModule session_module lib/apache2/mod_session.so
#LoadModule session_cookie_module lib/apache2/mod_session_cookie.so
#LoadModule session_crypto_module lib/apache2/mod_session_crypto.so
#LoadModule session_dbd_module lib/apache2/mod_session_dbd.so
#LoadModule slotmem_shm_module lib/apache2/mod_slotmem_shm.so
#LoadModule slotmem_plain_module lib/apache2/mod_slotmem_plain.so
#LoadModule ssl_module lib/apache2/mod_ssl.so
#LoadModule dialup_module lib/apache2/mod_dialup.so
#LoadModule http2_module lib/apache2/mod_http2.so
#LoadModule md_module lib/apache2/mod_md.so
#LoadModule lbmethod_byrequests_module lib/apache2/mod_lbmethod_byrequests.so
#LoadModule lbmethod_bytraffic_module lib/apache2/mod_lbmethod_bytraffic.so
#LoadModule lbmethod_bybusyness_module lib/apache2/mod_lbmethod_bybusyness.so
#LoadModule lbmethod_heartbeat_module lib/apache2/mod_lbmethod_heartbeat.so
LoadModule unixd_module lib/apache2/mod_unixd.so
#LoadModule heartbeat_module lib/apache2/mod_heartbeat.so
#LoadModule heartmonitor_module lib/apache2/mod_heartmonitor.so
#LoadModule dav_module lib/apache2/mod_dav.so
LoadModule status_module lib/apache2/mod_status.so
LoadModule autoindex_module lib/apache2/mod_autoindex.so
#LoadModule asis_module lib/apache2/mod_asis.so
#LoadModule info_module lib/apache2/mod_info.so
#LoadModule suexec_module lib/apache2/mod_suexec.so
<IfModule !mpm_prefork_module>
#LoadModule cgid_module lib/apache2/mod_cgid.so
</IfModule>
<IfModule mpm_prefork_module>
LoadModule cgi_module lib/apache2/mod_cgi.so
</IfModule>
#LoadModule dav_fs_module lib/apache2/mod_dav_fs.so
#LoadModule dav_lock_module lib/apache2/mod_dav_lock.so
LoadModule vhost_alias_module lib/apache2/mod_vhost_alias.so
#LoadModule negotiation_module lib/apache2/mod_negotiation.so
LoadModule dir_module lib/apache2/mod_dir.so
LoadModule actions_module lib/apache2/mod_actions.so
#LoadModule speling_module lib/apache2/mod_speling.so
#LoadModule userdir_module lib/apache2/mod_userdir.so
LoadModule alias_module lib/apache2/mod_alias.so
LoadModule rewrite_module lib/apache2/mod_rewrite.so
<IfModule unixd_module>
User apache
Group apache
</IfModule>
ServerName wrt3200acm.fullspectrum.lan:80
DocumentRoot "/usr/share/apache2/htdocs"
<Directory "/usr/share/apache2/htdocs">
DirectoryIndex index.php index.html index.htm
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
<Files ".ht*">
Require all denied
</Files>
ErrorLog "/var/log/apache2/error_log"
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog "/var/log/apache2/access_log" common
</IfModule>
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/usr/share/apache2/cgi-bin/"
</IfModule>
<IfModule cgid_module>
Scriptsock /var/run/cgid.sock
</IfModule>
<Directory "/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
<IfModule headers_module>
RequestHeader unset Proxy early
</IfModule>
<IfModule mime_module>
TypesConfig /etc/apache2/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
</IfModule>
MIMEMagicFile /etc/apache2/magic
# Supplemental configuration
#
# The configuration files in the /etc/apache2/extra/ directory can be
# included to add extra features or to modify the default configuration of
# the server, or you may simply copy their contents here and change as
# necessary.
# Server-pool management (MPM specific)
#Include /etc/apache2/extra/httpd-mpm.conf
# Multi-language error messages
#Include /etc/apache2/extra/httpd-multilang-errordoc.conf
# Fancy directory listings
#Include /etc/apache2/extra/httpd-autoindex.conf
# Language settings
#Include /etc/apache2/extra/httpd-languages.conf
# User home directories
#Include /etc/apache2/extra/httpd-userdir.conf
# Real-time info on requests and configuration
#Include /etc/apache2/extra/httpd-info.conf
# Virtual hosts
#Include /etc/apache2/extra/httpd-vhosts.conf
# Local access to the Apache HTTP Server Manual
#Include /etc/apache2/extra/httpd-manual.conf
# Distributed authoring and versioning (WebDAV)
#Include /etc/apache2/extra/httpd-dav.conf
# Various default settings
#Include /etc/apache2/extra/httpd-default.conf
# Configure mod_proxy_html to understand HTML4/XHTML1
<IfModule proxy_html_module>
Include /etc/apache2/extra/proxy-html.conf
</IfModule>
# Secure (SSL/TLS) connections
#Include /etc/apache2/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
<Files ".user.ini">
<IfModule mod_authz_core_module>
Require all denied
</IfModule>
<IfModule !mod_authz_core_module>
Order allow,deny
Deny from all
Satisfy All
</IfModule>
</Files>
<IfModule alias_module>
ScriptAlias /php /usr/bin
</IfModule>
# Either the AddType or AddHandler Directive can be used
# AddType application/x-httpd-php .php
AddHandler application/x-httpd-php .php
Action application/x-httpd-php /php/php-cgi
<Directory "/usr/bin">
AllowOverride None
Options none
Order allow,deny
Allow from all
</Directory>
<Directory "/usr/share/apache2/htdocs/phpMyAdmin">
AllowOverride All
Options none
Order allow,deny
Allow from all
</Directory>
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
The above configuration file also includes settings for PHP and CGI.
Also make sure the following lines exist or are not commented out in the /etc/apache2/apache2.conf file for CGI functionality;
LoadModule mpm_prefork_module lib/apache2/mod_mpm_prefork.so
LoadModule cgi_module lib/apache2/mod_cgi.so
ScriptAlias /cgi-bin /usr/share/apache2/cgi-bin
<Directory /cgi-bin>
AllowOverride None
Options None
Require all granted
</Directory>
Set permissions for the Apache document 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 {} \;
Notes for Apache
In other installations, such as Redhat or CentOS, apache or apache2 is referred to as HTTPD in binary / executables, configuration files, commands, etc.
To test Apache configuration file: apachectl configtest
The below settings 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
In the OpenWRT packages Lighttpd has CGI and FastCGI capability unlike Apache which only has CGI capability. OpenWRT has PHP 7 packages for CGI and FastCGI (opkg install php7-fastcgi) available to make use of the Lighttpd capabilities. The FastCGI capability also allows Lighttpd to utilize the PHP FPM capbability covered in several sections below.
Installation of Lighttpd
opkg update
opkg install lighttpd lighttpd-mod-cgi lighthttpd-mod-fastcgi
Configuration of Lighttpd
Configuration Files: /etc/lighttpd/lighttpd.conf
Additional Configuration Files: /etc/lighttpd/conf.d (see PHP sections below for additional information)
Service Command: service lighttpd (stop / start / restart)
Be Aware;
- The OpenWRT Lighttpd package sets the default document directory to the same directory used by uHTTPd (the web service that provides the LuCI GUI). It is recommended modify the setting to a directory such as /usr/share/lighttpd (which follows the Apache directory convention used by OpenWRT).
- The port number is set to 81 by default. This is done so as to not interfere with uHTTPd and LuCI. This can be changed to port 80, but the uHTTPd port must be changed to a different (non port 80) port in /etc/config/uhttpd and the uhttpd service restarted.
Below is a working /etc/lighttpd/lighttpd.conf configuration file;
server.document-root = "/usr/share/lighttpd"
server.port = 80
server.upload-dirs = ( "/tmp" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "http"
server.groupname = "www-data"
index-file.names = ( "index.php", "index.html",
"index.htm", "default.htm",
)
#dir-listing.activate = "enable"
#server.dir-listing = "enable"
#dir-listing.encoding = "utf-8"
# Prevents a web browser from offering to download the file in text form
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
# To enable PHP with the Lighttpd Module, this line is the minimum necessary for it to function and should be placed in the /etc/lighttpd/conf.d/30-cgi.conf file;
# cgi.assign = ( ".php" => "/usr/bin/php-cgi" )
### Options that are useful but not always necessary:
#server.chroot = "/"
#server.bind = "localhost"
#server.tag = "lighttpd"
#server.errorlog-use-syslog = "enable"
#server.network-backend = "writev"
### Use IPv6 if available
#include_shell "/usr/share/lighttpd/use-ipv6.pl"
include "/etc/lighttpd/mime.conf"
include "/etc/lighttpd/conf.d/*.conf"
The above configuration file also contains settings relevant to additional items such as CGI and PHP which is covered in several below sections.
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 {} \;
Notes for Lighttpd
To see the various modules compiled within the Lighttpd binary: lighttpd -V (that's a CAPITAL "V")
CGI and FastCGI
See the below PHP section for Lighttpd
php-cgi -b 127.0.0.1:9123
PHP
First the bad news (which really isn't bad news): The mod_php module is not available for Apache. But that's OK, because there are several Apache Proxy Modules and PHP Modules that allow for PHP functionality with Apache using CGI, FastCGI, and PHP-FPM (see below for several external links that discuss the differences between the technologies).
The php-cgi (opkg install php7-cgi) package is available from OpenWRT and is necessary for PHP function with any of the above mentioned web servers. 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 or its documentation.
PHP Installation
opkg update
opkg install php7 php7-cgi php7-cli php7-fastcgi php7-fpm The php-cli (PHP Command Line) is not necessary, but is useful for troubleshooting. Most examples utilizing the PHP command line program refer to it as just php, not php-cli. OpenWRT installs it as php-cli, so instead of having to remember that, it maybe useful to create a symbolic link with this command: ln -s /usr/bin/php-cli /usr/bin/php
PHP Configuration in /etc/php.ini
Comment out or change the line in /etc/php.ini;
- doc_root
OR
- #doc_root = WhatEver
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 is unnecessary;
- extension=gd.so
OR
- extension=/usr/lib/php/gd.so
If the php7-mod-gd (opkg install php7-mod-gd) is installed, then the gd.so extension may be useful. It is related to graphics. And it isn't necessary to add that setting after the php7-mod-gd is installed, because when the package is installed it includes the /etc/php7/20_gd.ini file. The OpenWRT PHP binary / executable file is configured to automatically scan that directory for additional php module settings (-config-file-scan-dir=/etc/php7' is the included setting).
PHP Configuration for CGI
There are no specific settings for a "PHP CGI Service" as there are for the FastCGI PHP and PHP-FPM services. There are additional settings needed for Apache, Lighttpd, or Nginx to execute PHP scripts with their CGI capability (see below sections)
PHP FastCGI
The php7-mod-fastcgi is configured as a service named php7-fastcgi and configured in /etc/config/php7-fastcgi. There are only two settings. One that enables the service and the other that sets the listening port (port 1026).
PHP-FPM
Additional Information about CGI, FastCGI, and PHP-FPM
CGI (Common Gateway Interface), FastCGI (Fast Common Gateway Interface), and PHP-FPM are different methods that each of the web servers included with OpenWRT can handle PHP script files. CGI is the oldest, easisest to setup, and slowest (although in low load environments, it will suffice). FastCGI and PHP-FPM require additional software packages and configuration.
Below are a couple of websites that discuss the differences, advantages, etc. of each technolgy;
- https://blog.layershift.com/which-php-mode-apache-vs-cgi-vs-fastcgi/
- https://serverfault.com/questions/645755/differences-and-dis-advanages-between-fast-cgi-cgi-mod-php-suphp-php-fpm
- Not very well written, but does address all technologies: https://aleen42.github.io/PersonalWiki/qa/cgi_difference.html
PHP for Apache
Installing and Configuring Apache for PHP using CGI
Configuration Files;
- Apache: /etc/apache2/apache2.conf
- Apache Optional: /etc/apache2/extra/WhatEverAdditionalFile.conf
- Useful in optimizing performance: httpd-mpm.conf (for more information see https://en.wikipedia.org/wiki/List_of_Apache_modules)
- Useful in
- PHP: /etc/php.ini and /etc/php7
- PHP CGI: NONE
Service Commands;
- service apache2 (stop / start / restart / reload)
Add and make sure the following settings exist in /etc/apache2/apache2.conf;
# When using PHP with "plain" CGI, the mpm_event_module must be disabled in favor of the mpm_prefork_module. The mpm_event_module is utilized with php-fpm.
#LoadModule mpm_event_module lib/apache2/mod_mpm_event.so
LoadModule mpm_prefork_module lib/apache2/mod_mpm_prefork.so
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
# Choose / Uncomment either the above or below setting. They are functionally equivalent.
# AddType application/x-httpd-php .php
Action application/x-httpd-php /php/php-cgi
The above configuration settings are not the only ones that should be present in the /etc/apache2/apache2.conf file. They are only related to PHP functionality with CGI and are in addition to a functional apache.conf file that contains <Directory> and <VirtualHost> Directives along with other settings that allow for static .htm or .html files made available by Apache.
Notes on PHP for Apache and CGI
The cgi_module is necessary for for Apache to utilize the PHP binary / executable php-cgi file (the program that makes PHP function).
In addition to the similar functionality it shares with the Alias Directive, the ScriptAlias Directive designates the directory alias as containing PHP files that will be handled by CGI.
As noted in the comments in the above Code Block, either the AddHandler or AddType Directive can be used to configure what Apache does with files that end with the .php extension. 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>
PHP for Lighttpd
Installing and Configuring Lighttpd for PHP using CGI (see FastCGI below too)
The lighttpd, lighttpd-mod-cgi, php7, and php7-cgi packages should be installed as noted above in the Lighttpd and PHP Installation Sections.
Configuration Files;
- Lightttpd: /etc/lighttpd/lighttpd.conf
- Lighttpd CGI: /etc/lighttpd/conf.d/30-cgi.conf
- PHP: /etc/php.ini and /etc/php7
- PHP CGI: NONE
Service Commands;
- service lighttpd (stop / start / restart)
Remember, the configuration file OpenWRT creates for CGI settings is /etc/lighttpd/conf.d/30-cgi.conf, not /etc/lighttpd/lighttpd.conf. It can be configured in the lighttpd.conf file, but to adhere to the OpenWRT convention it is recommended to place it in the 30-cgi.conf file.
Only the following lines are needed in the /etc/lighttpd/conf.d/30-cgi.conf ".php" => "/usr/bin/php-cgi", see example below;
server.modules += ( "mod_cgi" )
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" )
The instructions also note the following setting be configured in the /etc/php.ini file, but it is already enabled by default in the OpenWRT php7 package: cgi.fix_pathinfo = 1
The remaining lines in the default configuration file are related to the default document directory chosen by OpenWRT for the Lighttpd installation. As recommended earlier, unless there are limited hardware resources available for a router, the location should be changed, thus negating the need for the additional settings.
Notes on PHP for Lighttpd and CGI
/usr/bin/php-cgi (with a bit of foreshadowing): The php-cgi binary / executable included with the php7-cgi OpenWRT package also includes FastCGI functionality. The php7-fastcgi package does not contain an additional binary. When installed, the php7-cgi package creates a symbolic link named /usr/bin/php-fcgi that points to the php-cgi file in the same directory. Additionally, a configuration file is inluded in /etc/config/php7-fastcgi package that enables FastCGI functionality. Type the following command to view the modules /usr/bin/php-cgi has available: php-cgi -m (this includes modules compiled in the php-cgi executable / binary file as well as added modules that are in separate files).
The instructions at https://openwrt.org/docs/guide-user/services/webserver/lamp#lighttpd1 indicate the above configuration is added to the /etc/lighttpd/lighttpd.conf file, but as noted, the /etc/lighttpd/conf.d/30-cgi.conf is the correct location for the AC Series of routers. If the instructions are followed it will cause a "Validation failed" error when starting the Lighttpd service because of two cgi.assign statements, as it is already present in the 30-cfi.conf file. It is possible the instructions are old or written for a different router platform, or the CGI configuration was separated and put into a different file at a later point.
Installing and Configuring Lighttpd for PHP using FastCGI
The lighttpd, lighttpd-mod-cgi, lighttpd-mod-fastcgi, php7, php7-cgi, and php7-fcgi packages should be installed as noted above in the Lighttpd and PHP Installation Sections.
Configuration Files;
- Lightttpd: /etc/lighttpd/lighttpd.conf
- Lighttpd FastCGI: /etc/lighttpd/conf.d/30-fastcgi.conf
- PHP: /etc/php.ini and /etc/php7
- PHP FastCGI: /etc/config/php7-fastcgi
Service Commands;
- service lighttpd (stop / start / restart)
- service php7-fastcgi (stop / start / restart)
Verify the following settings in the /etc/lighttpd/conf.d/30-fastcgi.conf file; and remove the comment hash tag (#) to enable them;
fastcgi.server = ( ".php" =>
# Be careful: lighty does *not* warn you if it doesn't know a specified option here (make sure you have no typos)
((
#
# To enable FastCGI PHP functionality, enable the below host and port settings (default port for FastCGI is 1026)
#"host" => "127.0.0.1" ,
#"port" => "1026" ,
#
#
# To use FPM, disable the above host and port and enable either the port or socket method below (only one)
#
# Socket Method
"socket" => "/var/run/php7-fpm.sock", # either socket or host+port
#
# Port Method (default port for PHP-FPM is 9000)
#"host" => "127.0.0.1" ,
#"port" => "9000" ,
#
# Which to use (Port or Socke)?
# Research indicates there is less overhead associated with a socket. A disadvantage for using a socket instead of a port is functionality is limited to a local server with some potential issues that occur with high usage situation. A Port is also technically noted to be a type of socket with a disadvantage of slightly higher overhead and potential exhaustion of usable TCP ports.
#
#"bin-path" => "/usr/bin/php-fpm", # 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)
))
)
fastcgi.map-extensions = ( ".php3" => ".php",
".php4" => ".php",
".php5" => ".php",
".phps" => ".php",
".phtml" => ".php" )
The above example includes comments and settings related to PHP FPM (see below). And remember, most examples given by OpenWRT note the above settings in /etc/lighttpd/lighttpd.conf file, but that is not the case for the AC series of routers. An more detailed explanation of the above settings can be found here: https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI If additional FastCGI extensions other than .php, such as .php3, .php4, etc ensure the following items are configured in /etc/lighttpd/conf.d/30-fastcgi.conf;
fastcgi.map-extensions = ( ".php3" => ".php",
".php4" => ".php",
".php5" => ".php",
".phps" => ".php",
".phtml" => ".php" )
And finally, in order to ensure FastCGI is handling the PHP calls, disable or delete the /etc/lighttpd/conf.d/30-cgi.conf file.
Notes on PHP for Lighttpd and FastCGI
As noted above, if CGI (not FastCGI) is left enabled and everything is left in the default configuration order supplied by OpenWRT, the CGI interface will intercept PHP files before FastCGI. And as noted, the solution is to 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. Why did OpenWRT not name it this way in the first place? Not sure, but it seems like it might be a good idea to change it at some point.
/usr/bin/php-cgi (with a bit of foreshadowing): The php-cgi binary / executable included with the php7-cgi OpenWRT package also includes FastCGI functionality. The php7-fastcgi package does not contain an additional binary. When installed, the php7-cgi package creates a symbolic link named /usr/bin/php-fcgi that points to the php-cgi file in the same directory. Additionally, a configuration file is inluded in /etc/config/php7-fastcgi package that enables FastCGI functionality. Type the following command to view the modules /usr/bin/php-cgi has available: php-cgi -m (this includes modules compiled in the php-cgi executable / binary file as well as added modules that are in separate files).
There does not seem to be a good way to verify whether CGI or FastCGI are handling PHP functionality for Lighttpd. Adding the single line of: <?php phpinfo(); ?> into a file named "info.php" will return an abundant amount of information including a line that states: Server API: CGI/FastCGI, whether using CGI or FastCGI, so it isn't very helpful. A method to confirm FastCGI is being used instead of CGI would be to disable or delete the /etc/lighttpd/conf.d/30-cgi.conf file.
Installing and Configuring Lighttpd for PHP using FPM (which relies on FastCGI)
The lighttpd, lighttpd-mod-cgi, lighttpd-mod-fastcgi, php7, php7-cgi, php7-fcgi, and php-fpm packages should be installed as noted above in the Lighttpd and PHP Installation Sections.
Configuration Files;
- Lightttpd: /etc/lighttpd/lighttpd.conf
- Lighttpd FastCGI: /etc/lighttpd/conf.d/30-fastcgi.conf
- PHP: /etc/php.ini and /etc/php7
- PHP FastCGI: /etc/config/php7-fastcgi
- PHP FPM: /etc/config/php7-fpm, /etc/php7-fpm.conf, and /etc/php7-fpm.d
Service Commands;
- service lighttpd (stop / start / restart)
- service php7-fastcgi (stop / start / restart)
- service php7-fpm (stop / start / restart)
Modify the settings in /etc/php7-fpm.d/www.conf as follows;
; A Port or Socket can be defined for the php7-fpm Service (only choose one)
; And remember to change the settings in the Lighttpd 30-fastcgi.conf file depending on which choice is made.
;
; Port
; listen = 127.0.0.1:9000
;
; Socket
listen = /var/run/php7-fpm.sock
; If the Socket method above is chosen, the following items must also be set, otherwise a "Permission denied socket" error will occur when the php7-fpm service is started.
listen.owner = http
listen.group = www-data
listen.mode = 0666
Do not make the mistake of using hash tags ( # ) for comments as they will prevent the php7-fpm service from running. Modify the settings in /etc/lighttpd/conf.d/30-fastcgi.conf noted in the above section as follows;
#"host" => "127.0.0.1" ,
#"port" => "1026" ,
"socket" => "/var/run/php7-fpm.sock",
Notes on PHP for Lighttpd and FPM (with FastCGI)
Make sure FastCGI is functioning correctly before FPM is added and configured. Adding the single line of: <?php phpinfo(); ?> into a file named "info.php" will now include useful information about what service is handling PHP requests: Server API: FPM/FastCGI
Additional Information about PHP with CGI VS PHP with FastCGI VS PHP with FPM can be found here;
- https://www.basezap.com/difference-php-cgi-php-fpm/
- https://serverfault.com/questions/645755/differences-and-dis-advanages-between-fast-cgi-cgi-mod-php-suphp-php-fpm
Testing PHP Functionality
Create and save a PHP file (test.php) with this single line of code in it: <?php phpinfo(); ?>
PHP functionality can be tested with that file;
- From a command line type the following: php-cgi /WhatEverPath/test.php
- Place the file in a directory served by Apache (/usr/share/apache2/htdocs) and navigate to that file
As noted previously, but worth mentioning again, OpenWRT names the interactive command line interface for PHP php-cli. Most sites give examples that use the command php, so to make it easier create a symbolic link with this command: ln -s /usr/bin/php-cli /usr/bin/php
MariaDB Server
Installing
- 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
- Modify the following items in the /etc/mysql/50-server.cnf file;
- Use the ARIA database engine instead of the default InnoDB to streamline RAM usage in the [mysqld] category of the file: default-storage-engine = aria (after finishing configuration, check at the MySQL command prompt with this command: SHOW ENGINES;
- Move the database to an external eSATA drive: datadir = /mnt/sdb3/mysql
- Move the tmp directory to an external eSATA drive: datadir = /tmp (This directory is relative to the datadir, in that it will be created at the same level as the mysql directory, so this is not an abolute path where it will utilize the /tmp directory in the root of the file system)
- 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 or use phpMyAdmin see below
Optimizing for a Low Memory Footprint with the ARIA Engine
from: https://mariadb.com/kb/en/mariadb-memory-allocation/
Importing and Migrating Data from Other SQL Servers
To take advantage of the ARIA database engine, any databases imported should not have any information about engine="WhatEverDBengine". If they do, the database engine defined for each table will be used. If they do not have any information about which engine is assigned to a database, the default engine for the database server will be used. Use the below command to export a .sql database file (no method appears to be available with phpMyAdmin to export a database without the engine information included);
- mysqldump -u root -p --skip-create-options WhatEverDatabaseName > WhatEverDatabaseFile.sql;
- If using phpMyAdmin to import the database note the following
- It is far slower and far more resource intensive (on the order of about 25 times) than using the command line to import a database.
- For Apache web servers, when importing large databases, the TimeOut Directive should be set to a higher value to avoid a "Gateway Timeout" error. The default is 60 seconds.
- This setting in the phpMyAdmin configuration file, config.inc.php, can be set too, but isn't necessary: $cfg['ExecTimeLimit'] = 3600;
- Alternatively, use this command to import a database via the command line: mysql -u root -p WhatEverDatabaseName < /PathTo/DatabaseFile
General Information
Default database location: /mnt/data/mysql/ Default TEMP directory: /tmp Default database engine: InnoDB
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).
Make sure the /usr/share/apache2/htdocs/phpMyAdmin/tmp has 777 permissions, otherwise Apache based phpMyAdmin sites may stop responding: chmod 777 /usr/share/apache2/htdocs/phpMyAdmin/tmp
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
OS Choices available when installing Webmin: Pick 110) Geric Linux for OpenWRT
1) Pardus Linux 2) SmartOS 3) Sun Solaris
4) Lycoris Desktop/LX 5) Caldera OpenLinux eS 6) Caldera OpenLinux
7) Asianux Server 8) Asianux 9) Whitebox Linux
10) Tao Linux 11) CentOS Linux 12) Springdale Linux
13) Virtuozzo Linux 14) Scientific Linux 15) Gralinux
16) NeoShine Linux 17) Endian Firewall Linu 18) Oracle Enterprise Li
19) Oracle Linux 20) Oracle VM 21) XenServer Linux
22) CloudLinux 23) MostlyLinux 24) Cloudrouter Linux
25) Sangoma Linux 26) Citrix Hypervisor 27) Redhat Enterprise Li
28) Redhat Linux Desktop 29) AlphaCore Linux 30) X/OS Linux
31) Haansoft Linux 32) cAos Linux 33) Wind River Linux
34) Amazon Linux 35) Redhat Linux 36) Fedora Linux
37) White Dwarf Linux 38) Slamd64 Linux 39) Slackware Linux
40) Xandros Linux 41) APLINUX 42) BigBlock
43) Ubuntu Linux 44) Mepis Linux 45) Devuan Linux
46) Raspbian Linux 47) Linux Mint 48) Debian Linux
49) SuSE OpenExchange Li 50) SuSE SLES Linux 51) SuSE Linux
52) United Linux 53) Corel Linux 54) TurboLinux
55) Cobalt Linux 56) Mandrake Linux Corpo 57) pclinuxos Linux
58) Mageia Linux 59) Mandrake Linux 60) Mandriva Linux
61) Mandriva Linux Enter 62) Conectiva Linux 63) ThizLinux Desktop
64) ThizServer 65) MSC Linux 66) SCI Linux
67) LinuxPPC 68) Trustix SE 69) Trustix
70) Tawie Server Linux 71) TinySofa Linux 72) Cendio LBS Linux
73) Ute Linux 74) Lanthan Linux 75) Yellow Dog Linux
76) Corvus Latinux 77) Immunix Linux 78) Gentoo Linux
79) Secure Linux 80) OpenNA Linux 81) SoL Linux
82) Coherent Technology 83) Playstation Linux 84) StartCom Linux
85) Yoper Linux 86) Caixa Magica 87) openmamba Linux
88) FreeBSD 89) DragonFly BSD 90) OpenBSD
91) NetBSD 92) BSDI 93) HP/UX
94) SGI Irix 95) DEC/Compaq OSF/1 96) IBM AIX
97) SCO UnixWare 98) SCO OpenServer 99) macOS Catalina
100) macOS Mojave 101) macOS High Sierra 102) macOS Sierra
103) OS X 104) Mac OS X 105) Darwin
106) OpenDarwin 107) Cygwin 108) Sun Java Desktop Sys
109) Synology DSM 110) Generic Linux 111) Windows
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;
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