* 13 May 2021
Broke my initial build due to a sys upgrade then re did all of below. Not sure what caused the problem. The main blockage I experienced is the expanding of the second partion, see here for the update.
* 18 April 2021
More or less complete by now, any updates or workarounds I will just keep on adding here
* 13-16 April 2021
Content for this post is still in progress as I'm compiling all the workarounds, fixes and commands for all this to work
OpenWrt is meant as an "embedded operating systems based on Linux" and using it for the goals I highlighted below is not as simple as using Ubuntu or CentOS. And still, OpenWrt is quite amazing at what it does.
- To have a router + ads blocker (similar to pi-hole)
- To be able to connect via wifi, use my mobile phone with ads block by default
- To have a wordpress multisite environment
- Having this as an external server is better so that it would not eat my local resources. I was using devilbox and it takes 4GB++ of ram.
- Portable, of course, with the Pi I should be able to move from office and home
I almost read every information related to the tools listed and until now I'm still encountering weird things along the way. As problems arise I just put my mindset to be more patient. This page said "From now on, you're on your own..." which did stick in my mind in the days grinding for solutions per problem.
So keep in mind, OpenWrt is not as easy to work with compared to Ubuntu or CentOS. With that in mind
I still hope this page would help you on your adventure.
Do multiple tests
Every update you do, please do test by doing a servive {ur-service} reload
and a full reboot. From there you would know if the updated settings in either luci or SSH does work.
Always check if the service is running, if not then read the errors. You need to do lots of trial-and-error plus deep reading on how a certian package work (can check the package readme or package repo), maybe a package has dependency or maybe the package is not compiled for arm cpu (which raspberry pi does use). Lots of things to check which would test your patience.
Below are the hardware I do have
- Raspberry Pi 4 Model B 8GB BCM2711 Quad core Cortex-A72
- USB3 Ethernet Adapter (Vention brand, i think any brand would do)
- SanDisk Extreme 64GB
- 2x Ethernet cable (1 for lan, 1 for wan)
- microSD card reader (used to flash/install OpenWrt)
- I use Raspberry Pi Imager from raspberrypi.org here to flash the SD Card
- The OpenWrt build I used is from here https://github.com/wulfy23/rpi4/tree/master/builds/
I would not go into step by step on how to flash OpenWrt into the microSD since there are lots of tutorials for that.
Default lan IP Address for luci is 192.168.1.1
I did change the default to 192.168.7.1 (can be anything) to avoid conflict with the main router
- Edit
/etc/config/network
change from 192.168.1.1 to 192.168.7.1 - Run
/etc/init.d/network restart
I needed to have internet via wan which would use the USB3 Ethernet Adapter. In Luci > Interfaces,
- I did not touch the default LAN interface
- I added a new "WAN" interface with
- Name: WAN
- Protocol: DHCP client
- Interface: eth1
- Firewall Settings > Create / Assign firewall-zone: wan
Wireless
For wireless to work I need to follow the comment in this page
wulfy23
This is the main glaringly obvious wifi alteration... so you could try remove wpad-openssl and put back plain wpad
Do a reboot and check if Wireless page in luci does show the wifi is enabled or you can enable it there.
Initially adblock package was working without any setup. I just enabled it via luci. After more than two days I noticed that it is not working and I did the following
opkg update
opkg remove libustream-openssl20201210
opkg install libustream-mbedtls20201210
service adblock enable
service adblock start
/etc/init.d/adblock status
I'm still not sure why adblock does not start in my initial test after removing/installing libustream, i needed to do this three times before it did work. I did a couple of reboots to make sure that my setup for adblock works fully.
Currently I have the following in luci
- Blocked Domains: 500K+
- Startup Trigger Interface: wan
I did try to use simple-adblock after having issues with adblock. It is installed by default and the only command I did run is
opkg update
opkg --force-overwrite install gawk grep sed coreutils-sort
Then I enables and started the service via luci here http://{ur.openwrt.ip.addr}/cgi-bin/luci/admin/services/simple-adblock
Do take note that when you reboot there is a delay of 120 seconds (default) before simple-adblock would start. This is the only drawback I noticed with simple-adblock other than this it is preferably simple than adblock.
One of the hardest thing for me to accomplish is expanding the OpenWrt's second partition (ext4) to use the full 64GB of my microSD card.
I'm using macos and I did try using VirtualBox to detect the microSD and failed. When I tried to use Parallels (trial version) then booted GParted it was able to detect and expand the second partition of the microSD card.
Mainly, GParted is heaven sent but you need to find a way to boot it then detect the microSD card (with OpenWrt installed already), with this you should be able to expand the second partition.
Update, 13 May 2021
Expanding the second partion (ext4) does breaks the OpenWrt installed in the SD Card, tested this more than 5 times with lots of scenarios with the hope to find the problem.
The only solution I did do is to use an external thumb drive to be able to have more space.
This development environment is mainly focused on getting Wordpress to work well.
Initially I was focused on apache2+php7 but after I read this post and found that libphp7.so did not have an OpenWrt or an Arm Cortext 72 build while nginx is completely supported, I quickly tried to work with Nginx regardless of me not having any experience using it.
Before installing Nginx, I updated the Luci to not use the default port 80. To do this just edit /etc/config/uhttpd then update the port like below
config uhttpd 'main'
list listen_http '0.0.0.0:801'
list listen_http '[::]:801'
list listen_https '0.0.0.0:4431'
list listen_https '[::]:4431'
Now I could have Nginx take the default port 80.
$ opkg update
$ opkg install nginx
$ nginx -v
nginx version: nginx/1.19.6 (x86_64-pc-linux-gnu)
$ service nginx start # /etc/init.d/nginx start #can be used also
Make sure to use /etc/nginx/nginx.conf
uci set nginx.global.uci_enable=false
uci commit
service nginx reload
Let's double check /etc/config/nginx by running cat /etc/config/nginx
# /etc/config/nginx
config main 'global'
option uci_enable 'false'
Here is a sample of my /etc/nginx/nginx.conf
Do take note that I do not use httpS on this development environment.
I also learned a lot from the Nginx webserver guide. It is worth knowing how Nginx works in OpenWrt, mix that with non-OpenWrt Nginx tutorials and you should be able to configure it the way you needed.
$ opkg update
$ opkg install php7 php7-cgi php7-cli php7-fastcgi php7-fpm php7-mod-mysqli php7-mod-pdo php7-mod-pdo-mysql
$ php-cli --version
PHP 7.4.16 (cli) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
Here are the PHP modules that was required for some of the wordpress plugins I used
php7-mod-filter
php7-mod-ctype
php7-mod-pdo
php7-mod-pdo-mysql
php7-mod-pdo-sqlite
php7-mod-gd
php7-mod-mbstring
php7-mod-gettext
php7-mod-dom
php7-mod-simplexml
# just install any module depending on your needs
Here is my /etc/php.ini
I failed to run mariadb inside OpenWrt which I looked for alternative which is SQLite. The good thing about SQLite is that it has no heavy dependency with other libraries plus it is super light.
$ opkg update
$ opkg install sqlite3-cli
$ sqlite3 --version
3.33.0 ...
Import mysql database to SQLite
Since I already have a wordpress multisite installed in my localhost now I needed to export then import the database inside SQLite.
- Do backup your all your localhost databases
- Use Search Replace DB to search/replace all ".localhost" to ".lan" (I do this inside my mac since Search-Replace-DB did not work inside OpenWrt)
- Dump the "ready for .lan" localhost database then copy to OpenWrt's /webdev/wpms/wp-content/database (I did this with nfsd)
- To import to SQLite I needed to use mysql2sqlite
- Below is to make mysql2sqlite executable, read the sql files, lastly let sqlite3 create a new database
chmod +x mysql2sqlite
./mysql2sqlite wordpress_localhost_mysqldump.sql | sqlite3 sample.db
mv sample.db .ht.sqlite
There are lots of weird problems when the sqlite database does not have the right permission.
Update all permissions using chmod -R 777 /webdev
Manual search and replace in SQLite database
If you just need to do a manual search and replace in the database. I use adminer
UPDATE wp_options SET option_value = replace(option_value, 'yoursitename.localhost', 'yoursitename.lan') WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE wp_posts SET post_content = replace(post_content, 'yoursitename.localhost', 'yoursitename.lan');
UPDATE wp_postmeta SET meta_value = replace(meta_value, 'yoursitename.localhost', 'yoursitename.lan');
Wordpress does not support SQLite natively and we need to use wp-sqlite-db
- Download db.php
- Move db.php to /webdev/wpms/wp-content/db.php
Just a reference, here is my wp-config.php
// Since we are using sqlite, no need for database permission
define( 'DB_NAME', '' );
define( 'DB_USER', '' );
define( 'DB_PASSWORD', '' );
define( 'DB_HOST', '127.0.0.1' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
/* That's all, stop editing! Happy publishing. */
define('DOMAIN_CURRENT_SITE', 'wpms.lan');
Wordpress Multisite subfolders
This took me a day to figure out since I do lack experience in Nginx. If you can make my nginx.conf better in the comments, I would really appreciate that.
The following code blocks are the most important sections in my nginx.conf
- map_hash_* and map $http_host $blogid
- This requires Nginx Helper wordpress plugin to be installed
- In the plugin, you need to Network Activate then in /wp-admin/network/settings.php?page=nginx check Enable Nginx Map.
- server locations
MacOS zip to OpenWrt
Whenever I copy a zip file then extract it inside OpenWrt there would be "._" files. These files may cause problem with either PHP or Wordpress. So to delete them I would run
cd /webdev
find . -name "._*" -exec rm '{}' \; -print
In my computer I just need to make sure that wpms.lan is mapped to OpenWrt's IP Address
{ur.openwrt.ip.addr} wpms.lan
We need access to /webdev for us to read/write to files.
Inside OpenWrt's /etc/exports
add the ip address of your computer.
/mnt *(ro,all_squash,insecure,sync)
/webdev ur.computer.ip.addr(rw,sync)
/webdev another.computer.ip.addr(rw,sync)
You can make ip address static via luci so that it would not change just in case.
Enable and start nfsd
$ service nfsd enable && service nfsd start
In my case since I use mac, I mount nfs by running
# mount OpenWrt's /webdev in mac
sudo mount -t nfs -o resvport {ur.openwrt.ip.addr}:/webdev /private/nfs
Thanks to the people who contributed to each content below. They did ease the problems and solutions along the way
- https://www.youtube.com/watch?v=TsOpO6O4xDE - A good how to on setting up WAN and LAN interfaces
- https://forum.openwrt.org/t/rpi4-community-build/69998 - The openwrt build used
- https://forum.openwrt.org/t/rpi4-step-by-step-set-up-please-help/75184/8 - Thanks to stargeizer for the step by step
- https://openwrt.org/docs/guide-user/services/nas/nfs_configuration
- https://www.wdiaz.org/how-to-mount-nfs-share-on-mac/
- https://gist.github.com/pansila/f96337680a154658bd8bac026cb07cf5 - I did not use or run this script, mainly read it as reference