kls0e hi :-)

How to host a (small) website on your Freifunk node

Due to the versatility of OpenWrt, being a fully equipped Linux distribution itself, there are all tools already installed on your Freifunk node that are required turn it into a small web server. In fact its web gui LuCI is a website served by the node already. I suggest starting with static html+css and I can recommend Hugo as a Framework to generate it. So let’s use the existing infrastructure to host our own website:

selecting the best storage option for your webroot

  1. First think about where you would like to store your web files aka your webroot. This can be anywhere accessible by your nodes’ file system. Essentially, we have three options: ramdisk, external usb storage and router flash memory.
    Check out your options and the free available space with its corresponding mount points with df -h.

  2. I decided to use the routers’ ramdisk, already available at /tmp using tmpfs. If you have a device with at least 128 MB of RAM and your website is not too large, I think this is a good way to go since ram is blazing fast and tmpfs size is configured as 50% spare by default, i.e. it grows with the content it holds, up to a size of 64 MB. Rest of RAM is available to the system.
    As we know, RAM gets zapped on every boot so I set up a small script to run with /etc/rc.local. The script pulls a tarball using wget every time the router boots and extracts it to /tmp/wwwroot which is the path to my webroot.
    Of course you can also mount external usb storage and use it as a webroot, it will be slower than tmpfs but persistent. Although technically possible, I would not use the routers’ own flash chips to store a webroot if the device has NOR flash because there might be no error correction and the blocks wear out after a certain amount of write cycles.
    If your device sports a NAND flash chip, such as the Fritzbox 3370 or the GL.iNet AR-300-M, using NAND as webroot is fine.

configuring the webserver

  1. Let’s use uhttpd, which already serves LuCI on your freifunk node, as the webserver. It actually performs very well. Edit the config at /etc/config/uhttpd:

Just copy the config uhttpd ‘main’ block, insert it at the end of the file and rename the new section. also adjust the path at home to your webroot, raise max_requests and max_connections a bit and, if you want to leave LuCI enabled, choose some other ports for the listen_http and listen_https entries.
Here’s my sample config:

config uhttpd 'kls0e'                      
        list listen_http '0.0.0.0:10178'   
        list listen_http '[::]:10178'      
        list listen_https '0.0.0.0:10785'  
        list listen_https '[::]:10785'     
        option home '/tmp/wwwroot'
        option max_requests '48'                
        option max_connections '400'            
        option cert '/etc/uhttpd.crt'           
        option key '/etc/uhttpd.key'            
        option cgi_prefix '/cgi-bin'            
        list lua_prefix '/cgi-bin/luci=/usr/lib/lua/luci/sgi/uhttpd.lua'
        option script_timeout '60'                                      
        option network_timeout '30'                                     
        option http_keepalive '20'                                      
        option tcp_keepalive '1'                                        
        option ubus_prefix '/ubus'                                      
        option rfc1918_filter '0'                                       
        option redirect_https '0'

As you can see, this website is served at port 10178. Maybe you can guess from looking at the config that I am planning to get proper SSL running as well, so the website is reachable using https:// without certificate warnings, as every website should be, to avoid plain-text MitM manipulation.
There is a tutorial on how to do that: LE-HTTPS on OpenWRT with uhttpd by stokito
If you have an idea on how to fully automate the Let’s Encrypt certbot renewal process directly on an OpenWrt device, please let me know.