Last Updated: 05-19-2024
  1. You'll need a registered domain name and a VPS (Virtual Private Server) provider that allows uploading of iso images for the OS.

    I use namecheap to get my registered domain names.

    I use contabo.com as my VPS provider, and they work great for this, and use Proxmox for their VE. You then find the version of Slackware you want to install at your
    provider, which for this how-to is slackware64-15.0-install-dvd.iso, and add that link in the add custom images upload page of the provider. At contabo make sure the
    cloud init switch is green(on) for the VPS designated for Slackware. If you get a VPS at contabo for setting up a mailserver I'd highly recommend getting at minimum
    the VPS with 16gb memory and 6 CPU cores. I've tried the cheaper 8gb memory with 4 CPU cores, and it was pretty sluggish for a mailserver. I just tested my SlackerMail
    server with 16gb memory and 6 cores by subscibing to the linux-kernel mailing list, and get about 1500+ emails a day from them, and the server handles that load with
    no problems so far.

    I setup a mailserver for a internet based stock market news company back in 2010 using CentOS/iRedMail on a dedicated server that a friend of mine hired me to put
    together for his webhosting and dedicated server hosting company. I knew Linux pretty good, but didn't know mailservers, so had to do some intense learning to get it
    setup right. That just goes to show you how easy it is to setup a mailserver using iRedMail or SlackerMail. It was an old loud pizza box HP-ProLiant-DL360 G3 1U server,
    but it did the job. Here are 2 pics of that old HP server that got me started with mailservers.

    Here is the link for slackware64-15.0-install-dvd.iso you'll need to upload to your VPS provider.

    I do have 2 qcow2 images of Slackware-15.0 that have already been setup and updated to work with SlackerMail mail server. They were made using Proxmox, and can
    be used instead of doing the ISO install. I've tested both the qcow2 images, and they do work and are easier and faster than the ISO install.

    Make sure to read this How-To for directions on how to set these qcow2 images up properly at your provider!

    The qcow2 image below uses the ext4 filesystem and the lilo bootloader.
    Slackware-15.0-vps-ext4-lilo-05172024.qcow2 (4.38gb) SHA256: 1610efe335c6f019e41142b12db2de69bede42fb7fc2885e07f39fa44391854a

    The qcow2 image below uses the btrfs filesystem and the grub bootloader.
    Slackware-15.0-vps-btrfs-grub-05172024.qcow2 (3.67gb) SHA256: 46a96efc5bcadc5d44ea24afa4d27edf732038ea685bd8f78b3c414e04085d70

    Just thought I'd mention that contabo.com seems to have the problems fixed with uploading qcow2 images, and they are rockin' and rollin' now. I've tried the other big
    name VPS providers, but contabo blows them away. I don't recieve anything from contabo, just thought I'd give people a heads up. I wouldn't be able to do what I do here
    on anyother VPS provider I know of.
  2. Install Slackware

    After the Slackware iso has been uploaded to the provider, initiate the install process in their control panel. Then you'll need to VNC to the ip address given for VNC access
    to your Slackware server. I now use TigerVNC for my VNC client. TigerVNC is availible for Windows and Linux.

    Pick your Bootloader - Lilo or Grub

    *Lilo as bootloader - Recommeded for use with the Ext4 filesystem
    Once you VNC to the ip address you'll be welcomed with the Slackware boot up screen. Follow the steps below.

    01. Use fdisk to setup the drive for your server. I do "fdisk /dev/sda", then enter "g" to create a GPT disklabel.
    02. Enter "n" to create the partition for your Slackware installation, labeled 8300 Linux filesystem. I just hit enter on all prompts to use the full disk.
    03. Enter "n" again if you want to create a swap partition labeled 8200 Linux swap. I don't use swap partitions, no need if you have 8gb+ memory.
    04. Enter "w" to write to disk and quit fdisk.

    Now enter "setup" at the prompt to begin installation. We'll need to choose the (A, AP, D, K, L, N) packages to be installed during setup. We will need some X libs
    installed even though this is a command line server, but we'll install the needed X libs latter with the slackpkg command. I select NetworkManager to handle my
    network. You can set httpd to start at boot if you plan on using httpd as your webserver. I choose the Ext4 filesystem during install. When at the INSTALL LILO message
    box choose "simple - Try to install LILO automatically". Then when at the SELECT LILO DESTINATION message box choose "MBR - Intall to Master Boot Record"

    Now you've got Slackware installed do a reboot while still in the VNC. Once rebooted run "mc" at the command prompt, and go to "/etc/ssh/sshd_config" to edit
    that file and allow root login. If you don't want to login as root then you'll need to add a user with "useradd -m username" and create a password for that user with
    "passwd username", then you "su - root" to become root once you are logged in. Then while still in "mc" go to "/etc/slackpkg/mirrors" to edit that file and uncomment
    "#https://mirrors.slackware.com/slackware/slackware64-15.0/". Then while still in "mc' you'll probably want to edit" /etc/lilo.conf" and adjust the boot screen
    timeout time from 1200 (2 minutes) to something lower. I set mine to "timeout = 0". Always run "lilo" at the command prompt after making any chages in /etc/lilo.conf,
    or upgrading the kernel. Once that is done you are ready to reboot and login with the actual ip address given to you by your provider for your VPS with a ssh client like
    PuTTY.

    I log in and run as root. It's an old habit, and I've never had a problem doing this, but I know most people will want to login as a user and su to become root.

    *Grub as bootloader - Recommeded for use with the Btrfs or Ext4 filesystems
    Once you VNC to the ip address you'll be welcomed with the Slackware boot up screen. Follow the steps below.

    01. Use fdisk to setup the drive for your server. I do "fdisk /dev/sda", then enter "g" to create a GPT disklabel.
    02. Enter "n" to create a 1mb "BIOS Boot" partition by entering "+1m" at the "Last sector" prompt.
    03. Enter "t" to change the type for the "BIOS Boot" partition enter "4" at the prompt.
    04. Enter "n" again to create the partition for your Slackware installation, labeled 8300 Linux filesystem. I just hit enter on all prompts to use the full disk.
    05. Enter "n" again if you want to create a swap partition labeled 8200 Linux swap. I don't use swap partitions, no need if you have 8gb+ memory.
    06. Enter "w" to write to disk and quit fdisk.

    Now enter "setup" at the prompt to begin installation. We'll need to choose the (A, AP, D, K, L, N) packages to be installed during setup. We will need some
    X libs installed even though this is a command line server, but we'll install the needed X libs latter with the slackpkg command. I select NetworkManager to
    handle my network. You can set httpd to start at boot if you plan on using httpd as your webserver. I choose the Btrfs filesystem during install for this server.
    Toward the end of installation when asked about lilo, choose "skip do not install Lilo".

    After installation is finished exit to shell and enter "chroot /mnt" at the command prompt.
    Now enter "grub-install --modules=part_gpt /dev/sda" at the command prompt.
    Then enter "grub-mkconfig -o /boot/grub/grub.cfg" at the command prompt.
    Now exit chroot with the "exit" command.
    Lastly reboot the server with the "reboot" command. Now grub is your bootloader.

    Now you've got Slackware installed and have done a reboot while still in VNC, once rebooted run "mc" at the command prompt, and go to "/etc/ssh/sshd_config"
    to edit that file and allow root login. If you don't want to login as root then you'll need to add a user with "useradd -m username" and create a password
    for that user with "passwd username", then you "su - root" to become root once you are logged in. Then while still in "mc" go to "/etc/slackpkg/mirrors"
    to edit that file and uncomment "#https://mirrors.slackware.com/slackware/slackware64-15.0/". Then while still in "mc' you'll probably want to edit"
    /etc/default/grub" and adjust the boot screen timeout GRUB_TIMEOUT. I set mine to "GRUB_TIMEOUT=0". Always run "grub-mkconfig -o /boot/grub/grub.cfg"
    at the command prompt after making any chages in /etc/default/grub, or upgrading the kernel. Once that is done you are ready to reboot and login with
    the actual ip address given to you by your provider for your VPS with a ssh client like PuTTY.
  3. Slackware Server Initial Setup:

    Now ssh to your new Slackware server with PuTTY or other ssh client.

    First make sure dnsmasq is set to start at boot with:
    chmod 0755 /etc/rc.d/rc.dnsmasq
    /etc/rc.d/rc.dnsmasq start
    
    You've probably already setup your hostname on the install, but if you didn't you need to do that now. Edit the /etc/HOSTNAME file and enter your Fully
    Qualified Domain Name(FQDN). Adjust /etc/HOSTNAME below to match your actual FQDN:
    mail.example.org
    
    Then check your /etc/hosts file, and make sure there are lines there referencing your server just like below, but adjust the bottom line for your FQDN:
    127.0.0.1 localhost.localdomain localhost
    127.0.0.1 mail.example.org mail
    
    If you made any changes above to your network or NetworkManager then restart them and see how it goes with:
    /etc/rc.d/rc.networkmanager restart
    /etc/rc.d/rc.inet1 restart
    
    Next I setup the DNS records at my VPS provider for this server. This includes the SPF records, DMARC records, and DKIM key:
    Resource record      TTL      Type      Priority      Data
    ---------------------------------------------------------------------
    mail.example.org            14400      A           0     ip.address
    example.org                 14400      A           0     ip.address
    www.example.org             14400      A           0     ip.address
    example.org                 14400      MX          10    example.org
    example.org                 14400      TXT         0     v=spf1 mx -all # This is how I do the SPF record, but you can adjust this to your liking.
    _dmarc.example.org          14400      TXT         0     v=DMARC1; p=none; pct=100; fo=1; rua=mailto:you@example.org # This is how I do the DMARC record, but you can adjust this to your liking.
    dkim._domainkey.example.org 14400      TXT         0     v=DKIM1;p= # This is where you put the DKIM key that was generated during the SlackerMail install.
    
    You will have to wait until SlackerMail is installed to retrieve and enter the DKIM key in your DNS Zone Management at your VPS provider.

    Then I setup reverse DNS at my VPS provider with:
    ip.address          mail.example.org
    
    We'll need to do a full system upgrade next to get the latest security patches and kernel for our system. If you haven't already edited "/etc/slackpkg/mirrors"
    and uncommented #https://mirrors.slackware.com/slackware/slackware64-15.0/, then do so now. I use mc to edit when in the console.

    Run the commands below to do a full system upgrade:
    slackpkg update gpg
    slackpkg update
    slackpkg upgrade-all
    
    You will be asked what you want to do with the new config files. I always enter "k" to keep the old config files and install the new config files with a .new extension
    for latter consideration.

    Important! The kernel is updated during this upgrade, so you'll have to update your bootloader.

    If lilo is your bootloader, run the command below:
    lilo
    
    If grub is your bootloader, run the command below:
    grub-mkconfig -o /boot/grub/grub.cfg
    
    Now do a reboot!

    Next we'll install some needed X libs, fontconfig, and bash-completion with:
    slackpkg install libX11 libXpm libxcb libXau libXdmcp libXext libXt libSM libICE libglvnd libXrender pixman fontconfig bash-completion
    
    Lastly we'll need to install some perl modules needed by SlackerMail:
    Just copy, paste, and run the entire block of commands at once in PuTTY.
    export PERL_MM_USE_DEFAULT=1
    cpan install CPAN
    cpan install App::cpanminus
    cpanm -n Log::Log4perl
    cpanm -n Test::Deep Test::Base Test::YAML YAML Module::Signature Module::Build Test::Pod Test::Pod::Coverage Test::Perl::Critic \
    inc::latest Encode::Detect Image::Info TimeDate Net::LibIDN Net::SSLeay Socket6 IO::Socket::IP IO::Socket::SSL IO::Socket::INET6 \
    Crypt::OpenSSL::Bignum Crypt::OpenSSL::Random Crypt::OpenSSL::RSA Geography::Countries IP::Country Digest::SHA Digest::SHA1 Digest::HMAC \
    Digest::MD5 HTML::Tagset HTML::Parser Test::LeakTrace Authen::NTLM Data::Dump LWP Net::CIDR::Lite PAR::Dist ExtUtils::MakeMaker ExtUtils::Install \
    Net::HTTP WWW::RobotRules HTTP::Date File::Listing IO::HTML Encode::Locale LWP::Protocol::https LWP::MediaTypes HTTP::Message HTTP::Negotiate \
    HTTP::Cookies HTTP::Daemon Bundle::LWP NetAddr::IP Net::Server Net::Ident MailTools Net::IP Net::DNS Net::DNS::Resolver::Programmable \
    Mail::SPF Mail::DKIM Geo::IP Net::Patricia Convert::TNEF Convert::UUlib Convert::BinHex Archive::Zip IO::Stringy MIME::Tools Unix::Syslog \
    BerkeleyDB IO::Multiplex Net::LibIDN File::LibMagic Archive::Tar Archive::SevenZip Inline::C Authen::PAM IO::Pty Razor2::Client::Agent \
    Algorithm::Diff B::COW Net::DNS::Resolver::Mock File::Copy::Recursive File::Slurp Hook::LexWrap Sub::Uplevel Text::Diff YAML::LibYAML \
    Tie::IxHash
    
    We are now ready to install SlackerMail with the SlackerMail install script at this point.

    After SlackerMail has installed go to /root/SlackerMail/SlackerMail.setup for needed info about your server. You'll also need to go to
    /root/SlackerMail/example.org.pub.txt to get your preformated DKIM pub key to enter in your DNS Zone at your provider.

    You can also setup SlackerMail by hand following all the directions below. It takes about 5 minutes to install from the script. It will take at minimum
    1 day to install by hand, but it's a good learning experience.
  4. Install Webmin as the server control panel - 0ptional

    You can copy all the commands in the block below, then paste and run in PuTTY:
    mkdir -p /root/tmp
    cd /root/tmp/
    wget https://github.com/webmin/webmin/releases/download/2.111/webmin-2.111.tar.gz
    tar -xf webmin-2.111.tar.gz
    rm /root/tmp/webmin-2.111.tar.gz
    cd webmin-2.111
    ./setup.sh /usr/local/webmin
    cd /root
    rm -R /root/tmp/webmin-2.111
    
    You will be asked a few questions, then webmin will install. For this howto it is best to accept all the defaults, and enter your desired password when asked.
    We don't have a firewall running yet, so you should be able get to the webmin control panel with https://your.domain:10000 or https://your.ip.address:10000.
    Make sure to answer "y" to SSL use.

    One of the main reasons I use webmin is for editing files, and to do that you'll need to go to Tools / File Manager, then click on the small gear at the very
    top right (module preferences), then go to the 4th page and change "Hide column containing action icons" to "no", then save.

    You'll need to run the following echo command to make sure Webmin is started at boot and to remove the miniserv.pid file, because it doesn't get removed
    when Webmin exits sometimes.
    echo '#!/bin/bash
    rm /var/webmin/miniserv.pid >/dev/null 2>&1
    /etc/webmin/start >/dev/null 2>&1' > /etc/rc.d/rc.local
    
    If webmin is started at boot we'll need to shut it down on reboot or shutdown. We'll need to create the /etc/rc.d/rc.local_shutdown file, and add the needed
    commands to do this with the following commands below.
    echo '#!/bin/bash
    /etc/webmin/stop >/dev/null 2>&1
    rm /var/webmin/miniserv.pid >/dev/null 2>&1' > /etc/rc.d/rc.local_shutdown
    chmod 0755 /etc/rc.d/rc.local_shutdown
    
    The reason I put "rm /var/webmin/miniserv.pid" after webmin is stopped is, in some situations webmin doesn't delete the old miniserv.pid file when stopped.

    One thing you can do to help security is only allow webmin to work with your ip address. To do that edit the /etc/webmin/miniserv.conf file, and add the
    following line:
    allow=your-ip-address
    
    If you want webmin to be even more secure don't start it at boot, but only start it when you need it with the command above at the command line.

    If you dont want to use webmin, then Midnight Commander is a great command line file manager/editor with mouse support. Just run "mc" at the command
    prompt. To copy in Midnight Commander (hold) Shift + select with mouse. To paste in Midnight Commander (hit) Shift + Insert.
  5. Next we setup either Apache or Nginx as our web server:

    I've tried Apache and Nginx with SlackerMail for awhile, and both work great, but Nginx uses less memory, so if you have a mail server with limited resources
    Nginx would probably be the better choice.

    First we need to install php-imagick for ImageMagick support in Apache or Nginx:
    cd /root/tmp
    wget https://the-slacker.com/download/php-imagick-3.7.0-x86_64-2_SBo.tgz
    installpkg php-imagick-3.7.0-x86_64-2_SBo.tgz
    rm php-imagick-3.7.0-x86_64-2_SBo.tgz
    
    Then create new /etc/php.d/imagick.ini file with:
    echo -e 'extension=imagick.so' > /etc/php.d/imagick.ini
    
    Then we need to create a Diffie–Hellman key exchange (DH) that we will use in our webserver, postfix, dovecot, etc.
    cd /root/tmp
    openssl dhparam -out dh2048_param.pem 2048
    mv -f dh2048_param.pem /etc/ssl/
    

    Apache:

    If you want to use the Apache web server instead of Nginx follow instructions below.

    First download and install the preconfigured httpd.conf, and edit ServerAdmin and ServerName to match your domain name:
    cd /root/tmp
    wget https://the-slacker.com/download/httpd.conf
    mv -f httpd.conf /etc/httpd/
    
    Next make sure Apache is startable at boot:
    chmod 0755 /etc/rc.d/rc.httpd
    
    Download and install /etc/php-fpm.d/www.conf:
    cd /root/tmp
    wget https://the-slacker.com/download/www.conf.apache
    mv -f www.conf.apache /etc/php-fpm.d/www.conf
    
    Now we make sure php-fpm is executable and can be started at boot with:
    chmod 0755 /etc/rc.d/rc.php-fpm
    
    To make sure php-fpm starts at boot we'll need to append to the rc.local file with:
    echo -e '/etc/rc.d/rc.php-fpm start > /dev/null 2>&1' >> /etc/rc.d/rc.local
    
    Then if you haven't aleready done so for webmin, create and make executable the /etc/rc.d/rc.local_shutdown file:
    echo -e '#!/bin/bash' > /etc/rc.d/rc.local_shutdown
    chmod 0755 /etc/rc.d/rc.local_shutdown
    
    Then we need to append the following to the /etc/rc.d/rc.local_shutdown file:
    echo -e '/etc/rc.d/rc.php-fpm stop > /dev/null 2>&1' >> /etc/rc.d/rc.local_shutdown
    
    Apache will not work like we need it to yet without SSL certs. Next we get free Let's Encrypt certs.

    Nginx:

    If you want to use the Nginx web server instead of Apache follow instructions below.

    First make sure Apache is shutdown and disabled at start up with:
    /etc/rc.d/rc.httpd stop
    chmod 0644 /etc/rc.d/rc.httpd
    
    Then create the nginx user and group with:
    useradd -r -M -U -c "Nginx web server" -d /var/lib/nginx -s /bin/false nginx
    
    Then download and install Nginx with:
    cd /root/tmp
    wget https://the-slacker.com/download/nginx-1.26.0-x86_64-1_SBo.tgz
    installpkg nginx-1.26.0-x86_64-1_SBo.tgz
    rm nginx-1.26.0-x86_64-1_SBo.tgz
    
    Next download and install the needed Nginx config files with:
    wget https://the-slacker.com/download/nginx.conf
    mv -f nginx.conf /etc/nginx/
    wget https://the-slacker.com/download/mailserver.conf
    mv -f mailserver.conf /etc/nginx/conf.d/
    
    Then we need to change ownership of /var/lib/php:
    chown root:nginx /var/lib/php
    
    Download and install /etc/php-fpm.d/www.conf:
    wget https://the-slacker.com/download/www.conf.nginx
    mv -f www.conf.nginx /etc/php-fpm.d/www.conf
    
    Now we make sure nginx and php-fpm are executable and can be started at boot:
    chmod 0755 /etc/rc.d/rc.nginx
    chmod 0755 /etc/rc.d/rc.php-fpm
    
    Now make Nginx and PHP-FPM start at boot with the following echo command:
    echo -e '/etc/rc.d/rc.nginx start >/dev/null 2>&1
    /etc/rc.d/rc.php-fpm start >/dev/null 2>&1' >> /etc/rc.d/rc.local
    
    Then we need to add the following to /etc/rc.d/rc.local_shutdown with the following echo command:
    echo -e '/etc/rc.d/rc.nginx stop >/dev/null 2>&1
    /etc/rc.d/rc.php-fpm stop >/dev/null 2>&1' >> /etc/rc.d/rc.local_shutdown
    
    Finally you can download and install a preconfigured robots.txt file to your web server's root directory if you want. It has rules to allow some good bots
    and disallow some bad ones.
    For Apache:
    wget https://the-slacker.com/download/robots.txt
    mv -f robots.txt /var/www/htdocs/
    
    For Nginx:
    wget https://the-slacker.com/download/robots.txt
    mv -f robots.txt /var/www/html/
    
    Next we setup free Let's Encrypt SSL certs so our webserver can serve legit https.
  6. Let's Encrypt SSL certs with Dehydrated:

    Apache and Nginx are not configured for SSL out of the box, so we need to change that.

    Slackware comes with a utility called dehydrated that can be used to get free ssl certs from Let's Encrypt. I was using the certbot utility to do this, but since
    dehydrated is the Slackware default utility for this, and I've read it uses less resources, I'll be using dehydtrated now.

    Let's Encrypt setup with Apache web server

    First prepare for the Let’s Encrypt’s verification challenge:
    mkdir -p /var/www/htdocs/.well-known/acme-challenge
    chgrp -R apache /var/www/htdocs/.well-known
    
    Then create a new /etc/dehydrated/config file with the following echo command, and edit it with your email address:
    echo -e 'CA="https://acme-v02.api.letsencrypt.org/directory"
    CHALLENGETYPE="http-01"
    WELLKNOWN="/var/www/htdocs/.well-known/acme-challenge"
    CONTACT_EMAIL="admin@example.org"' > /etc/dehydrated/config
    
    Then create the /etc/dehydrated/domains.txt file, and then edit for your FQDN and subdomains:
    echo -e 'mail.example.org www.example.org example.org' > /etc/dehydrated/domains.txt
    
    Next restart Apache with:
    /etc/rc.d/rc.httpd restart
    
    Notice! Make sure you can reach your domain at http://example.org before you proceed with Let's Encrypt SSL certs.

    Now run the dehydrated commands below one line at a time to get your Let's Encrypt certs.
    /usr/bin/dehydrated --register --accept-terms
    dehydrated -c
    
    If everything seemed to work properly then set the permissions below, and of coarse adjust for your domain name.
    chmod 0755 /etc/dehydrated/certs /etc/dehydrated/certs/mail.example.org
    chmod 0644 /etc/dehydrated/certs/mail.example.org/{cert-*,chain-*,fullchain-*}
    
    Then download the preconfigured httpd-ssl.conf file and move it to /etc/httpd/extra/httpd-ssl.conf:
    cd /root/tmp
    wget https://the-slacker.com/download/httpd-ssl.conf
    mv -f httpd-ssl.conf /etc/httpd/extra/
    
    Then edit /etc/httpd/httpd.conf and uncomment the following:
    # Secure (SSL/TLS) connections
    Include /etc/httpd/extra/httpd-ssl.conf
    
    Then edit /etc/httpd/extra/httpd-ssl.conf and adjust for your domain starting at line 124.
    Then add the reference to your Let's Encrypt certs in /etc/httpd/extra/httpd-ssl.conf with:
    SSLCertificateFile "/etc/dehydrated/certs/mail.example.org/fullchain.pem"
    SSLCertificateKeyFile "/etc/dehydrated/certs/mail.example.org/privkey.pem"
    
    Next restart httpd to see if it's working properely:
    /etc/rc.d/rc.httpd restart
    
    If you want to allow only https, then uncomment the 3 Rewrite lines below in the /etc/httpd.conf file:
    Listen 80
    
    #RewriteEngine On
    #RewriteCond %{HTTPS} off
    #RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    

    Let's Encrypt setup with Nginx web server

    First prepare for the Let’s Encrypt’s verification challenge:
    mkdir -p /var/www/html/.well-known/acme-challenge
    chgrp -R nginx /var/www/html/.well-known
    
    Then create a new /etc/dehydrated/config file with the following echo command, and edit it with your email address:
    echo -e 'CA="https://acme-v02.api.letsencrypt.org/directory"
    CHALLENGETYPE="http-01"
    WELLKNOWN="/var/www/html/.well-known/acme-challenge"
    CONTACT_EMAIL="admin@example.org"' > /etc/dehydrated/config
    
    Then create the /etc/dehydrated/domains.txt file, and then edit for your FQDN and subdomains:
    echo -e 'mail.example.org www.example.org example.org' > /etc/dehydrated/domains.txt
    
    Next we need to run Nginx in http mode to get the Let's Encrypt certs for the first time, so we'll need to use a temporary
    mailserver.conf file. Run the following move command to backup our mailserver.conf file.
    mv -f /etc/nginx/conf.d/mailserver.conf /etc/nginx/conf.d/mailserver.conf.bak
    
    Then create the temporary mailserver config file with the following echo command.
    echo -e "# HTTP
        server {
            listen       80;
            server_name  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            location / {
                root   /var/www/html;
                index  index.html index.htm;
            }
    }" > /etc/nginx/conf.d/temp.conf
    
    Next restart Nginx with:
    /etc/rc.d/rc.nginx restart
    
    Notice! Make sure you can reach your domain at http://example.org before you proceed with Let's Encrypt SSL certs.

    Now run the dehydrated commands below one line at a time to get your Let's Encrypt certs.
    /usr/bin/dehydrated --register --accept-terms
    dehydrated -c
    
    If everything seemed to work properly then set the permissions below, and of coarse adjust for your domain name.
    chmod 0755 /etc/dehydrated/certs /etc/dehydrated/certs/mail.example.org
    chmod 0644 /etc/dehydrated/certs/mail.example.org/{cert-*,chain-*,fullchain-*}
    
    Then change back to the original mailserver.conf file
    rm /etc/nginx/conf.d/temp.conf
    mv -f /etc/nginx/conf.d/mailserver.conf.bak /etc/nginx/conf.d/mailserver.conf
    
    Then edit /etc/nginx/mailserver.conf and adjust the following two lines to match your domain.
    ssl_certificate /etc/dehydrated/certs/mail.example.org/fullchain.pem;
    ssl_certificate_key /etc/dehydrated/certs/mail.example.org/privkey.pem;
    
    Next restart php-fpm and nginx to see if it's working properely:
    /etc/rc.d/rc.php-fpm restart
    /etc/rc.d/rc.nginx restart
    
    You should be able to reach https://example.org (with your doamain name)

    Next we setup automated renewal of the Let's Encrypt certs. The following works for Apache or Nginx.

    Let's Encrypt certs are good for 90 days, so you have to renew them. We'll create a cron.weekly job to check for renewals, and send you an email
    with the results with the following echo command, and of course edit for your domain name.
    echo -e '#!/bin/sh
    MYLOG=/var/log/dehydrated
    echo "Checking cert renewals at `date`" > $MYLOG
    /usr/bin/dehydrated -c >> $MYLOG 2>&1
    chmod 0644 /etc/dehydrated/certs/mail.example.org/{cert-*,chain-*,fullchain-*}
    mail -s "Let'\''s Encrypt Certs Renewal" -r dehydrated@example.org root@example.org < /var/log/dehydrated' > /etc/cron.weekly/dehydrated-renew
    
    Then make it executable with the following:
    
    chmod 0755 /etc/cron.weekly/dehydrated-renew
    
    Then run dehydrated-renew to see if it's working and logging properly:
    /etc/cron.weekly/dehydrated-renew
    cat /var/log/dehydrated
    
  7. Setting up the firewall with iptables:

    For the firewall I'll be using what a lot of Slackware people use, Alien Bob's EFG, Easy Firewall Generator. You can go to the link and fill in how you want
    the firewall setup, then copy the resulting firewall script to /etc/rc.d/rc.firewall and make it executable.

    You can download the rc.firewall that I use for this how-to setup, and it should work for most people. Do the following to download and install rc.firewall:
    cd /root/tmp
    wget https://the-slacker.com/download/rc.firewall
    mv -f rc.firewall /etc/rc.d/
    
    You may need to change the line INET_IFACE="eth0" in the downloaded /etc/rc.d/rc.firewall to match your system.

    In the downloaded rc.firewall I have ping enabled, but you can disable it if you want by changing the following line:
    "$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT" to "$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j DROP"
    
    I have ports 80, 443, 25, 587, 110, 143, 995, 993, 22, 10000 open in the downloaded rc.firewall. These are the ports needed to be open for this how-to, but you
    can always change that for your needs.

    Finally make /etc/rc.d/rc.firewall executable and start it with:
    chmod 0755 /etc/rc.d/rc.firewall
    /etc/rc.d/rc.firewall start
    
    The iptables firewall should be running now and doing it's job. It will automatically start at boot.
  8. Setup MySQL (mariadb):

    Important! I was thinking that iRedMail was using encrypted passwords in the config files, but they aren't, just good strong passwords. Make sure to use
    very strong passwords from here on out with a mix of upper and lower case letters and numbers. Roundcube can not handle special charaters properly, so
    best not to use any special characters from here on and save yourself a real big headache, Ooch! That Hurt!

    Note! You can use special characters in the MySQL root password if you want, it can handle it.

    Now we do the initial setup of mysql and create the mail database that will be needed by postfix, dovecot, Postfixadmin, and Roundcube.
    As root run:
    mysql_install_db --user=mysql
    chmod 755 /etc/rc.d/rc.mysqld
    
    enable networking by commenting #SKIP="--skip-networking in the /etc/rc.d/rc.mysqld file with the following sed command:
    
    sed -i '/SKIP="--skip-networking"/c\#SKIP="--skip-networking"' /etc/rc.d/rc.mysqld
    
    Start mysqld with: 
    
    /etc/rc.d/rc.mysqld restart > /dev/null 2>&1
    
    Set a password for MySQL's root account with:
    mysqladmin -u root password put-mysql-password-here 
    
    Since we enabled networking, we need to run:
    mysqladmin -u root -h localhost password put-mysql-password-here
    
    For security reasons you should delete the anonymous users and drop the test database with:
    mysql -u root
    [none]> drop database test;
    [none]> use mysql;
    [mysql]> SELECT user, host FROM user;
    [mysql]> DELETE FROM user WHERE user='';
    [mysql]> FLUSH PRIVILEGES;
    [mysql]> QUIT;
    
    Next download and install a preconfigured /etc/my.cnf.d/server.cnf file with the following:
    cd /root/tmp
    wget https://the-slacker.com/download/server.cnf
    mv -f server.cnf /etc/my.cnf.d/
    
    Next create a new /etc/my.cnf.d/client.cnf file with the following echo command:
    echo -e '[client]
    default-character-set = utf8mb4
    
    [client-mariadb]' > /etc/my.cnf.d/client.cnf
    
    Next we need to create the directory for the mysql logs:
    mkdir /var/log/mysql
    chown mysql:mysql /var/log/mysql
    
    Now restart mysqld and see if it works with:
    /etc/rc.d/rc.mysqld restart > /dev/null 2>&1
    
    Next create the vmail user and database we'll need for Postfix, Postfixadmin, and Roundcube. Make it a strong password with
    only upper and lower case letters and numbers, no special characters. Special characters will not work with Roundcube later.
    mysql -u root
    CREATE DATABASE vmail;
    GRANT ALL PRIVILEGES ON vmail.* TO 'vmail'@'localhost' IDENTIFIED BY 'vmailpassword';
    FLUSH PRIVILEGES;
    QUIT;
    
  9. Setting up Dovecot

    First thing I noticed is that dovecot is complaining about not having any cert files. We can use our letsencrypt certs for dovecot.

    First create a new /etc/dovecot/conf.d/10-ssl.conf file:
    echo -e "ssl_min_protocol = TLSv1.2
    ssl = required
    verbose_ssl = no
    ssl_cert = </etc/dehydrated/certs/mail.example.org/fullchain.pem
    ssl_key = </etc/dehydrated/certs/mail.example.org/privkey.pem
    ssl_dh = </etc/ssl/dh2048_param.pem
    # Fix 'The Logjam Attack'
    ssl_cipher_list = EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH
    ssl_prefer_server_ciphers = yes" > /etc/dovecot/conf.d/10-ssl.conf
    
    Make sure to adjust the above to reflect the location of your ssl certs.

    Now run:
    chmod 0755 /etc/rc.d/rc.dovecot
    /etc/rc.d/rc.dovecot start
    
    Dovecot should start now.

    Next we create the vmail group and user with the following commands:
    groupadd -g 150 vmail
    useradd -r -d /var/vmail -s /bin/false -u 150 -g 150 vmail
    mkdir /var/vmail
    chmod 770 /var/vmail
    chown vmail:vmail /var/vmail
    
    Then we create a new /etc/dovecot/dovecot-sql.conf.ext file with:
    echo -e "driver = mysql
    connect = host=127.0.0.1 port=3306 dbname=vmail user=vmail password=vmailpassword
    default_pass_scheme = SHA512-CRYPT
    
    password_query = \\
      SELECT username as user, password, '/var/vmail/%d/%n' as \\
      userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, \\
      150 as userdb_uid, 150 as userdb_gid \\
      FROM mailbox WHERE username = '%u' AND active = '1'
    
    user_query = \\
      SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' \\
      as vmail, 150 AS uid, 150 AS gid, \\
      concat('dirsize:storage=', quota) AS quota \\
      FROM mailbox WHERE username = '%u' AND active = '1'" > /etc/dovecot/dovecot-sql.conf.ext
    
    Make sure to adjust /etc/dovecot/dovecot-sql.conf.ext with your earlier made vmail password.
    Then set secure permissions on /etc/dovecot/dovecot-sql.conf.ext with:
    chmod 0600 /etc/dovecot/dovecot-sql.conf.ext
    
    Next create a new /etc/dovecot/conf.d/10-auth.conf file with:
    echo -e 'disable_plaintext_auth = yes
    auth_mechanisms        = plain login
    !include auth-sql.conf.ext' >  /etc/dovecot/conf.d/10-auth.conf
    
    Next append to the /etc/dovecot/conf.d/10-mail.conf file with the following:
    echo -e 'mail_location   = maildir:/var/vmail/%d/%n
    mail_uid        = vmail
    mail_gid        = vmail
    first_valid_uid = 150
    last_valid_uid  = 150' >> /etc/dovecot/conf.d/10-mail.conf
    
    Next we download a preconfigured Dovecot 10-master.conf file, and move it to /etc/dovecot/conf.d/:
    cd /root/tmp
    wget https://the-slacker.com/download/10-master.conf
    mv -f 10-master.conf /etc/dovecot/conf.d/
    
    Next append the following to /etc/dovecot/conf.d/10-logging.conf file with the following echo command,
    and direct the log files to the /var/log/dovecot directory:
    echo -e '## Log destination.
    ##
    log_path       = /var/log/dovecot/dovecot.log
    info_log_path  = /var/log/dovecot/dovecot-info.log' >> /etc/dovecot/conf.d/10-logging.conf
    
    Dovecot Pigeonhole for Sieve and ManageSieve support.

    We'll need to download and install dovecot-pigeonhole for Sieve and ManageSieve support with:
    cd /root/tmp
    wget https://the-slacker.com/download/dovecot-pigeonhole-0.5.17-x86_64-1_SBo.tgz
    installpkg dovecot-pigeonhole-0.5.17-x86_64-1_SBo.tgz
    rm dovecot-pigeonhole-0.5.17-x86_64-1_SBo.tgz
    
    Next we'll need to copy the following example configuration files into the /etc/dovecot/conf.d directory:
    cp /usr/doc/dovecot-2.3.17.1/example-config/conf.d/90-sieve.conf /etc/dovecot/conf.d/
    cp /usr/doc/dovecot-2.3.17.1/example-config/conf.d/90-sieve-extprograms.conf /etc/dovecot/conf.d/
    cp /usr/doc/dovecot-2.3.17.1/example-config/conf.d/20-managesieve.conf /etc/dovecot/conf.d/
    
    We will need to create the following Dovecot configuration files now:

    Create new /etc/dovecot/conf.d/20-lmtp.conf file with the following echo command, and edit for your domain.
    echo -e 'protocol lmtp {
      postmaster_address = admin@example.org
      mail_plugins       = $mail_plugins sieve quota
      log_path           = /var/log/dovecot/dovecot-lmtp-errors.log
      info_log_path      = /var/log/dovecot/dovecot-lmtp.log
    }' > /etc/dovecot/conf.d/20-lmtp.conf
    
    Create new /etc/dovecot/conf.d/15-lda.conf file with the following echo command, and edit for your domain.
    echo -e 'protocol lda {
      postmaster_address = admin@example.org
      mail_plugins       = $mail_plugins sieve quota
      auth_socket_path   = /var/run/dovecot/auth-master
      log_path           = /var/log/dovecot/dovecot-lda-errors.log
      info_log_path      = /var/log/dovecot/dovecot-lda.log
    }' > /etc/dovecot/conf.d/15-lda.conf
    
    Append the following to the /etc/dovecot/conf.d/10-mail.conf file with this echo command.
    echo -e 'mail_home       = /var/vmail/%d/%n/sieve' >> /etc/dovecot/conf.d/10-mail.conf
    
    Create new /etc/dovecot/conf.d/20-managesieve.conf file with the following echo command:
    echo -e 'protocols = $protocols sieve
    
    service managesieve-login {
      inet_listener sieve {
        port = 4190
      }
    }
    
    service managesieve {
      process_limit = 1024
    }
    
    protocol sieve {
      log_path                          = /var/log/dovecot/dovecot-sieve-errors.log
      info_log_path                     = /var/log/dovecot/dovecot-sieve.log
      managesieve_max_line_length       = 65536
      managesieve_implementation_string = Dovecot Pigeonhole
    }' > /etc/dovecot/conf.d/20-managesieve.conf
    
    Create new /etc/dovecot/conf.d/90-sieve.conf file with the following echo command:
    echo -e 'plugin {
        sieve = file:/var/vmail/%d/%n/sieve;active=/var/vmail/%d/%n/sieve/.dovecot.sieve
        sieve_default = /etc/dovecot/sieve/default.sieve
        sieve_global = /etc/dovecot/sieve/global/
    }
    lda_mailbox_autocreate = yes
    lda_mailbox_autosubscribe = yes' > /etc/dovecot/conf.d/90-sieve.conf
    
    Now we need to create some files that are needed for our configuration to work:
    mkdir -p /etc/dovecot/sieve/global
    chown -R vmail:vmail /etc/dovecot/sieve/
    mkdir /var/log/dovecot
    chown vmail:vmail /var/log/dovecot
    chmod 771 /var/log/dovecot
    
    Then create the file /etc/dovecot/sieve/default.sieve with the following commands.
    It will send Spam to the Junk folder.
    echo -e 'require "fileinto";
    if header :contains "X-Spam-Flag" "YES" {
        fileinto "Junk";
    }' > /etc/dovecot/sieve/default.sieve
    
    chown vmail:vmail /etc/dovecot/sieve/default.sieve
    
    Add postfix to the dovecot group with:
    usermod -G dovecot -a postfix
    
    Dovecot will automatically start at boot if /etc/rc.d/rc.dovecot is set to executable. To make sure it is run the command below:
    chmod 0755 /etc/rc.d/rc.dovecot
    
  10. Postfix

    We'll need to make a mysql directory for postfix with:
    mkdir -p /etc/postfix/mysql
    
    Now we'll create the 5 needed mysql map files with the needed content.

    First the /etc/postfix/mysql/mysql_virtual_alias_domainaliases_maps.cf file:
    echo -e "user = vmail 
    password = vmailpassword
    hosts = 127.0.0.1:3306 
    dbname = vmail 
    query = SELECT goto FROM alias,alias_domain 
      WHERE alias_domain.alias_domain = '%d' 
      AND alias.address=concat('%u', '@', alias_domain.target_domain) 
      AND alias.active = 1" > /etc/postfix/mysql/mysql_virtual_alias_domainaliases_maps.cf
    
    Second the /etc/postfix/mysql/mysql_virtual_alias_maps.cf file:
    echo -e "user = vmail
    password = vmailpassword
    hosts = 127.0.0.1:3306
    dbname = vmail
    table = alias
    select_field = goto 
    where_field = address
    additional_conditions = and active = '1'" > /etc/postfix/mysql/mysql_virtual_alias_maps.cf
    
    Third the /etc/postfix/mysql/mysql_virtual_domains_maps.cf file:
    echo -e "user = vmail
    password = vmailpassword
    hosts = 127.0.0.1:3306
    dbname = vmail
    table = domain
    select_field = domain 
    where_field = domain
    additional_conditions = and backupmx = '0' and active = '1'" > /etc/postfix/mysql/mysql_virtual_domains_maps.cf
    
    Fourth the /etc/postfix/mysql/mysql_virtual_mailbox_domainaliases_maps.cf file:
    echo -e "user = vmail
    password = vmailpassword
    hosts = 127.0.0.1:3306
    dbname = vmail
    query = SELECT maildir FROM mailbox, alias_domain
      WHERE alias_domain.alias_domain = '%d' 
      AND mailbox.username=concat('%u', '@', alias_domain.target_domain )
      AND mailbox.active = 1" > /etc/postfix/mysql/mysql_virtual_mailbox_domainaliases_maps.cf
    
    Fifth the /etc/postfix/mysql/mysql_virtual_mailbox_maps.cf file:
    echo -e "user = vmail
    password = vmailpassword
    hosts = 127.0.0.1:3306
    dbname = vmail
    table = mailbox
    select_field = CONCAT(domain, '/', local_part) 
    where_field = username
    additional_conditions = and active = '1'" > /etc/postfix/mysql/mysql_virtual_mailbox_maps.cf
    
    Make sure to set your vmail database password created earlier in the 5 files just created.

    Then set secure permissions on all the /etc/postfix/mysql/* files with:
    chmod 0600 /etc/postfix/mysql/*
    
    Next download and install the /etc/postfix/main.cf file that I use for this how-to, and of course adjust for your domain and ssl certs:
    *Note - I've updated the main.cf file to prevent SMTP Smuggling with the installed Postfix v3.6.13.
    cd /root/tmp
    wget https://the-slacker.com/download/main.cf
    mv -f main.cf /etc/postfix/
    
    Then download and install the /etc/postfix/master.cf file that I use for this how-to. Shouldn't have to make any adjustments here:
    cd /root/tmp
    wget https://the-slacker.com/download/master.cf
    mv -f master.cf /etc/postfix/
    
    Then download and install the needed aliases file for this mail serever, then run newaliases at the prompt. Before you run newaliases
    at the prompt, make sure to adjust the bottom line of the aliases file to match the email address that gets root's mail.
    wget https://the-slacker.com/download/aliases
    mv -f aliases /etc/
    newaliases
    
    Postfix like Dovecot starts automatically at boot if /etc/rc.d/rc.postfix is set to executable, so make sure it is with:
    chmod 0755 /etc/rc.d/rc.postfix
    
  11. Amavis with ClamAV and SpamAssassin:

    Install Spamassassin SlackBuild package with:
    cd /root/tmp
    wget https://the-slacker.com/download/spamassassin-3.4.6-x86_64-1_SBo.tgz
    installpkg spamassassin-3.4.6-x86_64-1_SBo.tgz
    rm spamassassin-3.4.6-x86_64-1_SBo.tgz
    
    Spamassassin will be called by Amavisd when needed, so we don't need the spamd daemon enabled. Disable it with:
    chmod 0644 /etc/rc.d/rc.spamd
    
    Then update the Spamassassin rules with:
    sa-update
    
    Rust16 is now required to build the latest ClamAV, so you'll need to install the Rust16 SlackBuild package with:
    cd /root/tmp
    wget https://the-slacker.com/download/rust16-1.78.0-x86_64-1_SBo.tgz
    installpkg rust16-1.78.0-x86_64-1_SBo.tgz
    rm rust16-1.78.0-x86_64-1_SBo.tgz
    
    Next we need to install the libmspack SlackBuild package, now required by the latest Clamav:
    wget https://the-slacker.com/download/libmspack-0.10.1alpha-x86_64-1_SBo.tgz
    installpkg libmspack-0.10.1alpha-x86_64-1_SBo.tgz
    rm libmspack-0.10.1alpha-x86_64-1_SBo.tgz
    
    Next install the ClamAV SlackBuild package with:
    groupadd -g 210 clamav
    useradd -u 210 -d /dev/null -s /bin/false -g clamav clamav
    cd /root/tmp
    wget https://the-slacker.com/download/clamav-1.3.1-x86_64-1_SBo.tgz
    installpkg clamav-1.3.1-x86_64-1_SBo.tgz
    rm clamav-1.3.1-x86_64-1_SBo.tgz
    
    After ClamAV is installed run the following sed command to set LocalSocketGroup amavis:
    sed -i "/LocalSocketGroup clamav/c\LocalSocketGroup amavis" /etc/clamd.conf
    
    Next we install the amavisd-new SlackBuild package with:
    groupadd -g 225 amavis
    useradd -m -d /var/lib/amavis -s /bin/bash -u 225 -g 225 amavis
    usermod -G clamav -a amavis
    usermod -G amavis -a clamav
    cd /root/tmp
    wget https://the-slacker.com/download/amavisd-new-2.11.1-noarch-2_SBo.tgz
    installpkg amavisd-new-2.11.1-noarch-2_SBo.tgz
    rm amavisd-new-2.11.1-noarch-2_SBo.tgz
    
    Next install the alterMIME Slackbuild pkg for writing to mail headers and inserting disclaimers with:
    cd /root/tmp
    wget https://the-slacker.com/download/altermime-0.3.10-x86_64-1_SBo.tgz
    installpkg altermime-0.3.10-x86_64-1_SBo.tgz
    rm altermime-0.3.10-x86_64-1_SBo.tgz
    
    Now download and install the /etc/amavisd.conf file:
    cd /root/tmp
    wget https://the-slacker.com/download/amavisd.conf
    mv -f amavisd.conf /etc/
    
    You will need to adjust the downloaded /etc/amavisd.conf to match your domain and vmail database password.

    I have the dkim_key statement commented out in the downloaded /etc/amavisd.conf file. That's because we haven't made the dkim
    key yet. Latter we'll make the needed dkim pem file and put it's location in the dkim_key statement and uncomment it.

    We need to make the /var/spool/amavisd directory and it's subdirectories:
    mkdir /var/spool/amavisd /var/spool/amavisd/tmp /var/spool/amavisd/db /var/spool/amavisd/var /var/spool/amavisd/quarantine
    chown -R amavis:amavis /var/spool/amavisd
    
    We need to change ownership and permissions of /etc/amavisd.conf with:
    chown root:amavis /etc/amavisd.conf
    chmod 0640 /etc/amavisd.conf
    
    We also need to fix some permissions to get all three of these to play nicely:
    chmod 775 /var/lib/spamassassin/
    chown -R amavis:amavis /var/lib/spamassassin
    chown -R amavis:amavis /var/lib/amavis
    chown -R clamav:amavis /var/lib/clamav
    
    Now go ahead and update your virus database by running as root:
    freshclam
    
    Don't worry if you get a message from freshclam saying clamd was not updated. This is because we have not started clamd yet.

    We need to start amavisd and clamd at boot up and stop them at reboot or shutdown:

    Run the 2 echo commands below to add clamav and amavisd-new to the rc.local startup file.
    echo -e "/etc/rc.d/rc.clamav start >/dev/null 2>&1" >> /etc/rc.d/rc.local
    echo -e "/etc/rc.d/rc.amavisd-new start >/dev/null 2>&1" >> /etc/rc.d/rc.local
    
    Then run the below 2 echo commands to append clamav and amavisd-new to the rc.local_shutdown file:
    echo -e "/etc/rc.d/rc.clamav stop >/dev/null 2>&1" >> /etc/rc.d/rc.local_shutdown
    echo -e "/etc/rc.d/rc.amavisd-new stop >/dev/null 2>&1" >> /etc/rc.d/rc.local_shutdown
    
    Do a reboot and see if everything is working okay so far.
  12. DKIM and SPF/Dmarc records

    We'll be using the DKIM perl module to verify and sign emails.
    We'll first need to make our private and public keys (adjust for your domain) with:
    cd /root/tmp
    openssl genrsa -out example.org.priv 2048
    openssl rsa -in example.org.priv -pubout > example.org.pub
    
    Then we'll install the dkim keys:
    mv -f example.org.priv /etc/ssl/example.org.pem
    mv -f example.org.pub /etc/ssl/
    chown amavis:amavis /etc/ssl/example.org.pem /etc/ssl/example.org.pub
    chmod 600 /etc/ssl/example.org.pem 
    chmod 644 /etc/ssl/example.org.pub
    
    Then we need to edit /etc/amavisd.conf and uncomment the dkim_key line and set your domain name and the path to your
    dkim pem file:
    # Add dkim_key here.
    dkim_key('example.org', 'dkim', '/etc/ssl/example.org.pem');
    
    Now restart amavisd with:
    /etc/rc.d/rc.amavisd-new restart
    
    Next we need to setup our DNS Zone for DKIM:
    I go to the DNS Zone Management control panel for this VPS at contabo.com and enter the below record:
    dkim._domainkey.example.org 14400 TXT v=DKIM1;p=here is where you put your dkim public key from the example.org.pub file we created earlier, all on one line with no spaces.
    
    Run the following line of piped commands to format your example.org.pub file for entering into a DNS Zone Record for DKIM, and of course adjust for your domain:
    sed '1d;$d' "/etc/ssl/example.org.pub" | sed '1s/.*/v=DKIM1;p=&/' | tr -d '\n' > /root/example.org.pub.txt
    
    That should do it for DKIM

    SPF and DMARC records:
    We need to set the SPF (Sender Policy Framework) text record in the DNS Zone Management control panel. Below is how I have mine set:
    example.org 14400 TXT "v=spf1 mx -all"
    
    Next we set the DMARC text record in the DNS Zone Management control panel. Below is how mine is set:
    _dmarc.example.org 14400 TXT "v=DMARC1; p=none; pct=100; fo=1; rua=mailto:you@example.org"
    
    With the above DKIM, SPF, and DMARC records I get a 100% perfect score from mail-tester.com
  13. Postgrey

    Next we setup Postgrey which is used to greylist emails from unknown users. It can be helpful with reducing spam.
    First we add the Postgrey user and group:
    groupadd -g 301 postgrey
    useradd -u 301 -d /var/lib/postgrey -s /bin/false -g postgrey postgrey
    
    Then we install the SlackBuild Postgrey package:
    cd /root/tmp
    wget https://the-slacker.com/download/postgrey-1.37-x86_64-1_SBo.tgz
    installpkg postgrey-1.37-x86_64-1_SBo.tgz
    rm postgrey-1.37-x86_64-1_SBo.tgz
    
    Then update the postgrey_whitelist_clients file:
    cd /root/tmp
    wget https://postgrey.schweikert.ch/pub/postgrey_whitelist_clients
    mv -f postgrey_whitelist_clients /etc/postfix/
    
    Then create a new /etc/postgrey.conf file, and edit for your domain:
    echo -e 'PORT=10023
    PIDFILE=/var/run/postgrey/postgrey.pid
    USER=postgrey
    GROUP=postgrey
    HOST=mail.example.org' > /etc/postgrey.conf
    
    Then make /etc/rc.d/rc.postgrey executable with:
    chmod 0755 /etc/rc.d/rc.postgrey
    
    Then run the following echo command to append "rc.postgrey start" in the /etc/rc.d/rc.local start file:
    echo -e "/etc/rc.d/rc.postgrey start >/dev/null 2>&1" >> /etc/rc.d/rc.local
    
    Then run the following echo command to append "rc.postgrey stop" to the /etc/rc.d/rc.local_shutdown file:
    echo -e "/etc/rc.d/rc.postgrey stop >/dev/null 2>&1" >> /etc/rc.d/rc.local_shutdown
    
    Then start it up and see if it works with:
    /etc/rc.d/rc.postgrey start
    
  14. Logwatch - Optional

    Logwatch parses through your system's logs and creates a report analyzing areas that you specify, and can send you an emailed report daily.
    Download and install the logwatch Slack Build with:
    cd /root/tmp
    wget https://the-slacker.com/download/logwatch-7.10-noarch-1_SBo.tgz
    installpkg logwatch-7.10-noarch-1_SBo.tgz
    rm logwatch-7.10-noarch-1_SBo.tgz
    
    Then we need to setup a cron.daily job to email root a daily report:
    rm /etc/cron.daily/0logwatch
    touch /etc/cron.daily/0logwatch
    chmod 0755 /etc/cron.daily/0logwatch
    
    Then run the following echo command to create the logwatch daily cron job:
    echo '#!/bin/sh
    #Set logwatch location
    LOGWATCH_SCRIPT="/usr/sbin/logwatch"
    #Add options to this line. Most options should be defined in /etc/logwatch/conf/logwatch.conf,
    #but some are only for the nightly cronrun such as --output mail and should be set here.
    #Other options to consider might be "--format html" or "--encode base64", man logwatch for more details.
    OPTIONS="--output mail"
    #Call logwatch
    $LOGWATCH_SCRIPT $OPTIONS
    exit 0' >> /etc/cron.daily/0logwatch
    
    Then create the /etc/logwatch/conf/services/postfix.conf file with the following echo command:
    echo '$postfix_Enable_Long_Queue_Ids = Yes' > /etc/logwatch/conf/services/postfix.conf
    
  15. Postfix Admin

    Postfixadmin will be our mail admin panel. We will install it with:
    cd /var/www
    wget https://github.com/postfixadmin/postfixadmin/archive/refs/tags/postfixadmin-3.3.13.tar.gz
    tar -xf postfixadmin-3.3.13.tar.gz
    rm postfixadmin-3.3.13.tar.gz
    ln -s postfixadmin-postfixadmin-3.3.13 postfixadmin
    cd postfixadmin
    mkdir -p templates_c
    
    If Apache is your webserver run the following:
    chown apache:root templates_c
    
    If Nginx is your webserver run the following:
    chown nginx:root templates_c
    
    Make a copy of config.inc.php to config.local.php and make your changes there.
    cp /var/www/postfixadmin/config.inc.php /var/www/postfixadmin/config.local.php
    
    Then we'll create the setup_password for postfixadmin. Copy, paste, and run all 7 lines of code below at once to get postfixadmin
    setup and hashed setup passwords. The postfixadmin setup password will be in the /root/SlackerMail/postfixadmin_setup.pass file,
    and the hashed password that we use in config.local.php file will be in the /root/SlackerMail/postfixadmin_hashed.pass file.
    mkdir -p /root/SlackerMail
    PASSWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 24 | head -n 1)
    echo $PASSWD > /root/SlackerMail/postfixadmin_setup.pass
    SETUPPASS=$(cat /root/SlackerMail/postfixadmin_setup.pass)
    HASHPASS=$(doveadm pw -p $SETUPPASS)
    echo $HASHPASS | cut -c 8- > /root/SlackerMail/postfixadmin_setup_hashed.pass
    chmod 0600 /root/SlackerMail/postfixadmin_setup.pass /root/SlackerMail/postfixadmin_setup_hashed.pass
    
    Then enter the hashed password from /root/SlackerMail/postfixadmin_setup_hashed.pass in the setup_password field in
    /var/www/postfixadmin/config.local.php like below. I left all settings at default values except what I changed below, and of
    course adjust for your domain and passwords. Here are the settings I set in config.local.php:
    $CONF['configured'] = true;
    $CONF['setup_password'] = 'hashed-password-here';
    $CONF['database_type'] = 'mysqli';
    $CONF['database_user'] = 'vmail';
    $CONF['database_password'] = "vmail-db-password-here";
    $CONF['database_name'] = 'vmail';
    $CONF['database_host'] = 'localhost';
    $CONF['database_port'] = '3306';
    //$CONF['database_socket'] = ''; Comment out, since we are using port instead of socket.
    $CONF['admin_email'] = 'admin@example.org';
    $CONF['default_aliases'] = array (
        'abuse' => 'admin@example.org',
        'hostmaster' => 'admin@example.org',
        'postmaster' => 'admin@example.org',
        'webmaster' => 'admin@example.org',
        'virusalert' => 'admin@example.org',
        'root' => 'admin@example.org'
     );
    $CONF['domain_path'] = 'NO';
    $CONF['domain_in_mailbox'] = 'YES';
    $CONF['footer_text'] = 'Return to example.org';
    $CONF['footer_link'] = 'https://example.org';'
    $CONF['emailcheck_resolve_domain']='NO';
    $CONF['password_expiration'] = 'NO';
    $CONF['version'] = '3.3.13';
    
    Next create the needed postfixadmin tables for the vmail mysql database with:
    php /var/www/postfixadmin/public/upgrade.php
    
    Then create the superadmin user for postfixadmin. The password and password2 must be the same password that you want for the superadmin
    login of postfixadmin. The reason for entering the same password twice is because of the postfixadmin setup script asking to confirm password.
    /var/www/postfixadmin/scripts/postfixadmin-cli admin add admin@example.org --superadmin 1 --active 1 --password admin-password --password2 admin-password
    
    Then add your domain to postfixadmin. You can adjust --aliases, --mailboxes, and --description to whatever you want.
    /var/www/postfixadmin/scripts/postfixadmin-cli domain add example.org --aliases 100 --mailboxes 100 --active 1 --description example.org
    
    Lastly add the mailbox for admin@example.org, and again enter the same password twice. You can adjust --name to your liking, and you can
    adjust --quota. I have --quota set to 100 here, which is 100mb.
    /var/www/postfixadmin/scripts/postfixadmin-cli mailbox add admin@example.org --name admin --quota 100 --active 1 --password roundcube-mailbox-password --password2 roundcube-mailbox-password
    
    Now you should be able to login to postfixadmin at https://example.org/postfixadmin as admin@example.org with your admin-password. After
    Roundcubemail is setup you will be able to login to your admin@example.org mailbox with your roundcube-mailbox-password.
  16. Roundcube Webmail Client

    Important! Don't use any special characters in the roundcubemail database password, just upper and lower case letters
    and numbers.

    You can use the following commands to create a roundcube password for you, and put it in the file /root/SlackerMail/roundcube_password.pass,
    or you can make up your own password in the mysql creation of the roundcubemail database.
    PASSWD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 24 | head -n 1)
    echo $PASSWD > /root/SlackerMail/roundcube_password.pass
    chmod 0600 /root/SlackerMail/roundcube_password.pass
    
    We'll need to create the mysql database for roundcubemail with:
    mysql -u root
    CREATE DATABASE roundcubemail CHARACTER SET utf8 COLLATE utf8_general_ci;
    CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'roundcube_password';
    GRANT ALL PRIVILEGES ON roundcubemail.* TO 'roundcube'@'localhost';
    FLUSH PRIVILEGES;
    QUIT;
    
    Then we'll download and install Roundcube Webmail with:
    Note! Make sure to put your roundcube_password in the bottom mysql command directly after the -p without any quotes.
    cd /var/www
    wget https://github.com/roundcube/roundcubemail/releases/download/1.6.6/roundcubemail-1.6.6-complete.tar.gz
    tar -xf roundcubemail-1.6.6-complete.tar.gz
    rm roundcubemail-1.6.6-complete.tar.gz
    ln -s roundcubemail-1.6.6 roundcubemail
    
    If Apache is your webserver run the following:
    chown apache:root -h /var/www/roundcubemail
    chown -R apache:root /var/www/roundcubemail-1.6.6
    
    If Nginx is your webserver run the following:
    chown nginx:root -h /var/www/roundcubemail
    chown -R nginx:root /var/www/roundcubemail-1.6.6
    
    Then run the following:
    cd roundcubemail
    mysql -u roundcube roundcubemail -proundcube_password < SQL/mysql.initial.sql
    
    Next I had to create a postfix file that roundcube expects:
     
    echo '#submission header checks file' >> /etc/postfix/submission_header_checks
    
    You can setup Roundcube with the installer wizard, but it's easier for me to do it manually.
    First we need to generate the 24 character Des-Key that Roundcube needs with:
    DESKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 24 | head -n 1)
    echo $DESKEY > /root/SlackerMail/roundcubemail.deskey
    
    The 24-character-Des-Key will be in the /root/SlackerMail/roundcubemail.deskey file, so just copy that and paste it into
    the /var/www/roundcubemail/config/config.inc.php file in the appropriate config section.

    Then download the needed /var/www/roundcubemail/config/config.inc.php file, and adjust for
    your domain, roudcube password, and 24-character-DES-Key with the following:
    cd /root/tmp
    wget https://the-slacker.com/download/config.inc.php.txt
    mv -f config.inc.php.txt /var/www/roundcubemail/config/config.inc.php
    
    If your webserver is Apache run the following:
    chown apache:apache /var/www/roundcubemail/config/config.inc.php
    
    If your webserver is Nginx run the following:
    chown nginx:nginx /var/www/roundcubemail/config/config.inc.php
    
    Then run the following:
    chmod 0600 /var/www/roundcubemail/config/config.inc.php
    
    You'll need to edit the following fields in /var/www/roundcubemail/config/config.inc.php:
    $config['db_dsnw'] = 'mysql://roundcube:password-here@localhost/roundcubemail';
    $config['support_url'] = 'https://example.org';
    $config['des_key'] = '24-character-Des-Key';
    
    Now go to https://example.org/mail and login to admin@example.org that you created earlier with postfixadmin, good luck! There
    are many more config options for Roundcube. Check out /var/www/roundcubmail/config/defaults.inc.php for the full list.
  17. Fail2ban - Optional

    I'm getting about 400/hour attempts to login to this server. Fail2ban will help with this, and latter I will also set sshd to deny root
    login and change the sshd port from 22 to something else, which in itself helps a lot at keeping the login attempts down.

    First we need append to the /etc/ssh/sshd_config file to set logging properly like below:
    echo "SyslogFacility AUTHPRIV" >> /etc/ssh/sshd_config
    
    Now we download and install the Fail2ban SlackBuild pkg to help with all the attempts to break in to the server:
    cd /root/tmp
    wget https://the-slacker.com/download/fail2ban-1.0.2-x86_64-1_SBo.tgz
    installpkg fail2ban-1.0.2-x86_64-1_SBo.tgz
    rm fail2ban-1.0.2-x86_64-1_SBo.tgz
    
    You'll see a warning during installation, but it will install, and work properly.

    Next we setup fail2ban. First we need to create the local fail2ban config files where we put our settings in.

    Create the /etc/fail2ban/fail2ban.local file with needed content with the following echo command:
    echo "[Definition]
    # Option: loglevel. Default is ERROR
    # Available options: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG
    loglevel = INFO
    # Set the log target
    logtarget = /var/log/fail2ban.log" > /etc/fail2ban/fail2ban.local
    
    Create the /etc/fail2ban/jail.local file with needed content with the following echo command:
    Adjust to your liking.
    echo "[DEFAULT]
    # time is in seconds. 3600 = 1 hour, 86400 = 24 hours (1 day)
    findtime    = 3600
    bantime     = 86400
    maxretry    = 2
    ignoreip    = 127.0.0.1 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16" > /etc/fail2ban/jail.local
    
    You can put your ip address at the end of the ignoreip line if you want fail2ban to ignore it.

    Next we create our first jail for sshd.
    Create the /etc/fail2ban/jail.d/sshd.local file with the following echo command:
    echo "[sshd]
    backend = polling
    enabled = true
    filter  = sshd
    logpath = /var/log/secure" > /etc/fail2ban/jail.d/sshd.local
    
    Notice! - If you use /etc/hosts.allow and /etc/hosts.deny to limit access to sshd you can omit the fail2ban sshd jail.

    Now we make /etc/rc.d/rc.fail2ban executable and start it up:
    chmod 755 /etc/rc.d/rc.fail2ban
    /etc/rc.d/rc.fail2ban start
    
    Hopefully fail2ban is running and banning ip's now.

    Next we'll create five more jails. The six important jails that get a workout are sshd, postfix-pregreet, postfix, dovecot,
    apache-noscript, and apache-4xx. The dovecot jail gets the least use of any, and you could omit that one if you want.
    The new jail apache-4xx gets a real workout and is as important as the others.

    Create the postfix-pregreet jail:
    Create the /etc/fail2ban/jail.d/postfix-pregreet.local file with the following echo command:
    echo "# Got this from iRedMail
    [postfix-pregreet]
    backend  = polling
    enabled  = true
    maxretry = 1
    filter   = postfix-pregreet
    logpath  = /var/log/maillog" > /etc/fail2ban/jail.d/postfix-pregreet.local
    
    Create the /etc/fail2ban/filter.d/postfix-pregreet.conf file with the following echo command:
    echo "# Got this from iRedMail
    [Definition]
    # Block clients which cannot pass Postfix postscreen pregreet test.
    # FYI: http://www.postfix.org/POSTSCREEN_README.html#pregreet
    #
    # The SMTP protocol is a classic example of a protocol where the server speaks
    # before the client. postscreen(8) detects zombies that are in a hurry and that
    # speak before their turn.
    failregex = postscreen\[\d+\]: PREGREET .* from \[<HOST>\]:\d+:
    
    # while setting up new account, Thunderbird doesn't wait for server connection
    # greeting/banner, this causes Thunderbird cannot pass the Postfix pregreet
    # test and caught by \`failregex\` rules listed above (the rule contains
    # 'PREGREET' line).
    # FYI: https://bugzilla.mozilla.org/show_bug.cgi?id=538809#c41
    ignoreregex = postscreen\[\d+\]: PREGREET .* from \[<HOST>\]:\d+: (EHLO|HELO) we-guess.mozilla.org" > /etc/fail2ban/filter.d/postfix-pregreet.conf
    
    Create the postfix jail:
    Create the /etc/fail2ban/jail.d/postfix.local file with the following echo command:
    echo "# Got this from iRedMail
    [postfix]
    backend = polling
    enabled = true
    filter  = postfix-2
    logpath = /var/log/maillog" > /etc/fail2ban/jail.d/postfix.local
    
    Create the /etc/fail2ban/filter.d/postfix-2.local file with the following echo command:
    echo "# Got this from iRedMail
    [Definition]
    # *) '554 5.7.1' is 'Helo command rejected: ACCESS DENIED'
    #
    #   'ACCESS DENIED' is string defined in postfix restriction rule \`check_helo_access\`.
    #   no all rules contains 'ACCESS DENIED', so we use status code insead.
    
    failregex = \[<HOST>\]: SASL (PLAIN|LOGIN) authentication failed
                lost connection after AUTH from (.*)\[<HOST>\]
                reject: RCPT from .*\[<HOST>\]: .*: Relay access denied
                reject: RCPT from .*\[<HOST>\]: .*: Sender address rejected: Domain not found
                reject: RCPT from .*\[<HOST>\]: .*: Helo command rejected: Host not found
                reject: RCPT from .*\[<HOST>\]: .*: Helo command rejected: need fully-qualified hostname
                reject: RCPT from .*\[<HOST>\]: 554 5.7.1
                reject: RCPT from .*\[<HOST>\]:\d+: 550 5.5.1 Protocol error
                warning: Illegal address syntax from (.*)\[<HOST>\] in RCPT command
                postfix\/submission\/smtpd.*: too many errors after AUTH from .*\[<HOST>\]
    
    ignoreregex =" > /etc/fail2ban/filter.d/postfix-2.conf
    
    Create the dovecot jail:
    Create the /etc/fail2ban/jail.d/dovecot.local file with the following echo command:
    echo "# Got this from iRedMail
    [dovecot]
    backend     = polling
    enabled     = true
    filter      = dovecot-2
    logpath     = /var/log/dovecot/*.log" > /etc/fail2ban/jail.d/dovecot.local
    
    Create the /etc/fail2ban/filter.d/dovecot-2.conf file with the following echo command:
    echo "# Got this from iRedMail
    [Definition]
    failregex = Authentication failure.* rip=<HOST>
                \(auth failed.* rip=<HOST>
    
    ignoreregex =" > /etc/fail2ban/filter.d/dovecot-2.conf
    
    If Apache is your webserver Create the apache-noscript jail:
    Create the /etc/fail2ban/jail.d/apache-noscript.local file with the following echo command:
    echo "[apache-noscript]
    enabled  = true
    port     = http,https
    filter   = apache-noscript
    logpath  = /var/log/httpd/error_log
    maxretry = 1" > /etc/fail2ban/jail.d/apache-noscript.local
    
    If Apache is your webserver Create the apache-4xx jail:
    Create the /etc/fail2ban/jail.d/apache-4xx.local file with the following echo command:
    echo "[apache-4xx] 
    enabled  = true 
    port     = http,https 
    filter   = apache-4xx
    logpath  = /var/log/httpd/access_log 
    findtime = 1000
    maxretry = 2" > /etc/fail2ban/jail.d/apache-4xx.local
    
    If Apache is your webserver Create the /etc/fail2ban/filter.d/apache-4xx.conf file with the following echo command:
    echo '[Definition] 
    failregex = ^<HOST>.*"(GET|POST|HEAD).*" (404|444|403|400) .*$ 
    ignoreregex =' > /etc/fail2ban/filter.d/apache-4xx.conf
    
    If Nginx is your webserver Create the nginx-http-auth jail:
    Create the /etc/fail2ban/jail.d/nginx-http-auth.local file with the following echo command:
    echo "[nginx-http-auth]
    backend     = polling
    journalmatch=
    enabled     = true
    filter      = nginx-http-auth
    logpath     = /var/log/nginx/error.log" > /etc/fail2ban/jail.d/nginx-http-auth.local
    
    Then fail2ban needs to be started at boot and stopped at reboot or shutdown.

    Append "rc.fail2ban start" to the /etc/rc.d/rc.local file with the following echo command:
    echo "/etc/rc.d/rc.fail2ban start >/dev/null 2>&1" >> /etc/rc.d/rc.local
    
    Append "rc.fail2ban stop" to the /etc/rc.d/rc.local_shutdown file with the following echo command:
    echo "/etc/rc.d/rc.fail2ban stop >/dev/null 2>&1" >> /etc/rc.d/rc.local_shutdown
    
    Restart fail2ban to see if it works:
    /etc/rc.d/rc.fail2ban restart
    
  18. Netdata - Optional

    Netdata is a monitoring and troubleshooting tool with a very nice web based graphical interface. It has tons of info about your server
    that you can use to troubleshoot problems.

    First we need to install a required python module and python SlackBuild package with:
    pip install mysql-connector-python
    
    wget https://the-slacker.com/download/python2-PyYAML-3.13-x86_64-1_SBo.tgz
    installpkg python2-PyYAML-3.13-x86_64-1_SBo.tgz
    rm python2-PyYAML-3.13-x86_64-1_SBo.tgz
    
    Then we need to add the netdata group and user:
    groupadd -g 338 netdata
    useradd -u 338 -g 338 -c "netdata user" -s /bin/false netdata
    
    Then you'll need to grant usage to netdata@localhost. Put your chosen password in the "mysql-netdata-password" field.
    mysql -u root
    GRANT USAGE ON *.* TO netdata@localhost IDENTIFIED BY 'mysql-netdata-password';
    FLUSH PRIVILEGES;
    QUIT;
    
    Then download and install Netdata. Netdata will be installed in /opt/netdata.
    cd /root/tmp
    wget https://github.com/netdata/netdata/releases/download/v1.45.4/netdata-v1.45.4.gz.run
    chmod 0755 netdata-v1.45.4.gz.run
    ./netdata-v1.45.4.gz.run --accept
    rm netdata-v1.45.4.gz.run
    
    I have Netdata set so authentication is required to sign into netdata, so you'll need to create a netdata.users file with username
    and password. I have the user name set to netdata as you can see in the printf command below, but feel free to change that if
    you want. You'll need to put the password you want in the password field in the printf command. The password will be hashed
    in the /etc/httpd/netdata.users or /etc/nginx/netdata.users file.

    For Apache webserver run the following:
    printf "netdata:$(openssl passwd -apr1 password)" > /etc/httpd/netdata.users
    chown apache:apache /etc/httpd/netdata.users
    chmod 0400 /etc/httpd/netdata.users
    
    For Nginx webserver run the following:
    printf "netdata:$(openssl passwd -apr1 password)" > /etc/nginx/netdata.users
    chown nginx:nginx /etc/nginx/netdata.users
    chmod 0400 /etc/nginx/netdata.users
    
    Next download the /etc/rc.d/rc.netdata file, install it, and start netdata:
    wget https://the-slacker.com/download/rc.netdata
    mv -f rc.netdata /etc/rc.d/
    chmod 0755 /etc/rc.d/rc.netdata
    
    For Apache webserver
    /etc/rc.d/rc.httpd restart
    
    For Nginx webserver
    /etc/rc.d/rc.nginx restart
    
    /etc/rc.d/rc.netdata start >/dev/null 2>&1
    
    I am able to get to netdata at https://example.org/netdata now.

    Got fail2ban to show up in netdata by doing the following:
    chmod 0644 /var/log/fail2ban.log
    
    Then in /etc/logrotate.d/fail2ban put the following line in the fail2ban bracketed commands:
    create 644 root root
    
    Got Apache to show up in netdata by doing the following:
    touch /opt/netdata/etc/netdata/go.d/apache.conf
    chown netdata:netdata /opt/netdata/etc/netdata/go.d/apache.conf
    chmod 0640 /opt/netdata/etc/netdata/go.d/apache.conf
    
    Add the following to /opt/netdata/etc/netdata/go.d/apache.conf:
    jobs:
      - name: local
        url: https://127.0.0.1/server-status?auto
        tls_skip_verify: yes
    
    Got mysql to show up in netdata by doing the following:
    touch /opt/netdata/etc/netdata/go.d/mysql.conf
    chown netdata:netdata /opt/netdata/etc/netdata/go.d/mysql.conf
    chmod 0400 /opt/netdata/etc/netdata/go.d/mysql.conf
    
    Add the following to /opt/netdata/etc/netdata/go.d/mysql.conf with the mysql netdata password you created earlier:
    jobs:
      - name: local
        dsn: netdata:mysql-netdata-password@tcp(127.0.0.1:3306)/
    
    Got PHP-FPM to show up in netdata by doing the following:
    touch /opt/netdata/etc/netdata/go.d/phpfpm.conf
    chown netdata:netdata /opt/netdata/etc/netdata/go.d/phpfpm.conf
    chmod 0640 /opt/netdata/etc/netdata/go.d/phpfpm.conf
    
    Add the following to /opt/netdata/etc/netdata/go.d/phpfpm.conf:
    jobs:
      - name: local_socket
        socket: '/var/run/php-fpm.sock'
    
    Create the empty .opt-out-from-anonymous-statistics file to opt out:
    touch /opt/netdata/etc/netdata/.opt-out-from-anonymous-statistics
    chown netdata:netdata /opt/netdata/etc/netdata/.opt-out-from-anonymous-statistics
    
    If you don't want to recieve emails from netdata, and it can send a lot of emails. I recommend doing the following:
    echo 'SEND_EMAIL="NO"' > /opt/netdata/etc/netdata/health_alarm_notify.conf
    chown netdata:netdata /opt/netdata/etc/netdata/health_alarm_notify.conf
    
    If you want netdata to start at boot put the following in /etc/rc.d/rc.local:
    /etc/rc.d/rc.netdata start >/dev/null 2>&1
    
    Then put the following in /etc/rc.d/rc.local_shutdown:
    /etc/rc.d/rc.netdata stop >/dev/null 2>&1
    
    Download and install the needed netdata.conf file for this server:
    wget https://the-slacker.com/download/netdata.conf
    mv -f netdata.conf /opt/netdata/etc/netdata/
    
    Disable Netdata cloud:
    echo "[global]
        enabled = no" > /opt/netdata/var/lib/netdata/cloud.d/cloud.conf
        
    Then change ownership of cloud.conf:
    
    chown netdata:netdata /opt/netdata/var/lib/netdata/cloud.d/cloud.conf
    
    Next, if Apache is your web server then you'll need to edit /etc/httpd/extra/httpd-info.conf to allow Netdata to get server-status.
    You just need to replace example.org with your actual domain name. You can uncomment "#ExtendedStatus On" if that's what
    you want:
    <Location /server-status>
        SetHandler server-status
        Require host .example.org
        Require ip 127
    </Location>
    
    #ExtendedStatus On
    
    <Location /server-info>
        SetHandler server-info
        Require host .example.org
        Require ip 127
    </Location>    
    
    If Apache is your web server you need to restart it:
    /etc/rc.d/rc.httpd restart
    
    Lastly restart netdata:
    /etc/rc.d/rc.netdata restart
    
    Hopefully Netdata is up and running properly now.
  19. SlackerMail Mailing List Manager (smmlm) v.03 - Optional

    I made a mailing list manager for SlackerMail (smmlm). I was wanting to use the same mailing list manager that slackware.com uses, majordomo, but had such a hard
    time trying to figure out how to set it up that I just made my own. It's simple and consist of postfix header checks, two bash scripts, and a sqlite3 database. It doesn't
    have all the functionality of majordomo, mailman, or iRedMail's mlmmj, but it works for a basic and simple mlm.

    To subcribe to the SlackerMail mailing list send an email to: mailinglist@the-slacker.com with subscribe in the body of the email. To unsubscribe just put unsubscribe in
    the body of the email.

    SlackerMail mailing list manager (smmlm) setup:

    First create a mailbox for mailinglist@example.org. You can do this with posfixadmin at https://example.org/postfixadmin, or do it on the command line like below:
    Of course change example.org to your domain name. The --password password and --password2 password must be the same.
    /var/www/postfixadmin/scripts/postfixadmin-cli mailbox add mailinglist@example.org --name mailinglist --quota 100 --active 1 --password password --password2 password
    
    Then create group, user, and directory for smmlm:
    groupadd -g 401 smmlm
    useradd -u 401 -d /var/spool/smmlm -s /bin/false -g smmlm smmlm
    mkdir /var/spool/smmlm
    chown smmlm:smmlm /var/spool/smmlm
    chmod 0750 /var/spool/smmlm
    
    Next create the sqlite3 database for email addresses:
    cd /var/spool/smmlm
    
    echo "CREATE TABLE lists(
        list_id INTEGER PRIMARY KEY,
        email TEXT UNIQUE
    );" > /var/spool/smmlm/smmlm.sql
    
    sqlite3 mailinglist.db < smmlm.sql
    
    chown smmlm:smmlm /var/spool/smmlm/smmlm.sql
    chown smmlm:smmlm /var/spool/smmlm/mailinglist.db
    
    Then download the smmlm bash script that controls the email addresses list:
    wget https://the-slacker.com/download/smmlm
    chown smmlm:smmlm /var/spool/smmlm/smmlm
    chmod 0750 /var/spool/smmlm/smmlm
    
    Make sure to change example.org to your domain in this smmlm script.
    
    Then create the /var/spool/smmlm/init.sql file:
    This ".timeout 1000" sqlite3 option helps to keep the sqlite3 database from locking up under heavy loads.
    echo ".timeout 1000" > /var/spool/smmlm/init.sql
    chown smmlm:smmlm /var/spool/smmlm/init.sql
    
    Then we need to download the email2subs script that sends emails to all your subscribers:
    cd /var/spool/smmlm
    wget https://the-slacker.com/download/email2subs
    chown smmlm:smmlm /var/spool/smmlm/email2subs
    chmod 0750 /var/spool/smmlm/email2subs
    
    Make sure to change example.org to your domain in this email2subs script.
    
    Then we need the file that holds the message you want to send to your mailing list subscribers:
    echo "Hello subscribers! This is a test of my mailing list.
    
    
    To unsubscribe: send an email to mailinglist@example.org with unsubscribe in the body of the email.
    
    Thanks,
    admin@example.org" > /var/spool/smmlm/message
    
    chown smmlm:smmlm /var/spool/smmlm/message
    
    Next create the welcome message that is automatically sent out when you get a new subscriber:
    echo "Welcome to the my mailing list.
    
    
    To unsubscribe: Send an email to mailinglist@example.org with unsubscribe in the body of the email.
    
    Thanks,
    admin@example.org" > /var/spool/smmlm/welcome-message
    
    chown smmlm:smmlm /var/spool/smmlm/welcome-message
    
    Next we need to do postfix header checks to direct emails to mailinglist@example.org to the smmlm mail filter.
    Edit the file /etc/postfix/header_checks, and add the following two lines:
    /^To: "mailinglist@example.org"/ FILTER smmlm:
    /^To: mailinglist@example.org/ FILTER smmlm:
    
    Make sure to change example.org to your domain.
    
    Then we need to edit /etc/postfix/master.cf to add the smmlm mail filter.
    Add the following lines to /etc/postfix/master.cf:
    smmlm  unix  -        n       n       -       10      pipe
      flags=Rq user=smmlm null_sender=
      argv=/var/spool/smmlm/smmlm -f ${sender} -- ${recipient} 
       
    127.0.0.1:10022 inet n  -   -   -   -  smtpd
      -o content_filter=smmlm:
    
    With the above setup people should be able to subscribe or unsubscribe to your mailing list by sending an email to mailinglist@yourdomain.com, and
    putting subscribe or unsubscribe in the body of the email. To send emails to everyone subscribed to your mailing list run /var/spool/smmlm/email2subs
    on the command line. To change the message you want to send to subscribers edit /var/spool/smmlm/message. When someone subscribes to your mailing
    list they are sent a welcome email with a message from /var/spool/smmlm/welcome-message.

    The SlackerMail mailing list manager (smmlm) is an option in the SlackerMail install script now. In this latest version it seems to be working well.
  20. Finishing Setup

    SSHD - Optional
    Notice! The #1 thing to do to secure SSHD believe it or not is to change the port from 22 to a different port. It will drastically cut down on hack attempts more
    than anything else. I've proved this to myself many times.

    You can make sshd even more secure by denying all ip's but yours. Put the following in the /etc/hosts.allow file:
    sshd: put.your.ip.here
    
    Then put the following in the /etc/hosts.deny file:
    sshd: ALL
    
    This works great if you access your server by sshd with a static ip, and I guess you could add more ip's to the hosts.allow file, but I haven't tried that. If you do
    this you could stop using fail2ban for sshd.

    SSHD - Key Based Authentication - I am initially setting this server up to use login with passwords. After you get the server up and running you can change to "key
    based authentication". I use PuTTYgen to generate the public and private keys. Save the public and private keys to the computer you generated them on. You'll need
    to copy the public key directly from the PuTTYgen app with your mouse, because that is the proper form it needs to be in to go into the /root/.ssh/authorized_keys
    file. The directory /root/.ssh needs to be set to 0700 permissions and the file /root/.ssh/authorized_keys needs to be set to 0600 permissions. You'll need to add the
    private key in PuTTY at "Connections/SSH/Auth/Credentials". After you've tested that login with PuTTY using pubkeys works you can disable password login by setting
    "PasswordAuthentication no" in /etc/ssh/sshd_config. You can use a passphrase or not for your newly generated pubkey.

    PHP
    1. edit /etc/php.ini at about line 1005 and uncomment and set date.timezone = your_time_zone. I have mine set to date.timezone = America/New_York
    2. For security reasons we'll disable some php functions. Edit the /etc/php.ini file around line 312 with the following:
    Important! The following disable_functions statement needs to be on 1 continuous line in the /etc/php.ini file. Just copy and paste this in /etc/php.ini, and it will
    paste as one continous line.

    disable_functions = system, posix_uname, eval, pcntl_wexitstatus, posix_getpwuid, xmlrpc_entity_decode, pcntl_wifstopped, pcntl_wifexited, pcntl_wifsignaled, phpAds_XmlRpc, pcntl_strerror, ftp_exec, pcntl_wtermsig, mysql_pconnect, proc_nice, pcntl_sigtimedwait, posix_kill, pcntl_sigprocmask, fput, phpinfo, phpAds_remoteInfo, ftp_login, inject_code, posix_mkfifo, highlight_file, escapeshellcmd, show_source, pcntl_wifcontinued, fp, pcntl_alarm, pcntl_wait, ini_alter, posix_setpgid, parse_ini_file, ftp_raw, pcntl_waitpid, pcntl_getpriority, ftp_connect, pcntl_signal_dispatch, pcntl_wstopsig, ini_restore, ftp_put, passthru, proc_terminate, posix_setsid, pcntl_signal, pcntl_setpriority, phpAds_xmlrpcEncode, pcntl_exec, ftp_nb_fput, ftp_get, phpAds_xmlrpcDecode, pcntl_sigwaitinfo, shell_exec, pcntl_get_last_error, ftp_rawlist, pcntl_fork, posix_setuid

    MySql Databases Backup

    Next we need to download the MySQL database backup bash script.

    This script will make a daily backup of the vmail, mysql, and roundcubemail mysql databases, remove backups older than 30 days, and send a daily email report to root.
    I got this from iRedMail, but made some changes. Run the following:
    cd /root/tmp
    mkdir /var/vmail/backup
    wget https://the-slacker.com/download/mysql_backup.sh
    mv -f mysql_backup.sh /var/vmail/backup/
    chmod 0500 /var/vmail/backup/mysql_backup.sh
    
    Then we need to create a cron.daily job to run mysql-backup. Run the following echo command:
    echo -e '# Daily backup of the mysql databases.
    #!/bin/sh
    /var/vmail/backup/mysql_backup.sh > /dev/null 2>&1' > /etc/cron.daily/mysql-backup
    
    Then make it executable:
    
    chmod 0755 /etc/cron.daily/mysql-backup
    
    Configure Logging

    Next we need to adjust the /etc/logrotate.conf file to compress and put a date suffix on the compressed logs.

    This is what I put in the /etc/logrotate.conf file:
    # rotate log files weekly:
    weekly
    
    # keep 4 weeks worth of backlogs:
    rotate 4
    
    # create new (empty) log files after rotating old ones:
    create
    
    # don't rotate empty log files
    notifempty
    
    # uncomment if you want to use the date as a suffix of the rotated file
    dateext
    
    # uncomment this if you want your log files compressed:
    compress
    compresscmd /bin/bzip2
    uncompresscmd /bin/bunzip2
    compressext .bz2
    
    This is how I do logrotate, but you can do it how you like. You may need to go to /etc/logrotate.d/* and adjust the various logs to your
    liking, but the /etc/logrotate.conf sets the default.

    Webmin SSL Certs:

    If you installed Webmin, then you can use the Let's Encrypt ssl certs to avoid having to add an exception to get to the login.

    Edit the /etc/webmin/miniserv.conf file and add the following:
    keyfile=/etc/dehydrated/certs/YOURDOMAIN/privkey.pem
    certfile=/etc/dehydrated/certs/YOURDOMAIN/fullchain.pem
    
    Install some needed utilities:

    Install p7zip and unrar packages for added compression/uncompression support needed by the mailserver:
    cd /root/tmp
    wget https://the-slacker.com/download/p7zip-17.04-x86_64-1_SBo.tgz
    installpkg p7zip-17.04-x86_64-1_SBo.tgz
    rm p7zip-17.04-x86_64-1_SBo.tgz
    wget https://the-slacker.com/download/unrar-6.2.12-x86_64-1_SBo.tgz
    installpkg unrar-6.2.12-x86_64-1_SBo.tgz
    rm unrar-6.2.12-x86_64-1_SBo.tgz
    
    Keep the time right with a daily ntpdate time update:
    echo -e '# Daily time update
    #!/bin/sh
    /usr/sbin/ntpdate pool.ntp.org > /dev/null 2>&1' > /etc/cron.daily/time-update
    
    chmod 0755 /etc/cron.daily/time-update
    
    If you've already set your timezone during installation then run the command below now to update time:
    
    /etc/cron.daily/time-update
    
    Need to set time at boot because sometimes time is set wrong at boot. Run command below to add the command to set time at boot:
    
    echo -e "/usr/sbin/ntpdate pool.ntp.org >/dev/null 2>&1" >> /etc/rc.d/rc.local
    
    Create /etc/cron.daily/free-mem job to free up memory:
    echo '#!/bin/sh
    # Free up memory
    sync && echo 3 | sudo tee /proc/sys/vm/drop_caches' > /etc/cron.daily/free-mem
    chmod 0755 /etc/cron.daily/free-mem
    
    Setup sudo for an unprivileged user:
    Slackware Sudo Setup
    
  21. Testing Mail Server

    I test this mailserver at mail-tester.com and get a perfect score of 10/10. With this mailserver you should be able to send and recieve email from and to
    anybody, including gmail.

    Then I go to MX Toolbox Super Tools and do a "Test Email Server" test, and it comes back with no problems. I was getting warnings on my SMTP Connection
    and Transaction times of 6+ seconds, and if I did the mxtoolbox email server test over 1 time it wouldn't connect at all. It turns out that the long delays and
    not being to connect after 1 try was caused by fail2ban's postfix jail. If I whitelist mxtoolbox's ip's 18.209.86.113, 18.205.72.90, 52.55.244.91, 44.194.168.193,
    in /etc/fail2ban/jail.local in the ignoreip line, then everything works fine with the mxtoolbox tests. The fail2ban postfix jail is pretty agressive, and really does
    it's job. No problem with recieving real email with the fail2ban postfix jail, but it catches anything that seems strange, like mxtoolbox getting nosy, and bans
    it quick.

    Next we test Spamassassin for filtering out SPAM:
    Send an email to the server you want to test for spam recognition containing only the following text in the body:
    XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
    
    This server passed the test and marked the email as SPAM and delivered it to the Junk folder.

    Spamassassin is working properly and email taged as SPAM is delivered to the Junk folder and the SPAM email is not BOUNCED. This way you can tune
    spamassassin in /etc/amavisd.conf so that it is more or less aggressive at tagging emails as spam.

    Next we test Clamav for dealing with viruses:

    To test how Clamav is dealing with viruses go to https://www.aleph-tec.com/eicar/ and enter the email address you want the eicar virus test email delivered to.

    This server passed the test and Clamav recognized the virus, but it just defanged it and then delivered the email without the virus, which seems like the right
    way to do it. Just make sure you have the following in your /etc/amavisd.conf file:
    $defang_virus = 1;
    $final_virus_destiny = D_DISCARD;
    
    I then tried to send an email with the eicar virus from this server to another mailserver of mine, and it was blocked from being sent by clamav, so that's good.

    One way to check how your email server handles receiving a lot of emails, if your server doesn't already receive a lot of emails, is to subscribe to the linux-kernel
    mailing list. Just send an email to: linux-kernel+subscribe@vger.kernel.org and put subscribe linux-kernel in the body. You will be sent an email to confirm your
    subscription, then you'll start receiveing a bunch of emails, maybe 1500+ a day. You also then get to see what the linux kernel developers are doing.
  22. Slackware Security Updates

    Slackware Linux has slackpkg for getting security updates. It's a great package manager that's been around probably longer than any other.
    slackpkg is a lot like apt, yum, or dnf, but it doesn't have package dependecy checking, but for getting security updates that doesn't matter,
    because the updates or patches for your system have been made for your particular system, and have been made with that in mind.

    The first thing you need to do is edit /etc/slackpkg/mirrors and uncomment the link to the mirror that matches your system. This server is
    slackware64-15.0, so I uncomment https://mirrors.slackware.com/slackware/slackware64-15.0/

    If you followed the instuctions from "Slackware Server Initial Setup:" earlier in this doc, then you already did a Slackware security update,
    but you'll need to check for updates periodically.

    If you did the Slackware security update earlier in this doc, and you want to check if there are any new updates for your system then run:
    slackpkg check-updates
    
    Then if slackpkg check-updates comes back with Slackpkg: Updated packages are available since last check., and you want to upgrade run:
    slackpkg update
    slackpkg upgrade-all
    
    After you run the above command slackpkg upgrade-all you will be presented with a ncurses window with a list of all the packages that can be
    upgraded. You can choose what to upgrade or upgrade all. After the upgrade is finished you will be asked what you want to do with the new config
    files. I just choose K to keep the old config files and consider the new config files that will be given a .new extension.

    Important! If the kernel was updated and you use lilo as your boot loader then run lilo at the command prompt or you won't be able to boot. If
    you're not sure if the kernel was updated run lilo at the command prompt. It won't hurt anything to run lilo after every upgrade, just to be on the
    safe side. If you installed Slackware to use the Grub bootloader then run grub-mkconfig -o /boot/grub/grub.cfg at the command prompt after
    kernel updates.

    If this is your first time doing a Slackware security update then run:
    slackpkg update gpg
    slackpkg update
    slackpkg upgrade-all
    
    Then just follow the instructions from above on what to do after you run slackpkg upgrade-all.

    Upgrading Packages:

    Slackware has an easy way to upgrade packages with the "upgradepkg" command. This is good for packages that were installed outside of the Slackware tree,
    and can't be upgraded with slackpkg. For example, if I wanted to upgrade to the latest Clamav package I'd just run "upgradepkg clamav-1.3.1-x86_64-1_SBo.tgz"

    There are a total of 15 packages installed on SlackerMail v0.36.1 that are not from the Slackware tree that can be upgraded with upgradepkg. They are listed below:
    01. altermime v0.3.10 ---------- Check for updates
    02. amavisd-new v2.11.1 -------- Check for updates
    03. libmspack v0.10.1alpha ----- Check for updates Required by Clamav
    04. clamav v1.3.1 -------------- Check for updates
    05. dovecot-pigeonhole v0.5.17 - Check for updates
    06. fail2ban v1.0.2 ------------ Check for updates Had to modify fail2ban.SlackBuild to compile with python3.
    07. logwatch v7.10 ------------- Check for updates
    08. p7zip v17.04 --------------- Check for updates
    09. php-imagick v3.7.0 --------- Check for updates Had to modify php-imagick.SlckBuild to use the latest stable version of php-imagick.
    10. postgrey v1.37 ------------- Check for updates
    11. python2-PyYAML v3.13 ------- Check for updates
    12. rust16 v1.78.0 ------------- Check for updates Required by Clamav
    13. spamassassin v3.4.6 -------- Check for updates
    14. unrar v6.2.12 -------------- Check for updates
    15. Nginx v1.26.0 -------------- Check for updates Had to modify nginx.SlackBuild to use the latest stable version of Nginx.
    
    To check if there are any upgrades for the above packages go to SlackBuilds.org, and enter the packages names I have listed above in the search box. If you
    see there is a newer version for any of the above packages, then follow the instructions on how to build those packages. Then just upgrade the packages
    with the "upgradepkg" command.

    Here are the packages external to the SlackBuilds Repository that can be updated on Slackermail v0.36.1:
    01. Webmin v2.111 ----------- Check for updates
    02. Roundcube v1.6.6 -------- Check for updates Download the Complete version.
    03. PostfixAdmin v3.3.13 ---- Check for updates
    04. Netdata v1.45.4 --------- Check for updates
    
    Join the slackware-security mailing list:
    It's a good idea to join the slackware-security mailing list to get the latest info on slackware security. To do that send an email to majordomo@slackware.com
    with the phrase "subscribe slackware-security" in the body of the email.

    I've just finished about the 150th SlackerMail mail server install on my test server, and it seems to be doing well now, so I've changed the status from Beta
    to Release Candidate starting with SlackerMail v.025.

    Slackware is a great OS, and my favorite of all the Linuxes. It can be a job at first trying to get accustomed to it, and will take a lot of RTFM, but once you
    do, it's very logical, and just seems right. Slackware forces you to have a deeper understanding of the OS, and while at first it makes it seem harder, in the
    long run it makes things easier. I used to cuss all those RTFM'n #@! at first, but they were right, RTFM!
  23. SlackerMail Install Script v0.36.1 - 05/19/2024

    Changes in SlackerMail v0.36.1:
    1. Fixed mistake I had in the Nginx config file.
    2. Upgraded Rust16 to the latest stable version v1.78.0.
    3. Added the nginx-bad-request jail for fail2ban.
    4. Changed default fail2ban bantime to 604800 (1 week).
    
    Upgrade from earlier versions of SlackerMail Here.

    The SlackerMail install script comes in a tar.gz package with the bash install script, config files, and most of the needed packages. You will need to go thru steps
    1-3 from the top of this page before you can use this script. At this point SlackerMail can only be installed on a freshly intalled and updated Slackware64-15.0
    distro.

    I decided to go with self signed SSL certs for the install script. Doing Let's Encrypt SSL certs from a bash script can be unpredictable, and is better done after the
    install script has setup the server. It will work most of the time, but sometimes it won't, so better to do self signed, and then do Let's Encrypt after the server is
    up and running. Go to Let's Encrypt Setup for the howto on switching from the self signed certs to Let's Encrypt certs after you've installed SlackerMail from the
    intall script.

    For ease of use the script randomly generates 12, 24, or 36 character passwords for most of the servers passwords, 9 in all. There will be a file at
    /root/SlackerMail/SlackerMail.setup with the needed information about the mail server setup.

    Download and install SlackerMail:
    cd /root
    wget https://the-slacker.com/download/SlackerMail-0.36.1.tar.gz
    tar -xf SlackerMail-0.36.1.tar.gz
    cd SlackerMail-0.36.1
    ./SlackerMail.sh
    
    Below is the checksum for SlackerMail-0.36.1.tar.gz:
    SHA256: b75e686ff7b0fdd25f66c8535ae7899a030174ed819d3d1a8147748aabc8a095
    
    If you want to check the checksum run the command below:
    sha256sum /root/SlackerMail-0.36.1.tar.gz
    
    The SlackerMail install script is working very good for me now, and it consistantly installs with no problems at this point.
    I would like to hear any feedback, bad or good, from others that have tried it, Thanks!



Powered by: Slackware64-15.0 Slackware Lunux Nginx v1.26.0 Nginx SlackerMail v0.36.1 SlackerMail

Please send any feedback to: wjack@the-slacker.com