Monthly Archives: April 2018

Sending mail on the Linux command line (Ubuntu 18.04)

How to send end-to-end encrypted emails on the Linux command line.

If you want to add attachments, use mutt or mail from GNU Mailutils as the mail client. The following examples use mailx and ssmtp.

Unencrypted mail

Install package “bsd-mailx”:

$ sudo apt-get install bsd-mailx

Edit /etc/mail.rc and add the following lines:

set smtp=smtp://mail.example.com
alias root postmaster@example.com

Run mailx:

$ mailx root
Subject: test 
This is a test. 
. 
Cc: 

Notes:

  • Mail gets sent to postmaster@example.com (see mail.rc).
  • Mail server is mail.example.com (see mail.rc).
  • Email message body is terminated by a single “.” as the last line.

Encrypted mail (Inline PGP)

Make sure you can send unencrypted mail (s. “Unencrypted mail” above).

Check that you have GnuPG version 2 installed, and If you haven’t done so before, create private and public GnuPG key.

$ gpg --version
gpg (GnuPG) 2.2.4
libgcrypt 1.8.1
...
$ gpg --gen-key
...

Import public PGP key from recipient.

$ gpg --import alice.pub

First sign message (clearsign – ascii signature will be appended to text), then encrypt message, then mail message.

$ echo "Hello Alice, if you can read this your PGP mail client is working." | 
    gpg --clearsign | 
    gpg -a -r alice@example.com --encrypt | 
    mailx -s "PGP encrypted mail test" alice@example.com

Notes:

  • First sign the message. “gpg –clearsign” uses the default private key to sign message. Check with “gpg -K”. Otherwise use option “–default-key bob@example.com” to choose a specific private key.
  • Then encrypt the message. Check with “gpg -k” that the recipient’s user id is properly added to your GPG keyring.
  • The user id of the public key used for encryption does not necessarily has to correspond with the recipient email address. You can encrypt a message with the public key of “bob@example.com”, and then send the email to “alice@example.com”. If Alice has the corresponding private key for “bob@example.com”, she will be able decrypt and read the email without any problems.
  • Finally send the mail message. The email body is simply the signed and encrypted message text in ASCII format.
  • The email subject will not be encrypted.

Encrypted mail (S/MIME)

Make sure you can send unencrypted mail (s. “Unencrypted mail” above).

You need your own public certificate / private key pair, and the public certificate from the recipient (all in PEM format).

You can get a S/MIME email certificate for free from COMODO. Or you run your own certificate authority. Either way, both your own certificate and your own key need to be in a single file in PEM format (in the following example it is called “bob.pem”).

-----BEGIN PRIVATE KEY-----
 ...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
 ...
-----END CERTIFICATE-----

The public certificate of the recipient must be in PEM format too (in the following example it is called “alice.pem”). You can extract it from an email signature if the recipient already sent you a signed email.

-----BEGIN CERTIFICATE-----
 ...
-----END CERTIFICATE-----

Install the package “ssmtp”.

$ sudo apt-get install ssmtp

Again (as in the above example for PGP encrypted mail), all commands for signing, encrypting and sending the message can be chained together to a single command line.

$ echo "Hello Alice, if you can read this your S/MIME mail client is working." | 
    openssl smime -sign -signer bob.pem -text | 
    openssl smime -encrypt -from bob.example.com -to alice@example.com -subject "S/MIME encrypted mail test" -aes-256-cbc alice.pem | 
    ssmtp -t

Notes:

  • Email body is simply the signed and encrypted message text in ASCII format. OpenSSL adds all required headers to it (sender, recipient, subject).
  • If you are using a S/MIME certificate from a public CA (like COMODO) to sign your message, it is easier for the recipient to validate your signature, compared to PGP encrypted emails.
  • You still need the public certificate of the recipient, and make somehow sure that it is authentic.
  • Again, the email subject will not be encrypted.

Upgrading from Ubuntu 16.04 LTS to 18.04 LTS

Overall changes

Canonical support has been dropped from the following packages. They have been moved to the universe repo.

  • tcpd
  • xinetd
  • isc-dhcp-server-ldap
  • ntp, ntpdate
    There might be problems to automatically start previously configured ntp service at boot time. As a replacement, systemd-timesyncd.service is now enabled by default and provides SNTP client services. Default time server is ntp.ubuntu.com, or the one obtained from systemd-networkd.service (s. “man timesyncd.conf” for configuration).
  • firewalld
  • ssmtp

New versions

Installing Bacula client from source

Again the new bacula-fd version 9.0.6 might be a problem, if you are running a Bacula server with an older version (s. Upgrade from Ubuntu Desktop 14.04 LTS to 16.04 LTS). In your job output, you will see an error like this:

25-Apr 02:15 server-dir JobId 5638: FD compression disabled for this Job because AllowCompress=No in Storage resource.
25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=9 level=1524615306 client-fd JobId 5638:      Unchanged file skipped: /etc/inputrc

25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=9 level=1524615306 client-fd JobId 5638:      Unchanged file skipped: /etc/bind/db.empty

25-Apr 02:15 server-sd JobId 5638: Fatal error: bsock.c:547 Packet size=1073742451 too big from "client:192.168.0.1:9103. Terminating connection.
25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=9 level=1524615306 client-fd JobId 5638:      Unchanged file skipped: /etc/bind/Kexample2.+163+42584.private

25-Apr 02:15 server-sd JobId 5638: Fatal error: append.c:149 Error reading data header from FD. n=-2 msglen=0 ERR=No data available
25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=9 level=1524615306 client-fd JobId 5638:      Unchanged file skipped: /etc/bind/zones.rfc1918

