Linux find running display manager

In GNU/Linux, if you ever need to know what your currently running display manager is, here is how you can find it:

x="$( sudo lsof -F '' /tmp/.X11-unix/X0 | head -n1 )" ; x="${x#p}"
display_manager="$( ps -p $( ps -o ppid -p ${x} | tail -n +2 ) -ho command )"
thisdm="$( basename "${display_manager}" )"




Automated certreq for GNU/Linux

Last updated 2018-01-25


Microsoft provides the certreq utility for its non-free operating system. This tool makes it easy to get certificates from the Microsoft sub-CA on your network.

GNU Linux hosts do not get that tool, so a viable alternative is to script the interaction with the website. My content in this post is shamelessly ripped from a StackOverflow post and beefed up.

In my research, I came across a question: “How to submit certificate request from red hat to windows ca“.

The solution

The script

I present my shell script,
This shell script:

  • Generates CSR and submits it to the Microsoft Sub-CA.
  • Saves private key, public key (the certificate), and cert chain to a temporary directory
  • Removes the temp directory after 5 minutes automatically to remove the private key
  • Sends to standard out the file names and purposes, for consumption by automation tool, e.g., ansible

Code walkthrough

Instead of copying and pasting the whole code here, I will discuss only snippets.
Here is the usage block.

usage: [-dhV] [-u username] [-p password] [-w tempdir] [-t template] [--cn CN] [--ca ]
version ${certreqversion}
 -d debug   Show debugging info, including parsed variables.
 -h usage   Show this usage block.
 -V version Show script version number.
 -u username User to connect via ntlm to CA. Can be "username" or "domain\\username"
 -p password
 -w workdir  Temp directory to work in. Default is a (mktemp -d).
 -t template Template to request from CA. Default is "ConfigMgrLinuxClientCertificate"
 --cn        CN to request. Default is the \$( hostname -f )
 --ca        CA hostname or base URL. Example:
Return values under 1000: A non-zero value is the sum of the items listed here:
 0 Everything worked
 1 Cert file is still a CSR
 2 Cert file is html, probably due to permissions/credentials issue
 4 Return code of curl statement that saves cert file is non-zero
 8 Cert file does not contain whole certificate
16 Cert does not contain an issuer
Return values above 1000:
1001 Help or version info displayed
1002 Count or type of flaglessvals is incorrect
1003 Incorrect OS type
1004 Unable to find dependency
1005 Not run as root or sudo

All the magic happens at line 239, the main loop. These blocks perform the different web requests, and are the real meat of this script.

Block GENERATE PRIVATE KEY makes the csr and saves in to the file that will eventually hold the cert.

   openssl req -new -nodes \
      -out "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" \
      -keyout "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.key" \
      -subj "${CERTREQ_SUBJECT}"
   CERT="$( cat "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" | tr -d '\n\r' )"
   CERT="$( echo ${CERT} | sed -e 's/+/%2B/g' | tr -s ' ' '+' )"


   OUTPUTLINK="$( curl -k -u "${CERTREQ_USER}:${CERTREQ_PASS}" --ntlm \
      "${CERTREQ_CA}/certsrv/certfnsh.asp" \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Encoding: gzip, deflate' \
      -H 'Accept-Language: en-US,en;q=0.5' \
      -H 'Connection: keep-alive' \
      -H "Host: ${CERTREQ_CAHOST}" \
      -H "Referer: ${CERTREQ_CA}/certsrv/certrqxt.asp" \
      -H 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      --data "Mode=newreq&CertRequest=${CERT}&CertAttrib=${CERTATTRIB}&TargetStoreFlags=0&SaveCert=yes&ThumbPrint=" | grep -A 1 'function handleGetCert() {' | tail -n 1 | cut -d '"' -f 2 )"

FETCH SIGNED CERTIFICATE downloads the cert that the previous page links to.

   curl -k -u "${CERTREQ_USER}:${CERTREQ_PASS}" --ntlm $CERTLINK \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Encoding: gzip, deflate' \
      -H 'Accept-Language: en-US,en;q=0.5' \
      -H 'Connection: keep-alive' \
      -H "Host: ${CERTREQ_CAHOST}" \
      -H "Referer: ${CERTREQ_CA}/certsrv/certrqxt.asp" \
      -H 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' \
      -H 'Content-Type: application/x-www-form-urlencoded' > "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt"

