Site Index
 Wiki

External Links
 Public Directory

Search Site


 

Puffy Security


OpenBSD Email Server

This Wiki page will walk through the setup of an OpenBSD Email Server.

The server will be built with: OpenSMTPD , LibreSSL , spamd , Dovecot ,and DKIMproxy

OpenSMTPD will be configured to:

  • Receive mail for Local User Accounts
  • Receive mail for Virtual Domains
  • Provide Virtual Domain aatch-all aliases for local user accounts
  • Use SSL Cert Signed by a Personal Certificate Authority for SMTPS
  • Use SSL Cert Signed by a Public Certificate Authority for STARTTLS
  • Require STARTTLS for MTA-to-MTA Connections on Port 25
  • Send Un-Signed email through dkimproxy_out Before Relay

Table of Contents

  1. Install Packages
  2. Create Maildir
  3. Configure PF Firewall
    1. /etc/pf.conf
  4. Configure Daemons
    1. /etc/rc.conf.local
  5. Configure OpenSMTPD
    1. /etc/mail/smtpd.conf
    2. OpenSMTPD Tables
      1. /etc/mail/domains
      2. /etc/mail/users
      3. /etc/mail/blacklist-recipients
  6. DKIM and DomainKey
    1. Create DKIM DomainKey
    2. Make DNS Record
      1. /var/dkimproxy/default.txt
    3. Configure Outbound Mail Signing
      1. /etc/dkimproxy_out.conf
  7. Configure Dovecot for IMAP
    1. /etc/dovecot/dovecot.conf
    2. /etc/dovecot/conf.d/10-auth.conf
    3. /etc/dovecot/conf.d/10-mail.conf
    4. /etc/dovecot/conf.d/10-ssl.conf

1 Install Packages

In this setup we will not use dkim-milter, but we install it anyway because it brings with some useful programs.

    pkg_add dkim-milter dkimproxy dovecot

2 Create Maildir

    rm /var/mail/{root,thomas}
    mkdir -p /var/mail/{root,thomas}/{Inbox,Drafts,Sent,Trash,Spam}/{new,cur,tmp}
    chown -R thomas:thomas /var/mail/thomas
    chmod 700 /var/mail/{root,thomas}

3 Configure PF Firewall

The following OpenBSD 5.6 PF firewall configuration will:

  • Reassemble Fragmented Packets
  • Return ICMP for dropped packets
  • Enable logging on egress interfaces
  • Allow everything on loopback interfaces
  • Scrub Packets of weirdness
  • Define tables <bruteforce>, <spamd>
  • Set Default policy for in to Drop and Log
  • Drop urpf-failed packets add label uRPF
  • Drop packets from IPs in <bruteforce> table
  • Randomize TCP Sequence Numbers
  • Respond to ICMPv4 Echo-Requests and Destination-Unreachable
  • Allow SSH connections
    • Limit 15 connections from a Source IP
    • Limit 15 Connection Attempts in 5 minute window
    • Violating IPs are added to <bruteforce> table and associated states flushed
  • Allow HTTP, HTTPS connections
    • Limit 100 connections from a Source IP
    • Limit 25 Connection Attempts in 5 minute window
    • Violating IPs are added to <bruteforce> table and associated states flushed
  • Allow IMAPS connections
    • Limit 50 connections from a Source IP
    • Limit 15 Connection Attempts in 5 minute window
    • Violating IPs are added to <bruteforce> table and associated states flushed
  • Tarpit SMTP, SMTPS packets from IPs found in <spamd> table to spamd on localhost
  • Allow IMAPS connections
    • Limit 50 connections from a Source IP
    • Limit 15 Connection Attempts in 5 minute window
    • Violating IPs are added to <bruteforce> table and associated states flushed

3.1 /etc/pf.conf

