FTP Firewall Fix

My IPv6 FTP server was easy to access from within my LAN, but after I got to work, I realized I couldn’t complete a transfer, even in passive mode. In passive mode, the client must be able to initiate a command connection on port 21, but also it must be able to initiative a data connection on some other random unprivileged port. I opened up port 21 of course, but my firewall was blocking all the other ports.

So, I needed to open up some unprivileged ports, but which ones. I suppose I could open up all of them, but that seemed excessive. I believed 1000 ports would be enough. So, in /etc/vsftpd.conf on the ftp server, I set a passive port range of between 10000 and 11000:


Then I created a rule in the libreCMC firewall router, to allow access to these ports for traffic heading to the FTP server.

Screenshot from 2018-04-23 19-04-48.png

I was confused at first about how to create a rule with a port range rather than just a single port. But it is as simple as putting a range (e.g., 10000-11000) into the port field.

So, now my FTP server is accessible from the Internet in PASV (passive) mode, though still only through IPv6:

ftp://lavender.qlfiles.net or

ftpes://lavender.qlfiles.net (encrypted, through FileZilla).

For a good read on Active vs. Passive FTP, see Active FTP vs. Passive FTP, a Definitive Explanation.


The darkstat package in libreCMC is useful as a low resource method of tracking overall bandwidth usage up through the last month. darkstat tracks stats of your network usage on an interface, and displays them as 1 minute, 1 hour, 1 day, and 1 month graphs:

Screenshot from 2018-04-17 19-09-10

It doesn’t seem to use much processing resources, about 1% CPU load on my 300Mhz GL-AR300M router. The LuCi interface does have a nice bandwidth graph display built in, but it only displays a 3 minute window. So, this seems like a useful tool, especially as it does not require much CPU resources and has a package size of only about 40KB.

In theory, you could use this for analysis and logging of traffic, because of the hosts tracking and logging functionality.

Screenshot from 2018-04-17 19-10-11If you click on a host record you get port and protocol information.

Screenshot from 2018-04-17 19-12-04

This is a tricky, though, as darkstat doesn’t index the host information by time. So, you are just getting running totals from since darkstat started. However, you can send POSIX signals to the daemon which will cause it to clear out its host memory tables and/or log the data to a file. The logging though requires some tweaking to the darkstat command line arguments. In libreCMC, the command line arguments are translated to a config file at /etc/config/darkstat. It seems, though, that the config file does not support the logging options, so you would find yourself tweaking the init.d file. And then you would need scripts to send the signals and delete old logs and so forth. Also, you probably would want to tweak the config file some more to filter out traffic on just the local network, or change over to the wan interface. In summary, you could log lots of useful host data, but you’ll have to do some configuration and scripting to get there.


libreCMC has an iftop package. It is a program which allows you to watch your connections and their bandwidth usage in real time. It does not run in the Web interface, but rather you ssh into the router and run it on the console.

Screenshot from 2018-04-16 17-39-57

It lists the the source and destination of each connection, as well as the bandwidth rate each direction. It also can display bar graphs to give you a visual on the relative bandwidth usage. And it has a few options for sorting and displaying the connections which can be useful.

Screenshot from 2018-04-16 17-27-32.png

It is not useful for long term logging, only for getting a live snapshot view. But it is lightweight, with the package file at about 20KB. So I plan on adding it to all my future builds.

Running it on a libreCMC router, you’ll usually need to carefully pick which interface you want to watch, using the -i option, so you find the connection information you are looking for. E.g., if you want to see the local IPs, you’ll want your LAN interface (maybe called the eth1 interface).

v1.4.3a Builds

Here are all my v1.4.3a builds on one page:

Build Features

See post v1.4.3a Source and NAND build.





GL-AR300M (16MB NOR Flash)


GL-AR300M (128MB NAND Flash)


Note: The NAND Flash image is a factory bin which must be installed from uboot, and clears all the settings. So you must backup and reload your settings to upgrade your image.

Additional Packages


  • openvpn
  • luci-app-openvpn
  • opentracker
  • opentracker6

Source Code


First Let’s Encrypt Certificate

Domain Validation (DV) certificates allow a host to prove that it is the correct host for a particular domain name. A common use case of DV certs is if a Web browser tries to connect to the Web server for a particular domain name, then the DV cert provided by the Web server gives the user confidence that he has accessed the desired Web server, rather than an impostor server than has somehow hijacked the connection.

