Introduction

Have you ever thought about setting up your own email server, but then left it behind. However, setting up a email server is not complicated. In this article, we will build it step by step from scratch.

Here we will need the following environments:

  • Nginx - an lightweight and open-source web server to offer low memory usage and high concurrency.
  • Docker - a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers.
  • iRedMail - The right way to build your mail server with open source softwares.

Installation

we will install and configure all necessary software in order. And following the steps you will almost get your own email server.

Install iRedMail

For convenience, we use docker-compose to defining and running the iRedMail applications, create the Compose file with the name iredmail.yml and it’s content below:

version: "3"

services:
  ehub_iredmail:
    container_name: iredmail
    image: lejmr/iredmail:mysql-latest
    restart: always
    hostname: mail.example.com
    networks:
      eztnet:
        ipv4_address: 172.20.0.2
    volumes:
      - iredmail_mysql:/var/lib/mysql
      - iredmail_vmail:/var/vmail
      - iredmail_clamav:/var/lib/clamav
    environment:
      DOMAIN: example.com
      HOSTNAME: mail
      MYSQL_ROOT_PASSWORD: password
      SOGO_WORKERS: 1
      TIMEZONE: "Europe/London"
      POSTMASTER_PASSWORD: password
      IREDAPD_PLUGINS: "['reject_null_sender', 'reject_sender_login_mismatch', 'greylisting', 'throttle', 'amavisd_wblist', 'sql_alias_access_policy']"

networks:
  eztnet:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24

volumes:
  iredmail_mysql:
  iredmail_vmail:
  iredmail_clamav:

Building and running the service:

$ sudo docker-compose -f iredmail.yml up

Press Ctrl+C (or Ctrl+\ ) to detach you from the container.

If you encounter starting server(s) uwsgi failed, you should do the uwsgi checking:

image

Attach to the container:

$ sudo docker exec -it iredmail /bin/bash

Run uwsgi with specific iredmail.ini mannually:

$ uwsgi --ini /etc/uwsgi/apps-available/iredadmin.ini

Configuring DNS Records

Best practices for email authentication, here I recommend you always set up these email authentication methods for your domain:

  • SPF helps servers verify that messages appearing to come from a particular domain are sent from servers authorized by the domain owner.
  • DKIM adds a digital signature to every message. This lets receiving servers verify that messages aren’t forged, and weren’t changed during transit.
  • DMARC enforces SPF and DKIM authentication, and lets admins get reports about message authentication and delivery.

Create A record

mail.example.com  a

Create MX record

mail.example.com  mx

Create TXT record for SPF

v=spf1 ip4:<server_ip> ~all

or

v=spf1 mx mx:mail.example.com ~all

Create TXT record for DMARC

_dmarc.example.com  txt  v=DMARC1;p=reject;rua=mailto:[email protected]; adkim=s;aspf=s

Create TXT record for DKIM

At frist, we need to attach to the container:

Find below setting in Amavisd config file amavisd.conf (find its location on different Linux/BSD distributions):

dkim_key('example.com', "dkim", "/var/lib/dkim/example.com.pem");

@dkim_signature_options_bysender_maps = ( {
    ...
    "example.com"  => { d => "example.com", a => 'rsa-sha256', ttl => 10*24*3600 },
    ...
});

And then we need to get the DKIM keys:

$ amavisd-new showkeys

image

Now we copy the DKIM keys and create the TXT record:

dkim._domainkey.example.com v=DKIM1; p=MIIBIjANBgkqhkiG9...8ZEqo/QIDAQAB

Subsequently, we test the txt record:

$ amavisd-new testkeys

or

$ dig -t txt dkim._domainkey.example.com

image

image

Nginx config

Create the nginx site config:

$ sudo vim /etc/nginx/sites-available/iredadmin

Type the following content:

# mail.example.com
server {
  listen 80;

  server_name mail.example.com;
  access_log  /var/log/nginx/mail.example.com.access.log;

  location /.well-known/ {
    root /var/www/acme/;
  }

  location / {
    return 302 https://$host$request_uri;
  }
}

server {
  listen 443;

  # using web sub domain to access
  server_name mail.example.com;
  access_log  /var/log/nginx/mail.example.com.access.log;

  ssl_certificate       /etc/nginx/ssl/mail.example.com/fullchain.cer;
  ssl_certificate_key   /etc/nginx/ssl/mail.example.com/private.key;
  ssl_protocols         TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers           HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers on;

  location / {
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;

    proxy_pass   https://172.20.0.2:443;
  }
}

Create the nginx stream config:

$ sudo vim /etc/nginx/streams-available/iredadmin

Type the following content:

# mail server proxy
server { listen 25; proxy_pass 172.20.0.2:25; }     # SMTP
server { listen 587; proxy_pass 172.20.0.2:587; }   # SMTP(STARTTLS)
server { listen 143; proxy_pass 172.20.0.2:143; }   # IMAP(STARTTLS)
server { listen 993; proxy_pass 172.20.0.2:993; }   # IMAP
server { listen 110; proxy_pass 172.20.0.2:110; }   # POP3
server { listen 995; proxy_pass 172.20.0.2:995; }   # POP3

And then create the symbolic links:

$ ln -s /etc/nginx/sites-available/iredmail /etc/nginx/sites-enabled/iredmail
$ ln -s /etc/nginx/streams-available/iredmail /etc/nginx/streams-enabled/iredmail

Afterwards, don’t forget to restart the nginx service:

$ sudo service nginx force-reload

Finish

Up to this point, all the installation work has been completed, and we are almost about to get our own email server,

Login iRedAdmin

Open the iredmail Admin:

https://mail.example.com/iredadmin

Login use default account [email protected], and then create your own email account.

image

image

Test Email Server

For better use and no spammyness, we use this free online service to test the emails for Spam, Malformed Content and Mail Server Configuration problems.

If all goes well, we will get full marks, otherwise, we will get the tips on current problems:

image

References