Centos 7 mail server

In this blog I am adding a few comments / observations on installation and configuration of mail server with the following features:

  • firewalld enabled
  • selinux enabled
  • postfix
  • dovecot
  • spam assassin
  • clamav
  • amavisd
  • Roundcube

Personally, I am a huge fan of selinux and it is painful to see tutorials advising disabling selinux on RHEL/Centos/Fedora. There is nothing special about the installation and configuration of the above services that requires disabling selinux (or firewalld).

All services were installed using yum:

yum install postfix dovecot amavisd-new clamav-update


This post in NOT intended to be a tutorial on firewalld, rather it is a brief summary working with firewalld.

I would refer you to one of the many tutorials available online firewalld for reference.

firewall-cmd –add-service=smtp –permanent

The current open ports / services on the mail server are:

firewall-cmd --list-all
  target: default
  icmp-block-inversion: no
  services: ssh dhcpv6-client smtp pop3s imaps http https
  ports: 587/tcp 465/tcp 110/tcp 143/tcp 25/tcp
  masquerade: no
  rich rules:


As with firwalld, this post is NOT intended to be a tutorial on postfix, again there are many online tutorials.

Key configuration options

Some KEY options include:

#Required to send to most mail servers such as gmail.com
always_add_missing_headers = yes

#Option is all 1 line
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination

#Option is all 1 line
smtpd_relay_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination

#Set custom mail location, if unset mail is in /var/spool/mail
#This puts mail in /home/$USER/mail
home_mailbox = mail/

IF you set a location for mail (home_mailbox = mail) you must then either:

  1. add a .mailrc for each user with the following lines:

    set MAIL=/home/bodhi/mail
    set folder=mail

  2. In a multi-user system, add the following edits to system files to enable ~/mail via login, su, sudo, or ssh:

    #command is all 1 line
    echo ‘export MAIL=~/mail’ | sudo tee -a /etc/bash.bashrc | sudo tee -a /etc/profile.d/mail.sh

Here is a test email from the mail server (logged into localhost)

bodhi@mail:~$mail bodhi.zazen@ubuntu.com
Subject: Postfix working

This is a test email


And to read the reply

Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/panther": 2 messages
>   1 bodhi@mail.org    Sun Dec  3 18:08  20/573   "test"
    2 bodhi zazen           Sun Dec  3 18:09  75/3559  "Re: it works"
& 2

test dovecot

Dovecot is a little more obscure !

