Archive for

June, 2017

...

C++ and gtest setup

Comments Off

The neat thing about C and C++ on Linux, is that it’s very much a native language. It means that compilers, tools and libraries are part of the core repositories, and easily installed. The following includes the basic setup to get started with C++ development.

apt-get install gcc g++ gdb cmake make libgtest-dev

Unit tests are great, and the Google Test (gtest) framework makes it straight forward to write and run. The gtest Debian / Ubuntu package requires a bit of manual installation as well, as described here. The crux of it:

cd /usr/src/gtest
sudo cmake CMakeLists.txt
sudo make
sudo cp *.a /usr/lib

The following is a minimal example, which includes the test code and method under test in the same file for the sake of simplicity. Normally, the tests and code would of course be split.

#include "gtest/gtest.h"
 
int multiply(int a, int b) {
  return a * b;
}
 
TEST(HelloTest, Multiply) {
  EXPECT_EQ(2, multiply(1, 2));	
}
 
 
int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

To compile the code above, take care to include all required arguments. The default executable binary output is “a.out” (or use the -o option to set a custom name), which can be executed, and the test result output should show.

g++ -pthread hello_test.c -lgtest_main -lgtest
./a.out

Comments Off

QNAP compatible encrypted disks

Comments Off

I’ve previously written about encryption on the QNAP TS-431P NAS and basic cryptsetup usage. Since then, encryption standards and defaults have changed, and it is now easy to create an external encrypted disk which cannot be mounted by a QNAP NAS. The following shows how to work around the issues with cipher and ext4 journaling settings.

The first issue has to do with the default cipher algorithms on Ubuntu and QNAP. As of Ubuntu 16.10, the default cipher is Advanced Encryption Standard (AES) in xts-plain64 mode with a SHA256 hash. The default and supported encryption on the QNAP NAS is also AES, using “128-bit block size, with key sizes of 128, 192 or 256 bits”. However, the supported mode is cbc-essiv:sha256 with hash spec SHA1, as with older Ubuntu and Debian distributions. When trying to decrypt the drive on the NAS, you might see errors like “Failed to setup dm-crypt key mapping for device /dev/sdc1. Check that kernel supports aes-xts-plain64 cipher (check syslog for more info)” and in /var/log/storage_lib.log an error like “crypt: IV mechanism required”.

It should be noted that this is most likely not an issue with volumes created by the NAS itself on its internal drives, unless you start moving drives from one NAS box to another, which is probably not recommended in the first place.

To see the supported ciphers, both on a normal GNU/Linux distribution and the QNAP, use the following commands:

cat /proc/crypto
 
cryptsetup --help

Also, to see the currently used cipher and LUKS formatted volume, use the luksDump command:

cryptsetup luksDump /dev/sdX1

Formatting

If you start from scratch, it’s easy to work around the incompatibility. Follow the instructions in the cryptsetup basics article, but add the following options for cipher and hash function to the luksFormat command. Note that this will format and erase all data on the partition.

cryptsetup luksFormat --cipher aes-cbc-essiv:sha256 --hash sha1 /dev/sdX1

You might also consider ext3 over ext4, since the former seems better supported by the QNAP NAS at the time of writing. See below for further details.

Changing the cipher

If on the other hand, you discover the incompatibility a bit too late, and have already filled up the external disk with a lot of content, you’re not all out of luck. You’ll just have to decide which way you’d like to waste your time: You can transfer it all over to another disk, reformat, and then transfer back. It will take a few hours, and a bit of work. Or, you can change the encryption cipher on the existing volume, using the cryptsetup-reencrypt tool. However, you’ll probably have to wait multiple days while the whole disk is re-encrypted. On a 2 TB external disk over USB 2.0, it took about 35 hours to complete.

cryptsetup-reencrypt --cipher aes-cbc-essiv:sha256 --hash sha1 --key-file /tmp/keyfile --key-slot 0 /dev/sdX1

Notice that the command uses the same cipher and hash arguments above. However, it adds arguments for the key file to unlock the volume, and which key slot that file is linked to. This is necessary to avoid being asked about each and every password for each of the key slots. Of course, if you have only added a single password based key slot, these arguments can be skipped, and you’ll have to type the password once.

ext4 journaling compatibility

Once the encrypted volume can be opened, there might still be hurdles. The default settings for the ext4 journaling might also not be compatible with the QNAP NAS. At this point, I have to admit I lost interest in researching exactly what the cause was, and fired off multiple changes at once. The error when using the mount command was “mount: wrong fs type, bad option, bad superblock on /dev/mapper/sdc1, missing codepage or other error”.

The default features set from the Ubuntu 16.10 created ext4 formatted partition was:

dumpe2fs /dev/mapper/sdc1
...
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum

The following commands removed a few of them, changed to 32 bits, finished with a check:

tune2fs -O ^huge_file /dev/mapper/sdc1
tune2fs -O ^dir_nlink /dev/mapper/sdc1
tune2fs -O ^extra_isize /dev/mapper/sdc1
tune2fs -O ^metadata_csum /dev/mapper/sdc1
 
e2fsck -f /dev/mapper/sdc1
 
tune2fs -O ^64bit /dev/mapper/sdc1
resize2fs -s /dev/mapper/sdc1

In the end, the following features remained, and the volume mounted.

Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file uninit_bg

Comments Off