Jump to content

# OpenSMTPD

1 language

- 日本語

From ArchWiki

Related articles

- Mail server

OpenSMTPD is a free mail transfer agent, developed as part of the OpenBSD project. This article builds upon Mail server.

## Installation

Install the opensmtpd package.

## Configuration

OpenSMTPD is configured in `/etc/smtpd/`. The main configuration file is `/etc/smtpd/smtpd.conf`; see smtpd.conf(5) for its documentation.

Make sure to test the configuration using:

    # smtpd -n

If you get a message that says `configuration OK`—you are ready to start or restart `smtpd.service`. If not, work on any configuration errors and try again.

### Local mail

To have local mail working, for example for cron mails, it is enough to simply start `smtpd.service`.

The default configuration of OpenSMTPD is to do local retrieval and delivery of mail to Maildir, and also relay outgoing mail. See smtpd.conf(5).

#### Local mail only

To do only local mail, the following is enough:

    /etc/smtpd/smtpd.conf

    listen on localhost
    action "local" maildir alias <aliases>
    match for local action "local"

#### Hybrid : local mail and relay

These two lines in `/etc/smtpd/smtpd.conf` :

    action "local" maildir alias <aliases>
    action "relay" relay host "smtps://smtp.example.net" mail-from "@example.net"
    match for local action "local"
    match for any action "relay"

configure OpenSMTPD to:

- send local email locally, without going through a relay (useful for cron & at mail notifications)
- use a relay to send a mail outside of localhost

Simply replace `smtp.example.net` by your ISP mail server, or another server at your convenience.

#### Relay only

To send all local emails through a relay invoke procmail:

    /etc/smtpd/smtpd.conf

    action "local" mda "procmail -f -" virtual <aliases>
    action "relay" relay host "smtps://label@smtp.example.net" auth <secrets> mail-from "@example.net"
    match for local action "local"
    match for any action "relay"

The aliases option is used for the local user mapping, for a simplified mapping you can use virtual aliases with a catch all:

    /etc/smtpd/aliases

    @ user@example.net

#### /var/spool/mail/

OpenSMTPD 6.6.3p1 changed the default local mail configuration to use maildir in `~/Maildir/` instead of `mbox` in `/var/spool/mail/username` to avoid security issues.

To have your local mails go to the `/var/spool/mail/username` instead, replace `action "local" maildir alias <aliases>` with `action "local" maildir "/var/spool/mail/%{user.username}" alias <aliases>` in `/etc/smtpd/smtpd.conf`.

Alternatively, set the `MAIL` environment variable, that is understood by most email clients, to point to `~/Maildir/`. E.g.:

    export MAIL="${HOME}/Maildir/"

### Simple OpenSMTPD/maildir configuration

#### TLS

To obtain a certificate, see OpenSSL#Usage.

Note: OpenSMTPD has solid defaults, SSLv3 is always disabled and the default `ciphers` are not known to be insecure. You might still want to test the server as described in Server-side TLS.

#### Create user accounts

- Create a user account on the mail server for each desired mailbox.

    # useradd -m roger
    # useradd -m shirley

- OpenSMTPD will deliver messages to the user account's maildir in `/var/spool/mail/username/`
- Multiple SMTP email addresses can be routed to a given maildir if desired.

#### Craft a simple smtpd.conf setup

A working configuration can be had in as little as nine lines:

    /etc/smtpd/smtpd.conf

    pki mx.domain.example cert         "/etc/smtpd/tls/smtpd.crt"
    pki mx.domain.example key          "/etc/smtpd/tls/smtpd.key"

    table creds file:/etc/smtpd/creds
    table vdoms file:/etc/smtpd/vdoms
    table vusers file:/etc/smtpd/vusers

    listen on eth0 tls pki mx.domain.example
    listen on eth0 port 465 smtps pki mx.domain.example auth <creds>
    listen on eth0 port 587 tls-require pki mx.domain.example auth <creds>

    action "receive" maildir "/var/spool/mail/%{user.username}" virtual <vusers>
    action "send" relay

    match from any for domain <vdoms> action "receive"
    match for any action "send"

#### Create tables

For the domain table file; simply put one domain per line:

    /etc/smtpd/vdoms

    example.org
    example.com

For the user table file; list one inbound SMTP email address per line and then map it to an maildir user account name, SMTP email address, or any combination of the two on the right, separated by commas.

    /etc/smtpd/vusers

    roger@example.org          roger
    newsletters@example.org    roger,roger.rulz@mail.example

    roger@example.com          roger
    shirley@example.com        shirley
    info@example.com           roger,shirley
    contact@example.com        info@example.com

For the creds table file; put the user name in the 1st column and the password hash in the 2nd column

    /etc/smtpd/creds

    roger                              password_hash_created_using_'smtpctl encrypt'_command
    shirley                            password_hash_created_using_'smtpctl encrypt'_command

### DKIM

To sign messages with DomainKeys Identified Mail (DKIM), install opensmtpd-filter-dkimsign.

filter-dkimsign(8) supports RSA and Ed25519 keys. While RFC 8463 requires for verifiers to support Ed25519, not all of them do, so it may be best to use both Ed25519 and RSA.

#### Create private keys for DKIM