telnet localhost 143
Trying ::1...
Connected to localhost.
Escape character is '^]'.
a LIST "" "*"
* LIST (\HasNoChildren) "." INBOX
a OK List completed.
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1512325183] UIDs valid
* OK [UIDNEXT 6] Predicted next UID
a OK [READ-ONLY] Examine completed (0.001 secs).
* 2 FETCH (BODY[] {546}
X-Original-To: bodhi@mail.org
Delivered-To: bodhi@mail.org
Received: by mail.mail.org (Postfix, from userid 1001)
	id E4F7E178044E; Sun,  3 Dec 2017 16:58:04 +0100 (CET)
Date: Sun, 03 Dec 2017 16:58:04 +0100
To: bodhi@mail.org
Subject: Test
User-Agent: Heirloom mailx 12.5 7/5/10
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20171203155804.E4F7E178044E@mail.mail.org>
From: bodhi.zazen@ubuntu.com

It works , thank you

a OK Fetch completed.
* BYE Logging out
a OK Logout completed.
Connection closed by foreign host.

Prevent mail server from being marked as spam, install and configure opendkim

See : Install opendkim Centos 7

Test your key with (change “mail.org” to your domain name) :

dig mail.org._domainkey.ceae.info TXT


; <<>> DiG 9.10.3-P4-Ubuntu <<>> mail.org._domainkey.ceae.info TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 50764
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 65494
;mail.org._domainkey.ceae.info. IN TXT

;; Query time: 333 msec
;; WHEN: Tue Dec 05 14:33:07 MST 2017
;; MSG SIZE  rcvd: 65

Spam assassin and clamav

I used This tutorial

HOWEVER that tutorial is incomplete and does not work with selinux enabled

To complete the setup , with selinux enabled, run

setsebool -P antivirus_can_scan_system 1
setsebool -P clamd_use_jit on

yum install clamav clamav-scanner-systemd

cd /usr/lib/systemd/system
cp clamd\@scan.service clamd\@amavisd.service

systemctl start clamd@amavisd
systemctl enable clamd@amavisd
systemctl restart amavisd

Now, while tailing the mail log, send a test email containing the following message


In the logs we will see

Dec  3 22:27:41 mail postfix/qmgr[350]: 9E79B17806EE: from=, size=7448, nrcpt=1 (queue active)
Dec  3 22:27:41 mail postfix/smtpd[1663]: disconnect from mail-wr0-f175.google.com[]
Dec  3 22:27:52 mail clamd[1583]: /var/spool/amavisd/tmp/amavis-20171203T222741-01661-aAF7S5Ck/parts/p004: Eicar-Test-Signature FOUND
Dec  3 22:27:52 mail clamd[1583]: /var/spool/amavisd/tmp/amavis-20171203T222741-01661-aAF7S5Ck/parts/p001: Eicar-Test-Signature FOUND
Dec  3 22:27:52 mail amavis[1661]: (01661-01) Blocked INFECTED (Eicar-Test-Signature) {DiscardedInbound,Quarantined}, []:46159 []  -> , Queue-ID: 9E79B17806EE, Message-ID: , mail_id: 1bM4Cqm5z69m, Hits: -, size: 7606, 10249 ms
Dec  3 22:27:52 mail postfix/lmtp[1668]: 9E79B17806EE: to=, relay=[]:10024, delay=10, delays=0.16/0.04/0.02/10, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=01661-01 - INFECTED: Eicar-Test-Signature)
Dec  3 22:27:52 mail postfix/qmgr[350]: 9E79B17806EE: removed
Dec  3 22:31:01 mail postfix/anvil[1665]: statistics: max connection rate 1/60s for (smtp: at Dec  3 22:27:41
Dec  3 22:31:01 mail postfix/anvil[1665]: statistics: max connection count 1 for (smtp: at Dec  3 22:27:41
Dec  3 22:31:01 mail postfix/anvil[1665]: statistics: max cache size 1 at Dec  3 22:27:41

To test spam assassin, use GTUBE to send the following test spam message

Subject: Test spam mail (GTUBE)
Date: Wed, 23 Jul 2003 23:30:00 +0200
From: Sender 
To: Recipient 
Precedence: junk
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

This is the GTUBE, the
	Test for

If your spam filter supports it, the GTUBE provides a test by which you
can verify that the filter is installed correctly and is detecting incoming
spam. You can send yourself a test mail containing the following string of
characters (in upper case and with no white spaces and line breaks):


You should send this test mail from an account outside of your network.


Roundcube is in the centos repos

yum install roundcube

The following booleans were used for selinux

setsebool -P httpd_can_sendmail on
setsebool -P httpd_can_network_connect_db on

And to allow web access outside localhost, use the following configuration

<Directory /usr/share/roundcubemail/>
    <IfModule mod_authz_core.c>
        # Apache 2.4
        # Require local
        Require all granted

And to get rid of localhost in domain name

nano config.inc.php

$config['default_host'] = 'ssl://%n';
$config['smtp_server'] = 'tls://%n';

How to tell if it is working

On Ubuntu I installed the package clamav-testfiles and packaged them up in a .zip , .xz , and .bz2 file and sent them from mutt

bodhi@Ubuntu:~$mutt -s "Config2" -a /home/bodhi/config.tar.bz2 -- bodhi@mail.org

bodhi@Ubuntu:~$mutt -s "Config2" -a /home/bodhi/config.xz -- bodhi@mail.org

bodhi@Ubuntu:~$mutt -s "Config2" -a /home/bodhi/config.zip -- bodhi@mail.org

On the server tail -f the log and you will see messages such as:

Dec  5 02:32:08 mail amavis[30150]: (30150-07) Blocked BANNED (.exe,.exe-ms,usr/share/clamav-testfiles/clam_IScab_int.exe) {BouncedInbound,Quarantined}, []:59838 []  -> , Queue-ID: E158517802D8, Message-ID: <20171205013139.tikx5ynbexyln3qg@Ubuntu.com
Posted in Fedora, Linux | Leave a comment


Recently one of my RAID drives failed failed on my server and I had to learn to use MegaCli.

MegaCli is a command line tool used to manage DELL hardware RAID devices, however, the available guides are cryptic and difficult to follow. This post shows how I was able to install and use megacli on a Debian Server.

TL:DR – As I had a hotswap RAID controller I was able to simply pull the failed drive, insert the new drive, and the RAID array was restored. I was able to confirm the success using megacli over ssh, however, the megacli guides are cryptic at best. Most of the guides show output from a working system and do not show the actual output and commands on a failed system.

I am running a Debian server and The Debian Raid Guide was invaluable as was Erik’s cheatsheet

For those who are interested, calomel.org provides information on installing from Broadcom and a wrapper script form MegaCli.

Unfortunately the process was cryptic enough to warrant some additional information.

First identify the RAID controller

lspci -nn | grep RAID
02:0e.0 RAID bus controller [0104]: Dell PowerEdge Expandable RAID controller 5 [1028:0015]

MegaCLI is NOT in the debian repos, however, a .deb is available at Debian MegaCLI packages at hwraid.le-vert.net . Alternately you can download the source code from Source Forge

Add the following repository to /etc/apt/sources.list :

deb http://hwraid.le-vert.net/debian jessie main

Add the gpg key and install

wget -O – https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key | sudo apt-key add –

sudo apt-get install megacli

Here is where the fun starts =)

First, although most online guides use the command MegaCli, the actual command after installing the package is megacli making copy paste difficult.

First you have to identify the raid device and physical drives as you need to specify them with the commands.

To see all information, run megacli -AdpAllInfo -aALL. I suggest you pipe the output to less or a file.

megacli -AdpAllInfo -aALL >raid.info
megacli -AdpAllInfo -aALL | less

The relevant information from my system was

Enclosure Device ID: 8

Device Present
Virtual Drives : 1
Degraded : 1
Offline : 0
Physical Devices : 2
Disks : 1
Critical Disks : 0
Failed Disks : 0


Note: From Erik’s cheatsheet, Drives are specified using :

the -PhysDrv [E:S] parameter is used, where E is the enclosure device ID in which the drive resides and S the slot number (starting with zero)

The “S” parameters were easy enough, drive 0 and drive 1 , but the E parameter was obscure. Turns out it is identified in the line “Enclosure Device ID: 8” shown above. Common numbers on other posts on megacli are 0 and 256 .

So on my system drive 0 = [8:0] and drive 1 = [8:1]

Because my default shell is zsh rather then bash, when using the command megacli -PdInfo -PhysDrv [8:0] -a0 I HAD TO ESCAPE THE BRACKETS like so megacli -PdInfo -PhysDrv\[8:0\] a0

Drive 0

megacli -PdInfo -PhysDrv \[8:0\] -a0

Adapter 0: Device at Enclosure – 8, Slot – 0 is not found.

Exit Code: 0x00

Drive 1

>megacli -PdInfo -PhysDrv \[8:1\] -a0

Enclosure Device ID: 8
Slot Number: 1
Drive’s position: DiskGroup: 0, Span: 0, Arm: 1
Enclosure position: N/A
Device Id: 1
Sequence Number: 4
Media Error Count: 0
Other Error Count: 17
Predictive Failure Count: 0
Last Predictive Failure Event Seq Number: 0

Raw Size: 931.512 GB [0x74706db0 Sectors]
Non Coerced Size: 931.012 GB [0x74606db0 Sectors]
Coerced Size: 931.0 GB [0x74600000 Sectors]
Sector Size: 0
Firmware state: Online, Spun Up
Device Firmware Level: SN04
Shield Counter: 0
Successful diagnostics completion on : N/A
SAS Address(0): 0x1221000001000000
Connected Port Number: 1
Inquiry Data: 5QJ09SPBST31000340NS SN04
FDE Capable: Not Capable
FDE Enable: Disable
Secured: Unsecured
Locked: Unlocked
Needs EKM Attention: No
Foreign State: None
Device Speed: Unknown
Link Speed: Unknown
Media Type: Hard Disk Device
Drive Temperature : N/A
PI Eligibility: No
Drive is formatted for PI information: No
Port-0 :
Port status: Active
Port’s Linkspeed: Unknown
Drive has flagged a S.M.A.R.T alert : No

So drive 0 had failed. As my raid controller is hot swap and, as the drive had failed, I could not run any additional commands suggested on Eirk’s cheatsheet.

megacli -PDPrpRmv -PhysDrv \[8:0\] -a0

Adapter #0: Failed to Perform prepare for removal Operation.

So just replace the failed drive. You can see the drive being rebuilt with the command

megacli -PDRbld -ShowProg -PhysDrv \[8:0\] -aALL

Rebuild Progress on Device at Enclosure 8, Slot 0 Completed 79% in 5 Minutes.

Exit Code: 0x00

Once the rebuild is done, you can check the log (after generating it).

megacli -fwtermlog -dsply -a0 -nolog > megacli.log

The log file is extensive, but scrolling to the bottom we see the new drive recognized and rebuilt

06/20/17 17:40:50: EVT#15853-06/20/17 17:40:50: 91=Inserted: PD 00(e1/s0)
06/20/17 17:40:50: EVT#15854-06/20/17 17:40:50: 247=Inserted: PD 00(e1/s0) Info: enclPd=08, scsiType=0, portMap=01, sasAddr=1221000000000000,0000000000000000
06/20/17 17:40:50: EVT#15855-06/20/17 17:40:50: 236=PD 00(e1/s0) is not a certified drive
06/20/17 17:40:50: EVT#15856-06/20/17 17:40:50: 114=State change on PD 00(e1/s0) from UNCONFIGURED_GOOD(0) to OFFLINE(10)
06/20/17 17:40:50: EVT#15857-06/20/17 17:40:50: 106=Rebuild automatically started on PD 00(e1/s0)
06/20/17 17:40:50: EVT#15858-06/20/17 17:40:50: 114=State change on PD 00(e1/s0) from OFFLINE(10) to REBUILD(14)
06/20/17 17:42:23: EVT#15859-06/20/17 17:42:23: 103=Rebuild progress on PD 00(e1/s0) is 0.99%(93s)

…… clipped output …..

06/20/17 21:03:16: EVT#15958-06/20/17 21:03:16: 103=Rebuild progress on PD 00(e1
/s0) is 99.94%(12146s)
06/20/17 21:03:26: EVT#15959-06/20/17 21:03:26: 100=Rebuild complete on PD 00(e1
06/20/17 21:03:27: EVT#15960-06/20/17 21:03:27: 81=State change on VD 00/0 from DEGRADED(2) to OPTIMAL(3)

