netatalk-classic-20200921 released

I’ve been repairing old 68030- and 68040-class Macintoshes for the past few years. It’s a fun hobby, and allows me to reconnect to an Apple era that was long-gone by the time I joined Apple.

At this point, we have a SE/30, a Classic II, a IIsi, an LC III, a Centris 650, a Quadra 700, and a Quadra 950. All are networked, either through Asanté PhoneNet-to-Ethernet bridges or direct Ethernet.

For the last quarter-century, Netatalk has been the go-to solution for file/printer sharing between UNIX and AppleTalk. Version 2.2.6 was the last release that supported classic DDP AppleTalk (as opposed to AppleTalk-over-TCP/IP, aka “DSI”). Unfortunately, the codebase rotted a bit and needed cleanup to run on current Linux and NetBSD releases.

Now that I’m retired, I have time to work on fun projects like this. I’ve spent the past few months refactoring the 2.2.6 codebase; it’s now at the point where I consider it good enough for public consumption.

I’m calling it “netatalk-classic”. It works out-of-the-box with NetBSD, and seemed okay on Linux once they fixed the Huawei commit that broke AppleTalk (as discussed at — full disclosure, I’m the guy that tried and failed to get the maintainer to fix the broken code that he himself had approved, so I’m a bit bitter).

Release tarball is at and the GitHub source is at

Share and enjoy. Please drop me a line if you find this useful or need functionality that was removed.

Posted in Apple, Macintosh (m68k) | 2 Comments

LineageOS 15.1 builds for Sony Xperia Tablet Z LTE (pollux)

The LineageOS team is shutting down builds for 15.1.

Ari Opari has asked for Sony Xperia Tablet Z LTE (pollux) builds. They’ve been added to the rooster and are at

Posted in LineageOS | Leave a comment

LineageOS 15.1 builds for Huawei Honor 5X (kiwi)

At the request of Sachin Saini, I’ve added the Huawei Honor 5X (kiwi) to the weekly 15.1 build rooster. Share and enjoy.

Posted in LineageOS | 2 Comments

LineageOS 15.1 hammerhead builds working again

It looks like the LineageOS team got around to fixing what they’d broken in the hammerhead 15.1 tree. Builds have commenced.

Kudos to Uwe for giving me a heads-up — much appreciated.

Posted in LineageOS | Leave a comment

LineageOS 15.1 builds broken on Nexus 5 (hammerhead)

It looks like a commit last week to the 15.1 branch broke builds for hammerhead:

ERROR: /mnt/second/android/lineage15/packages/apps/LineageParts/src/org/lineageos/lineageparts/livedisplay/ config_enableLiveDisplay cannot be resolved or is not a field

I’m seeing discussion about this on other devices (, for example) that indicates that this isn’t isolated to hammerhead. It seems that devices that don’t have active maintainers weren’t updated to handle a feature change.

15.1 on hammerhead builds are going to fail until this is fixed.

Posted in LineageOS | 5 Comments

Making MacSSH work with current OpenSSH servers

The OpenSSH team has a habit of turning off ciphers/features every few releases. The rationale behind this decision is open to debate (this breaks compatibility with Cisco switches, for example), but so far they are only disabling by default rather than removing.

So long as it’s just disabled, it’s easy enough to re-enable. Here’s what to tweak when trying to connect a MacSSH client to a OpenSSH server:

  • Add this to sshd_config on the server and bounce the process:
Ciphers                         +aes256-cbc
MACs                            +hmac-md5
KexAlgorithms                   +diffie-hellman-group1-sha1
  • Create a profile for the server in MacSSH. You’ll want to turn compression completely off (it defaults to zlib).
  • If you’re using public key authentication, you must export the public key from MacSSH and run it through ssh-keygen thusly:
ssh-keygen -f ${PUBLIC_KEY_FILE} -i >> ~/.ssh/authorized_keys

That should do it. At some point I may hack a more current version of lsh into MacSSH to add new ciphers into the suite, but this works for now.

