Tag: Linux

Iterating through files/folders with spaces in name using find in bash

Ran into a problem using Sphinx to document some Python modules and scripts that Scott put together for OpenHAB. They’re making some changes to the files to get Sphinx to process them, thus making copies of the original code. Problem is, some of the folders just weren’t showing up in the copy. Needed to change IFS in order to tokenize the find results into full paths that don’t break on spaces in file or folder names.

SAVEDIFS=$IFS
IFS=$(echo -en "\n\b")

for DIRNAME in $(find "$COMMUNITY_DIR" -maxdepth 1 -type d 2>/dev/null); do
     echo $DIRNAME
done
IFS=$SAVEDIFS

Finding Block ID

I upgraded my Fedora kernel to 5.1 and the secondary disk mounted to /var disappeared. I use the old-school device notation in fstab;  when a disk comes up with a different name, the partition fails to mount. I wanted to change fstab to use a UUID. But first I needed to find the UUID. Enter blkid

[root@linux123 ~]# blkid /dev/sdb1
/dev/sdb1: LABEL=”mnt-var” UUID=”50545e50-75c5-45q5-95b5-34f5456515d5″ TYPE=”ext4″ PARTUUID=”m50525d5-05″

The command output includes the device UUID which is used instead of the /dev/sdb# string.

#/dev/sdb1                                                                           /var ext4 nodev,nosuid 0 2
UUID=50545e50-75c5-45q5-95b5-34f5456515d5 /var ext4 nodev,nosuid 0 2

Rebooted and my partition mounted.

Using sed to insert lines into a file

I’ve used sed to replace file content — use a regex to replace the sendmail.cf line that routes mail directly with a smarthost directive

sed -i -e 's/^DS/DS\\\[mailTWB.example.com\\\]/' $strSendmailDirectory/etc/mail/sendmail.cf

But I’ve needed to prepend text to a file. Turns out sed acn do that. In fact, you can insert strings at any line number. Using “sed -i ‘5s;^;StringsToInsert\n;’ filename.xtn will insert “StringsToInsert\n” at line 5. To prepend text to a file, use “1s”

[lisa@fedora tmp]# cat test.txt;sed -i ‘5s;^;NewLine1\nNewLine2\n;’ test.txt;cat test.txt
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
**********
Line 1
Line 2
Line 3
Line 4
NewLine1
NewLine2
Line 5
Line 6
**********

 

I’ve also come across an oddity in the Win32 sed — the method I usually use to blow away everything after a newline for some reason blows away everything after the first line. Works fine on RHEL7 and Fedora29, so the quick solution is “run it from the Linux box”.

C:\temp>cat input.txt
line 1
line 2

line 3
line 4
line 5
C:\temp>sed -i ‘/^$/q’ input.txt&cat input.txt
line 1

Kernel Updates In GNOME

Since I usually do not install X11 ‘stuff’ on my Linux hosts — using the console interface — I do not have any experience installing kernel updates on “desktop” type systems. Evidently, the best practice is to drop out of the GUI into what I’d call init 3 then install the kernel updates. You can get random hangs and malfunctions when you attempt to update the kernel whilst in the graphic console.

Recovering A Seriously Screwed Up Fedora System

The graphical interface on a Fedora 28 laptop was unavailable — buggered up video device/driver. Change to what used to be called run level 3, and we could not log in! We know the root password, but it would not take it. Single user is password protected too — and we were unable to log in there.

Normal recovery process:

Get to the grub menu, highlight the kernel you want to boot, and hit ‘e’ to edit it. Scroll down. On line that starts with linux16, change “rhgb quiet” to say “rd.break enforcing=0”
ctrl-x to boot

Once you get a shell:
mount -o remount,rw /sysroot
chroot /sysroot

Voila, you’ve got access to your files. Use vi to edit whatever has the box seriously screwed up (passwd if your problem is that you don’t know the root password) and you’re set. We reset the root password just in case. Aaaand … we still couldn’t log in on init 1 or init 3! And at this point I was feeling stubborn about getting logged into the box.

Now you can tweak up the system so it is not using sulogin when booting into single user mode but that isn’t a good way to install network-sourced packages. For some reason, we had to disable selinux before we could log into anything other than the graphical target. I’m sure there is a policy we could have tweaked, but it was far easier to disable the thing, boot into the multi-user target, sort the video driver, and then boot into the graphical target.

Systemd (a.k.a. where did my log files go!?!?!)

A systemd Primer For sysvinit Users

Background:

Starting in Fedora 15 and RHEL 7, systemd replaces sysvinit. This is a touchy subject among Unix folks – some people think it’s a great change, others think Linux has been ruined forever. Our personal opinions of the shift doesn’t matter: vendors are implementing it, WIN Linux servers use it, so we need to know it. Basically, throw “systemd violates the minimalist, modular philosophy at the core of Unix development” on the “but emacs is so awesome, why are we using vim” and “BETA outperforms VHS any day of the week” pile.

Quick terminology – services are now called units. You’ll see that word a lot. A unit is configured in a “unit file”. Additionally, “run levels” (0-6) have been replaced with the concept of “targets” that have friendly names.

What’s the difference?

Sysvinit wasn’t designed to know about your system, it was designed to run scripts on your system. Sysvinit essentially runs scripts, whereas systemd is a service manager. Systemd knows about the system. One place this becomes apparent – if you manually run the run line from a sysvinit script then check the service status, it will show running because the binary has a PID. If you do the same with systemd, it will say the service is down. This is like Windows – if you have a Docker service that runs “”C:\Program Files\Docker\Docker\com.docker.service”” set to run manually, and use start-run to run the exact same string … the service will not show as running.

Systemd manages a lot of different unit types. As application owners, we’ll use ‘service’ units. ‘Mount’ or ‘automount’ type units manage mountpoints. Socket and device unit types manage sockets (which have associated service unit files using the socket) and devices. Because systemd manages sockets, inetd/xinetd have been obsoleted.

Sysvinit scripts could run user-defined commands. If the init script for myapplication has a section called “bob”, you can run “service myapplication bob” and it will do whatever the ‘bob’ part of the script says to do. Systemd has a fixed list of directives – start, stop, restart, reload, status, enable, disable, is-enabled, list-unit-files, list-dependencies, daemon-reload. You cannot just make a new one.

Systemd may also require a system reboot for more than just kernel patches. This is really different, and I expect there will be a learning curve as to what requires a reboot.

Log files have “vanished”. If you are using a default installation, you won’t find /var/log/messages. You can use “journalctl -f” to tail the equivalent of the messages file. The systemd log files are stored in binary format – potentially corruptible, which is another aspect of the change Unix-types don’t care for.

What does systemd give me?

Systemd doesn’t just start/stop a service when run levels change. A unit can be started because it is configured to start on the runlevel (just like sysvinit scripts), if another service requires it, if the service abends, or if dbus triggers it. “If another service requires it” – that’s a dependency chain. Instead of defining an order and hoping everything you need was loaded by the time the init script ran, systemd allows you to include an “After” directive – units started before the current unit or “Before” – units that will not be started until the current unit starts. Additional directives for “Requires” – units which must be activated to activate the current unit and “Wants” – units that will be started in parallel with the current unit but failing to start these units will not fail the current unit.

