Monday January 9 Meetup: Social House in Chantilly

So maybe you’re in Nova and have been craving one of these meetups, but maybe you’ve been busy, or maybe you’ve been battling your social anxiety, or maybe you’ve been having pressing issues at home, or maybe you’re wearing an ankle monitor.

Whoever you are, and whatever brings you to our meetup, you are invited, and welcome. We’ll be at Social House in Chantilly. Look for the group of tired, jaded tech folks, probably mostly dressed in black, and probably mostly drinking. Maybe I’ll bring some swag to reward anyone brave enough to join us.

There’s a Dairy Queen across the parking lot if that sways you. Official meetup time is 1830 eastern, but some show up earlier, and some show up later. Come out. You deserve this. We deserve each other.

Less than a week left to follow our YouTube for prizes

We’re giving away a couple of badges and a few other soldery trinkets for new year’s.

Enter by following our YouTube. We’ll choose at random on New Year’s Eve (hell, maybe even live!) from the email connected to your youtube follower account and notify you there.

Content is becoming more frequent. PCB design classes, modular synth explorations, and who knows what we’ll get into in 2023? Follow and stay tuned!

https://www.youtube.com/@dc5402

An Update on Serial Number 0123456789ABCDEF

So I managed to find a satisfactory and effective resolution to my problem with serial number 0123456789ABCDEF. If you recall, the problem is that certain consumer-grade USB devices ship with non-unique serial numbers, making it difficult to use them with USB pass-through under VirtualBox.

  • Serial number on multiple devices = 0123456789ABCDEF
  • VirtualBox USB filtering (permanently mapping a device to a specific VM) relies a unique field. With diverse devices, this can be the vendor/product ID. With normal devices with unique serial numbers, the serial number can be used in the filters.
  • With identical product, vendor and serial numbers, you’re stuck with “Port,” which at least in CentOS/Rocky’s USB subsystem, is dynamically assigned when the device is plugged in to the host. Example: Plug in a device, it shows up on Bus 001, Device 005. Unplug it, plug it back in, and it’s now on Bus 001, Device 006.
  • Allegedly, udev rules can be set to assign a specific port (or a port “nickname”) using some other unique identifier, like the actual physical port the device is connected to. Still less than ideal, since that would require adherence to a strict protocol of unplugging and plugging into the same port. Anyway, I couldn’t get that to work.

So I dug around a bit, and found that the devices DO have a unique component — the device’s MAC address. It’s visible when using lsusb in verbose mode. But VirtualBox can’t see it, and it’s not an option in the VirtualBox filtering.

So what I ended up doing was abandoning VirtualBox’s USB filtering entirely.

I created a text file mapping those MAC addresses to VMs. Then I created a script which iterates through LSUSB, and checks the MAC addresses of every USB device it finds through that mapping file. When it finds one, it needs two things to make the usb attachment happen via command line. It needs either the UUID or machine name of the VM, and it needs the UUID or “address” of the USB device. My mapping file stores the MAC address of the device (discovered via lsusb) and the UUID of the VM, which is available via vboxmanage list vms.

The UUID of the USB device can be found by comparing the Bus and Port values found in lsusb to the output of vboxmanage list usbhost. With creative use of bash and awk, I was able to iterate through the devices, determine which ones are assigned to VMs, check to see if they’re currently attached, and if not, issue the vboxmanage controlvm vm-uuid usbattach usb-uuid command to attach the device to its home VM. So in case of a host reboot or someone rejiggering ports, a single command is enough to get things back where they belong.

I realize that there are probably only three people on the planet who have run into this particular problem, but I thought the solution was an interesting exercise in information-gathering on a VirtualBox host on a Rocky Linux platform, so I felt i was worth sharing.

Serial Number 0123456789ABCDEF is killing me.

I generally prefer to blog when I’ve solved an obscure problem, or even a not-so-obscure problem, because I’m proud of myself for doing it, and because for everyone out there who already knows the answer, there are 20 people out there who don’t, and I like to be helpful.

Not this time. I’m blogging about it this time in the hopes that explaining it in sufficient detail might trigger an a-ha moment for me, or maybe that someone out there in the ether will find it and know, and feel that same urgent need to be helpful that I frequently feel.

So I’ll be as concise as possible here:

CentOS-based server running VirtualBox.

