Skip to content

Blog

The future of password management, for me

In a number of ways, I have become a dinosaur. One of those ways is an insistence that my password management solution has one of its layers of security being the fact that the data is not in the cloud. There is nothing on someone else’s commodity service, and, thus, no data to potentially be compromised in bulk as a result of an attack on a common service. Those services are probably pretty secure, but they are also huge, concentrated targets.

I have a really high standard to meet for the security of password management for my personal computing. That is how I feel comfortable.

So the march of password managers into the cloud presented me a problem. To move forward and to maintain my investment became incompatible with this principle.

Additionally, I became more and more disillusioned with macOS as a desktop platform. Increasingly, maintaining control over what the system is actually doing became impossible. (Why is the News app refreshing in the background when I have never opened it on this brand new install??) So the new solution needs to be native to the Linux desktop.

So my requirements discounted me from my long-time password management app 1Password (clearly moving towards cloud only) — a migration of some kind was in order.

The Options

BitwardenInteresting. Open source.
Yes, you can self host, but for syncing purposes you are still exposing a host to the whole web, presumably, which centralises all that data and you would likely need to have this in the cloud.
PassCommand line based, and built around GnuPG. I got somewhere with this, but ultimately found myself wanting a bit more of a GUI for managing and sorting the password data.
KeePassXCProvides a desktop GUI app with the categorisation and management I am used to, with import capabilities from 1Password. Locally syncable (albeit not bidirectionally with great ease) with Strongbox on iOS.

I have found myself with a combination of KeePassXC and Strongbox on iOS.

I do sacrifice some convenience on the desktop with browser integration, as I have not yet installed the browser extension for KeePassXC. I would love it to be in Mozilla’s “Recommended” category, where they review the extension on an ongoing basis. I trust the KeePassXC developers are not malicious, but there are lots of risks with browser integration that I don’t fully understand the implications of — the boundary from the external app into the browser context affects the principle of data isolation in ways I haven’t studied.

So, KeePassXC + Strongbox + local network syncing of data is where I have landed.

And because supporting the projects that we depend upon is important, I have paid for the premium version of Strongbox and made an annual donation to the KeePassXC project. I am one of a decreasing number of people who will want to maintain this level of control, so, given that I am fortunate enough to be able to, providing the resources to keep this alive is something I wanted to do.

“Unknown beats protocol version: 71 /69”: using Winlogbeat with Graylog Beats input

I found myself scratching my head on a new deployment of the Elastic Winlogbeat client on Windows, where the intent was to forward Event Logs to Graylog.

In the graylog-server.log file, I saw:

ERROR [AbstractTcpTransport] Error in Input [Beats/...] (...) (cause io.netty.handler.codec.DecoderException: java.lang.IllegalStateException: Unknown beats protocol version: 71)
ERROR [AbstractTcpTransport] Error in Input [Beats/...] (...) (cause io.netty.handler.codec.DecoderException: java.lang.IllegalStateException: Unknown beats protocol version: 69)

I turned off TLS on the client and the receiving Graylog Input, thinking it might be some TLS-related issue, to the same error.

To cut a long story short, decimal 71 and decimal 69 are ASCII codes for capital G and capital E — the first two bytes of an HTTP request that the Winlogbeat client was making to the Graylog input. Clearly the input is not expecting to receive ASCII “GE” to start the request!

It turns out the Graylog beats input desires the logstash format, not elasticsearch. I had been ignorant in just modifying the example config in the output.elasticsearch section, when this is not what Graylog wants.

I commented out the entire output.elasticsearch section and moved that configuration (hosts and the ssl options) into an output.logstash YML node.

output.logstash:
   hosts: ["x.y.z.aa:5044"]

This was unclear enough to me that I thought connecting the error messages above with this solution may prove useful for someone else who has the issue.

Enabling Password Writeback with Azure AD Connect Cloud Sync (can’t find the cmdlet?)

