bg-tutorials

How to Generate a CSR on Qmail

This guide shows you how to generate a CSR (Certificate Signing Request) on qmail using the OpenSSL command line. Qmail (and its actively maintained fork, notqmail) does not include a built-in CSR tool. You use OpenSSL to create two files at once: a private key that stays on the server, and the CSR you submit to your Certificate Authority (CA).

The CSR encodes the mail hostname your server presents during STARTTLS, your organization details, and the public half of the key. The matching private key never leaves the server. If you lose it, the issued certificate becomes unusable and you have to generate a new pair.

A note on qmail vs. notqmail: the original qmail was frozen by Daniel J. Bernstein in 1998 and has received no upstream updates since. notqmail (latest release: 1.09, May 2024) is the community-maintained fork that includes security fixes, modern TLS support, and current build compatibility. The CSR generation process is identical for both, because it uses OpenSSL rather than any qmail binary. If you are still running the original qmail, consider migrating to notqmail or Postfix for ongoing security support.

Prerequisites

  • Root or sudo access to the server running qmail (or notqmail).
  • OpenSSL installed. It ships in the base system on every mainstream Linux and BSD distribution. Check with openssl version.
  • The fully qualified mail hostname you want on the certificate, for example mail.example.com. This must match the MX record clients connect to over STARTTLS, not the bare apex domain.

Step 1: Prepare a directory for the key and CSR

Qmail stores its TLS certificate at /var/qmail/control/servercert.pem by default. Create a subdirectory for the key material and lock it down to root:

sudo mkdir -p /var/qmail/control/ssl
sudo chmod 700 /var/qmail/control/ssl
cd /var/qmail/control/ssl

You will generate the key and CSR inside this directory. After the CA issues the certificate, you combine the files into the servercert.pem that qmail-smtpd reads on startup.

Step 2: Generate the private key and CSR

Run the command below. It creates the private key and the CSR in one step and includes the Subject Alternative Name (SAN) that modern mail clients and CAs require. The SAN must list the mail hostname (the one your MX record points to):

sudo openssl req -new -newkey rsa:2048 -nodes \
-keyout /var/qmail/control/ssl/mail.example.com.key \
-out /var/qmail/control/ssl/mail.example.com.csr \
-subj "/C=US/ST=YourState/L=YourCity/O=YourCompany/CN=mail.example.com" \
-addext "subjectAltName=DNS:mail.example.com"

Here is what each part does:

  • req -new creates a new certificate signing request.
  • -newkey rsa:2048 generates a new 2048-bit RSA private key. 2048 bits is the current minimum for public certificates; you can use rsa:4096 for a larger key.
  • -nodes leaves the private key unencrypted (no passphrase), so qmail-smtpd can load it on startup without prompting.
  • -keyout writes the private key. Keep this file private and never send it to anyone, including the CA.
  • -out writes the CSR you submit to the CA.
  • -subj fills in the subject fields inline so the command runs without interactive prompts. Set CN (Common Name) to your mail hostname.
  • -addext “subjectAltName=…” adds the SAN entry. CAs issue against the SAN list, so the mail hostname must appear here.

Replace mail.example.com with the real hostname clients connect to (often the same name as your MX record), and edit the -subj values to match your organization. The two-letter country code (C) must be uppercase, for example US or GB. For a domain-validated (DV) certificate, the organization fields are not verified, but the command still needs valid values. Modern OpenSSL signs the CSR with SHA-256 by default, which is what every public CA requires.

If you prefer to fill in the fields interactively instead of with -subj, drop that flag and OpenSSL will prompt you for each value:

sudo openssl req -new -newkey rsa:2048 -nodes \
-keyout /var/qmail/control/ssl/mail.example.com.key \
-out /var/qmail/control/ssl/mail.example.com.csr \
-addext "subjectAltName=DNS:mail.example.com"

When prompted, leave the challenge password and optional company name blank by pressing Enter. CAs ignore those fields, and a challenge password causes problems later.

Covering more than one hostname

If the same qmail instance answers on more than one name (for example, both mail.example.com and smtp.example.com), list every hostname in the SAN value, separated by commas:

-addext "subjectAltName=DNS:mail.example.com,DNS:smtp.example.com"

The Common Name should still be the primary mail hostname. Adding the bare apex domain to the SAN is only useful if mail clients ever connect to it directly; if your MX record points to a sub-hostname, you do not need the apex on the certificate.

Prefer an ECDSA key?