Posted in Apple, Macintosh (m68k) | Leave a comment

LineageOS build rooster being worked on

So yes, the weekly LineageOS builds have been a bit sporadic lately.

Both deb and flo 14 builds started claiming that the jack server had disappeared. I temporarily removed them, which made other builds complete, but the build times would range wildly between one hour to six-plus hours per.

I’ve tweaked the build infrastructure (yet again!) to spread out the load a bit. Builds are now going to happen a few batches per day, Monday through Wednesday. I’ll keep an eye on things and see how it goes.

Posted in LineageOS | 2 Comments

Setting a DeLonghi EO241250M Livenza convection oven to Celsius mode

I’ve been a fan of DeLonghi appliances since the mid-nineties. Every place I’ve lived, I’ve put an oil-filled DeLonghi heater into each room.

Needed a real convection oven a few months back; Japanese apartments typically don’t come with an oven that can be used for cooking, just for grilling fish. I chose one of the DeLonghi Livenza units, and I was pretty happy with it …

… but since I bought it from Amazon US, it was rigged for Fahrenheit. I haven’t thought in Fahrenheit for at least twenty years, none of the recipes that I cook are in Fahrenheit, and I’m too lazy to do the conversion ( 5/9 – 32 … right?) in my head.

The oven firmware pretty clearly could do Celsius, as there was a darkened “C” next to the lit “F” on the front panel. I searched the web for a few days looking for the magic button sequence to flip it, to no avail. I contacted DeLonghi support and they eventually got back to me. Here’s the gouge:

  • select the BAKE or CONVECTION function
  • press Cavity temperature check button (L) for 5 seconds
  • the visualization will change to °C with an acoustic signal
  • To come back to °F visualization repeat the same operation

… so hopefully the next guy that Googles for “DeLonghi EO241250M Livenza Celsius” will get this page in the search results.

Leave a comment

A bridging IPv6 Linux firewall for a NTT FLETS internet connection

It’s easy to make an IPv4 DSL connection work in Japan if you’re using NTT FLETS — just use any PPPoE client. FreeBSD, NetBSD, Linux … it doesn’t matter, the process is well-documented.

Using that same FreeBSD/NetBSD/Linux machine to handle IPv6 simultaneously, however, is not well-documented. In fact, I wasn’t able to find this scheme written up anywhere. I think I’ve figured it out, and I’m putting my notes up to help others that might be trying to do the same thing.

NTT does things a bit differently from the rest of the world. IPv4 is handled via PPPoE, which is standard. IPv6 is bridged, not routed. Anyone with a network and/or security engineering background is probably saying “oh, <expletive deleted>” about right now.

It’s been accepted practice to firewall one’s internal network from the outside world by use of a … well, a firewall. For IPv4, this means that one has a machine with two network interfaces between the internal network and the outside. One interface is plugged into the DSL router, one interface plugged into the internal network switch. The internal interface is set to be the default gateway for the internal machines, NATs outbound connections, and screens incoming connections.

In the NTT IPv6 scheme, the router just upstream from the firewall is broadcasting IPv6 router advertisements and responding to DHCPv6 requests. This means that the internal machines need to sit on the same physical network as the firewall’s outside interface. This adds a great deal of complexity to the situation, to say nothing of the security implications.

Most off-the-shelf routers will handle this transparently (the ASUS RT-68U, for example, which is what I was using previously). However, doing it that way resulted in bad client DNS settings — the upstream router was helpfully supplying the NTT DNS servers and search domain in the DHCPv6 response packet, which kept the MacOS machines on the internal network from resolving hosts. IPv6 packet-filtering was essentially non-existent.

So here’s what I came up with:

The firewall is running Arch Linux. This should be adaptable for other distributions that use systemd (yes, I dislike systemd very much, but that’s what’s bring rammed down our throats by the distribution makers, so I’ll just have to suck it up).