My additions to this secret sauce start with GET NUMBER OF CURRENT CA CERT. I needed the cert chain, so I automated fetching it from the server.
You have to find out how many different CA certs are being offered by this server, and then use the latest.

   RESPONSE="$( curl -s -k -u "${CERTREQ_USER}:${CERTREQ_PASS}" --ntlm \
      "${CERTREQ_CA}/certsrv/certcarc.asp" \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Encoding: gzip, deflate' \
      -H 'Accept-Language: en-US,en;q=0.5' \
      -H 'Connection: keep-alive' \
      -H "Host: ${CERTREQ_CAHOST}" \
      -H "Referer: ${CERTREQ_CA}/certsrv/certrqxt.asp" \
      -H 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' \
      -H 'Content-Type: application/x-www-form-urlencoded' )"
   CURRENTNUM="$( echo "${RESPONSE}" | grep -cE 'Option' )"

   CURRENT_P7B="$( curl -s -k -u "${CERTREQ_USER}:${CERTREQ_PASS}" --ntlm \
      "${CERTREQ_CA}/certsrv/certnew.p7b?ReqID=CACert&Renewal=${CURRENTNUM}" \
      -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
      -H 'Accept-Encoding: gzip, deflate' \
      -H 'Accept-Language: en-US,en;q=0.5' \
      -H 'Connection: keep-alive' \
      -H "Host: ${CERTREQ_CAHOST}" \
      -H "Referer: ${CERTREQ_CA}/certsrv/certrqxt.asp" \
      -H 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' \
      -H 'Content-Type: application/x-www-form-urlencoded' )"

   echo "${CURRENT_P7B}" | openssl pkcs7 -print_certs -out "${CERTREQ_TEMPFILE}"

I like having the domain name in the filename, so this last part renames the cert chain.

   # will read only the first cert, so get domain of issuer of it.
   CA_DOMAIN="$( openssl x509 -in "${CERTREQ_TEMPFILE}" -noout -issuer 2>&1 | sed -r -e 's/^.*CN=[A-Za-z0-9]+\.//;' )"
   mv -f "${CERTREQ_TEMPFILE}" "${CERTREQ_WORKDIR}/${CHAIN_FILE}" 1>/dev/null 2>&1

The ansible role

I needed this task deployed to my whole environment, so I rolled it into an ansible role saved to gitlab and also added another feature, where it converts the generated cert files into a pcks12 (pfx) file for a specific application’s need.



  6. Manipulating ssl certificates

VeraCrypt rpm for Fedora

In these post-TrueCrypt days, I migrated to VeraCrypt. For a very long time now, I have been maintaining an encrypted file container on a flash drive on my keychain. Additionally, I keep various binaries to help open it, like on Windows or GNU/Linux, should I ever need emergency access to my files when not on one of my regular machines. I’m not NSA-proof, but I do intend to keep my private files out of the view of the general public or any random person who might find a lost flash drive.

So about VeraCrypt, A user can download the latest binary packages, even for GNU/Linux, from the offical downloads page. And the source code is on gitlab at

But nobody I could find on the Internet has a Fedora rpm package for it. Well, I present to you now my Veracrypt rpm project. It took me a while to figure out the different releases of VeraCrypt don’t compile on Fedora 27 for various bug-related reasons. But the freshest commit version does, so this rpm is generated from the beta upstream point in time where I saved a copy of the repo.

The normal way to compile any of my rpms is to use the usr/share/${package}/build/pack script. It will download sources, prepare the file list in the spec, and perform the rpmbuild.

Add custom kickstart file and root ca certificates to iso file

Introduction and goals

This is intended to be one of my longer posts. This article describes how to accomplish the following tasks:

  1. Insert custom kickstart files into an iso file
  2. Insert custom root CA certificates into the initrd.img of an iso file, so you can fetch a custom repository over https
  3. Write a sample kickstart file
  4. Open up the initrd.img to add more files

The example file used is Fedora-Workstation-netinst-x86_64-27-1.6.iso available from

The files

You will need a few files, including:

  1. kickstart file
  2. Root certificate

Kickstart files

My 2 different kickstart files are
fc27c-ks.cfg (saved to WordPress as a .doc, but it is truly just a plain text file)
Quite a few things to note about the content:
I had to use http for all my local repositories, even though I got the ca certficate loaded. I think how my ISP bounces back my https traffic causes enough slowdown on the ssl handshake it prevents anaconda from using it correctly. It was working earlier in the day but I had to disable it.
Observe in the %pre scriptlet the lines

cp -p /run/install/repo/ /etc/pki/ca-trust/source/anchors 2>/dev/null || :
update-ca-trust || :

