Quick and dirty script to set up a terminal server with xfce

Who needs proprietary OSes and CALs to use a terminal server? Not this guy!

Here’s the guidelines I use when standing up a new terminal server with Xfce, because Gnome operates too slowly and is bloated. This is my file named el7ts201.txt.

# How to install terminal server

sudo su -
sed -i -r -e '/10\.200/s/^[^#]/#/;' -e '/^\&/s/^/#/;' /etc/rsyslog.conf
systemctl restart rsyslog

# install epel
# reference: https://www.tecmint.com/how-to-enable-epel-repository-for-rhel-centos-6-5/
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install epel-release-latest-7.noarch.rpm

# install xrdp
yum -y groupinstall xfce ; yum -y install xrdp tigervnc-server patch xfce4-whiskermenu-plugin ; yum -y remove gnome-session

# install fonts
yum -y install gnu-free-*-fonts open-sans-fonts libXfont xorg-x11-font*

touch "${tf}" ; chmod 0644 "${tf}" ; restorecon "${tf}" ; chown root.root "${tf}"
cat <<'EOF' 1> "${tf}"
<?xml version="1.0" encoding="utf-8"?>
  <description>Terminal services</description>
  <port protocol="tcp" port="3389"/>
firewall-cmd --reload
firewall-cmd --add-service=xrdp --permanent
firewall-cmd --reload

# add XFCE to the /etc/X11/xinit/Xclients file
cp -p "${tf}" "${tf}.$( date "+%s" )"
cat <<'EOFXCLIENTS' 1> "${tf}"

STARTXFCE="$(type -p startxfce4)"

# check to see if the user has a preferred desktop

# We should also support /etc/X11/xinit/Xclients.d scripts
if [ "$#" -eq 1 ] && [ -x "$XCLIENTS_D/Xclients.$1.sh" ]; then
    exec -l $SHELL -c "$SSH_AGENT $XCLIENTS_D/Xclients.$1.sh"

# Failsafe.

# these files are left sitting around by TheNextLevel.
rm -f $HOME/Xrootenv.0

systemctl enable xrdp xrdp-sesman
systemctl start xrdp xrdp-sesman

echo done

# Next steps
# apply valid ssl certificate

Control ansible verbosity and silence with tags

I wonder if I have stumbled upon a use case that other haven’t yet.

I just learned about how to use callback plugins in ansible, which are generally responsible for output.

I found one named “selective” which means that it will show the output for only the tasks with a tag titled “print_action.” My goals included having mundane tasks be silent, not whitelisting the important tasks. Plus, it shows every task anyway if you do a -v for verbose.

Also, using callbacks took me some effort. To even allow different callback plugins, you have to add the names you want available to the [defaults] callback_whitelist variable in ansible.cfg, which is comma-space-delimited. And place the plugin in of the directories specified by callback_plugins, normally /usr/share/ansible_plugins/callback_plugins.

Next, to actually use it for a play, define ANSIBLE_STDOUT_CALLBACK with the name of the plugin to use.


$ cat ansible.cfg
callback_whitelist = short
$ ANSIBLE_STDOUT_CALLBACK=short ansible-playbook myplaybook.yml

I present to you today my customized callback plugin! It operates just like the default callback, but with two modifications, both dependent on tags of the tasks.

  • tag: verbose will cause the output to always be like the -v flag
  • tag: silent will completely hide the task output when successful. Failures and skips appear like normal.

My plays tend to have a lot of minor tasks like deploying assistant scripts or cleaning up temp files, and I don’t want tons of scrollback in my terminal just because 5 different temp files were removed (or not) at the end of a play across 150 systems.

Verify ansible vault password

# prepare vault password file
printf 'Vault password: ' ; read -se VAULT_PASS ; printf '\n' ;
echo "${VAULT_PASS}" > "${PWFILE}"
# fail out if password is incorrect
! ansible-vault view --vault-password-file "${PWFILE}" "${VAULTFILE}" 1>/dev/null && exit 1

You can use shell to read in the password and save it to a file. Just remember to clean it up at the end!

I like to do this right before a shell loop that calls ansible with vaulted values multiple times, so I’m not prompted multiple times to enter the password.

Install openssl-1.1.0 on CentOS7

I really wanted the -proxy flag on the openssl command. It’s not available in the provided openssl package (1.0.1 series), but it is in the 1.1.0 which is now the base package in Fedora. But for the Enterprise Linux users, you need to do a little bit of work to get it.

Download a pre-compiled package

You could just download the package from my copr. Save the contents of the .repo file [copr.fedorainfracloud.org] or use them from here.