25-Apr 02:15 server-sd JobId 5638: Elapsed time=00:00:01, Transfer rate=186  Bytes/second
25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=4 level=1524615307 client-fd JobId 5638: Error: bsock.c:649 Write error sending 884 bytes to Storage daemon:192.168.0.1:9103: ERR=Broken pipe

25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=3 level=1524615307 client-fd JobId 5638: Fatal error: backup.c:843 Network send error to SD. ERR=Broken pipe

25-Apr 02:15 server-dir JobId 5638: Error: getmsg.c:178 Malformed message: Jmsg JobId=5638 type=4 level=1524615317 client-fd JobId 5638: Error: bsock.c:537 Socket has errors=1 on call to Storage daemon:192.168.0.1:9103

25-Apr 02:15 server-dir JobId 5638: Fatal error: bsock.c:547 Packet size=1073741935 too big from "Client: client-fd:client.example.com:9102. Terminating connection.
25-Apr 02:15 server-dir JobId 5638: Fatal error: No Job status returned from FD.

Here is how to install bacula-fd 5.2.13 from source on Ubuntu 18.04:

  • systemctl stop bacula-fd
  • Install packages required for building bacula client from source:
    apt-get install build-essentials libssl1.0-dev
  • Download bacula-5.2.13.tar.gz and bacula-5.2.13.tar.gz.sig from https://sourceforge.net/projects/bacula/files/bacula/5.2.13/
  • Import Bacula Distribution Verification Key and check key fingerprint (fingerprint for my downloaded Bacula key is 2CA9 F510 CA5C CAF6 1AB5  29F5 9E98 BF32 10A7 92AD):
    gpg –recv-keys 10A792AD
    gpg –fingerprint -k 10A792AD
  • Check signature of downloaded files:
    gpg –verify bacula-5.2.13.tar.gz.sig
  • tar -xzvf bacula-5.2.13.tar.gz
  • cd bacula-5.2.13
  • ./configure –prefix=/usr/local –enable-client-only –disable-build-dird –disable-build-stored –with-openssl –with-pid-dir=/var/run/bacula –with-systemd
  • check output of previous configure command
  • make && make install
  • check output of previous command for any errors
  • create new file /etc/ld.so.conf.d/local.conf:
    /usr/local/lib
  • ldconfig
  • Delete the following files:
    rm /lib/systemd/system/bacula-fd.service
    rm /etc/init.d/bacula-fd
    (In fact you can remove the bacula-fd 9.0.6 package completely, just make sure to copy the directory /etc/bacula somewhere safe before you do, and restore it afterwards.)
  • Create file /etc/systemd/system/bacula-fd.service (see below)
  • systemctl daemon-reload
  • systemctl start bacula-fd

/etc/systemd/system/bacula-fd.service:

[Unit] 
Description=Bacula File Daemon service 
Documentation=man:bacula-fd(8) 
Requires=network.target 
After=network.target 
RequiresMountsFor=/var/lib/bacula /etc/bacula /usr/sbin 
 
# from http://www.freedesktop.org/software/systemd/man/systemd.service.html 
[Service] 
Type=forking 
User=root 
Group=root 
Environment="CONFIG=/etc/bacula/bacula-fd.conf" 
EnvironmentFile=-/etc/default/bacula-fd 
ExecStartPre=/usr/local/sbin/bacula-fd -t -c $CONFIG 
ExecStart=/usr/local/sbin/bacula-fd -u root -g root -c $CONFIG 
ExecReload=/bin/kill -HUP $MAINPID 
SuccessExitStatus=15 
Restart=on-failure 
RestartSec=60 
PIDFile=/run/bacula/bacula-fd.9102.pid 

[Install] 
WantedBy=multi-user.target

Make sure that in you bacula-fd.conf, you have:

Pid Directory = /run/bacula

… and that the directory actually exists.

Some notable changes to systemd

When using systemd’s default tmp.mount unit for /tmp, the mount point will now be established with the “nosuid” and “nodev” options. This avoids privilege escalation attacks that put traps and exploits into /tmp. However, this might cause problems if you e. g. put container images or overlays into /tmp; if you need this, override tmp.mount’s “Options=” with a drop-in, or mount /tmp from /etc/fstab with your desired options.

systemd-resolved now listens on the local IP address 127.0.0.53:53 for DNS requests. This improves compatibility with local programs that do not use the libc NSS or systemd-resolved’s bus APIs for name resolution. This minimal DNS service is only available to local programs and does not implement the full DNS protocol, but enough to cover local DNS clients. A new, static resolv.conf file, listing just this DNS server is now shipped in /usr/lib/systemd/resolv.conf. It is now recommended to make /etc/resolv.conf a symlink to this file in order to route all DNS lookups to systemd-resolved, regardless if done via NSS, the bus API or raw DNS packets. Note that this local DNS service is not as fully featured as the libc NSS or systemd-resolved’s bus APIs. For example, as unicast DNS cannot be used to deliver link-local address information (as this implies sending a local interface index along), LLMNR/mDNS support via this interface is severely restricted. It is thus strongly recommended for all applications to use the libc NSS API or native systemd-resolved bus API instead.

systemd-resolved gained a new “DNSStubListener” setting in resolved.conf. It either takes a boolean value or the special values “udp” and “tcp”, and configures whether to enable the stub DNS listener on 127.0.0.53:53.

The new ProtectKernelModules= option can be used to disable explicit load and unload operations of kernel modules by a service. In addition access to /usr/lib/modules is removed if this option is set.

Units acquired a new boolean option IPAccounting=. When turned on, IP traffic accounting (packet count as well as byte count) is done for the service, and shown as part of “systemctl status” or “systemd-run –wait”. If CPUAccounting= or IPAccounting= is turned on for a unit a new structured log message is generated each time the unit is stopped, containing information about the consumed resources of this invocation.