Fix NAS4Free's Non-Working Google SMTP After Upgrade

Illustration

A few days after I updated NAS4Free to 11.1.0.4 (revision 5109), I noticed my e-mail reports were not arriving any longer. After making sure my script was working, I went onto checking my e-mail settings - first by sending a test e-mail.

There I received not really helpful message: “Failed to send test email. Please check the log files.” Further check in log showed equaly useless “root: Failed to send test email to: mail@example.com.” I guess it was time for the command line.

The easiest way to test e-mail is probably running msmtp directly from SSH and see what its issue is:

echo "Subject: Test" |& msmtp mail@example.com
 msmtp: account default from /usr/local/etc/msmtprc: cannot use tls_trust_file with tls_certcheck turned off

If you check that file, the offending line is indeed there:

cat /usr/local/etc/msmtprc
 account default
 domain example.com
 host smtp.gmail.com
 port 587
 protocol smtp
 from mail@example.com
 auth login
 user mail@example.com
 password 123
 tls on
 tls_starttls on
 tls_certcheck off
 !!tls_trust_file!! /usr/local/etc/ssl/cert.pem
 syslog LOG_MAIL

The easiest fix for this issue is to enable TLS Server Certificate Check in GUI. This will actually add a bit of security and there are no real downsides if you use Google’s SNMP as I do.

If you are using a custom e-mail server with self-signed certificate, removing offending line in post-startup script is your best bet:

sed -i -- '/^tls_trust_file/d' /usr/local/etc/msmtprc

Of course, proper solution would be for GUI to omit TLS trust file configuration when certificate check if off. Due to unrelated changes this seems to be already fixed in msmtp.in source file. Next version will have it all sorted out. :)

[2018-02-16: Issue is fixed in version 11.1.0.4.5127.]

[2018-07-22: NAS4Free has been renamed to XigmaNAS as of July 2018]

GELI With XTS-AES or AES-CBC?

If you are using GELI to encrypt disks on FreeNAS or NAS4Free, there are multiple algorithms you can use. However, in practice, for me this always becomes a choice between AES-XTS and AES-CBC. Since every modern processor had AES primitives supported in hardware, these two offer performance other algorithms cannot reach.

The current industry standard for disk encryption is XTS-AES and that is mode I usually default to. It has been made specifically to facilitate full-disk encryption and has no known attacks (other than malleability attack common to practically all such algorithms).

Using AES-CBC is not as crazy as it seems. While there is a known “watermark” attack, GELI is not vulnerable at it uses CBC-ESSIV. And, while it is still vulnerable against malleability attack, it’s more resilient than XTS to some (albeit rather unrealistic) attacks while sharing CBC’s “friendliness” to altering bits on per-block level.

In the absence of any new attack, you are probably fractionally more secure with XTS but realistically both XTS-AES and AES-CBC with ESSIV can be considered equivalent and well-suited for full-disk encryption. That said, as security is not concern, are there performance differences between those two?

And there are. At least on NAS4Free albeit I believe the same applies across the BSD family - including FreeNAS.

My ZFS mirror on i3-4010U used XTS-AES-128 for encryption and its median write speed was 197 MB/s. The same mirror had its write speed increased to 389 MB/s once both disks were set to use AES-CBC-128. Interestingly, changing the encryption mode on a single disk to CBC while the other was still using XTS also improved performance - all the way to 384 MB/s. Mind you there are no security benefits running two disks in different encryption modes. I just did it for fun. :)

My Atom C2558 server using software encryption with XTS-AES only wrote at 110 MB/s. Once both physical drives used AES-CBC, speed jumped to 162 MB/s. Again, changing only a single drive in mirror to CBC increased write speed to 157 MB/s.

The same server using hardware encryption could write 160 MB/s when both drives encrypted using XTS-AES. Both drives using AES-CBC achieved again 160 MB/s. Once more, the curiosity was half/half situation with write speed at 162 MB/s.

Based on these results it is obvious that AES-CBC performs much better than XTS-AES in some cases or both have the same speed at worst. The fact changing a single drive to CBC already brought 95% of improvement tells me that CPU was really straining with XTS despite hardware AES-NI support. On the slower CPU difference was non-existent albeit this was more related to its general slowness of AES-NI on Atom than to anything algorithm specific.

Intel’s own tests on the same generation (albeit vastly more powerful processors) shows that XTS implementation can actually be faster than CBC - especially when multiple cores can “exploit” XTS’ inherent parallelism.

This just shows that performance is highly dependent on everything in the pipeline - especially software support - and not just hardware. And one should be careful to occasionally retest if old assumptions are still valid. For example, the next version of BSD crypto library could improve performance of XTS to surpass CBC.

