Title: Full featured Slackware email server with sendmail and | |
cyrus-imapd | |
Author: Solène | |
Date: 14 November 2020 | |
Tags: slackware email | |
Description: | |
This article is about making your own mail server using Slackware | |
linux distribution, sendmail and cyrus-imap. This choice is because I | |
really love Slackware and I also enjoy non-mainstream stacks. While | |
everyone would recommend postfix/dovecot, I prefer using | |
sendmail/cyrus-imap. Please not this article contain ironical | |
statements, I will try to write them with some *emphasis*. | |
*While some people use fossil fuel cars, some people use Slackware.* | |
If you are used to clean, reproducible and automated deployments, the | |
present how-to is the totally opposite. *This is the /Slackware/ way*. | |
## Slackware | |
Slackware is one of the oldest (maybe the oldest with debian) linux | |
distribution out there and it's still usable. The last release (14.2) | |
is 4 years old but there are still security updates. I choose to use | |
the development branch slackware-current for this article. | |
I discovered an alternative to Windows in the early 2000' with a | |
friend showing me a « Linux » magazine, featuring Slackware | |
installation CDs and the instructions to install. It was my very first | |
contact with Linux and open source ever. I used Slackware multiple | |
times over time, and it was always a great system for me on my main | |
laptop. | |
The Slackware specifics could be said as: "not changing much" and | |
"quite limited". Slackware never change much between releases, from | |
2010 to 2020, it's pretty much the same system when you use it. I say | |
it's rather limited, package wise, the default Slackware installation | |
requires like 15 GB on your disk because it bundles KDE and all the | |
kde apps, a bunch of editors (emacs,vim,vs,elvis), lot of | |
compilers/interpreter (gcc, llvm, ada, scheme, python, ruby | |
etc..). While it provides a LOT of things out of the box, you really | |
get all Slackware can offer. If something isn't in the packages, you | |
need to install it yourself. | |
## Full Disk Encryption or nothing | |
I recommend to EVERYONE the practice of having a full disk encryption | |
(phone, laptop, workstation, servers). If your system get stolen, you | |
will only lose hardware when you use full disk encryption. | |
Without encryption, the thief can access all your data forever. | |
Slackware provides a file `README_CRYPT.txt` explaining how to install | |
on an encrypted partition. Don't forget to tell the bootloader *LILO* | |
about the initrd, and keep in mind the initrd must be recreated after | |
kernel upgrade | |
## Use ntpd | |
It's important to have a correct time on your server. | |
# chmod +x /etc/rc.d/rc.ntpd | |
# /etc/rc.d/rc.ntpd start | |
## Disable ssh password authentication | |
In `/etc/ssh/sshd_config` there are two changes to do: | |
Turn `UsePam yes` into `UsePam no` and add `PasswordAuthentication`. | |
Changes can be applied by restarting ssh with `/etc/rc.d/rc.sshd | |
restart`. | |
Before enabling this, don't forget to deploy your public key to an | |
user who is able to become to root. | |
## Get a SSL certificate | |
We need a SSL certificate for the infrastructure, so we will install | |
[certbot](https://certbot.eff.org/). Unfortunately, certbot-auto | |
doesn't work on Slackware because the system is unsupported. So we | |
will use pip and call certbot in standalone mode so we don't need a | |
web server. | |
# pip3 install certbot | |
# certbot certonly --standalone -d mydomain.foobar -m | |
usernam@example | |
My domain being `kongroo.eu` the files are generated under | |
`/etc/letsencrypt/live/kongroo.eu/`. | |
## Configure the DNS | |
Three DNS entries have to be added for a working email server. | |
1. SPF to tell the world which addresses have the right send your | |
emails | |
2. MX to tell the world which addresses will receive the emails and in | |
which order | |
3. DKIM (a public key) to allow recipients to check your emails really | |
comes from your servers (signed used a private key) | |
4. DMARC to tell recipient what to do with mails not respecting SPF | |
### SPF | |
Simple, add an entry with `v=spf1 mx` if you want to allow your MX | |
servers to send emails. Basically, for simple setups, the same server | |
receive and send emails. | |
@ 1800 IN SPF "v=spf1 mx" | |
### MX | |
My server with the address `kongroo.eu` will receive the emails. | |
@ 10800 IN MX 50 kongroo.eu. | |
### DKIM | |
This part will be a bit more complicated. We have to generate a pair | |
of public and private keys and run a daemon that will sign outgoing | |
emails with the private key, so recipients can verify the emails | |
signature using the public key available in the DNS. We will use | |
opendkim, I found this | |
[very | |
good](https://philio.me/setting-up-dkim-with-sendmail-on-ubuntu-14-04/) | |
article explaining how to use opendkim with sendmail. | |
Opendkim isn't part of slackware base packages, fortunately it is | |
available in [slackbuilds](https://slackbuilds.org/), you can check my | |
previous article explaining how to setup slackbuilds. | |
# groupadd -g 305 opendkim | |
# useradd -r -u 305 -g opendkim -d /var/run/opendkim/ -s | |
/sbin/nologin \ | |
-c "OpenDKIM Milter" opendkim | |
# sboinstall opendkim | |
We want to enable opendkim at boot, as it's not a service from the | |
base system, so we need to "register" it in rc.local and enable both. | |
Add the following to `/etc/rc.d/rc.local`: | |
if [ -x /etc/rc.d/rc.opendkim ]; then | |
/etc/rc.d/rc.opendkim start | |
fi | |
Make the scripts executable so they will be run at boot: | |
# chmod +x /etc/rc.d/rc.local | |
# chmod +x /etc/rc.d/rc.opendkim | |
Create the key pair: | |
# mkdir /etc/opendkim | |
# cd /etc/opendkim | |
# opendkim-genkey -t -s default -d kongroo.eu | |
Get the content of `default.txt`, we will use it as a content for a | |
TXT entry in the DNS, select only the content between parenthesis | |
without double quotes: your DNS tool (like on Gandi) may take | |
everything without warning which would produce an invalid DKIM | |
signature. *Been there, done that.* | |
The file should looks like: | |
default._domainkey IN TXT ( "v=DKIM1; k=rsa; t=y; " | |
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5iBUyQ02H5sfS54hg155eQBxtMuhc | |
wB4b896S7o97pPGZEiteby/RtCOz9VV2TOgGckz8eOEeYHnONdlnYWGv8HqVwngPWJmiU7x | |
byoH489ZkG397ouEJI4mBrU9ZTjULbweT2sVXpiMFCalNraKHMVjqgZWxzqoE3ETGpMNNSw | |
IDAQAB" ) | |
But the content I used for my entry at gandi is: | |
v=DKIM1; k=rsa; t=y; " | |
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5iBUyQ02H5sfS54hg155eQBxtMuhc | |
wB4b896S7o97pPGZEiteby/RtCOz9VV2TOgGckz8eOEeYHnONdlnYWGv8HqVwngPWJmiU7x | |
byoH489ZkG397ouEJI4mBrU9ZTjULbweT2sVXpiMFCalNraKHMVjqgZWxzqoE3ETGpMNNSw | |
IDAQAB | |
Now we need to configure opendkim to use our keys. Edit | |
`/etc/opendkim.conf` to changes the following lines already | |
there: | |
Domain kongroo.eu | |
KeyFile /etc/opendkim/default.private | |
ReportAddress [email protected] | |
### Dmarc | |
We have to tell DMARC, this may help being accepted by big corporate | |
mail servers. | |
_dmarc.kongroo.eu. IN TXT | |
"v=DMARC1;p=none;pct=100;rua=mailto:[email protected];" | |
This will tell the recipient that we don't give specific instruction | |
to what to do with suspicious mails from our domain and tell | |
[email protected] about the reports. **Expect daily mail from | |
every mail server reached in the day to arrive on that address.** | |
## Install Sendmail | |
*Unfortunately Slackware team dropped sendmail in favor to postfix* in | |
the default install, this may be a good thing but I want | |
sendmail. *Good news: sendmail is still in the extra directory*. | |
I wanted to use [citadel](https://citadel.org/) but *it was really | |
complicated, so I went to sendmail.* | |
### Installation | |
Download the two sendmail txz packages on a mirror in the "extra" | |
directory: | |
https://mirrors.slackware.com/slackware/slackware64-current/extra/sendm | |
ail/ | |
Run `/sbin/installpkg` on both packages. | |
### Configuration | |
We will disable postfix. | |
# sh /etc/rc.d/rc.postfix stop | |
# chmod -x /etc/rc.d/rc.postfix | |
Enable sendmail and saslauthd | |
# chmod +x /etc/rc.d/rc.sendmail | |
# chmod +x /etc/rc.d/rc.saslauthd | |
All the configuration will be done in `/usr/share/sendmail/cf/cf`, we | |
will use a default template from the package. As explained in the cf | |
files, we need to use a template and rebuild from this directory | |
containing all the macros. | |
# cp sendmail-slackware-tls-sasl.mc | |
/usr/share/sendmail/cf/cf/config.mc | |
Every time we want to rebuild the configuration file, we need to apply | |
the m4 macros to have the real configuration file. | |
# sh Build config.mc | |
# cp config.cf /etc/mail/sendmail.cf | |
My `config.mc` file looks like this (I stripped the comments): | |
include(`../m4/cf.m4') | |
VERSIONID(`TLS supporting setup for Slackware Linux')dnl | |
OSTYPE(`linux')dnl | |
define(`confCACERT_PATH', `/etc/letsencrypt/live/kongroo.eu/') | |
define(`confCACERT', `/etc/letsencrypt/live/kongroo.eu/cert.pem') | |
define(`confSERVER_CERT', | |
`/etc/letsencrypt/live/kongroo.eu/fullchain.pem') | |
define(`confSERVER_KEY', | |
`/etc/letsencrypt/live/kongroo.eu/privkey.pem') | |
define(`confPRIVACY_FLAGS', | |
`authwarnings,novrfy,noexpn,restrictqrun')dnl | |
define(`confTO_IDENT', `0')dnl | |
FEATURE(`use_cw_file')dnl | |
FEATURE(`use_ct_file')dnl | |
FEATURE(`mailertable',`hash -o /etc/mail/mailertable.db')dnl | |
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable.db')dnl | |
FEATURE(`access_db', `hash -T<TMPF> /etc/mail/access')dnl | |
FEATURE(`blocklist_recipients')dnl | |
FEATURE(`local_procmail',`',`procmail -t -Y -a $h -d $u')dnl | |
FEATURE(`always_add_domain')dnl | |
FEATURE(`redirect')dnl | |
FEATURE(`no_default_msa')dnl | |
EXPOSED_USER(`root')dnl | |
LOCAL_DOMAIN(`localhost.localdomain')dnl | |
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost') | |
MAILER(local)dnl | |
MAILER(smtp)dnl | |
MAILER(procmail)dnl | |
define(`confAUTH_OPTIONS', `A p y')dnl | |
define(`confAUTH_MECHANISMS', `LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl | |
TRUST_AUTH_MECH(`LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl | |
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl | |
DAEMON_OPTIONS(`Port=smtps, Name=MSA-SSL, M=Esa')dnl | |
LOCAL_CONFIG | |
O | |
CipherList=ALL:!ADH:!NULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:-LOW:+SSLv3:+ | |
TLSv1:-SSLv2:+EXP:+eNULL | |
Create the file `/etc/sasl2/Sendmail.conf` with this content: | |
pwcheck_method:saslauthd | |
This will tell sendmail to use saslauthd for PLAIN and LOGIN | |
connections. Any SMTP client will have to use either PLAIN or LOGIN. | |
If you start sendmail and saslauthd, you should be able to send | |
e-mails with authentication. | |
We need to edit `/etc/mail/local-host-names` to tell sendmail for | |
which domain it should accept local deliveries. | |
Simply add your email domain: | |
kongroo.eu | |
The mail logs are located under `/var/log/maillog`, every mail sent | |
well signed with DKIM should appear under a line like this: | |
[time] [host] sm-mta[2520]: 0AECKet1002520: Milter (opendkim) | |
insert (1): header: DKIM-Signature: [whole signature] | |
## Configure DKIM | |
This has been explained in a subsection of sendmail configuration. If | |
you didn't read this step because you don't want to setup dkim, you | |
missed information required for the next steps. | |
## Install cyrus-imap | |
**Slackware** ships with dovecot in the default installation, but | |
cyrus-imapd is available in slackbuilds. | |
The bad news is that the slackbuild is outdated, so here it a simple | |
patch to apply in `/usr/sbo/repo/network/cyrus-imapd`. This patch also | |
fixes a compilation issue. | |
diff --git a/network/cyrus-imapd/cyrus-imapd.SlackBuild | |
b/network/cyrus-imapd/cyrus-imapd.SlackBuild | |
index 48e2c54e55..251ca5f207 100644 | |
--- a/network/cyrus-imapd/cyrus-imapd.SlackBuild | |
+++ b/network/cyrus-imapd/cyrus-imapd.SlackBuild | |
@@ -23,7 +23,7 @@ | |
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
-VERSION=${VERSION:-2.5.11} | |
+VERSION=${VERSION:-2.5.16} | |
BUILD=${BUILD:-1} | |
TAG=${TAG:-_SBo} | |
$DATABASE \ | |
--build=$ARCH-slackware-linux | |
+ | |
make PERL_MM_OPT='INSTALLDIRS=vendor' | |
make install DESTDIR=$PKG | |
b/network/cyrus-imapd/cyrus-imapd.info | |
index 99b2c68075..6ae26365dc 100644 | |
--- a/network/cyrus-imapd/cyrus-imapd.info | |
+++ b/network/cyrus-imapd/cyrus-imapd.info | |
@@ -1,8 +1,8 @@ | |
PRGNAM="cyrus-imapd" | |
VERSION="2.5.11" | |
HOMEPAGE="https://www.cyrusimap.org/" | |
-DOWNLOAD="ftp://ftp.cyrusimap.org/cyrus-imapd/cyrus-imapd-2.5.11.tar.g | |
z" | |
-MD5SUM="674083444c36a786d9431b6612969224" | |
+DOWNLOAD="https://github.com/cyrusimap/cyrus-imapd/releases/download/c | |
yrus-imapd-2.5.16/cyrus-imapd-2.5.16.tar.gz" | |
+MD5SUM="d5667e91d8e094ef24560a148e39c462" | |
DOWNLOAD_x86_64="" | |
MD5SUM_x86_64="" | |
REQUIRES="" | |
You can apply it by carefully copying the content in a file and use | |
the command `patch`. | |
We can now proceed with cyrus-imapd compilation and installation. | |
# env DATABASE=sqlite sboinstall cyrus-imapd | |
As explained in the README file shown during installation, we need to | |
do a few instructions. | |
# mkdir -m 750 -p /var/imap /var/spool/imap /var/sieve | |
# chown cyrus:cyrus /var/imap /var/spool/imap /var/sieve | |
# su - cyrus | |
# /usr/doc/cyrus-imapd-2.5.16/tools/mkimap | |
# logout | |
Add the following to `/etc/rc.d/rc.local` to enable cyrus-imapd at | |
boot: | |
if [ -x /etc/rc.d/rc.cyrus-imapd ]; then | |
/etc/rc.d/rc.cyrus-imapd start | |
fi | |
And make the rc script executable: | |
# chmod +x /etc/rc.d/rc.cyrus-imapd | |
[The official](https://www.cyrusimap.org/imap/installing.html) cyrus | |
documentation is very well done and was very helpful while writing | |
this. | |
The configuration file is `/etc/imapd.conf`: | |
configdirectory: /var/imap | |
partition-default: /var/spool/imap | |
sievedir: /var/sieve | |
admins: cyrus | |
sasl_pwcheck_method: saslauthd | |
allowplaintext: yes | |
tls_server_cert: /etc/letsencrypt/cyrus/fullchain.pem | |
tls_server_key: /etc/letsencrypt/cyrus/privkey.pem | |
tls_client_ca_dir: /etc/ssl/certs | |
There is another file `/etc/cyrusd.conf` used but we don't need to | |
make changes in it. | |
We will have to copy the certificates into a separate place and allow | |
cyrus user to read them. This will have to be done every time the | |
certificate are renewed. Let's add the certbot command so we can use | |
this script as a cron. | |
#!/bin/sh | |
DOMAIN=kongroo.eu | |
LIVEDIR=/etc/letsencrypt/live/$DOMAIN/ | |
DESTDIR=/etc/letsencrypt/cyrus/ | |
certbot certonly --standalone -d $DOMAIN -m usernam@example | |
mkdir -p $DESTDIR | |
install -o cyrus -g cyrus -m 400 $LIVEDIR/fullchain.pem $DESTDIR | |
install -o cyrus -g cyrus -m 400 $LIVEDIR/privkey.pem $DESTDIR | |
/etc/rc.d/rc.sendmail restart | |
/etc/rc.d/rc.cyrus-imapd restart | |
Add a crontab entry to run this script once a day, using `crontab -e` | |
to change root crontab. | |
MAILTO="" | |
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin | |
0 5 * * * sh /root/renew_certs.sh | |
## Starting the mail server | |
We prepared the mail server to be working on reboot, but the services | |
aren't started yet. | |
# /etc/rc.d/rc.saslauthd start | |
# /etc/rc.d/rc.sendmail start | |
# /etc/rc.d/rc.cyrus-imapd start | |
# /etc/rc.d/rc.opendkim start | |
## Adding a new user | |
Add a new user to your system. | |
# useradd $username | |
# passwd $username | |
For some reasons the user mailboxes must be initialized. The same | |
password must be typed twice (or passed as parameter using `-w | |
$password`). | |
# USER=foobar | |
# DOMAIN=kongroo.eu | |
# echo "cm INBOX" | rlwrap cyradm -u $USER $DOMAIN | |
Password: | |
IMAP Password: | |
Voila! The user should be able to connect using IMAP and receive | |
emails. | |
## Check your email setup | |
You can use the web service [Mail | |
tester](https://www.mail-tester.com/) by sending an email. You could | |
copy/paste a real email to avoid having a bad mark due to spam | |
recognition (which happens if you send a mail with a few words). The | |
bad spam core isn't relevant anyway as long as it's due to the content | |
of your email. | |
## Conclusion | |
I had real fun writing this article, digging hard in Slackware and | |
playing with unusual programs like sendmail and cyrus-imapd. I hope | |
you will enjoy too as much as I enjoyed writing it! | |
If you find mistakes or bad configuration settings, please contact me | |
so, I will be happy to discuss about the change and fix this how-to. | |
Nota Bene: Slackbuilds aren't mean to be used on the current version, | |
but really on the last release. There is a github repository carrying | |
the -current changes on a github repository | |
[https://github.com/Ponce/slackbuilds/](https://github.com/Ponce/slackb | |
uilds/). |