Auto mount a disk that is encrypted with luks

Overview

The anaconda installer can ask you if you want to encrypt a partition when you are setting up a new system.
What if after the fact you want to add an encrypted disk that is auto-mounted at boot?
This post explains how to prepare a new partition that is encrypted and configure your system to mount it at boot. This guide is aimed at Fedora -based systems like RHEL and CentOS, and tested specifically on CentOS 7.3.

Preparing the system and disk

Ensure package cryptsetup is installed.

yum -y install cryptsetup

Prepare a valid disk and partition which the system can find.
Make a partition of the preferred size and of type Linux filesystem or Linux reserved.

# sudo fdisk /dev/vdb
Command (m for help): p
Disk /dev/vdb: 16.1 GB, 16106127360 bytes, 31457280 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: gpt
#         Start          End    Size  Type            Name
 1         2048     31457246     15G  Linux reserved

The example partition in this post is /dev/vdb1.

Initializing the encrypted partition

Perform the initial setup of the encrypted partition. The dash here means it will prompt for a password (or accept it from standard input).

cryptsetup luksFormat /dev/vdb1 -
# cryptsetup luksFormat /dev/vdb1 -

WARNING!
========
This will overwrite data on /dev/vdb1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase: 
Verify passphrase:

Get the UUID of the partition using the blkid command.

blkid
# blkid
/dev/vdb1: UUID="b8f055d6-cd91-43e8-afbc-85fa1f6d3d7b" TYPE="crypto_LUKS" PARTUUID="6614fac8-8d0c-45dd-a1a7-b799248bc370"

To get just the sole output you need:

thisblockid=$( blkid /dev/vdb1 -o value | head -n1 )

To open the encrypted partition, use luksOpen.

­cryptsetup luksOpen /dev/vdb1 "luks-${thisblockid}"
# cryptsetup luksOpen /dev/vdb1 luks-$( blkid /dev/vdb1 -o value | head -n1 )
Enter passphrase for /dev/vdb1: 
# ll /dev/mapper
lrwxrwxrwx. 1 root root       7 Jul  9 16:08 luks-b8f055d6-cd91-43e8-afbc-85fa1f6d3d7b -> ../dm-2

Now the /dev/mapper/luks-${thisblockid} path exists.
Make a filesystem of your choice.

mkfs.ext4 /dev/mapper/luks-b8f055d6-cd91-43e8-afbc-85fa1f6d3d7b

Now you can mount this wherever you wish.

Mounting the encrypted partition automatically

To mount this encrypted partition at boot, you will need to modify /etc/fstab and /etc/crypttab.
Add to /etc/fstab an entry:

/dev/mapper/luks-b8f055d6-cd91-43e8-afbc-85fa1f6d3d7b   /mnt/foo        ext4    defaul
ts        0 0

Add to /etc/crypttab an entry:

luks-b8f055d6-cd91-43e8-afbc-85fa1f6d3d7b UUID=b8f055d6-cd91-43e8-afbc-85fa1f6d3d7b -

Now for each boot, you will be prompted to provide the luks passphrase before it can mount the specified mount point (in this case, /mnt/foo). The system will fail to boot completely if you do not provide the passphrase, even for an unimportant directory like /mnt/foo: It will drop into single-user mode.

References

Weblinks

  1. Guide to placing a keyfile on a USB flash drive https://askubuntu.com/a/90911/533065
  2. Inspiration for learning this topic http://vsnapshots.blogspot.com/2014/07/well-i-thought-id-have-quiet-year-and.html

Man pages

crypttab
cryptsetup

Virsh get total cpu allocations

tl;dr

virsh list | awk '{print $1}' | grep -oIE "[0-9]*" | while read word; do virsh dominfo ${word} | grep "CPU.s"; done | awk 'BEGIN {a=0;} {a=a+$2;} END {print a;}'

The explanation

If you want to get the total allocation of vCPUs to all the guests on a kvm host, you can use this one-liner.
virsh list gets the list of running domains (virtual machines).
The awk and grep get only the domain id numbers (could do it by domain name if you wish).
virsh dominfo gets the cpu allocation for each listed domain, by iterating over the list.
The final awk statements counts the numbers.

Get total physical CPUs available

virsh nodeinfo
CPU model:           x86_64
CPU(s):              24
CPU frequency:       1899 MHz
CPU socket(s):       1
Core(s) per socket:  6
Thread(s) per core:  2
NUMA cell(s):        2
Memory size:         198310648 KiB

System selecting wrong time due to not UTC

The problem

I use kickstart files to configure my CentOS 7 virtual machines. One problem I discovered is that the vms can get the wrong time from the hwclock. I guess I haven’t mastered ntpd or chronyd. I can always just run ntpdate dns1.ipa.example.com but haven’t bothered to set up a cronjob/systemd unit for that.
Anyway, I finally discovered how to get the hwclock and system date to actually grab the time correctly from the host OS. If I don’t set the timezone correctly in the kickstart file with the –utc option:

timezone America/New_York --utc

I can go modify /etc/adjtime myself.
An incorrect file:

0.000000 1499048878 0.000000
1499048878
LOCAL

The correct file replaces the LOCAL with UTC, to tell the system that the hardware clock (hwclock) is showing the UTC time:

0.000000 1499048878 0.000000
1499048878
UTC

A reboot later, and now my vm has the correct time, so I have achieved my ultimate goal of gssapi auth.

References

Weblinks

  1. That such a file exists as /etc/adjtime https://eloquence.marxmeier.com/sdb/html/954237377.html
  2. https://bugzilla.redhat.com/show_bug.cgi?id=672194

Do task until it succeeds

A story

I was working on my vm and needed to reboot it. In order to ssh back into the machine, I would have to wait for it to come back online and start up ssh.

Instead of manually polling myself, I whipped up this little one-liner:

while ! ssh centos7-01a; do true; done

So it failed silently at first, and then started showing ssh_exchange_identification: Connection closed by remote host.
Then when OpenSSH was finally ready for me, my kerberos authentication proceeded normally and I was in.
Upon closing my session, the while loop concluded and returned me to my shell.

I came up with this little snippet on a whim, and it actually helped me out and was not obtrusive and did not fail in any way.

Boot systems into different targets manually

Boot system into different targets manually

You need to modify the boot command. On the grub2 screen where it shows the boot options, press e to edit.
On the line that starts with linux16, append one of these possible values:

systemd.unit=emergency.target
systemd.unit=rescue.target
systemd.unit=multi-user.target
systemd.unit=graphical.target

With one of those items added to the kernel instruction, press CTRL+X to boot the kernel.

Reference

Weblinks

  1. https://www.youtube.com/watch?v=LgAI_n7NueY