With a relatively recent Azure AD hybrid directory under our belts, we decided at work not to use the older Azure AD Connect tool and instead use the newer Azure AD Connect Cloud Sync. It’s lighter weight, doesn’t require a SQL database — lots of reasons to love it.

It does appear that, juuuust in time for our deployment, password writeback is supported, in preview.

However, I struggled to follow the official instructions to enable it, as the cmdlet did not seem to be available after importing the DLL.

Import-Module 'C:\\Program Files\\Microsoft Azure AD Connect Provisioning Agent\\Microsoft.CloudSync.Powershell.dll' 
Set-AADCloudSyncPasswordWritebackConfiguration -Enable $true -Credential $(Get-Credential)
Set-AADCloudSyncPasswordWritebackConfiguration : The term 'Set-AADCloudSyncPasswordWritebackConfiguration' is not
recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if
a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Set-AADCloudSyncPasswordWritebackConfiguration
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Set-AADCloudSyn...ckConfiguration:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

A little bit of investigating revealed that the DLL does indeed export the cmdlet, so what is going on?

I tried to run the above in PowerShell 7. It imported the cmdlet, but hit an issue with running it when importing its required libraries.

My Workaround

My workaround is to use PowerShell 7, but import the module with the -UseWindowsPowershell compatibility switch.

Import-Module "C:\Program Files\Microsoft Azure AD Connect Provisioning Agent\Microsoft.CloudSync.Powershell.dll" -UseWindowsPowerShell 
Set-AADCloudSyncPasswordWritebackConfiguration -Enable $true -Credential $(Get-Credential) 

And with that, password writeback is working on Azure AD Cloud Sync!

Emerging from the Shadows

I have been getting back into the swing of building things just for fun and for exploration. I think a pressure can emerge that the things we create have to mean something, have to hit some mark of quality to be worthy of pursuing at all. I think that is a mistake, especially in that it discourages you from being open to areas where you don’t already have great expertise. So, here I am, putting into practice rejecting that pressure.

Continuing my theme of trying to work with lower-level APIs and with unmanaged languages like C and C++, I have developed a very simple client for Windows’ Volume Shadow Copy service, that allows me to create a shadow copy of a volume, copy some files in a folder to a destination, and then release the shadow copy.

I can see a use for this as part of a very low-tech backup solution where a drive is (most of the time) physically disconnected, and where you want to keep the technology stack as simple as humanly possible for the greatest flexibility in disaster recovery scenarios — BitLocker for external drives (compatible even with Windows client systems), and a bunch of VHDX files on an NTFS volume, copied there using VSS so you don’t have to bring your VMs down.

A big disclaimer is prominently offered — this is not production quality code. My discipline with the responsibility of memory management and other lower-level concepts is “emerging”, to use a euphemism.

Still, I thoroughly enjoyed this — it was challenging for where I currently am, but achievable. You can’t improve at something if you don’t let yourself produce output that wouldn’t perhaps yet meet your highest quality standards. (And goodness knows there is plenty of production code out there that never met those standards before it was relied upon by the world.) The perfect shall not be allowed to be the enemy of personal growth and development.

So, here is ShadowDuplicator, your very untested, extremely rudimentary VSS snapshot based backup client. Even if it’s just a workaround for a lack of vssadmin create shadow on client operating systems, it’s something. 😉

DfontSplitter 0.4 for Windows

I’m delighted to announce DfontSplitter 0.4 for Windows. After a nine-year hiatus without software updates, this release has big under-the-bonnet changes!

The application is now built with .NET 4.7.2 and runs on Windows 7 – Windows 10. If you still need support going back as far as Windows 98(!), you can still use the old version.

A new, improved, fondu (which does the bulk of the work) is bundled as a DLL that is Windows-native and no longer requires the Cygwin library. It also includes a number of memory safety improvements.

To fix the long-standing issue where extracted TTFs didn’t quite play nicely with Windows, DfontSplitter 0.4 for Windows embeds functionality from FontForge to do some final conversion work to make your fonts work perfectly with Windows.

Source is available on GitHub (DfontSplitter, fondu-win-dll)