File Permissions: -rw------- 1 root wheel

    set reassemble yes
    set block-policy return
    set loginterface egress
    set skip on lo

    match in all scrub (no-df random-id max-mss 1440)

    table <bruteforce> persist
    table <spamd> persist

    block in log
    block in quick from urpf-failed label uRPF
    block quick from <bruteforce>

    pass out all modulate state

    pass in quick inet proto icmp icmp-type { echoreq, unreach }

    pass in quick proto tcp from any \
        to (egress) port ssh \
        flags S/SA modulate state \
        (max-src-conn 15, max-src-conn-rate 15/5, overload <bruteforce> flush global)

    pass in quick proto tcp from any \
        to (egress) port { http, https } \
        flags S/SA modulate state \
        (max-src-conn 100, max-src-conn-rate 25/5, overload <bruteforce> flush global)

    pass in quick proto tcp from any \
        to (egress) port imaps \
        flags S/SA modulate state \
        (max-src-conn 50, max-src-conn-rate 15/5, overload <bruteforce> flush global)

    pass in on egress inet proto tcp from <spamd> \
        to (egress) port { smtp, smtps } \
        rdr-to 127.0.0.1 port spamd

    pass in proto tcp from any \
        to (egress) port { smtp, smtps } \
        flags S/SA modulate state \
        (max-src-conn 50, max-src-conn-rate 25/5, overload <bruteforce> flush global)

4 Configure Daemons

Configure your system to start the daemons spamd, Dovecot, and dkimproxy to start at boot.

4.1 /etc/rc.conf.local

File Permissions: -rw-r--r-- 1 root wheel

    spamd_flags="-v -b"
    spamd_black=YES
    pkg_scripts="dovecot dkimproxy_in dkimproxy_out"

5 Configure OpenSMTPD

The following OpenSMTPD /etc/mail/smtpd.conf configuration will:

  • Enable Queue Compression
  • Enable Queue Encryption
    • Create a key with the following command
    • openssl rand -hex 16
  • Define table aliases as Berkly DB /etc/mail/aliases.db
  • Define table domains as File /etc/mail/domains
  • Define table users as File /etc/mail/users
  • Define table blacklist-recipients as File /etc/mail/blacklist-recipients
  • Define SSL Cert/Key comodo.puffysecurity.com.pki
    • Certificate /etc/ssl/comodo/full.comodo.puffysecurity.com.crt
    • Key /etc/ssl/private/comodo.puffysecurity.com.pem
  • Define SSL Cert/Key puffysecurity.com.pki
    • Certificate /etc/ssl/puffysecurity.com.crt
    • Key /etc/ssl/private/puffysecurity.com.pem
  • Listen on SMTP, STARTTLS in on egress interface
    • Use comodo.puffysecurity.com.pki SSL Cert/Key
    • Require STARTTLS
    • Server Hostname puffysecurity.com
  • Listen on SMTPS in on egress interface
    • Use puffyssl_ca01.puffysecurity.com.pki SSL Cert/Key
    • Require Authentication
    • Server Hostname puffysecurity.com
  • Accept mail from any
    • For recipient not found in <blacklist-recipients>
    • For domain found in <domains>
    • For Virtual User found in <users>
    • Deliver to Maildir /var/mail/%{user.username}/Inbox
  • Accept mail from any
    • For recipient not found in <blacklist-recipients>
    • For local domain
    • Lookup alias in <aliases>
    • Deliver to Maildir /var/mail/%{user.username}/Inbox
  • Listen on SMTP in on loopback interface
    • Server Hostname puffysecurity.com
  • Listen in on loopback interface
    • Port 10028
    • tag DKIM
    • Server Hostname puffysecurity.com
  • Accept mail tagged DKIM
    • For any
    • Relay
    • Server source $wan_ip
    • Server Hostname puffysecurity.com
  • Accept mail from local
    • For any
    • Relay via smtp://127.0.0.1:10027

5.1 /etc/mail/smtpd.conf

File Permissions: -rw-r--r-- 1 root wheel

    egress_int="bnx0"
    wan_ip="91.209.12.222"
    queue compression
    # Create Unique Queue Key `openssl rand -hex 16`
    queue encryption key 400e0bb7ac8c0368b2150a29e65d3de5

    table aliases db:/etc/mail/aliases.db
    table domains file:/etc/mail/domains
    table users file:/etc/mail/users
    table blacklist-recipients file:/etc/mail/blacklist-recipients

    pki comodo.puffysecurity.com.pki certificate "/etc/ssl/comodo/full.comodo.puffysecurity.com.crt" 
    pki comodo.puffysecurity.com.pki key "/etc/ssl/private/comodo.puffysecurity.com.pem"
    pki puffyssl_ca01.puffysecurity.com.pki certificate "/etc/ssl/puffysecurity.com.crt" 
    pki puffyssl_ca01.puffysecurity.com.pki key "/etc/ssl/private/puffysecurity.com.pem"

    listen on $egress_int pki comodo.puffysecurity.com.pki tls-require hostname puffysecurity.com
    listen on $egress_int pki puffyssl_ca01.puffysecurity.com.pki smtps auth hostname puffysecurity.com

    accept from any \
        recipient !<blacklist-recipients> \
        for domain <domains> \
        virtual <users> \
        deliver to maildir "/var/mail/%{user.username}/Inbox"
    accept \
        recipient !<blacklist-recipients> \
        for local alias <aliases> \
        deliver to maildir "/var/mail/%{user.username}/Inbox"

    listen on lo0 hostname puffysecurity.com
    listen on lo0 port 10028 tag DKIM hostname puffysecurity.com

    accept tagged DKIM \
        for any \
        relay \
        source $wan_ip \
        hostname puffysecurity.com
    accept from local \
        for any \
        relay via smtp://127.0.0.1:10027