A directive, “Conflicts”, allows systemd to identify other units that cannot coexist with the current unit. Conflicting units will be stopped to allow the current unit to start. In addition to the base command starting in the unit file (ExecStart), there are pre (ExecStartPre) and post (ExecStartPost) operations that are run before/after the base command. These could be related to the service itself but do not have to be. You could run a mail command line to alert an admin every time the unit starts or stops cleanly.

Another nice feature of systemd is user-level services – using systemctl –user will control unit files located in user-specific directories like /usr/lib/systemd/user/ and ~/.config/system/user/

Using systemd: (Warning: this is going to get odd)

You use systemctl to control units, and you use journalctl to view the binary blobs that have replaced log files. Use the man pages or your favourite search engine if you want details. The general syntax for systemclt is “systemctl operation unit.type” – e.g. “systemctl restart sendmail” would restart sendmail.

Chkconfig has been completely supplanted. Use “systemctl enable unit.type” and “systemctl disable unit.type” to control if a service auto-starts. Instead of using chkconfig –list, you can query the startup state of an individual unit. Use systemctl –is-enabled unit.type

There’s a service shell script that replaces ‘service’ that you used with sysvinit systems. It turns the old “service something-or-other action” into “systemctl action name.service” so it still works.

Here’s the odd part – it is quite easy to define a permitted sudo operation that allows a non-root user to control sysvinit services. Allow “service sendmail” and the user can run “service sendmail start”, “service sendmail stop”, “service sendmail status”, “service sendmail RandomStuffITossedIntoTheFile”. Because the service name and directive are swapped around in systemctl, we would have to enumerate each individual directive that should be permitted. More secure, because RandomStuffITossedIntoTheFile should not make the cut. But we haven’t done this yet. So until we go through and enumerate the reasonable actions (Are there directives beyond start/stop/status that we should be running? Do we have any business enabling and disabling our services?), submit the access request, confirm it’s all functioning as expected, and remove the “sudo service” access … continue using “sudo service something-or-other action”. We will advise you when the systemctl sudo access has been granted so we can start using the “new way” to control services on RHEL7 systems.

Unlike init scripts, changes to systemd unit files are not immediately activated on the system. Running “systemctl daemon-reload” makes systemd aware of the config change.

Using journalctl:

Our Unix team has implemented rsyslogd to output log data to the expected files. This means you can more or less ignore journalctl – tail/grep the log file as usual. I don’t foresee this changing in the near to mid term, but if you use cloud-hosted sandbox servers (i.e. boxes that don’t have the Unix group’s standard config) … journalctl is what happened to all the log files you cannot find.

To view logs specific to an individual unit, use journalctl -u unit.type. Additionally “systemctl unit.type status” will display the last handful of log lines from the unit.

Running Sendmail In A CHROOT Jail

My employer’s OS-support model restricts root access to members of the Unix support team. Applications are normally installed into a package directory and run under a service ID. While this model works well for most applications, sendmail is tightly integrated into the OS and is not readily built into an application directory. We attempted to run sendmail as a non-root user with modified permissions on application directories such as /var/spool/mqueue – this worked, until OS patches were applied and permissions reset. We needed a way to run sendmail as a non-root user and allow the OS support team to patch servers without impacting the sendmail application.

Chroot is a mechanism that uses a supplied directory path as the environment’s root directory. The jailed process, and its children, should not be able to access any part of the file hierarchy outside of the new root. As a security mechanism, the approach has several flaws – abridged version of the story is that it’s not terribly difficult to break out of jail here; and there are far more effective security approaches (e.g. SELinux). However, chroot jails have their own copies of system owned directories (such as /var/spool/mqueue), binaries, and libraries. Using a chroot jail will allow us to maintain a sendmail application in the package directory that is not impacted by OS updates.

This approach works on relaying mail servers (i.e. those that queue mail to /var/spool/mqueue and send it on its merry way). If sendmail is hosting mailboxes, there are additional challenges to designing a chroot configuration that actually drops messages into mailbox files that users can access.

Preliminaries: To copy/paste, view the single article. Create a service account under which sendmail will run. The installation directory should be owned by the service account user.

Set up the chroot jail location in the installation directory. In this example, that directory is /smt00p20.

mkdir /smt00p20/sendmail
mkdir /smt00p20/sendmail/dev
mkdir /smt00p20/opendkim

We need a null and random in the sendmail jail. On a command line, run:

# Create sendmail jail /dev/null
mknod /smt00p20/sendmail/dev/null c 1 3
# Create sendmail jail /dev/random
mknod /smt00p20/sendmail/dev/random c 1 8

We need an rsyslog socket added under each jail. In /etc/rsyslog.conf, add the following:

# additional log sockets for chroot'ed jail
# Idea from http://www.ispcolohost.com/2014/03/14/how-to-get-syslog-records-of-chrooted-ssh-sftp-server-activity/
$AddUnixListenSocket /smt00p20/sendmail/dev/log
$AddUnixListenSocket /smt00p20/opendkim/dev/log

 

Additionally, these instructions assume both sendmail and sendmail-cf have been installed on the server. If they have not, you can download the RPMs, unpack them, and copy the files to the appropriate relative jail locations.

Chrooting Sendmail

Logged in with the sendmail ID, ensure you have a .bash_profile that loads .bashrc

-bash-4.2$ cat ~/.bash_profile
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

Edit ~/.bashrc and add the following, where smt00p20 is the appropriate installation directory, to allow copy/paste

export SENDMAILJAIL=/smt00p20/sendmail
export OPENDKIMJAIL=/smt00p20/opendkim

Log out of the service account and back in (or just source in the .bashrc file). Verify SENDMAILJAIL and OPENDKIMJAIL are set.

Copy a whole heap of ‘stuff’ into the jail – this includes some utilities used to troubleshoot issues within the jail which aren’t strictly needed. I’ve also unpacked the strace RPM to the respective directories within the jail.

mkdir $SENDMAILJAIL/bin
mkdir $SENDMAILJAIL/etc
mkdir $SENDMAILJAIL/etc/alternatives
mkdir $SENDMAILJAIL/etc/mail
mkdir $SENDMAILJAIL/etc/smrsh
mkdir $SENDMAILJAIL/lib64
mkdir $SENDMAILJAIL/lib
mkdir $SENDMAILJAIL/lib/tls
mkdir $SENDMAILJAIL/tmp
mkdir $SENDMAILJAIL/usr
mkdir $SENDMAILJAIL/usr/bin
mkdir $SENDMAILJAIL/usr/sbin
mkdir $SENDMAILJAIL/usr/lib
mkdir $SENDMAILJAIL/usr/lib/sasl2
mkdir $SENDMAILJAIL/var
mkdir $SENDMAILJAIL/var/log
mkdir $SENDMAILJAIL/var/log/mail
mkdir $SENDMAILJAIL/var/run
mkdir $SENDMAILJAIL/var/spool
mkdir $SENDMAILJAIL/var/spool/mqueue
mkdir $SENDMAILJAIL/var/spool/clientmqueue
 
