Mikrotik Configuration Backup

Backing up Mikrotik configuration is easy. Just save the backup and copy it to your machine.

ssh router.local '/export file=mybackup' $ scp router.local:/mybackup.rsc /backup/mybackup.rsc

This results in a binary file you can directly load upon restore. And that’s ok for the backup. But what if you want to track changes over time? Binary file won’t do. Welcome text export.

Fortunately, we can also get /export to output the data in textual format. Since this data will include things like dates and similar things that change with every execution, we use awk and sed to remove those.

ssh router.local '/export' \
  | tr -d '\r' \
  | awk '{sub(/^ +/, "", $0); if (sub(/\\$/,"")) printf "%s", $0; else print $0}' \
  | sed "s/^# .* by RouterOS/# RouterOS/" \
  | sed "/^# managed by CAPsMAN$/d" \
  | sed "/^# channel: .*, CAPsMAN forwarding$/d" \
  | sed "/^# $/d" \
  > /backup/mybackup.txt

The result is reasonably clean file that can be committed to Git or any version control software of your choice.

Overthinking UART Pinout

Quite a few of my boards have a 4-pin UART output. And it’s always the same: [TXD GND RXD VCC]. But this pinout seems strange to quite a few people. I promise, there’s a method to the madness.

First of all, what is the most common UART pinout and why don’t use it? Well, the most common output I’ve seen on other people boards is [VCC RXD TXD GND] and I hate it because it’s really unforgiving if you accidentally plug it the wrong way. When I started playing with electronics, I used to use this pinout and, after frying a couple of boards, I’ve learned to triple-check that I don’t plug it rotated 180°. Even so, it still makes me nervous.

The other common pinout I’ve seen around is [VCC GND RXD TXD] and this one is slightly better as you can safely rotate it 180°. When it comes to common accidents (180° or off-by-one), it’s really hard to fry the board using this one. But this pinout also has its twin brother [VCC GND TXD RXD] thus ensuring you need 1x1 Dupont connector for each wire.

For my “standard” pinout I wanted to be able to easily switch TXD and RXD lines. Since UART really needs only three pins, it was clear that the first three pins had to be [TXD GND RXD]. This way rotating 180° allows you to connect two cables together allowing for point-to-point connection.

In order to provide power, I just added the extra pin for the final [TXD GND RXD VCC] pinout. If you accidently rotate it 180°, nothing happens. If you plug it off-by-one, nothing happens. And, if you don’t need power, you can plug only the first 3 pins and everything still works.

It’s as full-proof as it gets for me.

My ZFS Settings

In multiple posts so far I’ve created a ZFS pool using pretty much the same parameters. But I never bothered to explain why I chose them. Until now…

From my latest ZFS-related post, I have the following pool creation command:

zpool create -o ashift=12 -o autotrim=on \
    -O compression=lz4 -O normalization=formD \
    -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O atime=off \
    -O encryption=aes-256-gcm -O keylocation=prompt -O keyformat=passphrase \
    -O canmount=off -O mountpoint=none $POOL $DISK

ashift=12

This setting controls the block size of your pool and should match whatever your (spinning) disk uses. Realistically, you’ll probably use 4K sectors thus 12 is a good starting value. Why the heck 12? Well, this is expressed as 2ⁿ and 2¹² is 4 KB. I like to force it because often ZFS might wrongly auto-detect value 9 (512 bytes) which shouldn’t be really used these days. This is not really ZFS’ fault but consequence of some disks being darn liars to preserve compatibility.

Even if you do have 512-byte disks today, any replacement down the road will be at least 4K. Since the only way to change this option is to recreate the pool one should think ahead and go with 4K immediately.

When it comes to SSD setups there might be some benefit in going even higher since SSD usually use 8K or even larger erase blocks. However, since SSDs are much more forgiving when it comes to the random access, most of time it’s simply not worth it because large block sizes will cause other issues (e.g., slack space).

autotrim=on

Support for trim is really important for SSD and completely irrelevant when it comes to the spinning rust. Since my NAS uses good-old hard drives, this setting really doesn’t apply. But I also use ZFS on my laptop and there it makes a huge difference. So I include it always just not to forget it by accident when it matters.

compression=lz4

While zstd seems to be a compression darling, I still prefer lz4 for my local datasets because it’s much easier on the CPU. There’s also an option to turn off compression completely, but I honestly cannot determine any speed improvement in a general case. Using compression is like receiving free space, so why not?

normalization=formD

As ZFS uses Unicode (UTF-8 more specifically), it has an interesting problem that two filenames might look the same but they might have two different expressions. Most known example might be Å which can be expressed either as Å or as combination of A and a separate ring mark. From the point of user, both these are the same. But they have a different binary expression (U+00C5 vs U0041 U+030A).

Setting normalization explicitly just ensures each file name is stored in its canonical Unicode representation and thus things that look the same are going to be the same. I personally like formD on a philosophical level but any normalization will do the same. Just don’t stick with default value of none.

acltype=posixacl

This option allows you to store extra access attributes not covered by a “standard” user/group/world affair. The most common need for these attributes is with SELinux. However, even if you’re not using SELinux, you should enable it as it doesn’t really impact anything if not used. And you might consider using SELinux in the future.