Traditionally, DV certs cost money and were rather bothersome to obtain. Let’s Encrypt is a recognized Certificate Authority, which makes getting DV certificates easy, by making the process free, and by providing software and APIs which automate the process. In my opinion, projects like Let’s Encrypt are a necessary consequence of the move from IPv4 -> IPv6. IPv6 increases the bit length of IP addresses, making them more difficult to remember, while at the same time making it easier for individuals and small organizations to run many routable services on their own networks. So, it is important that you can easily give a DNS name to a particular host and that, having done so, you can have confidence that you are connecting to the correct host when you are on another part of the Internet. You might conceivably want 20 or 30 DV certs just for your home network, not to mention the office!

There is Let’s Encrypt compatible software for libreCMC, a package called acme. I haven’t actually tried it yet, though: it requires mbedtls, and I had stripped mbedtls from my builds in favor of openssl (a choice I might have to revisit). But I wanted a DV cert on my libreCMC gateway router. So, I used the certbot program from my Debian desktop to create the cert and then put it on my router.

root@nightshade:~# certbot certonly --manual --preferred-challenges dns
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):<snip email address>

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
(A)gree/(C)ancel: A
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel):maedhros.qlfiles.net
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for maedhros.qlfiles.net

NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
(Y)es/(N)o: Y

Please deploy a DNS TXT record under the name
_acme-challenge.maedhros.qlfiles.net with the following value:


Once this is deployed,
Press Enter to Continue

Then I logged into my domain registrar, and added a DNS TXT record as indicated. Then I pressed Enter.

Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem

 - Congratulations! Your certificate and chain have been saved at
 /etc/letsencrypt/live/maedhros.qlfiles.net/fullchain.pem. Your cert
 will expire on 2018-07-06. To obtain a new or tweaked version of
 this certificate in the future, simply run certbot again. To
 non-interactively renew *all* of your certificates, run "certbot
 - If you lose your account credentials, you can recover through
 e-mails sent to <snip email address>.
 - Your account credentials have been saved in your Certbot
 configuration directory at /etc/letsencrypt. You should make a
 secure backup of this folder now. This configuration directory will
 also contain certificates and private keys obtained by Certbot so
 making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
 Donating to EFF: https://eff.org/donate-le

Quite simple. Now, the cert chain and the corresponding private key needed to be loaded onto my libreCMC gateway router. However, libreCMC uses the DER file format, rather than the PEM format. So I needed to copy the files from fullchain.pem and privkey.pem from the /etc/letsencrypt/live/maedhros.qlfiles.net directory, and convert them:

christopher@nightshade:~/Scratch$ openssl rsa -in privkey.pem -outform DER -out uhttpd.key 
writing RSA key
christopher@nightshade:~/Scratch$ openssl x509 -in fullchain.pem -outform DER -out uhttpd.crt

Then, these files needed to be copied onto the router, and placed in the /etc directly, replacing the default uhttpd.key and uhttpd.crt files (I had to adjust permissions as well to match).

After rebooting the uhttpd server, I accessed the LuCi interface using my domain name, and this time I did not need a security exception!

Screenshot from 2018-04-06 18-04-18

Screenshot from 2018-04-06 18-04-34

Screenshot from 2018-04-06 18-04-53

The Let’s Encrypt certs are only valid for three months, so I’ll have to do that again later. But it was pretty easy. If I can get ACME running on my libreCMC router, in theory I should be able to completely automate the process.

Gateway Router Upgraded

I upgraded my home gateway from a TPE-R1100 to a GL-AR300M. This turned out to be fairly easy as the settings backup file was portable to the new hardware. That makes sense as it is basically just /etc config files in a tarball, and the two devices have equal interface counts.

One oddity is that, instead of replacing the old wireless interface settings with the new ones, it created two wireless interfaces, one being disabled. But that was a quick fix.

Another oddity, which I’ve experienced before when swapping out hardware running libreCMC, has to do with the DHCP. I got my ISP to swap my static IPv4 address (served by DHCP) to the MAC address of the new device. However, libreCMC udhcpc mysteriously clung to the non-static address it had when I first plugged it in. Even after rebooting everything multiple times, and enabling and disabling the interface, and even sending various signals to udhcpc, I kept getting the old IP. It seems like libreCMC is either storing and requesting the old address, or it is somehow requesting the DHCP server not to allow it to change addresses. I took a glance at the DHCP protocol extensions but it was a bit overwhelming. About 24 hours later, I toggled the interface again, and the proper address finally came up. I’d be curious if anybody could suggest a possible explanation for that delay.

Anyway, now everything seems to be working great, and I couldn’t find any serious problems in the logs. That extra 112MB of flash and extra CPU power should expand the possibilities for what I can do at my gateway.