5.2 OpenSMTPD Tables

  • Add domains you want to receive mail for to table domains file: one-per-line

  • Add /(recipient)([[:space:]])(user)/ mappings to table users file: one-per-line. The recipient may be a complete email addresses or apply to an entire domain if prefixed with '@'.

  • Add recipient to table blacklist-recipients file: one-per-line

5.2.1 /etc/mail/domains

File Permissions: -rw-r--r-- 1 root wheel

    puffysecurity.com
    tomd.tel
    venona.nl

5.2.2 /etc/mail/users

File Permissions: -rw-r--r-- 1 root wheel

    thomas@puffysecurity.com thomas
    @puffysecurity.com thomas
    thomas@tomd.tel thomas
    @tomd.tel thomas
    thomas@venona.nl thomas
    @venona.nl thomas

5.2.3 /etc/mail/blacklist-recipients

File Permissions: -rw-r--r-- 1 root wheel

    troll@puffysecurity.com
    igetspam@tomd.tel
    ticketsite@venona.nl

6 DKIM and DomainKey

This setup will sign out-going mail with DKIM DomainKey via dkimproxy_out.

6.1 Create DKIM DomainKey

Use dkim-genkey to create a 2048 RSA key in /var/dkimproxy.

    dkim-genkey -D /var/dkimproxy -r -b 2048 -d $HOSTNAME

6.2 Make DNS Record

The file /var/dkimproxy/default.txt will contain a valid Domainkey TXT record that you need to add to your DNS. Create a new TXT record for default._domainkey and copy everything in-between the double-quotes into the value field of the TXT record.

6.3 /etc/dkimproxy_out.conf

File Permissions: -rw-r--r-- 1 root wheel

    listen    127.0.0.1:10027
    relay     127.0.0.1:10028
    domain    puffysecurity.com,venona.nl
    signature dkim(c=relaxed)
    signature domainkeys(c=nofws)
    keyfile   /var/dkimproxy/default.private
    selector  default

7 Configure Dovecot for IMAP

7.1 /etc/dovecot/dovecot.conf

File Permissions: -rw-r--r-- 1 root wheel

    protocols = imap lmtp
    listen = *, ::
    base_dir = /var/dovecot/
    login_greeting = IMAP Server Ready.
    dict {
        #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
        #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
    }
    !include conf.d/*.conf
    !include_try local.conf

7.2 /etc/dovecot/conf.d/10-auth.conf

File Permissions: -rw-r--r-- 1 root wheel

    disable_plaintext_auth = yes
    auth_cache_size = 10M
    auth_cache_ttl = 1 hour
    auth_cache_negative_ttl = 1 hour
    auth_mechanisms = plain
    !include auth-system.conf.ext

7.3 /etc/dovecot/conf.d/10-mail.conf

File Permissions: -rw-r--r-- 1 root wheel

    mail_location = maildir:/var/mail/%u/Inbox
    namespace inbox {
        inbox = yes
    }
    mmap_disable = yes
    first_valid_uid = 1000
    mail_plugin_dir = /usr/local/lib/dovecot
    mbox_write_locks = fcntl

7.4 /etc/dovecot/conf.d/10-ssl.conf

File Permissions: -rw-r--r-- 1 root wheel

    ssl_cert = </etc/ssl/puffysecurity.com.crt
    ssl_key = </etc/ssl/private/puffysecurity.com.pem
    ssl_dh_parameters_length = 4096
# vim: set ts=4 sw=4 tw=80 et :

Powered By: OpenBSD, OpenNTPD, OpenIKED, OpenSSH, OpenSMTPD, LibreSSL, and mandoc
This site Copyright © 2015 Thomas Dwyer .