Multiple USB devices connected to the server, intended to be passed through to individual VMs.

These particular devices caused us to settle on VirtualBox, because it was on the only virtualization platform we found that could pass them through reliably in a usable way.

So we found one that we like as far as function set and usability. We’re happily plugging along and making our VM work happily with it. OK, let’s make another one. Spin up another VM, plug in another (identical) device.

Oh noes. The vendor, product, manufacturer name, and everything are all identical! What do we do? Those of you who’ve done this before, I know what you’re about to say. “Use the serial number in the VBox USB Filter, dumbass!” To that I say, “did you read the title of this post?”

Yeah. This particular vendor rolled out this product commercially with generic, identical serial numbers. Whatever fucktard made that decision, I curse their existence.

After a bit of futzing, we found that we could filter on “Port”, which is the port number assigned to the device, visible in lsusb and in the device in. /dev/bus/usb/001/###.

So yeah, we got on with our day and forgot about it. Oh yeah — then we got another one.

“No problem,” I said, “we know how to handle that.” So we’re working through setup, and I have the filter in place, and we pull it out and put it back in for whatever reason, and the filter’s not kicking in. I look again, and the port number has incremented!

Yeah. USB port numbers in linux, at least in this distro, are dynamic. So you can’t expect them to continue to work after a server reboot, or maybe even after a device reset. Bad news.

So a colleague sends me an article on using udev rules to find the uniqueness buried in udevadm attributes to generate a named symlink to the device. That sounds awesome.

Well, less than awesome. The only uniqueness I was able to find in the attributes was “bus” and “devpath”, which are the physical USB bus and port the device is connected to. The lovely non-unique serial number is in there glaring at me triumphantly with its useless stupid face.

So I futzed around with udev rules, trying to get that symlink to come up, and haven’t figured out quite the magic words yet. Maybe because the article is based on a ttyACM device that’s directly in /dev, and my particular situation involves a device that shows up way under /dev/bus/usb/001/### instead. In any case, I see no evidence of a symlink being created anywhere in the /dev tree, and I have no way of knowing whether it would be usable in VBox USB filtering even if it did show up. So I’m calling it a night, and I’ll put fresh eyes on it tomorrow maybe.

That’s my day, how’s youres?

DC540 this evening

I’m thinking we should meet in the backyard/basement this evening. Might be the last time in the season to enjoy a little bit of outdoor weather. I’ve refreshed the beer supply and improved the side path lighting. What say you? A little badd pizza & beer on the patio while discussing badgelife, job searches, and other relevant topics? Who’s in?

Explorations in Self-Hosted Password Managers

Nobody seems to get my niche.

There are many, many password manager apps out there, but none of them tick every box for me in my particular situation.

I don’t think I’m asking for much:

  • I want a self-hosted password manager app.
  • Not in the cloud. Obvs.
  • LDAP capability (for an IT Team to be able to share passwords, for example)

The closest I’ve found is BitWarden. Or more specifically, VaultWarden. I was so excited about BitWarden for so many reasons — Organizational capabilities, delegation, data structures for more than just passwords (credit cards, identity info, etc.), etc. And one of their enterprise features is… wait for it… a directory connector which includes AD, LDAP and others.

But it’s expensive. Their enterprise product runs between $3 and $6 per user per month. Doesn’t sound like much, but it adds up. I was a bit let down by the pricing, but then I found out about VaultWarden, which is I guess a “fork” of sorts of BitWarden which includes the enterprise features. I’m not sure of the mechanics of why it exists, but I decided to give it a try.

It was only then that I realized the fatal flaw in my plan. Both of these products are part of the new breed of password managers, billing themselves as zero-knowledge password vaults. And the great selling point of these is the way the encryption works, which is apparently by encrypting your vault with a key derived from your personal password. With me yet? That means it’s fundamentally incompatible with LDAP authentication. The LDAP features provided (in a most difficult manner) by BitWarden and VaultWarden only provide user and group synchronization, not authentication. They provide this by syncing the directory at admin-defined intervals, deleting inactive users and adding new users on each sync, and then sending those users an email inviting them to use the app (and setting their password).