xattr=sa

This option will tell ZFS to store extra access attributes (see above) with the metadata. This is a huge performance boost if you use them. If you don’t use them it has no effect so you might as well future-proof your setup.

dnodesize=auto

Assuming you already save all these extra attributes, it’s obvious they cannot really fit nicely in one metadata node. Unless it’s a big one. Once set, this option (assuming feature@large_dnode=enabled) will allow larger than normal metadata at the cost of some compatibility. Assuming you have ZFS 0.8.4 or above, you really have nothing to worry about.

atime=off

Posix standard specifies that one should always update access time whenever file or directory is accessed. You went into your home directory - update. You opened a file without changing anything - update. These darn updates really stack up and there is really no general use case where you would need to know when the file was read. This flag will turn off these updates.

encryption=aes-256-gcm

I like my datasets encrypted. Ideally one would use full disk encryption but using ZFS native encryption is a close second with unique benefits at a cost of minor data leaks (essentially only ZFS dataset names). And GCM encryption is usually the fastest here.

keyformat=passphrase

Call me old-fashioned but I prefer a passphrase to a binary key. Reason is that I can enter passphrase more easily in a pinch.

keylocation=prompt

For my laptop I keep prompt as a key source so I can easily type it. For servers, I use file:// syntax here since I keep my passphrase on a TmpUsb USB drive. This allows me to reboot server without entering key every time but in the case it’s ever stolen my data is inaccessible.

canmount=off, mountpoint=none

As a rule, I try not to have top-level dataset mountable. I just use it to set defaults and data goes only in sub-datasets.

And that’s all the explanation I’m ready to offer.

Rabbit Managed

One of my first vivid memories when it comes to having fun while programming definitely contains me implementing RC4 encryption in QBasic. Algorithm was perfect. It worked on per-byte text, was simple enough to have at least basic understanding what the heck was happening, and it gave me a bit of “el bandito” feeling as algorithm was leaked. Going over RC4 encouraged me to reinvent the wheel and was a direct cause of my love into creating own encryption algorithms. And I’ve created quite a few…

In time I learned a bit more about encryption. Or at least enough to understand why “rolling your own” is generally a bad idea. With time my beloved RC4 got its ass kicked by cryptoanalysis to be finally deprecated in 2015. My focus meantime went toward block algorithms, most notably Twofish and later AES version of Rijndael. My mind decided to go block cipher route but my heart still longed for good old stream cipher times.

As someone following crypto-world as a hobby, I was surprised I missed a whole stream cipher competition - eSTREAM. At this time it’s already an ancient news but results of that competition are still available in the form of 4 secure software stream ciphers: HC-128, Rabbit, Salsa20/12, and SOSEMANUK. All these eSTREAM finalists are still secure, completely free, and really nostalgia inducing for those with a soft spot for stream ciphers.

One that immediately drew my attention was Rabbit. As name suggests, this one was really fast. Additionally, it has quite understandable method of operation, uses no “exotic” operations, it has a reasonably small state (513 bits), and it’s specified in RFC4503. The only thing I couldn’t find was a C# implementation wrapping it into a SymmetricAlgorithm so it can be easily used with CryptoStream. Well, now there’s one…

If you want to use the Rabbit from C#, take a look at my RabbitManaged class. It derives from SymmetricAlgorithm and exposes ICryptoTransform interface so it can be used with CryptoStream. While it uses 128-bit blocks internally, it also allows usage without padding (i.e. more like a traditional stream algorithm). It also allows for all standard paddings.

Considering wide prevalence of AES, its usage will be limited at best but I believe into not having all eggs in one basket and you might find usage for it still. But damn, it was fun to implement this little gem.

PS: For nostalgia, I also have a SymmetricAlgorithm implementation of RC4.

Turning Off Narrator in Windows 10

My problem started with a cat. She loves enforcing my laptop breaks and having some laptop time herself. Whenever that happens, I lock my laptop and let her be for 5 minutes. Without fail she’ll manage to turn off wireless and enable the darn Windows Narrator. And no, turning off the Narrator shortcut doesn’t help.

Issue here is that lock screen works under completely different environment and permanently disabling narrator shortcut for your user will do nothing. No, solving this requires a bit more interaction and the easiest way I found is through registry editing.

To turn off the Narrator, there is a well documented WinEnterLaunchEnabled registry value. For our user we can find this at HKEY_CURRENT_USER\Software\Microsoft\Narrator\NoRoam but for logon user this hides at HKEY_USERS\S-1-5-18\Software\Microsoft\Narrator\NoRoam. Setting this DWORD value to 0 sorts the issue even without going for restart.

However, since my cat also plays with touchpad, I decided to remove the whole Ease of Access portion to ensure erroneous touchpad movements as cat lays down cannot turn anything on. For this we need the [BrandingNeutral](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-embedded-embeddedlogon-brandingneutral) value. This can be found at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Embedded\EmbeddedLogon. Setting DWORD value to 8 followed by a restart sorts out that issue.

Those full of trust can download registry file with these settings here and import them automatically while others can do the registry changes manually. In either case Windows 10 will become a bit more cat friendly.