EDIT 12.18.2017

First there is a helpful wrapper script on https://calomel.org/megacli_lsi_commands.html

I copied it to /root/bin/raid

I then used to identify and reinitialize a failed drive

root@banshee~/bin# ./raid drives
Slot Number: 0 – Online, Spun Up
Slot Number: 1 – Failed

root@banshee~/bin# megacli PDOffline -PhysDrv \[8:1\] -aALL

Adapter: 0: EnclId-8 SlotId-1 state changed to OffLine.

Exit Code: 0x00

root@banshee~/bin# megacli PDOnline -PhysDrv \[8:1\] -aALL

EnclId-8 SlotId-1 state changed to OnLine.

Exit Code: 0x00

root@banshee~/bin# ./raid drives
Slot Number: 0 – Online, Spun Up
Slot Number: 1 – Online, Spun Up

Posted in Linux | Leave a comment

How to determine if an application is using Wayland or Xwayland

With the release of Fedora 23 I noticed there is the option to run “gnome-wayland” so I took it for a test drive.

Although I am not normally a fan of gnome-shell I have to admit it looks and runs great.

Videocard – VGA compatible controller: NVIDIA Corporation G86 [Quadro NVS 290] , dual montiors


The question came up, how to easily determine if an application is using wayland or Xwayland.