As far down the road as they took me, it was sad to learn I wouldn’t be able to leverage my existing LDAP authentication on this particular app. And i get it. In a zero knowledge world, it’s unacceptable for an admin to reset a user’s LDAP password and then inherit knowledge of all of their stored passwords. But I’m not in a zero-knowledge world. I’m in a shared knowledge world.

I’ll probably use it anyway, with the complication that my users will not have their BitWarden password updated when they are forced to change their LDAP password. Because the organizational features and data structures seem to outweigh that complication. For now, anyway.

By the way, there is an SSO feature included with the enterprise version of BitWarden ($) that solves(-ish) the problem by offloading the key encryption/decryption to stored key pairs in an external database using a complicated, rickety scaffolding of tubes and wires. VaultWarden doesn’t seem to be leaning toward replicating that functionality, and neither do I.

The New Pinecils are Out.

I saw a deal pop up for Pinecils, and took a gamble. There’s been a little bit of buzz about their next generation model, but they don’t seem to be making a big deal of it on their website. So when I bought them, I wasn’t 100% sure I’d be getting the V2 product.

But since the offer did mention “short tip,” I assumed it was probably the V2 product, because the increased power and short tip are what distinguishes V2.

Here’s the V2 next to the previous version. You can see the difference in tip length and the difference in power spec.

From one write-up I found, the combination of increased power and short tip (less mass to heat up) results in ridiculously fast heat-up time. And yes, it has definitely improved. With my battery bank (EasyLonger 65W PD) heat-up time is down to about 6 seconds. As you can see, it will happily accept more PD power now. I have a 100W PD bank from a Kickstarter coming soon. Some reports indicate that with the right power, heat-up time is down to near-instant, which is amazing.

RPi Pico MCU and SD cards deep dive

For our Tarot Badge this year, we chose a display with an onboard SD Card slot. The flash amount on the Pico was nowhere near sufficient for storing even one tarot deck at the display resolution, much less the three decks we included in the badge.

Early on, superdev Kevin had major success in coding our routines. Everything pretty much worked, loading cards wasn’t super fast due to limitations of the hardware, but splitting off the animations to their own core while card loading happened made things appear more seamless for the user.

Of course in badgelife we count our pennies and look for deals, so I bought bulk microSD cards and adapters — in the quantities we were buying, even bulk retail was at least triple the cost of what we ended up with, which was a whole bunch of 512MB Nokia cards that appeared to be pulled from phones and surplussed.

Then we started noticing anomalies. Sometimes they would work, and sometimes they would simply fail to mount. We spent a lot of time troubleshooting this, and eventually bought a bunch of Gigastone MicroSD cards so that we’d have something to hand out at Defcon with the badges released there.

When we got back, however, we went into persistent mode. There was no way we were going to let this go without at least an explanation. SD cards are pretty low tech, and there aren’t that many variables in the mounting process — so why are they failing to mount when they read perfectly well on a PC.

The answer, it turned out, was baud rate. Kevin and I patiently sorted through numerous iterations of code with various cards, working with different variables until we found it. Turns out when you drop the baud rate down low enough, it mounts. And it doesn’t seem to really drastically affect the image load time. So it’s usable.

But we wanted to drill down even further. Because some Nokia cards worked and others didn’t. Eventually we came up with an iterative mount sequence, which is implemented in the current version of the release firmware. Basically, we try mounting at 4M. If that fails, we try at 1M. Then 500K. Then 100K. Then 50K. Then 4K. If it fails to mount at 4K, we call it a failure and toss that card.

try:
    sd_card_spi = SPI(1, baudrate=4000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(10, Pin.OUT),
                      mosi=Pin(11, Pin.OUT), miso=Pin(8, Pin.OUT))
    sd_card = SDCard(sd_card_spi, cs=Pin(9, Pin.OUT))
    vfs = uos.VfsFat(sd_card)
    uos.mount(vfs, '/sd')
    sd_card_status = 'sd_card: PASS (4M)'

So when you boot your badge, it tries that entire sequence described above behind the scenes, and reports the results once it settles on an acceptable baud rate.

I’d like to explore further and understand what determines the usable baud rate on a card, especially given that they are all, by all appearances, very similar models with the exact same capacity. If time permits, I may do a correlation of actual model numbers with detected baud rates.

If anyone knows, feel free to get in touch for further discussion. Meanwhile, I hope this helps anyone working with SD cards in the RPi Pico or RP2040 platform.