cp /etc/aliases $SENDMAILJAIL/etc/
cp /etc/aliases.db $SENDMAILJAIL/etc/
cp /etc/passwd $SENDMAILJAIL/etc/
cp /etc/group $SENDMAILJAIL/etc/
cp /etc/resolv.conf $SENDMAILJAIL/etc/
cp /etc/host.conf $SENDMAILJAIL/etc/
cp /etc/nsswitch.conf $SENDMAILJAIL/etc/
cp /etc/services $SENDMAILJAIL/etc/
cp /etc/hosts $SENDMAILJAIL/etc/
cp /etc/localtime $SENDMAILJAIL/etc/
 

# If cloning an existing server, scp /etc/mail/* from source to /smt00p20/sendmail/etc/mail

# Verify the sendmail.mc has a RUNAS_USER set to the same service account you are using - the account on our servers is named 'sendmail'. Our old servers are not all set up with a runas user, and failing to have one will cause write failures to the jail /var/spool/mqueue

cp -r /etc/mail/ $SENDMAILJAIL/etc/etc/mail/
cp /usr/sbin/sendmail.sendmail $SENDMAILJAIL/usr/sbin/sendmail.sendmail

cd /smt00p20/sendmail/etc/alternatives
ln -s ../../usr/sbin/sendmail.sendmail ./mta

cd /smt00p20/sendmail/usr/sbin
ln -s ../../etc/alternatives/mta ./sendmail
ln -s ./sendmail ./newaliases
ln -s ./sendmail ./newaliases.sendmail

cd /smt00p20/sendmail/usr/bin
ln -s ../sbin/sendmail ./mailq
ln -s ../sbin/sendmail ./mailq.sendmail
ln -s ../sbin/sendmail.sendmail ./hoststat
ln -s ../sbin/sendmail.sendmail ./purgestat
ln -s ../sbin/makemap ./makemap
ln -s ./rmail.sendmail ./rmail
cp /usr/lib64/libssl.so.10 $SENDMAILJAIL/usr/lib64/libssl.so.10
cp /usr/lib64/libcrypto.so.10 $SENDMAILJAIL/usr/lib64/libcrypto.so.10
cp /usr/lib64/libnsl.so.1 $SENDMAILJAIL/usr/lib64/libnsl.so.1
cp /usr/lib64/libwrap.so.0 $SENDMAILJAIL/usr/lib64/libwrap.so.0
cp /usr/lib64/libhesiod.so.0 $SENDMAILJAIL/usr/lib64/libhesiod.so.0
cp /usr/lib64/libcrypt.so.1 $SENDMAILJAIL/usr/lib64/libcrypt.so.1
cp /usr/lib64/libdb-5.3.so $SENDMAILJAIL/usr/lib64/libdb-5.3.so
cp /usr/lib64/libresolv.so.2 $SENDMAILJAIL/usr/lib64/libresolv.so.2
cp /usr/lib64/libsasl2.so.3 $SENDMAILJAIL/usr/lib64/libsasl2.so.3
cp /usr/lib64/libldap-2.4.so.2 $SENDMAILJAIL/usr/lib64/libldap-2.4.so.2
cp /usr/lib64/liblber-2.4.so.2 $SENDMAILJAIL/usr/lib64/liblber-2.4.so.2
cp /usr/lib64/libc.so.6 $SENDMAILJAIL/usr/lib64/libc.so.6
cp /usr/lib64/libgssapi_krb5.so.2 $SENDMAILJAIL/usr/lib64/libgssapi_krb5.so.2
cp /usr/lib64/libkrb5.so.3 $SENDMAILJAIL/usr/lib64/libkrb5.so.3
cp /usr/lib64/libcom_err.so.2 $SENDMAILJAIL/usr/lib64/libcom_err.so.2
cp /usr/lib64/libk5crypto.so.3 $SENDMAILJAIL/usr/lib64/libk5crypto.so.3
cp /usr/lib64/libdl.so.2 $SENDMAILJAIL/usr/lib64/libdl.so.2
cp /usr/lib64/libz.so.1 $SENDMAILJAIL/usr/lib64/libz.so.1
cp /usr/lib64/libidn.so.11 $SENDMAILJAIL/usr/lib64/libidn.so.11
cp /usr/lib64/libfreebl3.so $SENDMAILJAIL/usr/lib64/libfreebl3.so
cp /usr/lib64/libpthread.so.0 $SENDMAILJAIL/usr/lib64/libpthread.so.0
cp /usr/lib64/libssl3.so $SENDMAILJAIL/usr/lib64/libssl3.so
cp /usr/lib64/libsmime3.so $SENDMAILJAIL/usr/lib64/libsmime3.so
cp /usr/lib64/libnss3.so $SENDMAILJAIL/usr/lib64/libnss3.so
cp /usr/lib64/libnssutil3.so $SENDMAILJAIL/usr/lib64/libnssutil3.so
cp /usr/lib64/libplds4.so $SENDMAILJAIL/usr/lib64/libplds4.so
cp /usr/lib64/libplc4.so $SENDMAILJAIL/usr/lib64/libplc4.so
cp /usr/lib64/libnspr4.so $SENDMAILJAIL/usr/lib64/libnspr4.so
cp /usr/lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/usr/lib64/ld-linux-x86-64.so.2
cp /usr/lib64/libkrb5support.so.0 $SENDMAILJAIL/usr/lib64/libkrb5support.so.0
cp /usr/lib64/libkeyutils.so.1 $SENDMAILJAIL/usr/lib64/libkeyutils.so.1
cp /usr/lib64/librt.so.1 $SENDMAILJAIL/usr/lib64/librt.so.1
cp /usr/lib64/libselinux.so.1 $SENDMAILJAIL/usr/lib64/libselinux.so.1
cp /usr/lib64/libpcre.so.1 $SENDMAILJAIL/usr/lib64/libpcre.so.1
cp /usr/lib64/libnss_dns.so.2 $SENDMAILJAIL/usr/lib64/libnss_dns.so.2
cp /usr/lib64/libnss_files.so.2 $SENDMAILJAIL/usr/lib64/libnss_files.so.2

cd $SENDMAILJAIL/lib64
cp /lib64/libnss_dns-2.17.so $SENDMAILJAIL/lib64/libnss_dns-2.17.so
ln -s ./libnss_dns-2.17.so ./libnss_dns.so.2

cp /lib64/libresolv-2.17.so $SENDMAILJAIL/lib64/libresolv-2.17.so
ln -s ./lib64/libresolv-2.17.so ./libresolv.so.2

cp /lib64/libnss_files-2.17.so $SENDMAILJAIL/lib64/libnss_files-2.17.so
ln -s ./lib64/libnss_files-2.17.so ./libnss_files.so.2

cd $SENDMAILJAIL/lib 
cp /lib64/libnss_dns-2.17.so $SENDMAILJAIL/lib/libnss_dns-2.17.so
ln -s ./lib/libnss_dns-2.17.so ./libnss_dns.so.2

cp /lib64/libresolv-2.17.so $SENDMAILJAIL/lib/libresolv-2.17.so
ln -s ./lib/libresolv-2.17.so ./libresolv.so.2

