Archive for December, 2015

Strange behavior of “Allow IF(eth0)” directives in cupsd.conf

Wednesday, December 23rd, 2015

When configuring access controls for <Location> sections in the CUPS daemon configuration file cupsd.conf, one might notice the following in the man page cupsd.conf(5):

       The following directives may be placed inside Location and Limit sections in the cupsd.conf file:
       Allow @IF(name)
            Allows access from the named hosts, domains, addresses, or interfaces.  The Order directive controls whether Allow lines are evaluated before or after Deny lines.

On a multi-homed box, one might then be tempted to use this Allow @IF(name) directive as e.g. Allow @IF(eth0), further assuming that any requests received on that interface will be allowed in the context of the associated Location section.

Unfortunately, that is not how it works. How it actually works: Each incoming request is checked to determine whether it is on the same IP subnet as the interface named in the @IF directive! This means that requests routed from another network, or even requests from directly attached hosts configured for a different subnet, will be mysteriously rejected by this directive, and with no real useful message in the log to find out that it was this rule that failed.

So don’t use this directive unless you know exactly what you’re doing. It’s misleading and practically undocumented.

systemd, CUPS, and /var/run/cups/cups.sock refusing connections

Wednesday, December 23rd, 2015

I was debugging a strange problem with a printer server running CUPS the other day. The web admin interface (which executes the script /usr/lib/cups/cgi-bin/admin.cgi via CGI) was returning a 500 “Internal Server Error”, while running lpadmin or lpstat would return Bad file descriptor. Using strace on the script locally on the server, it could be seen that the attempt to connect to the control socket /var/run/cups/cups.sock was failing with ECONNREFUSED. Huh? Seems like CUPS forgot about the socket, so issue service cups restart. Well, that didn’t fix it either.

To make a long story short, when running with systemd, the /lib/systemd/system/cups.socket control file causes systemd itself to own the socket, and to pass it to CUPS inetd-style when the CUPS process is created. Unfortunately, if that socket gets into a bad state, it will be impossible to communicate with the CUPS child process of systemd through the socket.

How to fix it?

# systemctl restart systemd.socket
# service cups restart

The socket will be refreshed and the newly working socket will then be passed to the CUPS child process when it is re-created.

Recovering from a nasty BTRFS meltdown on an AFS fileserver

Friday, December 4th, 2015

A few years ago I was the victim of a bug in Btrfs which resulted in total inability to mount two Btrfs volumes containing AFS ‘vice’ partitions (partitions containing AFS file data, named and laid out as AFS ‘vnode’ structures).  It took a while, but I was able to recover the vast majority of the data with only minor corruption.  Here are my notes that might help someone in a similar situation.