Turns out is is easily determined by LG or Looking Glass

Looking Glass is GNOME Shell’s integrated debugger and inspector tool. It aims to be the Firebug of GNOME Shell.

To use looking glass, Hit Alt-F2 , type lg, and hit the enter key

You will see an option to show the windows in the upper right corner.

Double click on any window to bring up additional information

Gnome applications are using wayland


Other applications, firefox in this example, are using Xwayland


Posted in Fedora, Linux | 3 Comments

KDE Dual Monitors

I started using various music distros (KXStudio and Fedora Jam). One of the annoyances is that KDE does not remember the settings for dual monitors. Thus every time after logging in the screens need to be fixed. This seems to be a longstanding bug.

Turns out there is a simple fix, disable “KScreen 2”

Go to System Settings -> Startup and Shutdown -> Service Manager (on the left) -> disable KScreen 2

Screen Shot

Posted in Fedora, Linux | 3 Comments

Music practice

With the advent of YouTube , there is a plethora of music “lessons” available on the internet. When learning new riffs, however, it is helpful to be able to alter the speed of playback and play selective sections of the lesson.

For some time I have been using audacity, which has the advantage of cross platform availability. However, audacity is a bit of overkill and I find it a bit slow at times.

In addition, when selecting a particular segment within the lesson, skipping dialog or parts already mastered, audacity is a bit “clunky” and somewhat time consuming. Alternately one can splice the lessons with ffmpeg, again somewhat time consuming.

