Mount an lvm logical volume from a qcow2 file

Mounting qcow2 files to host filesystem

Converting to raw and mounting

kpartx does not work very well with qcow2 files. You can convert the qcow2 file to a raw file:

oldfile=file.qcow2
newfile=file.raw
qemu-img convert "${oldfile}" "${newfile}"

You can now find the partitions and map them:

kpartx -av "${newfile}"
mount /dev/loop2p2 /mnt/foo

Modifying a virtual machine to use the new image file

You can modify a virtual machine definition to use this new file:

virsh dumpxml ${domain} > domain.xml
vi domain.xml # Lines “source file=/path/file.raw” and “driver name=qemu type=raw"
virsh create domain.xml

Mounting lvm logical volumes from the image file

Update lvm with the currently attached disks.

pvscan; lvscan; lvdisplay

Now you can mount /dev/mapper/cl_centos7–02a_root to a mount point.

References

Weblinks

  1. Converting qcow2 file to raw to make it work with kpartx https://www.certdepot.net/rhel7-access-virtual-machines-console/#comment-41448
  2. An alternate way to mount a qcow2 file http://ask.xmodulo.com/mount-qcow2-disk-image-linux.html

Man pages

  1. virsh

Resize a live logical volume

Resizing a live logical volume

If you use lvm to abstract the filesystems away from the direct hardware, you might need to know how to add additional space without taking the filesystem offline. This post shows how you might do that.

Attach new disk

Save current state to a file for comparison.

ls -l /dev/{s,v}d* > ~/ls.dev.sd.before

Install additional disk to system (in hypervisor or attach to physical machine).
Scan with rescan-scsi-bus.sh (from sg3_utils package).
If that fails, try

find /sys/class/scsi_host/host*/scan | while read line; do echo "- - -" > $line; done
lsblk

Find the name of the new disk:

ls -l /dev/{s,v}d* > ~/ls.dev.sd.after
diff ~/ls.dev.sd.before ~/ls.dev.sd.after

The output should be the name of the new disk.

Create a new partition

How to do it in fdisk:

fdisk /dev/newdisk
n[enter]
p[enter]
1[enter]
[enter]
w[enter]

Add the partition to lvm and the logical volume

pvcreate /dev/newdisk1
vgextend vgname /dev/newdisk1
lvextend /dev/vgname/lvname /dev/newdisk1

Resize the filesystem

Filesystem type ext4 can be resized live:

resize2fs /dev/vgname/lvname

sshd_config match negate address

tl;dr

Match Address *,!192.168.1.0/24

Negating address in match statement in sshd_config

I was locking down my ssh server configuration on a host, so that it will not accept password auth from outside a certain IP address range.
I had to learn how to get the Match Address directive to work with a negation. To make it work, you need to insert a wildcard before you then state the exclusion.

Match Address *,!192.168.1.0/24

And then I added the directives for this matched IP address range.

   AuthenticationMethods publickey
   PubkeyAuthentication yes
   PasswordAuthentication no
   X11Forwarding no

References

Weblinks

  1. https://serverfault.com/questions/408284/how-can-the-address-condition-in-a-match-conditional-block-in-sshd-config-be-neg

Man pages

  1. sshd_config
  2. ssh_config

Send authenticated gmail from cli with mailx

Overview

I’ve shown how to send authenticated gmail from the command line before. That uses msmtp which takes some configuration.
This document shows how to use mailx itself to send authenticated gmail.

tl;dr

echo "this is the message" | mailx -s "Subject line here" \
-S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login \
-S smtp=smtp://smtp.gmail.com:587 -S from="bgstack15@gmail.com(B Stack)" \
-S smtp-auth-user="bgstack15@gmail.com" \
-S smtp-auth-password="${SMTPPASSWORD}" -S ssl-verify=ignore \
-S nss-config-dir=/etc/pki/nssdb/ destination@example.com

Explanation

You need a certificate chain somewhere. You could also try nss-config-dir=~/.mozilla/firefox/xxxxxxxx.default.
If you use the whole command in the tl;dr section, you don’t need any config file. Of course, be aware that any parameter passed on the command line is visible to any other program running, so passing in the password like seen above is risky.
You can redirect standard in from a file if you wish, of course, or from a here-document.
For a dedicated configuration, and better password security, consider adding in to your ~/.mailrc file:

set smtp-use-starttls
set nss-config-dir=/etc/pki/nss/
set ssl-verify=ignore
set smtp=smtp://smtp.gmail.com:587
set smtp-auth=login
set smtp-auth-user=bgstack15@gmail.com
set smtp-auth-password=QWERTYUIOP
set from="bgstack15@gmail.com(B Stack)"

And then just use:

mailx -s "Subject line" destination@example.com

References

Weblinks

  1. https://bgstack15.wordpress.com/2017/04/03/send-authenticated-gmail-from-command-line/
  2. Inspiration for entire contents https://www.systutorials.com/1411/sending-email-from-mailx-command-in-linux-using-gmails-smtp/

Cinnamon on VNC on CentOS 7

Overview

This document describes how to install Cinnamon desktop environment on CentOS 7 for use in VNC. Basically, you can take a headless server and turn it into a virtual desktop controller.

Caveats

Limitations of this design prevent this from scaling up past so many users, so this would be best suited for home or small office use.
VNC uses no security. Consider alternatives or additions to this process when security is a consideration.

Installing Cinnamon for VNC

Installing the components

Install the vnc server.

yum install tigervnc-server tigervnc vnc

Install the desktop environment.

yum install cinnamon

Install any applications to be used.

yum install firefox gnome-terminal

Configuring the components

For each user that uses a virtual desktop on this host, you will need a separate systemd service, as well as a vnc password which is separate from the regular user password. Also set up the xstartup file for vnc.

tu=bgstack15
tn=1
sudo cp -p /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@\:${tn}.service
sed -r -i -e "s//${tu}/g;' /etc/systemd/system/vncserver@\:${tn}.service
systemctl enable vncserver@\:${tn}.service
firewall-cmd --permanent --add-port 59$( printf '%02i' "${tn}")/tcp
printf "For user ${tu} please provide new "
su - ${tu} -c vncpasswd
tf=~/.vnc/xstartup
test -f "${tf}" && \cp -p "${tf}" "${tf}.$( date "+%Y-%m-%dT%H%M%S" )"; touch "${tf}"; chmod 0755 "${tf}"
cat <<EOF > "${tf}"
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
exec /usr/bin/cinnamon-session
EOF
systemctl start vncserver@\:${tn}.service

Connecting to the desktop

On a client, run

vncviewer hostname:1

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