I decided to use two external network interfaces — one for IPv4 (via PPPoE), one for IPv6. Separating the two into discrete physical interfaces simplifies the security model quite a bit. Two cheap USB GigE network dongles, plugged into a cheap dedicated switch that is also plugged into the DSL router. They’re enumerated by the Linux kernel as enp0s16f0u1 and enp0s16f0u2.

The third NIC is on-board. The kernel sees it as enp1s0. It sits on the internal network.

I’m going to skip the IPv4 PPPoE, NAT, and firewalling bits. That is documented in excruciating detail elsewhere. Drop me a line if you need help with that part of the configuration.

So, first thing we do is set up the IPv6 bridge between enp1s0 and enp0s16f0u1.

Name=enp1s0 enp0s16f0u1

Restart systemd-networkd. At this point you should be seeing IPv6 traffic on both bridge interfaces, and br0 should have picked up an IPv6 address.

We’re going to be using ip6tables instead of ebtables, because we need to drop bridged packets based on their layer-three characteristics. This is an egregious blurring of the OSI layers, but we’ll note that and move on.


Now we need to rig the IPv6 packet filter:


:DROPLOG - [0:0]
:TCP - [0:0]
:UDP - [0:0]
# We want to log dropped packets (except DHCPv6)
-A DROPLOG -p udp -j REJECT --reject-with icmp6-adm-prohibited
-A DROPLOG -p tcp -j REJECT --reject-with tcp-reset
-A DROPLOG -j REJECT --reject-with icmp6-adm-prohibited

# FORWARD chain handles everything on the bridge
# Block NTT DHCPv6 first.
-A FORWARD -m physdev --physdev-in enp1s0 --physdev-out enp0s16f0u1 -p udp --dport 547 -j DROP
-A FORWARD -m physdev --physdev-in enp0s16f0u1 --physdev-out enp1s0 -p udp --dport 546 -j DROP
-A FORWARD -m conntrack --ctstate INVALID -j DROPLOG
-A FORWARD -p icmpv6 -j ACCEPT
-A FORWARD -m physdev --physdev-in enp1s0 -p udp -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -m physdev --physdev-in enp1s0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -p udp --destination ${IP6_ADDR} --dport ${SOME_PORT} -j ACCEPT

# INPUT chain affects only this host
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m physdev --physdev-in enp1s0 -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROPLOG
-A INPUT -s fe80::/10 -p ipv6-icmp -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128 -m conntrack --ctstate NEW -j ACCEPT

This should be pretty straightforward. The only non-obvious bit is that we’re using the FORWARD table to process packets on the bridge. Anything originating from the firewall itself is going to be handled by the INPUT table, so there’s duplication.

It’s very important to note that we’re dropping the DHCPv6 packets. That’s because the upstream router is also issuing IPv6 router advertisments without DNS information. The slickest way I could see to have internal machines get their IPv6 addresses without having to run a DHCPv6 daemon on the firewall was to just have the clients use those router advertisements to self-configure using SLAAC. The Linux machines happily do both, and MacOS will use SLAAC if it doesn’t see DHCPv6 response packets. Problem solved.

There are still small things that need to be ironed out. I have a gratuitous “-A FORWARD -m physdev --physdev-in enp1s0 -j ACCEPT” in the FORWARD table that really shouldn’t be there, but packets were being dropped for no good reason that I could see. Please don’t hesitate to point out the error if you can see it.

So that’s it. It isn’t perfect, but it works, and it appears to be relatively secure. I hope this helps others that are trying to figure out how to deal with NTT’s interesting IPv6 design.

Posted in Network, Security | Tagged , , , , , , | Leave a comment

LineageOS build rooster going again.

The infrastructure hosting the build rooster was upgraded a bit, and it broke the build process.

It turned out to be a combination of three things: the build machine’s swap partition wasn’t prepared with mkswap (so the build was getting randomly zapped by the OOM killer), and the FreeNAS update blew away the crontab running the nightly rsync. After fixing those two, it turned out that the regular expression I was using to select which builds to rsync wasn’t matching anything built in December anyway.

The rooster should be good to go again. Sorry about the delay.

Posted in LineageOS | 6 Comments