Recently I came across a simple, no frills, light weight solution, “Play it slowly”

Home page

Download (github)

Play it slowly screen shot

Play it slowly is a light weight application but has a simple , clean interface. It is simple to use and has basic features such as:

  1. Slow the speed on playback without altering pitch.
  2. Easily mark, move, and reset sections of a track for playback.
  3. Easy to start/stop/restart playback.

Play is slowly is in the Debian and Ubuntu repositories

sudo apt-get install playitslowly

For Fedora, first install the dependencies:

yum install gstreamer-python gstreamer-plugins-bad-extras

Download the source code from the above link (version 1.4.0 at the time of this writing)

Extract the tarball and install

tar xvzf playitslowly-1.4.0.tar.gz
cd playitslowly-1.4.0
sudo python setup.py install

For additional options see the README or run:

python setup.py --help

Posted in Linux | Leave a comment

Display-dhammapada version 1.1

display-dhammapada is a small package I have been maintaining for the last 2 years and I recently found the time to update. Verses from the English, German, or Polish translations of the
Dhammapada are displayed, either in a terminal or graphically.

With the update display-dhammapada to version 1.1 The German translation was added and titles are now displayed in the appropriate language.

The source code is located at my web site as well as a 64 bit .deb and .rpm (in the Debian and Fedora directories).

The program itself can be compiled as follows

mkdir ~/src
cd ~/src
wget http://bodhizazen.com/display-dhammapada/display-dhammapada-1.1.tar.gz

tar xzvf display-dhammapada-1.1.tar.gz

cd display-dhammapada-1.1
sudo make install

To remove the program:

cd ~/src/display-dhammapada-1.1
sudo make uninstall

Posted in Linux | 6 Comments

Installing ddate

ddate is a utility to display the Discordian date with a colorful history. It was removed from util-linux but the source code is still available on GitHub

source https://github.com/bo0ts/ddate

Click the “Download Zip” box on the left.

save / extract in ~/src

cd ~/src/ddate-master
cmake CMakeLists.txt
sudo make install

There is no uninstall script, so to remove,

sudo rm /usr/local/bin/ddate
sudo rm /usr/local/share/man/man1/ddate.1.gz

For additional information see

Posted in Linux | 3 Comments

Printing HP Deskjet 1000

I was having trouble printing to my HP Deskjet 1000. When printing a test page, the print job would appear to work, without any error message in /var/log/cups/error_log . however, nothing would print from the printer.

Turned out to be a simple solution, I had to install hplip and hpijs

yum install hplip hpijs

apt-get install hplip hpijs

With more recent versions of Ubuntu (and likely Debian), hpijs is now printer-driver-hpijs

apt-get install hplip printer-driver-hpijs

Odd that the (graphical) system configuration tool did not suggest installing those drivers.

Posted in Fedora, Linux | 4 Comments

Set a hostname in Fedora

I know I have not been very active lately, but I came across a convenient command line tool to set a host name in Fedora. While it is possible to set a host name by manually editing a few system files, I recently came across a command that makes it even easier.

sudo hostnamectl set-hostname $new_hostname

Just set “$new_hostname” to your desired host name.

Posted in Fedora, Linux | Leave a comment

Selinux and confined users

I admit to a paranoid streak and have been confining my users with selinux.

I confine almost all users as user_u

/usr/sbin/semanage login -a -s user_u $user

Users who need admin access I confine as staff_u

/usr/sbin/semanage login -a -s staff_u $user

There are 2 minor annoyances with this method.

First I like regular users to be able to ping. This is enabled as a boolean.

setsebool -P selinuxuser_ping on

And second, although staff_u can use sudo, they are still restricted by selinux. To allow unlimited access, add or edit /etc/sudoers.d/sudo to read

%user ALL=(ALL) TYPE=unconfined_t ROLE=unconfined_r ALL

Change “%user” to the user name you wish to allow unconfined root access.

Posted in Fedora, Linux | 4 Comments