Over the last couple of years I’ve been a very happy customer of Linode for their low cost and low hassle Linux VPS boxes. More recently I had made the move from a single monolithic server hosting mail, databases, and web applications to a more distributed system where those services were spread across several hosts and then firewalled off from each other save for the minimum required access. That way, for example, my MySQL instance would only accept connections to port 3306 from my webserver on it’s private IP address. Great in theory, except when I ran an nmap scan recently and saw my server’s ports hanging out in the breeze.

User Error: Persistence Is Not Baked In

Part of the decentralization move was to change my hosts over from Arch Linux to Debian Jessie and it’s clear now I didn’t do my homework. I had configured my rules using a bit of Puppet (I’m now working on moving that configuration over to Ansible) but they were not persisting across reboots. I suppose that when I had originally configured things on Arch my memory glossed over the “save the rules” part of the exercise.

Intent upon not making that foolish mistake again, a quick Google search lead me to the iptables-persistent package in Debian. A call to sudo apt-get install iptables-persistent should have had me up and running. Should have…

System Error: Don’t Try to Load Modules That Don’t Exist

One of iptables-persistent dependencies is the package netfilter-persistent but when apt tried to install the package it failed saying that it couldn’t start the service and to check the logs. Pulling out sudo journalctl -xn I poked through the logs and found an entry very similar to this one, copied here from the Debian bug describing the error.

> Oct 17 17:46:56 prod sudo[5176]: puppet : TTY=pts/0 ; PWD=/home/puppet ; USER=root ; COMMAND=/bin/systemctl start netfilter-persistent
> Oct 17 17:46:56 prod sudo[5176]: pam_unix(sudo:session): session opened for user root by puppet(uid=0)
> Oct 17 17:46:56 prod systemd[1]: Starting Load Kernel Modules...
> -- Subject: Unit systemd-modules-load.service has begun with start-up
> -- Defined-By: systemd
> -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
> --
> -- Unit systemd-modules-load.service has begun starting up.
> Oct 17 17:46:56 prod systemd-modules-load[5179]: could not open builtin file '/lib/modules/3.15.4-x86_64-linode45/modules.builtin.bin'
> Oct 17 17:46:56 prod systemd-modules-load[5179]: Failed to find module 'loop'
> Oct 17 17:46:56 prod systemd[1]: systemd-modules-load.service: main process exited, code=exited, status=1/FAILURE
> Oct 17 17:46:56 prod systemd[1]: Failed to start Load Kernel Modules.
> -- Subject: Unit systemd-modules-load.service has failed
> -- Defined-By: systemd
> -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
> --
> -- Unit systemd-modules-load.service has failed.
> --
> -- The result is failed.
> Oct 17 17:46:56 prod systemd[1]: Dependency failed for netfilter persistent configuration.
> -- Subject: Unit netfilter-persistent.service has failed
> -- Defined-By: systemd
> -- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
> --
> -- Unit netfilter-persistent.service has failed.
> --
> -- The result is dependency.
> Oct 17 17:46:56 prod sudo[5176]: pam_unix(sudo:session): session closed for user root
> Oct 17 17:46:56 prod systemd[1]: Unit systemd-modules-load.service entered failed state.

From that it was clear that the loop module wasn’t being found for some reason. A quick poke around /lib/modules made it fairly clear that if it existed anywhere it had to be built into the kernel. Another hour later I came to the conclusion that figuring out what modules are built into your kernel when you weren’t the one that did the building is a bit of a tricky prospect. If anyone knows how to pull it off, please let me know, I’m quite curious.

After spending a little more time with Google and the bug report I stumbled across a Linode forum discussion about the same bug but in relation to the fuse module instead of loop. There a user suggested placing fuse in the modules.builtin file inside of /lib/modules and rebuilding the module index using the following commands.

sudo echo "fuse" >> /lib/modules/4.1.5-x86_64-linode61/modules.builtin
sudo touch /lib/modules/4.1.5-x86_64-linode61/modules.order
sudo depmod

Unfortunately, that and several reboots did not give me any more success in getting netfilter-persistent to install properly. It seems that contrary to what I thought, the loop module isn’t built into the custom kernel that the Linodes boot so obviously adding it as a builtin is useless.

Simple Solutions Work

After some more searching, I found someone who had come to the simplest but surprisingly effective solution, just comment out the loop module in /etc/modules. In his post he lays out exactly the same problem I encountered and suggests the removal of the offending module if nothing in your system currently relies on it. A quick comment and reboot later and iptables-persistent is happily installed along with all of its dependencies. Be sure when installing though to tell it to dump your current rule set to a file if you’ve already got it configured. If you don’t you’ll need to write them up and save them to /etc/iptables/rules.v4 for IPv4 and /etc/iptables/rules.v6 for IPv6 so that the service can load and save to them.

Give the server another few reboots and a couple of scans with nmap to make sure everything has taken properly. Finally, sit back to enjoy the improved security of your servers and ponder what problem is next on your list to fix. Don’t kid yourself, there’s always something new to fix.