The “T with chisel” DfontSplitter icon is licensed under the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. The icon includes a modified version of “Chisel wood 24mm” by Isabelle Grosjean, which is also licensed as such.

PFSense 2.4.5 on Hyper-V following 2020-05 Cumulative Update

Following applying the 2020-05 Cumulative Update for Windows Server 2016 (1607), a PFSense 2.4.5 Hyper-V virtual machine on this host OS suddenly became very unstable.

The machine appears to experience high load averages immediately following boot, with a large percentage of the vCPU usage (>99%) being shown as “system” in top.

Additionally, sometimes it is seen that the pfctl process is also using close to 100% of a CPU. The system is unresponsive, or intermittently responsive throughout this time — both in terms of the console, the web UI, and packet forwarding that the machine should be doing.

After a few minutes, Hyper-V appears to restart the guest OS. This isn’t a PFSense kernel panic and no dump is made by PFSense.

I spun up a new VM of the unstable daily snapshot of PFSense, a Generation 2 UEFI-based VM. This completely eliminated these problems for us in this new VM — it works fine, routes just fine for what we’re doing and is responsive.

I don’t have a solution — I just want to throw this issue out there in case others have experienced it, in case we might work together to figure out what’s going on here.

RoslynCodeAnalysisService creating SQLite Databases on C:

I recently opened an old version of my DfontSplitter C# project in Visual Studio 2019. I expected a process would need to be gone through to upgrade the project from its source version (VS2008 I believe) before it could be opened in Visual Studio 2019. Such a process did happen and it completed without errors.

A little later, I noticed something odd. A folder had appeared at the root of my C: drive with the name xyDQ7sfb+k4aZLT8oSso4yqXRQ=.

The unusual looking folder name contained a SQLite database.

Inside, a sqlite3 folder and the usual artifacts that you’d associate with a SQLite database.

At this point of my initial investigation, I hadn’t yet connected my opening of this Visual Studio project with this folder. It looked highly suspicious — a name that apparently was encoded and random.

Investigating the database

So, I fired up DB Browser for SQLite and pointed it at the database.

It contained tables including names like SolutionData2, ProjectData2, StringInfo2. Some investigation of the contents of these led me to this recent VS2008 project I’d opened.

I still felt it looked malicious though — was this something injecting itself into Visual Studio projects I was building?

Tracking down the source(?)

Some web searching later, I’d discovered a part of Roslyn, the C# compiler, which had references to these _SpellChecker_ entries I’d seen in SolutionData2 and the suggestion that this is dumped to persistent storage.

Catching it in the act

So, I deleted the folder from the C drive and replicated the process. I opened the same project again, but this time running Sysinternals Process Monitor in the background, filtering Path for sqlite or this folder name.

We can see calls to CreateFile (which creates a handle to a file — this is usually ‘opening’ the file rather than ‘creating’ it) with the result PATH NOT FOUND. Then, another call to CreateFile (highlighted) that actually creates the directory.

From there, it’s clear that this process, ServiceHub.RoslynCodeAnalysisService32.exe, is responsible for this database and its timing correlated exactly with me upgrading this project from VS2008 to VS2019.

But… what is this? Why?

I posted some Visual Studio Feedback about my observations, although this issue was closed as applying to sqlite, not Visual Studio. I understand that this isn’t high priority, but I disagree with the assessment that the use of SQLite in this case makes it SQLite’s fault!

So I remain curious. Do some code analysis on the solution, sure. But why store results in the root of the C drive? How is the encoded folder’s name decided? Why does this whole thing feel suspicious rather than behaviour I’d expect from an IDE?

And… it’s gone

As of Visual Studio 16.5.3, this appears to be fixed — the same filesystem behaviour by RoslynCodeAnalysisService32 is now prefixed with %LOCALAPPDATA%\Microsoft\VisualStudio\Roslyn\Cache\RemoteWorkspace. I guess it was indeed a bug — an oversight in actually setting the full path to this database properly.