ECDSA keys are smaller and faster than RSA at the same security level and are supported by every current mail client and CA. To generate a P-256 (prime256v1) key and CSR instead, swap the -newkey argument:

sudo openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes \
-keyout /var/qmail/control/ssl/mail.example.com.key \
-out /var/qmail/control/ssl/mail.example.com.csr \
-subj "/C=US/ST=YourState/L=YourCity/O=YourCompany/CN=mail.example.com" \
-addext "subjectAltName=DNS:mail.example.com"

Note that the original qmail with DJB’s TLS patches may not support ECDSA. If you run notqmail with a current OpenSSL, ECDSA works without issues.

Step 3: Protect the private key

Lock the private key down so only root can read it. The raw key file is only needed when you build the combined servercert.pem later, so root ownership and mode 600 are correct:

sudo chown root:root /var/qmail/control/ssl/mail.example.com.key
sudo chmod 600 /var/qmail/control/ssl/mail.example.com.key

The CSR file is not secret (it contains only the public key and your subject details), but keeping it in the same locked-down directory keeps the layout tidy.

Step 4: Verify the CSR

Before you submit the request, confirm it contains the right hostname and SAN and that its signature is valid:

openssl req -noout -text -verify -in /var/qmail/control/ssl/mail.example.com.csr

Look for verify OK in the output, check that the Subject line shows your mail hostname as the Common Name, and confirm the X509v3 Subject Alternative Name section lists every hostname you expect. If a SAN is missing, regenerate the CSR with the correct -addext value: a CA cannot add hostnames after issuance. You can also paste the CSR into our online CSR Decoder to check these fields in a browser.

Step 5: Submit the CSR

Open the CSR file and copy its entire contents, including the BEGIN and END lines:

cat /var/qmail/control/ssl/mail.example.com.csr

The block looks like this. Copy everything from the first line to the last, including the five hyphens on each side of the BEGIN and END markers:

-----BEGIN CERTIFICATE REQUEST-----
MIIC...base64-encoded data...AB
-----END CERTIFICATE REQUEST-----

Paste that block into your SSL order form. After the CA validates the CSR and issues the certificate, follow our qmail SSL installation guide to deploy it. Keep the .key file on the server: you need it together with the issued certificate to enable STARTTLS, and you must never send it to the CA or anyone else.

If you would rather not use the command line, build the request with our CSR Generator and paste the result into your order. The generator returns a matching private key that you place at the same path on the server.

Where the files go in qmail

For context, this is how the files you just generated are wired into qmail once the CA returns the certificate and intermediate (CA bundle). Qmail-smtpd reads its TLS material from a single combined PEM file at /var/qmail/control/servercert.pem. This file must contain the private key, the server certificate, and the intermediate certificates, concatenated in that order:

cat mail.example.com.key mail.example.com.crt intermediate.pem \
> /var/qmail/control/servercert.pem
sudo chown root:nofiles /var/qmail/control/servercert.pem
sudo chmod 640 /var/qmail/control/servercert.pem

The nofiles group is the default group for the qmaild user that qmail-smtpd runs as. Mode 640 lets qmaild read the file through group membership while keeping it unreadable by other users. If your system uses a different group for qmaild, substitute that group name in the chown command.

Qmail-smtpd offers STARTTLS when it detects this file at startup. On the original qmail, STARTTLS requires the UCSPITLS patch (or Russ Nelson’s TLS patch) and the UCSPITLS environment variable set in /service/qmail-smtpd/run. On notqmail, TLS support is built in. After placing the combined PEM file, restart the qmail-smtpd service:

sudo svc -t /service/qmail-smtpd

The full install walk-through, including verifying the certificate chain with OpenSSL, is in our qmail SSL installation guide.

Verify STARTTLS after installation

Once the certificate is installed, confirm that your server advertises STARTTLS and serves a valid chain:

openssl s_client -connect mail.example.com:25 -starttls smtp -servername mail.example.com

Look for Verify return code: 0 (ok) and confirm the subject and issuer match your certificate. You can also scan the server with our SSL Checker for a visual report of the certificate chain and expiration date.

Generate a CSR on other mail platforms

Running a different mail server? See our other CSR guides:

Save 10% on SSL Certificates when ordering from SSL Dragon today!

Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10

A detailed image of a dragon in flight
Written by

I've been writing for SSL Dragon for over 10 years, focusing entirely on SSL certificates and digital security. My job is to take complex cybersecurity topics and strip away the jargon, making sure you get the clear, practical information you need to keep your website safe.