name=Copr repo for stackrpms owned by bgstack15

Install with:

yum install openssl110

And then the binary has been named openssl110

Download and compile the source

wget https://www.openssl.org/source/openssl-1.1.0i.tar.gz
tar -zxf openssl-1.1.0i.tar.gz
cd openssl-1.1.0i
sudo make install

To prevent an error that resembles:

/usr/local/bin/openssl version
/usr/local/bin/openssl: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory

You have to provide the library files in a directory that the dynamic linker is looking in. There are multiple ways to tackle this.

Option 1: update library path

Add the directory containing the libcrypt.so.1.1 and similar files to the LD_LIBRARY_PATH environment variable.

export LD_LIBRARY_PATH=/usr/local/lib64:${LD_LIBRARY_PATH}

Option 2: move library files to lib directory

Or just move the files to the main library location. On a x86_64 system, that would be:

mv libcrypto.so.1.1 libssl.so.1.1 /usr/lib64/



Internet search openssl s_client http proxy [duckduckgo.com]
openssl s_client using a proxy [stackoverflow.com]
How to update openssl 1.1.0 in Centos 6.9/7.0 [linuxscriptshub.com]

Extract src.rpm files

Command is borrowed from How To: Extract an RPM Package Files Without Installing It (cyberciti.biz)

rpm2cpio myrpmfile.rpm | cpio -idmv

When you search for “rpm2cpio” it shows that page, but you have to click into it and scroll down to find the one command. Maybe this page will supplant that one in the Internet searches and make it easier to see the command to run from the lede in the search results.

Kerberos notes and sssd Internal credentials cache error

If sssd gives you errors about unable to connect, it’s probably the host password (keytab) is out of date with what AD has. You have to reset the host account in AD, or even delete the computer account and rejoin the domain.

kdestroy -A
kinit domainadmin
msktutil -f -s host
msktutil -u -s host
kinit -k "$( hostname -s | tr '[[:lower:]]' '[[:upper:]]' )\$@MSAD.EXAMPLE.COM"
klist -kt

The kvno value in the output of klist -kt should match the attribute “msDS-KeyVersionNumber” of the server object in AD.

Error can include:

(Thu Aug  9 15:28:57 2018) [[sssd[krb5_child[3177]]]] [create_ccache] (0x0020): 1009: [-1765328188][Internal credentials cache error]
(Thu Aug  9 15:28:57 2018) [[sssd[krb5_child[3177]]]] [map_krb5_error] (0x0020): 1657: [-1765328188][Internal credentials cache error]
(Thu Aug  9 15:29:22 2018) [[sssd[krb5_child[3333]]]] [privileged_krb5_setup] (0x0080): Cannot open the PAC responder socket
(Thu Aug  9 15:29:22 2018) [[sssd[krb5_child[3333]]]] [sss_send_pac] (0x0040): sss_pac_make_request failed [-1][2].
(Thu Aug  9 15:29:22 2018) [[sssd[krb5_child[3333]]]] [validate_tgt] (0x0040): sss_send_pac failed, group membership for user with principal [bgstack15\@MSAD.EXAMPLE.COM@MSAD.EXAMPLE.COM] might not be correct.

Monitor owner and permissions changes

A user on the Fedora forum asked for assistance monitoring owner and permissions changes to files. I whipped up a general solution in shell.

It uses a compressed database to store the last run, and will show the changes of the requested attributes of each file.

Here’s some of the business logic.

   # not empty
   test -n "${CO_DEBUG}" && echo "Comparing ${CO_INPUT} to database ${CO_OUTPUT}"

   # learn current status
   scan_dir "${CO_INPUT}" > "${CO_TMPFILE}"

   # compare to database
   zcat "${CO_OUTPUT}" | diff -W300 --suppress-common-lines -y "-" "${CO_TMPFILE}"

   # replace database
   cat "${CO_TMPFILE}" | gzip > "${CO_OUTPUT}"

And the scan function is pretty simple. Just change what stat outputs if you want to monitor different file characteristics.

scan_dir() {
   # call: scan_dir "${CO_INPUT}"
   # output: listing of hash, owner+perm hash for each file
   local td="${1}"

   find "${td}" -exec stat -L -c '%u,%U,%g,%G,%a,%n' {} + 2>/dev/null | sort -t ',' -k6

The script stores its compressed databases in /var/cache/check-owners/, and it will make files named based on the base directory it scans, so /home would be db file /var/cache/check-owners/co.home.db.gz.

You could write a cron entry to call this once a day on a particular directory and email the output to you. A poor man’s AIDE, if you will.