Installing OpenWRT 19.07.2 on TP-Link WA801ND v5

I recently had some success installing OpenWRT 19.07.2 on my TP-Link WA801ND v5 wireless access point, which I was happy to do since the stock firmware was untouched since 2017.

I’ve documented the process in a video. This isn’t a tutorial with absolutely everything covered — I don’t want to encourage people to brick their devices, so you’ll need competence and proficiency with configuring your network settings in your operating system, and running a TFTP server.

It’s all, obviously, at your own risk. Stay safe and don’t brick your only access point!

Sorry for the inconsistency in audio quality.

Provisioning Raspbian with WiFi and SSH

Raspberry Pi logo

UPDATE: This does not work since Raspberry Pi OS based on bullseye. sdm might be a good alternative approach.

I’ve been playing with some Raspberry Pi Zero W machines for a few projects. They are inexpensive, with a form factor that makes for all sorts of interesting possibilities.

They are also a pain to initially provision, because you need adapter cables for mini-HDMI and micro-USB to get a monitor and keyboard connected.

With some help from this post from Linuxconfig.org, here’s what I’ve been doing to get the Pi Zero W up and running, on the network and ready for SSH access without having to plug anything in except power and the SD card!

Mount the image

$ fdisk -l *raspbian.img 

The initial FAT /boot partition lies at 8192 sectors in. A sector is 512 bytes. So, now we’ll mount the /boot partition using the loop pseudo-device.

$ mkdir boot
$ mount -o loop,offset=$(( 512 * 8192)) *raspbian.img boot

Set up SSH

Let’s go into our new boot subfolder where the image’s first partition is now mounted.

All we need to do to enable SSH is create an empty file called ssh.

$ cd boot
$ sudo touch ssh

Configure WiFi

To configure WiFi, we’ll need to drop a wpa-supplicant.conf file in this folder. Upon first boot, Raspbian moves this into the correct config location and the Pi will be able to talk to our network out of the box.

Create a file called wpa-supplicant.conf with these contents:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB

network={
	ssid="Your network name"
	psk="Your network password"
	key_mgmt=WPA-PSK
}

You’ll need to replace the placeholders with your network name and password, and possibly change country too.

Unmount the image

$ cd ..
$ umount boot

Write the image

Insert the target SD card and verify which device it is using fdisk.

Take great care to ensure that the command below is run with the correct device as the target, or you’ll overwrite a hard drive on your local system.

$ sudo fdisk -l

Disk /dev/sdb ...
Model: Card Reader

I am confident that sdb is correct, because I see from fdisk that the model is Card Reader.

$ sudo dd if=*raspbian.img of=/dev/sdb

Security

Remember that once you’ve booted, you’ve just spun up a Raspberry Pi on your network with the default username of pi and the default password of raspberry. Check your router or network logs for the assigned DHCP address of the new Pi, log in promptly over SSH and change that password!

Licensing: Restricting the ability to prevent others exercising their rights

There is great potential in using open source and free software licensing to support and encourage the ethical use of technology — and indeed to deter its use in violating human rights and provide some legal mechanisms to challenge this when it happens.

But it’s also an extremely complex and difficult issue, as there are always a great number of implications, and they’re not always easy to anticipate.

This is an area I watch with keen interest, and I was interested to read Matthew Garrett posing some interesting questions around how a clause relating to taking away another’s ability to exercise their rights under the licence might work. The idea is taking the moral goal of preventing harm being done to others by means of the software and expressing that goal in terms of prohibiting actions that would prevent others from exercising their rights under the same licence.

This work may not be used in any way that impairs any individual’s ability to exercise the permissions granted by this license, whether or not they have received a copy of the covered work

To be clear, I don’t think this is a good license – it has a bunch of unfortunate consequences like it being impossible to use covered code in self-defence if doing so would impair your attacker’s ability to use the software. I’m not advocating this as a solution to anything. But I am interested in seeing whether the perception of the argument changes when we refocus it on user freedom as opposed to an independent ethical goal.

Matthew Garrett