I personally will still stick with XTS-AES. Encryption and decryption speeds, while not exhilarating, are more than adequate for sharing files over Samba connections. While AES-CBC will surely enjoy support in the future, XTS is the one standardized for full-disk encryption. Unless a security issue is discovered, support for it will only get better with time.


PS: Malleability attack on AES-XTS and AES-CBC is actually not that problematic for my setup as ZFS includes data checksum. To be completely sure, for sensitive applications, one should think about using SHA-256 instead of default Fletcher-16 checksum.

PPS: GELI actually doesn’t use ESSIV as you would find it on Linux. However, its implementation is pretty much equivalent to it in both security and performance.

PPPS: For curious, I used the following command to test write speed, repeating the measurement 5 times:

dd if=/dev/zero of=/mnt/Temp/Test.tmp bs=4096 count=1048576

PPPPS: You can also get rough idea which encryption method is faster by running OpenSSL speed test:

openssl speed -evp aes-128-xts
openssl speed -evp aes-128-cbc

[2018-07-22: NAS4Free has been renamed to XigmaNAS as of July 2018]

Configuring Classless Static Route Option

If you want to push routes to your client, the easiest way to do so would be adding a classless static route (DHCP option 121) as defined in RFC 3442. Every router has their way of setting these but usually they have one thing in common - you must do so manually. And yes, if you make a single mistake, your Internet connectivity will be lost.

Issue of easy entry has bothered me for long enough to actually do something about it. Below find classless static route option calculator. Just enter routes you want and you will get their hexadecimal representations.

NetworkGateway
Default
DHCP option 121:
OpenSense/Ubiquiti notation:
Mikrotik code:

[2019-12-13: Updated script to have default route first (workaround for Ubuntu 19.10 Server).] [2020-12-26: Added OpenSense/Ubiquiti notation.] [2022-07-22: Fixed to allow for /32 network.]

Change Default Shell in NAS4Free

Albeit I love almost everything about NAS4Free and his cousin FreeNAS, I can never get adjusted to its shell choice. It might be that tcsh is an awesome shell, but I am much more accustomed to bash.

Standard FreeBSD (and Linux) approach is to use chsh command. However, that command is not present in NAS4Free. Fortunately, there is an alternative choice.

Command pw offers that and much more. To change shell, we simply execute the following command:

pw user mod root -s /bin/bash

While we cannot make this default, we can add it under System, Advanced, Command Scripts. If we add this command as Post Init script, the next login will greet us with bash prompt.

[2018-07-22: NAS4Free has been renamed to XigmaNAS as of July 2018] [2018-08-13: This change does result loss of console menu. There is a slightly different method without that downside.]

Configuring Google's SMTP Via Smtpmail on Linode CentOS

When you install Wordpress on Linode, one thing that’s not supported out of box is mail - php requires sendmail installed and running.

Configurations might differ depending on the exact use case, but for my Wordpress I wanted to use Google’s SNMP server. While guides are plentiful, most of information is a bit obsolete - whether it is in regards to package name or exact configuration. So I went my own way…

To get us going, we need to install a few packages related to sendmail functionality and allow the same in SELinux (if enforced):

yum install -y sendmail sendmail-cf cyrus-sasl-plain cyrus-sasl-md5
setsebool -P httpd_can_sendmail on

First thing to prepare is file containing our authentication details for Google’s server. I will assume here that login you usually use is relay@gmail.com and password is password. Of course, these must be substituted for correct values:

mkdir -p -m 700 /etc/mail/authinfo
echo 'AuthInfo: "U:root" "I:^^relay@gmail.com^^" "P:^^password^^"' > /etc/mail/authinfo/gmail
makemap hash /etc/mail/authinfo/gmail < /etc/mail/authinfo/gmail

To /etc/mail/sendmail.mc we need to add the following lines just ABOVE the first MAILER line.

…
define(`SMART_HOST',`[smtp.gmail.com]')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl
define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnl
define(`confAUTH_OPTIONS', `A p')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confCACERT', `/etc/pki/tls/certs/ca-bundle.trust.crt')dnl
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
FEATURE(`authinfo',`hash -o /etc/mail/authinfo/gmail.db')dnl
``…``

Once configuration has been updated, we can proceed with “compiling” that new configuration and starting the daemon for the first time.

make -C /etc/mail
systemctl start sendmail

The easiest test is sending an e-mail via command line:

echo "Subject: Test via sendmail" | sendmail -v ^^youremail@example.com^^

If there are issues, you can always check journal for startup errors:

journalctl -xe

The most common error is “available mechanisms do not fulfill requirements” and that signals Cyrus SASL plugins are not installed for MD5 and PLAIN methods. Make sure cyrus-sasl-plain and cyrus-sasl-md5 packages are installed.

Lastly, if sendmail does work but it is very slow, add your hostname (output of hostname command) to the end of localhost (IPv4 and IPv6) entries in /etc/hosts file.