These 2 lines load up the root certificate authority cert into the running initrd trusted keys, so the ssl connections are trusted.
Please see the attached or indicated files.

Root certificate

A root certificate is the certificate that signs other certificates for that namespace. I use my own in my ipa domain, and I use it on my web server. So to connect with ssl because I want to encrypt everything possible, I need this cert in the runtime environment on the iso disc image. My root ca file is
not shared on this blog. Go get your own!

The steps

Mount original iso

mkdir -p /mnt/originaliso
mount -v -o loop /mnt/public/Support/SetupsBig/Linux/Fedora-Workstation-netinst-x86_64-27-1.6.iso /mnt/originaliso/

Copy contents to work directory

mkdir -p /mnt/newiso ; cd /mnt/
time cp -pr originaliso/* newiso/

Copy in kickstart files

cp -pf /mnt/public/Support/Platforms/Fedora/fc27{x,c}-ks.cfg /mnt/newiso/
chown root:root /mnt/newiso/*ks.cfg
echo done

Tell disc to use new ks file

This task:

  • Adds xfce and cinnamon menu options
  • Find all the append= lines, and add to the end this attribute: ks=hd:LABEL=fc26:/fc26x-ks.cfg

The important piece is to have the LABEL= the volume name that you give the mkisofs -V “label” a few commands later in this article. If you really want to use a file:/ks.cfg, then you have to open up the initrd, which Appendix A demonstrates.

Fedora 27 xfce and cinnamon
sed -r -e "/append/{s/LABEL=([A-Za-z0-9_\-]*)(\s|:)/LABEL=${label}\2/;s/quiet//;};" -e '/label linux/,/^\s*$/H;' -e '/^\s*$/{x;};' "${tf}" | \
awk "BEGIN{a=0;b=0;labels[1]=\"xfce\";labels[2]=\"cinnamon\";} /^label [^l]/{b=b+1} b < 1 && /label linux/{a=a+1;\$0=\$0\" \"labels[a];} b < 1 && /menu label/{\$0=\$0\" \"labels[a];} b < 1 && /append/{\$0=\$0\"ks=hd:LABEL=${label}:/${label}\"substr(labels[a],1,1)\"-ks.cfg\";} {print;}" > "${tf}.$$"
mv -f "${tf}.$$" "${tf}"
Centos 7
sed -r -e "/append/{s/LABEL=([A-Za-z0-9_\-]*)(\s|:)/LABEL=${label}\2/;s/quiet//;};" "${tf}" | \
awk "BEGIN{a=0;b=0;labels[1]=\"with my bgstack15 custom kickstart\";} /^label [^l]/{b=b+1} b < 1 && /label linux/{a=a+1;\$0=\$0\" \"labels[a];} b < 1 && /menu label/{\$0=\$0\" \"labels[a];} b < 1 && /append/{\$0=\$0\"ks=hd:LABEL=${label}:/${label}-ks.cfg\";} {print;}" > "${tf}.$$"
mv -f "${tf}.$$" "${tf}"

Copy in certificate file

This will be used by the kickstart file and injected into the running initrd so https connections can be trusted to download the repos.

/bin/cp -pf /mnt/public/www/smith122/certs/ /mnt/newiso/
chown root:root /mnt/newiso/*.crt

Make new iso

Fedora 27
ti="${label}manual.iso"; cd /mnt/newiso;
rm -f /mnt/newiso/"${ti:-NOTHINGTODELETE}" ; __func() { mkisofs -V "${label}" -m '*.iso' -o "../${ti}" -b isolinux/isolinux.bin -c isolinux/ -no-emul-boot -boot-load-size 4 -boot-info-table -r -J -v -T . ; implantisomd5 "/mnt/${ti}" ; } ; time __func
CentOS 7
ti=centos7manual.iso ; cd /mnt/newiso ;
rm -f /mnt/newiso/"${ti:-NOTHINGTODELETE}" ; __func() { mkisofs -V "${label}" -m '*.iso' -o "../${ti}" -b isolinux/isolinux.bin -c isolinux/ -no-emul-boot -boot-load-size 4 -boot-info-table -r -J -v -T . ; implantisomd5 "/mnt/${ti}" ; } ; time __func

Copy to server so vm1 can access

time su bgstack15 -c "cp -pf /mnt/${ti} /mnt/public/Support/SetupsBig/Linux/";
echo done

Next steps

After that, the iso is ready to be burned to disc or used by virt-install. I have not actually tried burning a disc or usb drive, but I assume it’s pretty similar to a regular Live iso.
For virt-install, I was simply unable to get my fancy customized iso to work fully automatically. For a regular, unattended vm install, I use the regular Fedora netinstall iso and I inject my kickstart file.

vm=fc27x-02a ; time sudo virt-install -n "${vm}" --memory 2048 --vcpus=1 --os-variant=fedora25 --accelerate -v --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=20 -l /mnt/public/Support/SetupsBig/Linux/Fedora-Workstation-netinst-x86_64-27-1.6.iso  --initrd-inject=/mnt/public/Support/Platforms/Fedora/fc27x-ks.cfg --extra-args "ks=file:/fc27x-ks.cfg SERVERNAME=${vm}" --debug --network type=direct,source=eno1

And to destroy that vm when I’m done with it:

vm=fc27x-02a; sudo virsh destroy "${vm}"; sudo virsh undefine --remove-all-storage "${vm}";

But this custom iso that we built is ready to be inserted into a vm, where you can manually select the xfce or the cinnamon option. After that initial menu choice, everything else is automatic and unattended.


Appendix A: Modify initrd.img file

Right after step “Copy in certificate file,” if you want to modify the initrd.img file, you can use these steps:

Open initrd.img xz file

mkdir -p /mnt/initrd1; cd /mnt/initrd1; time xzcat /mnt/originaliso/isolinux/initrd.img | cpio -d -i -m

Perform any file modifications to that filesystem in /mnt/initrd1.

Assemble new initrd.img file

cd /mnt/initrd1 ; time find . | cpio -o -H newc | xz --check=crc32 --x86 --lzma2=dict=512KiB > /mnt/newiso/isolinux/initrd.img




Internal documents

~/2017/Systems/guides/Add custom kickstart to iso file.odt

Palemoon 64-bit for Linux and Flash Player Plugin

  1. Install Palemoon using the from
  2. Visit the main page at or use this direct link: and install it.
  3. Load the libraries in the directory Pale Moon looks in:
    sudo ln -s /usr/lib64/flash-plugin/ /usr/lib/mozilla/plugins/


My links


Fedora 27 ssh and default kerberos config

On my new Fedora 27 system which I joined to my FreeIPA domain, I encountered an error I hadn’t seen before.
In the past I could just say “ssh remotehost” and it would connect me with GSSAPI auth using my kerberos key– no password or ssh key needed! It was wonderful. However, I ran into this issue, as seen with ssh -v remotehost

debug1: Unspecified GSS failure.  Minor code may provide more information
Server host/remotehost@IPA.EXAMPLE.COM not found in Kerberos database

But I know for a fact it’s in the kerberos database!
I duckducked (new verb) the error message and found the culprit.
In file /etc/krb5.conf, this variable should be set to this value:

  dns_canonicalize_hostname = true

The default is true according to man krb5.conf. but for whatever reason, whether by joining the domain, or some default of some package in Fedora 27, it was set to false.

For the followers of my bgscripts package, just use this command:

sudo updateval -a /etc/krb5.conf -s '[libdefaults]' '^(\s*dns_canonicalize_hostname\s*=\s*).*' '  dns_canonicalize_hostname = true'




Palemoon 64-bit for Linux and Google Talk Plugin

  1. Install Palemoon using the from
  2. Visit gmail and initiate a call, which will cause it to prompt you to download the google talk plugin. Install it.
  3. Load the libraries in the directory Pale Moon looks in:
    pushd /usr/lib/mozilla/plugins 1>/dev/null 2>&1
    sudo ln -s ../../../../opt/google/talkplugin/
    sudo ln -s ../../../../opt/google/talkplugin/
    popd 1>/dev/null 2>&1

    You don’t even need to close and re-open the browser!

You will still get the warning “Hangouts phone calls will temporarily stop working in Firefox.” When making an outgoing call, you can dismiss the warning. However, I was unable dismiss the warning when receiving a call, which means I was not able to receive calls. I don’t know how to fix that part.

Also, on occasion, it simply wouldn’t make an outgoing call. Just cancel and try again, and then it will work.



Original research

rpmrebuild google-talkplugin_current_x86_64.rpm

Python get Linux-compatible password hash

This snippet gets you a sha-512 ($6) password hash suitable for putting in /etc/shadow.

# Reference:
# python 2
import crypt, getpass, sys;
if len(sys.argv) >= 2: 
 thisraw=getpass.getpass(prompt='New password: ')