Create a directory for storing the keys:

    # install -dm750 -g smtpd /etc/smtpd/dkim

Create private keys using OpenSSL.

Ed25519:

    # openssl genpkey -algorithm ed25519 -out /etc/smtpd/dkim/dkim_ed25519.key

RFC 8301 mandates support for RSA keys ranging from 1024 bits to 4096 bits, so create a 4096 bit RSA key:

    # openssl genrsa -out /etc/smtpd/dkim/dkim_rsa4096.key 4096

Change the file permissions so that filter-dkimsign, which runs with the `smtpd` user and group permissions, can access it:

    # chown root:smtpd /etc/smtpd/dkim/dkim_*.key
    # chmod 640 /etc/smtpd/dkim/dkim_*.key

#### Prepare DNS records

DKIM uses a TXT record with the domain name `selector._domainkey.domainname`, e.g. `selector1._domainkey.mydomain.example`. See Wikipedia:DomainKeys Identified Mail#Verification for more details. The following example will use `selector1._domainkey.domain.example` for the Ed25519 key and `selector2._domainkey.domain.example` for RSA.

Use the following commands to get DNS record values from the public keys[1]:

    # openssl pkey -in /etc/smtpd/dkim/dkim_ed25519.key -pubout | openssl asn1parse -offset 12 -noout -out /dev/stdout | openssl base64 | sed '1s/^/v=DKIM1;h=sha256;k=ed25519;p=/'
    # openssl pkey -in /etc/smtpd/dkim/dkim_rsa4096.key -pubout | sed '1s/.*/v=DKIM1;h=sha256;k=rsa;p=/;:nl;${s/-----.*//;q;};N;s/\n//g;b nl;'

Update you DNS records using these values.

#### Configure filter-dkimsign

Define the filters in `/etc/smtpd/smtpd.conf` and add the filter chain to all `listen` directives. Replace `mydomain.example` with your domain name and `selector1` and `selector2` with the `_domainkey` selectors matching with your DNS records.

    /etc/smtpd/smtpd.conf

    ...
    filter "dkimsign_ed25519" proc-exec "filter-dkimsign -t -a ed25519-sha256 -d mydomain.example -s selector1 -k /etc/smtpd/dkim/dkim_ed25519.key"
    filter "dkimsign_rsa4096" proc-exec "filter-dkimsign -t -a rsa-sha256 -d mydomain.example -s selector2 -k /etc/smtpd/dkim/dkim_rsa4096.key"
    filter "dkimsign" chain { "dkimsign_ed25519", "dkimsign_rsa4096" }
    ...
    listen on mydomain.example port 465 smtps filter "dkimsign"
    listen on socket filter "dkimsign"
    ...

Tip: `listen on socket` is enabled by default and typically does not need to be added manually, but in this case it needs to be added so that the filter can be applied to it.

## Troubleshooting

### Console debugging

If you are having problems with mail delivery, try stopping the `smtpd.service` and launching the daemon manually with the "do not daemonize" and "verbose output" options. Then watch the console for errors.

    # smtpd -dv

### Subsystem tracing

Add the `-T` flag to get real-time subsystem tracing

    # smtpd -dv -T smtp

Alternately, use the `smtpctl trace subsystem` command if the daemon is already running. The trace output will appear in the console output above as well as the journalctl output for the smtpd.service. For example:

    # smtpctl trace expand && smtpctl trace lookup

...will trace both aliases/virtual/forward expansion and user/credentials lookups.

### Manual Submission port authentication

Encode username and password in base64

    $ printf '\0%s\0%s' 'username' 'password' | base64

Connect to submission port using `openssl s_client` command, using one of the following commands:

- To connect via port 465 (implicit TLS):

      $ openssl s_client -host mx.domain.example -port 465

- To connect via port 587 (STARTTLS):

      $ openssl s_client -host mx.domain.example -port 587 -starttls smtp

Enter `EHLO myhostname` followed by `AUTH PLAIN`. Paste in the base64 string from step above after `334` response:

    250 HELP
    EHLO test.domain.example
    250-mx.hostname.example Hello test.domain.example [127.0.0.1], pleased to meet you
    250-8BITMIME
    250-ENHANCEDSTATUSCODES
    250-SIZE 36700160
    250-DSN
    250-AUTH PLAIN LOGIN
    250 HELP
    AUTH PLAIN
    334
    dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ=
    235 2.0.0: Authentication succeeded

### "Helo command rejected: need fully-qualified hostname"

When sending email, if you get this kind of messages, set your FQDN in the file `/etc/smtpd/mailname`. Otherwise, the server name is derived from the local hostname returned by gethostname(3p), either directly if it is a fully qualified domain name, or by retrieving the associated canonical name through getaddrinfo(3).

### System users authentication failure

If you are using the system users and the authentication with valid credentials fails, you have to configure PAM:

    /etc/pam.d/smtpd

    auth required pam_unix.so
    account required pam_unix.so
    password required pam_unix.so
    session required pam_unix.so

## See also

- Wikipedia:OpenSMTPD
- OpenSMTPD pairs well with Dovecot. Combine the two for a nice minimalist mailserver
- OpenSMTPD project page
- Simple SMTP server with OpenSMTPD

Categories:

- Mail server
- OpenBSD