cp /lib64/libnss_files-2.17.so $SENDMAILJAIL/lib/libnss_files-2.17.so
ln -s ./lib/libnss_files-2.17.so ./libnss_files.so.2

mkdir $SENDMAILJAIL/usr/lib64/sasl2
cp /usr/lib64/sasl2/* $SENDMAILJAIL/usr/lib64/sasl2/

mkdir $SENDMAILJAIL/lib64/sasl2/
cp /lib64/sasl2/* $SENDMAILJAIL/lib64/sasl2/
cp /etc/sasl2/Sendmail.conf $SENDMAILJAIL/usr/lib64/sasl2/

mkdir $SENDMAILJAIL/etc/sasl2
cp /etc/sasl2/Sendmail.conf $SENDMAILJAIL/etc/sasl2/


cp /usr/sbin/makemap $SENDMAILJAIL/usr/sbin/makemap
ln -s ../sbin/makemap ./makemap
cp /usr/bin/rmail.sendmail $SENDMAILJAIL/usr/bin/rmail.sendmail
ln -s ./rmail.sendmail ./rmail

cp /usr/sbin/mailstats $SENDMAILJAIL/usr/sbin/mailstats
cp /usr/sbin/makemap $SENDMAILJAIL/usr/sbin/makemap
cp /usr/sbin/praliases $SENDMAILJAIL/usr/sbin/praliases
cp /usr/sbin/smrsh $SENDMAILJAIL/usr/sbin/smrsh

cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libcom_err.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libcrypt.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libcrypto.so.10 $SENDMAILJAIL/lib64/
cp /lib64/libdb-5.3.so $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libfreebl3.so $SENDMAILJAIL/lib64/
cp /lib64/libgssapi_krb5.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libhesiod.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libidn.so.11 $SENDMAILJAIL/lib64/
cp /lib64/libk5crypto.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libk5crypto.so.3: $SENDMAILJAIL/lib64/
cp /lib64/libkeyutils.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5support.so.0 $SENDMAILJAIL/lib64/
cp /lib64/liblber-2.4.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libldap-2.4.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libnsl.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libnspr4.so $SENDMAILJAIL/lib64/
cp /lib64/libnss3.so $SENDMAILJAIL/lib64/
cp /lib64/libnssutil3.so $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libplc4.so $SENDMAILJAIL/lib64/
cp /lib64/libplds4.so $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/
cp /lib64/librt.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libsasl2.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libselinux.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libsmime3.so $SENDMAILJAIL/lib64/
cp /lib64/libssl.so.10 $SENDMAILJAIL/lib64/
cp /lib64/libssl3.so $SENDMAILJAIL/lib64/
cp /lib64/libwrap.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libz.so.1 $SENDMAILJAIL/lib64/
cp /usr/lib64/libk5crypto.so.3 $SENDMAILJAIL/usr/lib64/

cp /lib64/libdns.so.100 $SENDMAILJAIL/lib64/
cp /lib64/liblwres.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libbind9.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libisccfg.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libisccc.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libisc.so.95 $SENDMAILJAIL/lib64/
cp /lib64/libgssapi_krb5.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libk5crypto.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libcom_err.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libcrypto.so.10 $SENDMAILJAIL/lib64/
cp /lib64/libcap.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libGeoIP.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libxml2.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libz.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libm.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libidn.so.11 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5support.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libkeyutils.so.1 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libattr.so.1 $SENDMAILJAIL/lib64/
cp /lib64/liblzma.so.5 $SENDMAILJAIL/lib64/
cp /lib64/libselinux.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /bin/dig $SENDMAILJAIL/bin/

cp /lib64/libtinfo.so.5 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /bin/bash $SENDMAILJAIL/bin/

cp /bin/ls $SENDMAILJAIL/bin/
cp /lib64/libcap.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libacl.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libattr.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/

cp /bin/vi $SENDMAILJAIL/bin/
cp /usr/sbin/pidof $SENDMAILJAIL/usr/sbin/pidof
cp /lib64/libprocps.so.4 $SENDMAILJAIL/lib64/
cp /lib64/libsystemd.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libcap.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libm.so.6 $SENDMAILJAIL/lib64/
cp /lib64/librt.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libselinux.so.1 $SENDMAILJAIL/lib64/
cp /lib64/liblzma.so.5 $SENDMAILJAIL/lib64/
cp /lib64/libgcrypt.so.11 $SENDMAILJAIL/lib64/
cp /lib64/libgpg-error.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libdw.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libgcc_s.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libattr.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libelf.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libz.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libbz2.so.1 $SENDMAILJAIL/lib64/
cp /bin/rm $SENDMAILJAIL/bin/

Under your ID, ensure the proper permissions are set on the chroot jail

sudo chown -R sendmail:mail /smt00p20/sendmail/
sudo chown sendmail /smt00p20/sendmail/var/spool/mqueue
sudo chmod 0700 /smt00p20/sendmail/var/spool/mqueue
sudo chmod -R go-w /smt00p20/sendmail
sudo chmod 0400 /smt00p20/sendmail/etc/mail/*.cf

Now verify it works – still under your ID as you have sudo permission to run chroot.

sudo /sbin/chroot /smt00p20/sendmail /bin/ls
# You should see a directory listing like this, not an error
bin  dev  etc  lib  lib64  tmp  usr  var

Assuming there are no problems, run sendmail:

sudo /sbin/chroot /smt00p20/sendmail /usr/sbin/sendmail -bd -q5m

Test sending mail through the server to verify proper functionality.

Unit Config: Edit the systemd unit file and add the “RootDirectory” directive

sudo vi /etc/systemd/system/multi-user.target.wants/sendmail.service

[Unit]
Description=Sendmail Mail Transport Agent
After=syslog.target network.target
Conflicts=postfix.service exim.service
Wants=sm-client.service

[Service]
RootDirectory=/smt00p20/sendmail
Type=forking
StartLimitInterval=0
# Known issue – pid causes service hang/timeout that bothers Unix guys
# https://bugzilla.redhat.com/show_bug.cgi?id=1253840
#PIDFile=/run/sendmail.pid
Environment=SENDMAIL_OPTS=-q15m
EnvironmentFile=-/smt00p20/sendmail/etc/sysconfig/sendmail
ExecStart=/usr/sbin/sendmail -bd $SENDMAIL_OPTS $SENDMAIL_OPTARG

[Install]
WantedBy=multi-user.target
Also=sm-client.service

Then run “systemctl daemon-reload” to ingest the changes.

You can now use systemctl to start and stop the sendmail service.

Chrooting opendkim

Create the chroot jail and lib64 directory, create the base directories, then add a few core Linux files so you have a bash shell:

mkdir $OPENDKIMJAIL
mkdir $OPENDKIMJAIL/lib64
mkdir $OPENDKIMJAIL/usr/lib64
mkdir $OPENDKIMJAIL/bin
mkdir $OPENDKIMJAIL/etc

cp /lib64/libtinfo.so.5 $OPENDKIMJAIL/lib64/
cp /lib64/libdl.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/libc.so.6 $OPENDKIMJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $OPENDKIMJAIL/lib64/

cp /bin/bash $OPENDKIMJAIL/bin/
cp /lib64/libstdc++.so.6* $OPENDKIMJAIL/lib64
cp /lib64/libm.so.6 $OPENDKIMJAIL/lib64
cp /lib64/libgcc_s.so.1 $OPENDKIMJAIL/lib64
cp /lib64/libnss_files* $OPENDKIMJAIL/lib64/

Unpack the following RPMs:

rpm2cpio opendkim-2.11.0-0.1.el7.x86_64.rpm | cpio -idmv
rpm2cpio libopendkim-2.11.0-0.1.el7.x86_64.rpm | cpio -idmv
rpm2cpio sendmail-milter-8.14.7-5.el7.x86_64.rpm | cpio -idmv
rpm2cpio opendbx-1.4.6-6.el7.x86_64.rpm | cpio -idmv
rpm2cpio libmemcached-1.0.16-5.el7.x86_64.rpm | cpio -idvm
rpm2cpio libbsd-0.6.0-3.el7.elrepo.x86_64.rpm | cpio -idvm

Then move the unpacked files into the corresponding location in the $OPENDKIMJAIL directory.

Copy host configuration ‘stuff’ from /etc

cp /etc/aliases $OPENDKIMJAIL/etc/
cp /etc/aliases.db $OPENDKIMJAIL/etc/
cp /etc/passwd $OPENDKIMJAIL/etc/
cp /etc/group $OPENDKIMJAIL/etc/
cp /etc/resolv.conf $OPENDKIMJAIL/etc/
cp /etc/host.conf $OPENDKIMJAIL/etc/
cp /etc/nsswitch.conf $OPENDKIMJAIL/etc/
cp /etc/services $OPENDKIMJAIL/etc/
cp /etc/hosts $OPENDKIMJAIL/etc/
cp /etc/localtime $OPENDKIMJAIL/etc/

Copy some more files:

cp /lib64/libcom_err.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/libcrypt.so.1 $OPENDKIMJAIL/lib64/
cp /lib64/libcrypto.so.10 $OPENDKIMJAIL/lib64/
cp /lib64/libdb-5.3.so $OPENDKIMJAIL/lib64/
cp /lib64/libfreebl3.so $OPENDKIMJAIL/lib64/
cp /lib64/libgssapi_krb5.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/libk5crypto.so.3 $OPENDKIMJAIL/lib64/
cp /lib64/libkeyutils.so.1 $OPENDKIMJAIL/lib64/
cp /lib64/libkrb5.so.3 $OPENDKIMJAIL/lib64/
cp /lib64/libkrb5support.so.0 $OPENDKIMJAIL/lib64/
cp /lib64/liblber-2.4.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/libldap-2.4.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/libnspr4.so $OPENDKIMJAIL/lib64/
cp /lib64/libnss3.so $OPENDKIMJAIL/lib64/
cp /lib64/libnssutil3.so $OPENDKIMJAIL/lib64/
cp /lib64/libpcre.so.1 $OPENDKIMJAIL/lib64/
cp /lib64/libplc4.so $OPENDKIMJAIL/lib64/
cp /lib64/libplds4.so $OPENDKIMJAIL/lib64/
cp /lib64/libpthread.so.0 $OPENDKIMJAIL/lib64/
cp /lib64/libresolv.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/librt.so.1 $OPENDKIMJAIL/lib64/
cp /lib64/libsasl2.so.3 $OPENDKIMJAIL/lib64/
cp /lib64/libselinux.so.1 $OPENDKIMJAIL/lib64/
cp /lib64/libsmime3.so $OPENDKIMJAIL/lib64/
cp /lib64/libssl.so.10 $OPENDKIMJAIL/lib64/
cp /lib64/libssl3.so $OPENDKIMJAIL/lib64/
cp /lib64/libz.so.1 $OPENDKIMJAIL/lib64/
cp /usr/lib64/libssl.so.10 $OPENDKIMJAIL/usr/lib64/

cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0 $OPENDKIMJAIL/usr/lib/
cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0.1 $OPENDKIMJAIL/usr/lib/

cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0 $OPENDKIMJAIL/lib64/
cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0.1 $OPENDKIMJAIL/lib64/

cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0 $OPENDKIMJAIL/usr/lib/
cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0.1 $OPENDKIMJAIL/usr/lib/

cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0 $OPENDKIMJAIL/lib64/
cp $OPENDKIMJAIL/usr/lib64/libmilter.so.1.0.1 $OPENDKIMJAIL/lib64/

Configure OpenDKIM ($DKIMJAIL/etc/opendkim.conf) and populate keys (copy from server being replaced or generate new keys). Then, under your ID, run:

sudo /sbin/chroot /smt00p20/opendkim /usr/sbin/opendkim -u sendmail -v

The systemd unit file, /usr/lib/systemd/system/opendkim.service, needs to contain:

# If you are using OpenDKIM with SQL datasets it might be necessary to start OpenDKIM after the database servers.
# For example, if using both MariaDB and PostgreSQL, change "After=" in the "[Unit]" section to:
# After=network.target nss-lookup.target syslog.target mariadb.service postgresql.service

[Unit]
Description=DomainKeys Identified Mail (DKIM) Milter
Documentation=man:opendkim(8) man:opendkim.conf(5) man:opendkim-genkey(8) man:opendkim-genzone(8) man:opendkim-testadsp(8) man:opendkim-testkey http://www.opendkim.org/docs.html
After=network.target nss-lookup.target syslog.target

[Service]
RootDirectory=/smt00p20/opendkim
Type=forking
PIDFile=/smt00p20/opendkim/var/run/opendkim/opendkim.pid
EnvironmentFile=-/etc/sysconfig/opendkim
ExecStart=/usr/sbin/opendkim -u sendmail -v $OPTIONS
ExecReload=/bin/kill -USR1 $MAINPID
User=sendmail
Group=mail

[Install]
WantedBy=multi-user.target

 

Upgrading Sendmail – After Unix Applies Patches

This process grabs a new copy of sendmail, associated diagnostic utilities, and their dependencies from the OS installation. If you want to apply patches prior to Unix support doing so, you can stage a sendmail build (everything up to ‘make install’) and copy the files out or, if an updated RPM is in the repo but just not installed, download the RPMs, unpack them, and copy the files in. I would do that in addition to (and after) this process to ensure library updates are reflected in our jailed sendmail installation (i.e. if there’s an update to the crypto libraries, we get those updates).

cp /usr/sbin/sendmail.sendmail $SENDMAILJAIL/usr/sbin/sendmail.sendmail
cp /usr/lib64/libssl.so.10 $SENDMAILJAIL/usr/lib64/libssl.so.10
cp /usr/lib64/libcrypto.so.10 $SENDMAILJAIL/usr/lib64/libcrypto.so.10
cp /usr/lib64/libnsl.so.1 $SENDMAILJAIL/usr/lib64/libnsl.so.1
cp /usr/lib64/libwrap.so.0 $SENDMAILJAIL/usr/lib64/libwrap.so.0
cp /usr/lib64/libhesiod.so.0 $SENDMAILJAIL/usr/lib64/libhesiod.so.0
cp /usr/lib64/libcrypt.so.1 $SENDMAILJAIL/usr/lib64/libcrypt.so.1
cp /usr/lib64/libdb-5.3.so $SENDMAILJAIL/usr/lib64/libdb-5.3.so
cp /usr/lib64/libresolv.so.2 $SENDMAILJAIL/usr/lib64/libresolv.so.2
cp /usr/lib64/libsasl2.so.3 $SENDMAILJAIL/usr/lib64/libsasl2.so.3
cp /usr/lib64/libldap-2.4.so.2 $SENDMAILJAIL/usr/lib64/libldap-2.4.so.2
cp /usr/lib64/liblber-2.4.so.2 $SENDMAILJAIL/usr/lib64/liblber-2.4.so.2
cp /usr/lib64/libc.so.6 $SENDMAILJAIL/usr/lib64/libc.so.6
cp /usr/lib64/libgssapi_krb5.so.2 $SENDMAILJAIL/usr/lib64/libgssapi_krb5.so.2
cp /usr/lib64/libkrb5.so.3 $SENDMAILJAIL/usr/lib64/libkrb5.so.3
cp /usr/lib64/libcom_err.so.2 $SENDMAILJAIL/usr/lib64/libcom_err.so.2
cp /usr/lib64/libk5crypto.so.3 $SENDMAILJAIL/usr/lib64/libk5crypto.so.3
cp /usr/lib64/libdl.so.2 $SENDMAILJAIL/usr/lib64/libdl.so.2
cp /usr/lib64/libz.so.1 $SENDMAILJAIL/usr/lib64/libz.so.1
cp /usr/lib64/libidn.so.11 $SENDMAILJAIL/usr/lib64/libidn.so.11
cp /usr/lib64/libfreebl3.so $SENDMAILJAIL/usr/lib64/libfreebl3.so
cp /usr/lib64/libpthread.so.0 $SENDMAILJAIL/usr/lib64/libpthread.so.0
cp /usr/lib64/libssl3.so $SENDMAILJAIL/usr/lib64/libssl3.so
cp /usr/lib64/libsmime3.so $SENDMAILJAIL/usr/lib64/libsmime3.so
cp /usr/lib64/libnss3.so $SENDMAILJAIL/usr/lib64/libnss3.so
cp /usr/lib64/libnssutil3.so $SENDMAILJAIL/usr/lib64/libnssutil3.so
cp /usr/lib64/libplds4.so $SENDMAILJAIL/usr/lib64/libplds4.so
cp /usr/lib64/libplc4.so $SENDMAILJAIL/usr/lib64/libplc4.so
cp /usr/lib64/libnspr4.so $SENDMAILJAIL/usr/lib64/libnspr4.so
cp /usr/lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/usr/lib64/ld-linux-x86-64.so.2
cp /usr/lib64/libkrb5support.so.0 $SENDMAILJAIL/usr/lib64/libkrb5support.so.0
cp /usr/lib64/libkeyutils.so.1 $SENDMAILJAIL/usr/lib64/libkeyutils.so.1
cp /usr/lib64/librt.so.1 $SENDMAILJAIL/usr/lib64/librt.so.1
cp /usr/lib64/libselinux.so.1 $SENDMAILJAIL/usr/lib64/libselinux.so.1
cp /usr/lib64/libpcre.so.1 $SENDMAILJAIL/usr/lib64/libpcre.so.1
cp /usr/lib64/libnss_dns.so.2 $SENDMAILJAIL/usr/lib64/libnss_dns.so.2
cp /usr/lib64/libnss_files.so.2 $SENDMAILJAIL/usr/lib64/libnss_files.so.2
cp /lib64/libnss_dns-2.17.so $SENDMAILJAIL/lib64/libnss_dns-2.17.so
cp /lib64/libresolv-2.17.so $SENDMAILJAIL/lib64/libresolv-2.17.so
cp /lib64/libnss_files-2.17.so $SENDMAILJAIL/lib64/libnss_files-2.17.so
cp /lib64/libnss_dns-2.17.so $SENDMAILJAIL/lib/libnss_dns-2.17.so
cp /lib64/libresolv-2.17.so $SENDMAILJAIL/lib/libresolv-2.17.so
cp /lib64/libnss_files-2.17.so $SENDMAILJAIL/lib/libnss_files-2.17.so
cp /usr/lib64/sasl2/* $SENDMAILJAIL/usr/lib64/sasl2/
cp /lib64/sasl2/* $SENDMAILJAIL/lib64/sasl2/
cp /etc/sasl2/Sendmail.conf $SENDMAILJAIL/usr/lib64/sasl2/
cp /etc/sasl2/Sendmail.conf $SENDMAILJAIL/etc/sasl2/
cp /usr/sbin/makemap $SENDMAILJAIL/usr/sbin/makemap
cp /usr/bin/rmail.sendmail $SENDMAILJAIL/usr/bin/rmail.sendmail
cp /usr/sbin/mailstats $SENDMAILJAIL/usr/sbin/mailstats
cp /usr/sbin/makemap $SENDMAILJAIL/usr/sbin/makemap
cp /usr/sbin/praliases $SENDMAILJAIL/usr/sbin/praliases
cp /usr/sbin/smrsh $SENDMAILJAIL/usr/sbin/smrsh

cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libcom_err.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libcrypt.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libcrypto.so.10 $SENDMAILJAIL/lib64/
cp /lib64/libdb-5.3.so $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libfreebl3.so $SENDMAILJAIL/lib64/
cp /lib64/libgssapi_krb5.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libhesiod.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libidn.so.11 $SENDMAILJAIL/lib64/
cp /lib64/libk5crypto.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libk5crypto.so.3: $SENDMAILJAIL/lib64/
cp /lib64/libkeyutils.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5support.so.0 $SENDMAILJAIL/lib64/
cp /lib64/liblber-2.4.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libldap-2.4.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libnsl.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libnspr4.so $SENDMAILJAIL/lib64/
cp /lib64/libnss3.so $SENDMAILJAIL/lib64/
cp /lib64/libnssutil3.so $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libplc4.so $SENDMAILJAIL/lib64/
cp /lib64/libplds4.so $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/
cp /lib64/librt.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libsasl2.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libselinux.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libsmime3.so $SENDMAILJAIL/lib64/
cp /lib64/libssl.so.10 $SENDMAILJAIL/lib64/
cp /lib64/libssl3.so $SENDMAILJAIL/lib64/
cp /lib64/libwrap.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libz.so.1 $SENDMAILJAIL/lib64/
cp /usr/lib64/libk5crypto.so.3 $SENDMAILJAIL/usr/lib64/

cp /lib64/libdns.so.100 $SENDMAILJAIL/lib64/
cp /lib64/liblwres.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libbind9.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libisccfg.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libisccc.so.90 $SENDMAILJAIL/lib64/
cp /lib64/libisc.so.95 $SENDMAILJAIL/lib64/
cp /lib64/libgssapi_krb5.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libk5crypto.so.3 $SENDMAILJAIL/lib64/
cp /lib64/libcom_err.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libcrypto.so.10 $SENDMAILJAIL/lib64/
cp /lib64/libcap.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libGeoIP.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libxml2.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libz.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libm.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libidn.so.11 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libkrb5support.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libkeyutils.so.1 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libattr.so.1 $SENDMAILJAIL/lib64/
cp /lib64/liblzma.so.5 $SENDMAILJAIL/lib64/
cp /lib64/libselinux.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /bin/dig $SENDMAILJAIL/bin/

cp /lib64/libtinfo.so.5 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /bin/bash $SENDMAILJAIL/bin/

cp /bin/ls $SENDMAILJAIL/bin/
cp /lib64/libcap.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libacl.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libattr.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/

cp /bin/vi $SENDMAILJAIL/bin/
cp /usr/sbin/pidof $SENDMAILJAIL/usr/sbin/pidof
cp /lib64/libprocps.so.4 $SENDMAILJAIL/lib64/
cp /lib64/libsystemd.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libdl.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libc.so.6 $SENDMAILJAIL/lib64/
cp /lib64/libcap.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libm.so.6 $SENDMAILJAIL/lib64/
cp /lib64/librt.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libselinux.so.1 $SENDMAILJAIL/lib64/
cp /lib64/liblzma.so.5 $SENDMAILJAIL/lib64/
cp /lib64/libgcrypt.so.11 $SENDMAILJAIL/lib64/
cp /lib64/libgpg-error.so.0 $SENDMAILJAIL/lib64/
cp /lib64/libdw.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libgcc_s.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpthread.so.0 $SENDMAILJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $SENDMAILJAIL/lib64/
cp /lib64/libattr.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libpcre.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libelf.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libz.so.1 $SENDMAILJAIL/lib64/
cp /lib64/libbz2.so.1 $SENDMAILJAIL/lib64/

cp /bin/rm $SENDMAILJAIL/bin/

 

Under your ID, ensure the proper permissions are set on the chroot jail

sudo chown -R sendmail:mail /smt00p20/sendmail/
sudo chown sendmail /smt00p20/sendmail/var/spool/mqueue
sudo chmod 0700 /smt00p20/sendmail/var/spool/mqueue
sudo chmod -R go-w /smt00p20/sendmail
sudo chmod 0400 /smt00p20/sendmail/etc/mail/*.cf

Then start sendmail and verify functionality.

Updating OpenDKIM

cp /lib64/libtinfo.so.5 $OPENDKIMJAIL/lib64/
cp /lib64/libdl.so.2 $OPENDKIMJAIL/lib64/
cp /lib64/libc.so.6 $OPENDKIMJAIL/lib64/
cp /lib64/ld-linux-x86-64.so.2 $OPENDKIMJAIL/lib64/
cp /bin/bash $OPENDKIMJAIL/bin/
cp /lib64/libstdc++.so.6* $OPENDKIMJAIL/lib64
cp /lib64/libm.so.6 $OPENDKIMJAIL/lib64
cp /lib64/libgcc_s.so.1 $OPENDKIMJAIL/lib64
cp /lib64/libnss_files* $OPENDKIMJAIL/lib64/

 

If there is an update to the opendkim packages, unpack the updated RPM files and move the new files into the corresponding jail locations.

rpm2cpio opendkim-2.11.0-0.1.el7.x86_64.rpm | cpio -idmv
rpm2cpio libopendkim-2.11.0-0.1.el7.x86_64.rpm | cpio -idmv
rpm2cpio sendmail-milter-8.14.7-5.el7.x86_64.rpm | cpio -idmv
rpm2cpio opendbx-1.4.6-6.el7.x86_64.rpm | cpio -idmv
rpm2cpio libmemcached-1.0.16-5.el7.x86_64.rpm | cpio -idvm
rpm2cpio libbsd-0.6.0-3.el7.elrepo.x86_64.rpm | cpio -idvm

 

Extracting RPM Packages

I’ve encountered a few scenarios of late where I couldn’t install an RPM package but needed its content. One is the security config at work where I have sudo access for cp but not install rights. Sigh! But more recently, I needed to compare a library from an updated package to the currently installed one. Listing package content confirms it is the same file name and path.

[root@fedora02 tmp]# rpm -q --filesbypkg -p ./mariadb-libs-10.2.13-2.fc27.i686.rpm
mariadb-libs              /etc/my.cnf.d/client.cnf
mariadb-libs              /usr/lib/.build-id
mariadb-libs              /usr/lib/.build-id/7c
mariadb-libs              /usr/lib/.build-id/7c/c8e65deafbdcc28b3089da60f295a6f757cf4f
mariadb-libs              /usr/lib/libmariadb.so.3

 

Extracting the rpm allowed me to actually compare the files, swap back and forth to see which worked, etc.

[lisa@fedora tmp]# rpm2cpio mariadb-libs-10.2.13-2.fc27.x86_64.rpm | cpio -idmv

Linux Authentication Over Key Exchange

On Linux, you can log in without logging in (essential for non-interactive processes that run commands on remote hosts, but also nice accessing hosts when you get paged at 2AM to look into an issue). The first thing you need is a key. You can use the openssh installation on a server to generate the key:

ssh-keygen -t rsa -b 2048

You’ll get an id_rsa and id_rsa.pub. Your private key (keep it somewhere safe) is in id_rsa; your public key is in id_rsa.pub.

Alternately you can run puttygen.exe (www.chiark.greenend.org.uk/~sgtatham/putty/download.html) for a GUI key generator. Click the “Generate” button & then move the mouse around over the blank area of the PuttyGen window – your coordinates are used as random data for the key seed.

Once the key is generated, click “save public key” and store it somewhere safe. Click “save private key” and store it somewhere safe. Copy the public key at the top of the window. You don’t have to – you can drop the newline characters from the saved public key file, but this saves time.

Either way, you’ve got a base 64 encoded public and private key.

** Key recovery isn’t a big deal – you can always generate a new public/private key pair and set it up. Time consuming if your public key is all over the place, but it isn’t a data loss kind if thing.

*** Anyone who gets your private key can log in as you anywhere you set up this key exchange. You can add a passphrase to your key for additional security.

 

Go to whatever box you want to log into using the key exchange. ** I have a key exchange set up from my Windows boxes (laptop, terminal server) to myid@jumphost. I then have a different key used from myid@jumphost to all of our other boxes. This allows me to change my on laptop key (i.e. the one more likely to get lost) out more frequently without having to get a new public key on dozens of hosts.

Once you are on the box you want as the ID you want (you can do a key exchange to any id for which you know the password – so you can log into serviceaccount@hostname or otherserviceaccount@otherhostname and do this, or you can be logged in as yourid@hostname). Run “cd ~/.ssh” – if it says no such file, run “ssh localhost” – it will ask you if you want to store the server public key – say yes, that creates the .ssh folder with proper permissions. Ctrl-c and cd ~/.ssh again. Now determine if there is an authorized_keys, authorized_keys2, or both. Vim the one you find – if there aren’t any, try “vi authorized_keys” first (authorized_keys2 on RedHat/Fedora, long story) – go into edit mode and paste in the public key line we copied earlier. Save the file. If you get an error like “The server refused our key”, you can “mv authorized_keys authorized_keys2” (or “mv authorized_keys2 authorized_keys” if you started with keys2).

In putty, load in your configuration for whatever host we just pasted the public key into. Under Connection -> Data, find the “Auto-login username” section. Put in whatever ID you used when you added the public key (my use case is me e0082643 … but if you were using ldapAdmin@hostname, you would put ldapAdmin in here)

Then under Connection ->SSH->Auth, find the “private key file for authentication” section and put in your private key location. Go back to the Session section and save the configuration changes.

Now connect & you shouldn’t need to supply a password (or you only need to supply your key passphrase).

** OpenSSH automatically uses the id_dsa or id_rsa (private keys) from ~/.ssh/ when you attempt to authenticate to other hosts. If the destination id@host has your public key in its ~/.ssh/authorized_keys (or ~/.ssh/authorized_keys2), then you’ll get magic key based authentication too. Caveat: on the source Linux host, your private key cannot be group or other readable. Run “chmod go-rw ~/.ssh/id_rsa” to ensure it is sufficiently private, otherwise auth will fail due to permissive access.

** Once you have a key exchange in place, it is fairly easy to update your key. Create a new one but do not yet replace your old one. You can make a shell script that updates all remote hosts with your new public key – per host, run:

ssh user@remoteHost “echo \”`cat ~/.ssh/new_id_rsa.pub`\” >> ~/.ssh/authorized_keys”

Once the new public key info has been pushed out, test it using “ssh -i new_id_rsa user@remoteHost” and verify the key authentication works. Once confirmed, rename your old id_rsa and id_rsa.pub files to something else. Then rename your new_id_rsa to id_rsa and new_id_rsa.pub to id_rsa.pub

Persisting Port Names For OpenHAB

If you only have one device connected to your Linux box, your controller may well always be assigned the same port when the system is rebooted. In the real world, multiple connected devices make this unlikely. We use udev rules to create symlinks used within the OpenHAB configuration. The udev rule essentially uses attributes of the device to identify the real port and creates a statically named symlink to that port on boot. So the first thing you need to identify is something unique about the device. We have several video capture cards and a Z-Wave/ZigBee combo controller attached to our server. If you do not have udevinfo, you can use lsusb to find details about the device. First list the devices, then identify the proper one and use the -d switch with the ????:???? formatted ID number. The -v switch outputs verbose information. Find a unique attribute or set of attributes that create a unique identifier. In this case, the interface name is unique and we can stop there.

[lisa@server ~]#  lsusb
Bus 001 Device 004: ID 0bda:0111 Realtek Semiconductor Corp. RTS5111 Card Reader Controller
Bus 001 Device 003: ID 1058:1230 Western Digital Technologies, Inc. My Book (WDBFJK0030HBK)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 10c4:8a2a Cygnal Integrated Products, Inc.
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
[lisa@server ~]# lsusb -d 10c4:8a2a -v
Bus 002 Device 002: ID 10c4:8a2a Cygnal Integrated Products, Inc.
Device Descriptor:
 bLength 18
 bDescriptorType 1
 bcdUSB 2.00
 bDeviceClass 0
 bDeviceSubClass 0
 bDeviceProtocol 0
 bMaxPacketSize0 64
 idVendor 0x10c4 Cygnal Integrated Products, Inc.
 idProduct 0x8a2a
 bcdDevice 1.00
 iManufacturer 1 Silicon Labs
 iProduct 2 HubZ Smart Home Controller
 iSerial 5 90F0016B
 bNumConfigurations 1
 Configuration Descriptor:
 bLength 9
 bDescriptorType 2
 wTotalLength 55
 bNumInterfaces 2
 bConfigurationValue 1
 iConfiguration 0
 bmAttributes 0x80
 (Bus Powered)
 MaxPower 100mA
 Interface Descriptor:
 bLength 9
 bDescriptorType 4
 bInterfaceNumber 0
 bAlternateSetting 0
 bNumEndpoints 2
 bInterfaceClass 255 Vendor Specific Class
 bInterfaceSubClass 0
 bInterfaceProtocol 0
 iInterface 3 HubZ Z-Wave Com Port
 Endpoint Descriptor:
 bLength 7
 bDescriptorType 5
 bEndpointAddress 0x81 EP 1 IN
 bmAttributes 2
 Transfer Type Bulk
 Synch Type None
 Usage Type Data
 wMaxPacketSize 0x0040 1x 64 bytes
 bInterval 0
 Endpoint Descriptor:
 bLength 7
 bDescriptorType 5
 bEndpointAddress 0x01 EP 1 OUT
 bmAttributes 2
 Transfer Type Bulk
 Synch Type None
 Usage Type Data
 wMaxPacketSize 0x0040 1x 64 bytes
 bInterval 0
 Interface Descriptor:
 bLength 9
 bDescriptorType 4
 bInterfaceNumber 1
 bAlternateSetting 0
 bNumEndpoints 2
 bInterfaceClass 255 Vendor Specific Class
 bInterfaceSubClass 0
 bInterfaceProtocol 0
 iInterface 4 HubZ ZigBee Com Port
 Endpoint Descriptor:
 bLength 7
 bDescriptorType 5
 bEndpointAddress 0x82 EP 2 IN
 bmAttributes 2
 Transfer Type Bulk
 Synch Type None
 Usage Type Data
 wMaxPacketSize 0x0020 1x 32 bytes
 bInterval 0
 Endpoint Descriptor:
 bLength 7
 bDescriptorType 5
 bEndpointAddress 0x02 EP 2 OUT
 bmAttributes 2
 Transfer Type Bulk
 Synch Type None
 Usage Type Data
 wMaxPacketSize 0x0020 1x 32 bytes
 bInterval 0

We then need to create a file under /etc/udev/rules.d. The file name begins with a number that is used for a load order – I generally number my custom files 99 to avoid interfering with system operations. The bit in “ATTRS” is the attribute name and value to match. The KERNEL section contains the search domain (i.e. look at all of the ttyUSB### devices and find ones where the interface is this). The symlink bit is the name you want to use (more on this later). Set the group and mode to ensure OpenHAB is able to use the symlink.

[lisa@server rules.d]# cat 99-server.rules
KERNEL=="ttyUSB[0-9]*", ATTRS{interface}=="HubZ Z-Wave Com Port", SYMLINK+="ttyUSB-5", GROUP="dialout", MODE="0666"
KERNEL=="ttyUSB[0-9]*", ATTRS{interface}=="HubZ ZigBee Com Port", SYMLINK+="ttyUSB-55", GROUP="dialout", MODE="0666"

The symlink name can be anything – when I created udev rules for our video capture cards, I named them something immediately obvious: video-hauppauge250 is the Hauppauge 250 card. Tried to do the same thing here, naming the ports controller-zigbee; while the symlink appeared and had the expected ownership and permissions … OpenHAB couldn’t use it.

Turns out there’s a nuance to Java RxTx where non-standard port names need to be accommodated in the java options. So I could have added -Dgnu.io.rxtxSerialPorts=/dev/controller-zigbee and -Dgnu.io.rxtxSerialPorts=/dev/controller-zwave to the OpenHAB startup and been OK (in theory), it was far easier to name the symlinks using the Linux standard conventions. Hence I have symlinks named ttyUSBsomethingsomethingsomething.