Airprint woes

It’s all my fault, really.  This wouldn’t have been an issue if I had just let Xtina use my computer to print her boarding pass, but in my defense I didn’t know that she was doing that.  So I gave her our iPad to use.

When it came time to print, she quite logically asked me how she would do that.  I, of course, did not know how — I’ve never tried printing from iPad or smartphone, though I vaguely knew it was possible.  The issue just never came up and I hate printers.

I knew that it would require avahi, so I started installing that on our printserver while I hit Google to see what else I would need.

The first hit was a very fine article by Linux Magazine, and it explained pretty much everything.  But it’s never that simple, because nothing printed and cups started using 100% of a CPU.

Repeated in the /var/log/cups/error_log a billion times were messages like these:

Request from "192.168.1.32" using invalid Host: field "dandelion.local:631"

That took a little more detective work because I didn’t read the Linux Magazine article carefully enough.  The solution was to add an additional directive to the cups config:

--- /backup/snapshots/dandelion.0/etc/cups/cupsd.conf   2015-06-08 08:33:31.000000000 -0400
+++ /etc/cups/cupsd.conf        2015-06-24 19:29:34.410488191 -0400
@@ -1,6 +1,7 @@
 LogLevel warn
 PageLogFormat
 # Allow remote access
+ServerAlias *
 Port 631
 Listen /run/cups/cups.sock
 # Share local printers on the local network.

Summary:

Gentoo packages required:

  • net-print/cups
  • net-dns/avahi

Also download and run airprint-generate after cups is configured and running.

If you have iOS 6+, which is pretty much a given nowadays, make sure you have the correct MIME types available, and add them if not:

echo 'image/urf urf string(0,UNIRAST<00>)' > \
    /usr/share/cups/mime/airprint.types
echo 'image/urf application/pdf 100 pdftoraster' > \
    /usr/share/cups/mime/airprint.convs

Add the appropriate services to your default runlevel, and start them as well:

# rc-update add cupsd default
# rc-update add cups-browsed default
# rc-update add avahi-daemon default

Adventures in WiFi

Apple and hostapd

The problem

I set up my fileserver to be a router and wireless gateway using hostapd and dnsmasq, after I got fed up with Verizon’s crappy Actiontec router.  Works great, except for Apple products.  Neither Megh’s Mac nor my iPad would connect.

The various Linux boxes, Android devices, Nintendo Wii, and HP printer connected to it without a problem, so I held out hope that this was a solvable configuration problem and not some fundamental hardware incompatibility.  I’ve been running both routers for weeks while I tried to figure this out.

My iPad has been prompting for a username and password to log into wifi, even though I’m only using WPA Personal.  Megh’s Mac refused to connect at all.

Logging hasn’t been much help, as it fills with messages like this, over and over:

Oct  3 21:30:02 dandelion hostapd: wlp3s6: STA 01:02:03:04:05:06 IEEE 802.11: authentication OK (open system)
Oct  3 21:30:02 dandelion hostapd: wlp3s6: STA 01:02:03:04:05:06 IEEE 802.11: authenticated
Oct  3 21:30:02 dandelion hostapd: wlp3s6: STA 01:02:03:04:05:06 IEEE 802.11: association OK (aid 2)
Oct  3 21:30:02 dandelion hostapd: wlp3s6: STA 01:02:03:04:05:06 IEEE 802.11: associated (aid 2)
Oct  3 21:30:11 dandelion hostapd: wlp3s6: STA 01:02:03:04:05:06 IEEE 802.11: deauthenticated due to local deauth request

Not much indication of what’s wrong there.

The Server

Wireless is provided by an Ralink RT61-based card.  I’ve used the same hardware to set up wireless networks before, because I know this chipset can enable master mode.  Not all wireless chipsets can.  This is the first where I know Apple hardware is in use, though.

Googling gave me some ideas, but nothing that I found solved the problem.  Various posts pointed fingers at hostapd’s integrated EAP server, AES, the wireless hardware itself (oh noes!), and more.

I started with a basic hostapd config file, no encryption, to rule out hardware issues.

/etc/hostapd/hostapd.conf

driver=nl80211
logger_syslog=1
logger_syslog_level=0
logger_stdout=-1
logger_stdout_level=2
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=My crappy wifi name
country_code=US
hw_mode=g
channel=1
macaddr_acl=0
deny_mac_file=/etc/hostapd/hostapd.deny
auth_algs=3
wmm_enabled=0
ap_max_inactivity=600
ieee8021x=0
eap_server=1
own_ip_addr=127.0.0.1

/etc/conf.d/modules

Apparently, the hardware crypto can be a little flaky with rt61 cards so it’s safer to load it as a module (instead of compiling it into the kernel, so you can unload/reload it) and disabling hardware crypto at run time.

modules="rt61pci"
module_rt61pci_args="nohwcrypt=1"

Like that, everything connected.  Hallelujah.

Now came the fun (if tedious is fun) process of enabling and modifying options until we get an encrypted signal that everything can connect to.  The linux-based devices, bless their little electronic souls, seem to be very tolerant about network settings and kept reconnecting no matter what the encryption config was.

Here’s my final configuration:

interface=wlp3s6
driver=nl80211
logger_syslog=1
logger_syslog_level=0
logger_stdout=-1
logger_stdout_level=2
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=My crappy wifi name
country_code=US
hw_mode=g
channel=1
macaddr_acl=0
deny_mac_file=/etc/hostapd/hostapd.deny
auth_algs=3
wmm_enabled=0
ap_max_inactivity=600
ieee8021x=0
eap_server=1
own_ip_addr=127.0.0.1
wpa=2
wpa_passphrase=My crappy wifi password
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP

Notes:

  • wpa_key_mgmt=WPA-PSK WPA-EAP does NOT work with Apple devices, though it does work in general
  • wpa_pairwise=TKIP DOES seem to work, but AES probably provides safer encryption