Friday, February 18, 2022

Installing VeraCrypt on Raspberry Pi4


Raspberry Pi 4 Project

I have been interested in small computing devices for awhile starting with various Arduino projects.  Recently I took on a new Raspberry project where I needed it to be able to read encrypted USB drives.  I ran into several issues along the way that I intend to document here to help others attempting similar things.

When working with a PI I generally use the Raspbian OS, it has been the one I have had the most success with.  For this project I tried both the Lite and the Full versions of the OS, and while they were both successful, the full version had one feature that caused me to go with it over Lite.

USB exFat Issue

The USB drives I was using were 64GB, which means they were too big for the older FAT32 format and were formatted exFat.  The full version of Raspbian auto mounted and read them perfectly, while the Lite version could not and needed the exFAT libraries installed using the following two commands:

sudo apt-get install exfat-fuse
sudo apt-get install exfat-utils

I didn't have any problem installing the libraries, but after install the drives would still not auto mount as the documentation indicated they should.  They did work correctly after performing a manual mount  using the following command:

sudo mount -t exfat /dev/sda1 /mnt/usb1

Part of this project was having an environment that wouldn't take me too long or too much work to re-create in the future if my micro SD card died.  So rather than continue to fight with why the USBs were not auto mounting, I ditched my preferred Lite version of Raspbian, and went with the Full version.

VeraCrypt

Now that my external USB drives were working correctly "out of the box", all I really needed to do was install the VeraCrypt software.  I use VeraCrypt because it is both free and one of the simplest and most portable encryption options available.

The first place I looked for a package was the recent downloads.  I grabbed the armhf version which is advertised as working on the 32bit Raspbian OS.  After installing and attempting to run it I was presented with the following errors:

veracrypt: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by veracrypt) veracrypt: /usr/lib/arm-linux-gnueabihf/libwx_gtk3u_core-3.0.so.0: version `WXU_3.0.5' not found (required by veracrypt)

I founded one post that indicated the errors meant I had the wrong version of the libraries installed.  It took me awhile to figure out the actual names of the libraries the dependencies were referring to, however Code Yarns finally solved that problem for me telling me to run this command.

sudo apt install libfuse-dev libwxbase3.0-dev

Unfortunately I was still getting the same error.  Considering Ashwin from Code Yards was successful in getting it to work, and remembering the errors were supposed to be version issues, not just if the libraries were installed at all, I decided to see if the version of VeraCrypt Ashwin used would work.

But of course I didn't want to go all the way back to his version, so I started walking my way back trying each version to see if one would work.  Not a particularly fun task as VeraCrypt is not compiled for Raspian with each iteration, you have to go into each folder and see if you can find an armhf version compiled.  Several people solved this issue by simply compiling the latest version of VeraCrypt for themselves; but again, I was trying to go for the most easily reproducible build.

I finally found a working version in VeraCrypt 1.24 Update 7.  My guess is that if I had looked for newer versions of libfuse and libwxbase I might have been able to use a newer version of VeraCrypt as well.

After that it was all down to testing the install and making sure encrypted files could be created and opened.  I had no more issues afterwards, the Raspberry Pi device is really becoming quite the powerful tool these days.

Tuesday, February 15, 2022

SQL Server fast failover in High Availability Groups

 I recently had the somewhat dubious honor of helping migrate a company from a physical data center to the Azure cloud.  I say dubious because for as many positives as there are about Azure, there are at least the same number of negatives.  The only feature Azure has that makes it worth migrating, in my opinion, for most smaller companies is the ability to work and see the environment the same way a data center would see it; so much more visibility, not good visibility, just visibility.

However, my feelings about Azure are not the point of this post.  As a part of this migration we went from a traditional failover SQL cluster to an Always on High Availability group; primarily because the dba doing the migration could not figure out how to do a failover cluster in Azure.

In my short exposure to the high availability option it is both good and bad.  The automated failover in SQL server is faster than it was using the old method, however the visibility into the individual server databases is worse.

The DBA handling the migration was unable to figure out how to manually fail back the system in a reasonable time frame.  He was using a SQL script that failed back one availability group at a time.  This approach would leave our system down for up to a minute, a time frame that would increase as we added more databases to the system, and this was a big problem.

To solve this problem I decided to go with a multi-threaded approach so I could fail back every availability group simultaneously.  Unfortunately SQL does not seem to have any form of reasonable multi-threaded capability available for a script to use.  So I turned to scripting languages.

While this script could be written in most scripting languages, I chose the older VBscript this time.  The general idea is that the script loops through all found availability groups, and spins up an instance of itself in a separate thread to start a failover for each one.


Const sqlUser = "<username>" ' add your server admin login username here
Const sqlPass = "<password>" ' add the password for the username here
Const Server = "<ip address>" ' enter the ip address of the DESTINATION server to fail to here

Const adOpenStatic = 3
Const adLockOptimistic = 3

'
' Here is where we fail over the current AG
'
If (WScript.Arguments.Count > 0) Then
    'Wscript.Echo WScript.Arguments.Item(0)
Set failConnection = CreateObject("ADODB.Connection")
    failConnection.Open _
        "Provider=SQLOLEDB;Data Source=" + Server + ";" & _
            "Trusted_Connection=No;Initial Catalog=master;" & _
                 "User ID=" + sqlUser + ";Password=" + sqlPass + ";"
failConnection.Execute "ALTER AVAILABILITY GROUP " + WScript.Arguments.Item(0) + " FAILOVER;"

failConnection.Close
Set failConnection = Nothing
    WScript.Quit 0
End If



'
' Below is where we get the list of AGs to fail over
'


Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
GetCurrentFolder = FSO.GetAbsolutePathName(".")

Set objConnection = CreateObject("ADODB.Connection")
Set WshShell = WScript.CreateObject("WScript.Shell")


objConnection.Open _
    "Provider=SQLOLEDB;Data Source=" + Server + ";" & _
        "Trusted_Connection=No;Initial Catalog=master;" & _
             "User ID=" + sqlUser + ";Password=" + sqlPass + ";"

Set objRecordSet = objConnection.Execute("SELECT name FROM master.sys.availability_groups")

objRecordSet.MoveFirst

Do Until objRecordSet.EOF
    'Wscript.Echo objRecordSet.Fields("name")
WshShell.Run Wscript.ScriptFullName + " " + objRecordSet.Fields("name")
objRecordSet.MoveNext
Loop

objRecordSet.Close
objConnection.Close
Set objConnection = Nothing

Wscript.Echo "All failover commands fired"


With this approach the entire fail back is reduced to a couple of seconds, and the time does not increase noticeably as additional groups get added in the future.