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

The Seven Dreamers fiasco

I wrote this up awhile back, but never got around to hitting the publish button. This is what transpired between Seven Dreamers and myself in the months leading up to their bankruptcy.

In November (2018), I was contacted by a guy recruiting for 7D. They wanted someone to take over factory operations, factory security, and so forth … they wanted to bring the laundroid to the Japanese market by Christmas 2019.

I wasn’t too enthusiastic about going back to China, but the laundroid was a project that I really wanted to see succeed. So I had a bunch of meetings with Shin, Makoto, and their former head of engineering. As the talks continued, the feeling grew that there was something not quite right with 7D. So I asked to have a frank discussion about the state of 7D/laundroid, with special emphasis on intellectual property and manufacturing rights, signed an NDA, and had that meeting.

They’d just received their third (or possibly fourth) round of funding (which seemed really odd for a “startup” that had been around since 2011), they were ready to do a production verification test run at the Chinese factory (Haier), and they just needed someone to shepherd to production ramp.

Little tidbits kept slipping out during the discussions, however. They’d done DVT and EVT (development/engineering verification test) runs at a factory in Japan (Panasonic, not Haier), and wanted to air-drop everything over to Haier and ramp there. This was tried without success at Apple, when they tried to move production of a random iPhone from Foxconn to Pegatron. Most of the gear arrived at Pegatron damaged. Foxconn denied responsibility, but anyone who spent any time at a Chinese contract manufacturer knows what happened.

It turned out that they hadn’t yet signed a contract with Haier. This bit will become rather important in this story a few paragraphs down.

At this point, I was starting to suspect that they were in a bit of trouble. Nobody sane jumps from one contract manufacturer to another after a PVT or two, and especially not without restarting the *VT process. The whole point of the progression is to make sure the factory is actually capable of making the product.

You don’t just throw the schematics and production documents over the fence to the CM and call it good. However, that was exactly what they were planning to do.

Panasonic was apparently very upset that 7D pulled out of the production deal in favor of Haier. They didn’t come right out and say that, but the asks of the role I was being brought in for made it pretty clear that they were not going to bring any production tooling from Panasonic to Haier.

At this point I told them that I’d need full disclosure in order to decide if I was going to take the gig. That’s when the NDA bit happened.

They were going to use an NVidia ARM platform. Their intention was to release the laundroid as an API; 7D would control the hardware and the OS, third-parties would write apps that ran on the laundroid. Ambitious, I thought …

… except for that pesky GPL. Which they had never heard of. Which essentially ensured that they’d have to provide source code for their OS value-add to any customer who asked. They asked why they couldn’t simply ignore that, as “nobody does that”. I urged them to check the license requirements and run it past their lawyers.

They had frozen the hardware design around December 2018. The firmware was in what we’d call a “slushy freeze”. The OS side was admittedly a heap of spaghetti, and was to be refactored sanely. Shin said that they’d run out of time, and were going to ship what they had as v1 come hell or high water, with dev resources being focused on v2. I’m personally unsure that the v1 firmware was anywhere near shippable; they were still asking how they should go about basic things like performance metric transmission … but that’s what they said.

Another highlight of the meeting was that they’d given Haier the rights to market the laundroid in mainland China; 7D intended to market it elsewhere. I further recommended that they go over that contract with a fine-toothed comb. “That’s not necessary,” they said, “they’re our trusted partner”.

I thought about it for a week or so, made a couple of adjustments to the proposed employment contract, they agreed, I signed, and was set to start on 18 March.

Then things started getting really weird. The Friday before my start date, 7D said that they had run into some contractual issues. Shin needed to go to China to meet with Haier, and the timetable was suddenly out the window. They asked me to hold off on starting until 01 June — it probably wouldn’t be that long, but they wanted to worst-case it.

I said that was fine, and I’d stand by awaiting instructions. No worries on my end; the contract said I was employed effective 18 March, they didn’t amend it, so I was taken care of … I thought. I was going to negotiate back-pay after I actually started deploying to China.

Not long after, they sent a one-page to me via the recruiter saying that they couldn’t hire me. You can read it at

That was, of course, extremely unacceptable. I demanded a meeting.

We met on 10 April. Only the executive secretary (Makoto Sato) attending. The first half of the meeting was me determining what in fact had happened (and getting gibberish in return), the second half me explaining that they couldn’t just do that, and giving them until 26 April to work out a deal.

“Sure, 26th April, that’s fair!”

They’d already filed for bankruptcy at that point, although Makoto denies it in the recording I made of the meeting. I thought I was safe because Japanese bankruptcy simply can’t happen that fast.

So I waited. I’d given up on them, tried to reconnect with recruiters, and abided by my NDA.

Yahoo Japan reported they’d declared bankruptcy on 23 April. I sent them an email demanding a response upon pain of legal action, they said “nope, talk to the bankruptcy trustee, and by the way, you weren’t an employee”.

I talked to my lawyer, who said a) they’re wrong and b) you’ll get nothing out of a bankrupt company. So I posted the situation on LinkedIn, and the trustee reached out to me at 0200 the following day (a Saturday!), inviting me to join the mass of creditors.

I’ve got email to back most of this (the recruiter helpfully cc’ed me on his discussions with 7D).

Posted in seven dreamers | Leave a comment

LineageOS 14.1 Sustaining Build for HTC 10 (pme)

By request, I’ve added the HTC 10 (pme) to the LineageOS 14.1 “build rooster”. Same deal as all the other builds — generated weekly, available at

As a side note, I’d like to publicly thank Adam_J_T from the XDA forum for his very kind donation toward defraying server hosting costs.

Posted in LineageOS | 3 Comments

Refurbishing a Quadra 700

I picked up a Quadra 700 on eBay. Although it powered on out-of-the-box, it needed a bit of upgrading to be useful. I pulled together information from a number of external resources, and am writing it up here in the hope that it’ll save someone else a few hours of research.

Here’s what you need:

(I’ll insert spinup guidelines here as time permits)

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

LineageOS 14.1 sustaining builds for Moto Z Play and Moto G4

It appears that my LineageOS 14.1 sustaining build service has been well-received. Some folks have pinged me on XDA about adding more devices; there’s still enough space on the web server, so I’ve added them.

Weekly builds for the Motorola Moto Z Play (addison) and Motorola Moto G4 (athene) are at and

As with the others, they’re built against the latest LineageOS source tree and therefore incorporate the latest available security patch (currently 05 October 2019).

Please drop me a line if you would like devices added to the build roster. I’ll keep this service going as long as there is interest (and I can afford the hosting bill!)

Posted in LineageOS | Leave a comment

LineageOS 14.1 security patch builds

I’ve resurrected a few of my older Android devices. They’re not supported by current LineageOS releases, and I really don’t like running gear without the latest security patches for obvious reasons.

Completely understandably, LineageOS sundowned 14.1 builds quite some time ago. Security patches still show up in the source tree, though, with the intention of enabling end users to build their own updated images.

So that’s what I did. I’ve rigged a build infrastructure to produce up-to-date images each Saturday night for the Nexus 5 (hammerhead), 2013 Nexus 7 (deb and flo), and Asus ZenBook 8.0 (P024, both Z380KL and Z380KNL variants).

I reckon there are others out there that have similar needs, so I’ve made them available at These images are built from a completely unmodified source tree, and that tree is updated nightly to pull in the latest patches.


Posted in LineageOS | 2 Comments