Patching qmail

Changelog

  • 2013-03-31
    qmail-auth updated to latest v. 0.8.1 Added authentication by recipient domain for qmail-remote. Look at README.auth for further details
  • 2013-02-11
    some code adjustments in qmail-smtpd.c smtpd_ehlo() to restore total compatibility with esmtp-size patch
  • 2013-02-08
    qmail-auth updated to latest v. 0.7.6. Look at README.auth for further details
  • 2013-01-28
    fixed an issue on qmail-pop3d which was causing a double +OK after the pass command (thanks to Rakesh, Orbit and Simplex for helping in testing and troubleshooting)
  • 2013-01-06
    environment variable GREETDELAY renamed to SMTPD_GREETDELAY
  • 2012-10-31
    qmail-auth updated to latest v. 0.7.5. Look at README.auth for further details
    The qmail-forcetls patch was simplyfied accordingly.
    You MUST export SMTPAUTH="" in your run file now.
  • 2012-04-25
    -added qmail-remote CRLF (thanks to Pierre Lauriente for the help on testing and troubleshooting)
    The qmail-remote CRLF patch solved a problem of broken headers after sieve forwarding that was caused by a bad handling of the CR (carriage return) by qmail-remote. The issue is also reported here http://www.dt.e-technik.uni-dortmund.de/~ma/qmail-bugs.html
  • 2012.04.16
    -added qmail-tap
  • 2012.02.08
    -added smtp-size patch
  • 2012.01.29
    -added doublebounce-trim patch
  • 2011.12.12
    -file update_tmprsadh modified to chown the .pem files to vpopmail to avoid hang-ups during the smtp conversation on port 587 caused by permission problems.
  • 2011.10.06
    -qmail-remote.c: fixed. It was not going into tls on authentication (thanks to Krzysztof Gajdemski)
    -force-tls now quits if the starttls command is not provided when required (thanks to Jacekalex)

I have created a combined patch which contains the latest versions of several commonly-used qmail patches. It includes:

[Follow the patch details here]

Other patches:

You're invited to take a look at the next page of this guide, which presents several tests for these patches toward the bottom of the page.

Installing libdomainkeys

This library is a prerequisite of the DKIM patch by Manvendra Bhangui, which is part of my package. You must compile this, otherwise the compilation will break.

cd /usr/local/src
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/tar/libdomainkeys-0.69.tar.gz
tar xzf libdomainkeys-0.69.tar.gz
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/libdomainkeys-0.69.diff
ln -s libdomainkeys-0.69 libdomainkeys
cd libdomainkeys
chown -R root.root .
patch < ../libdomainkeys-0.69.diff
make
cd ../

Apply the patch

wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/roberto-netqmail-1.06.patch-latest.gz
cd netqmail-1.06
gunzip -c ../roberto-netqmail-1.06.patch-latest.gz | patch

Configuring chkuser

The combined patch you downloaded has chkuser enabled. It’s configured to perform recipient verification and MAV (Mail From: Address Verification). 

You can customize your configuration by editing the chkuser_settings.h file(in /usr/local/src/netqmail-1.06) before compiling qmail. In order to enable chkuser, the following line must be commented out:

#define CHKUSER_STARTING_VARIABLE "CHKUSER_START"

Uncomment to enable the check of user and domain format for sender address.

#define CHKUSER_SENDER_FORMAT

Uncomment to enable checking of domain MX for rcpt addresses

#define CHKUSER_RCPT_MX

Uncomment to enable checking of domain MX for sender address

#define CHKUSER_SENDER_MX

This enables usage of "#" and "+" characters within sender address. It is used by SRS (Sender Rewriting Scheme) products.

As far as my MTA Is concerned, this solved an "invalid sender address format" reject message prompted by an email address of a mailman mailing list..

#define CHKUSER_ALLOW_SENDER_SRS

force-tls variables

By default the authentication will be denied if the client does not provide the STARTTLS command. If you want to allow connections without TLS, just do

export FORCETLS=0

in your run file. Values other than 0 (or not declaring this variable at all) will force TLS before the auth.

qmail-auth variables

By default the auth is allowed with LOGIN or PLAIN mechanism. You are invited to look at the README.auth file for further details concerning the use of the SMTPAUTH environment variable, expecially if you want to use CRAM-MD5.

Recompiling qmail

The BIG-TODO patch included in my combined patch may require that your queue be rebuilt. So be aware that all existing messages in the queue will be destroyed when you erase the queue below.

To discover if your qmail has messages in the queue:

> qmailctl stat

/service/qmail-send: up (pid 18127) 6 seconds
/service/qmail-send/log: up (pid 18134) 6 seconds
/service/qmail-smtpd: up (pid 18126) 6 seconds
/service/qmail-smtpd/log: up (pid 18135) 6 seconds
/service/qmail-submission: up (pid 18131) 6 seconds
/service/qmail-submission/log: up (pid 18132) 6 seconds
/service/vpopmaild: up (pid 18129) 6 seconds
/service/vpopmaild/log: up (pid 18128) 6 seconds
messages in queue: 0
messages in queue but not yet preprocessed: 0

If this will be the first time you install the combined patch (which contains the BIG-TODO patch), you’ll need to take these steps:

qmailctl stop
rm -r /var/qmail/queue

Now compile qmail:

make

If qmail is running stop the services before installing:

qmailctl stop

Finally install qmail:

make setup check

Creating an SSL key file

If you don’t want to enable SMTP relay (using SMTP/TLS access), you can skip this section.

To secure the smtp authentication you must create the SSL certificate. The certificate must be owned by the user which runs qmail-smtpd, in our case vpopmail.

> make cert

Generating a 1024 bit RSA private key
..................++++++
.......++++++
writing new private key to '/var/qmail/control/servercert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IT
State or Province Name (full name) [Some-State]:Italy
Locality Name (eg, city) []:Cagliari
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Your Name
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:smtp.yourdomain.net
Email Address []:postmaster@yourdomain.net

> make tmprsadh
> chown vpopmail.vchkpw /var/qmail/control/*.pem

It is important that the “Common Name” matches the domain name that your email clients will specify as their SMTP server.

Now let’s create a cronjob to update the certificate every day:

> crontab -e

03 05 * * * /var/qmail/bin/update_tmprsadh > /dev/null 2>&1

Important: If you run qmail-submission as a user other than vpopmail, and you’re installing my combined patch, you must adjust /var/qmail/bin/update_tmprsadh accordingly. Otherwise you’ll probably exceed the connection timeout due to privilege problems, and won’t be able to send messages when connected remotely.

Combined patch details

qmail-authentication

It provides cram-md5, login, plain authentication support for qmail-smtpd (port 587) and qmail-remote.

qmail-tls

It implements SSL or TLS encrypted and authenticated SMTP between the MTAs and from MUA to MTA. I have adjusted the file update_tmprsadh to chown the .pem files to vpopmail, which runs qmail-smtpd.

You may interested to take a look to the page concerning smtp-auth and TLS testing here.

force-tls

optionally gets qmail to require TLS before authentication to improve security.

chkuser

performs recipient verification and Mail From: Address Verification (MAV).

You may be interested to take a look to this page concerning chkuser testing.

qmail-queue-custom-error.patch

Enables simscan and qmail-dkim to return the appropriate message for each e-mail it refuses to deliver. Simscan rejects with the name of the virus or the spam-score; qmail-dkim rejects with the verification failure message.

qmail-SPF

It can check incoming mails inside the SMTP daemon, add Received-SPF lines and optionally block undesired transfers.

Oversize DNS

This patch enables qmail to handle large DNS packets.

Reread concurrency patch

rereads control/concurrencylocal and control/concurrencyremote files when qmail-send receives a HUP signal.

Big Concurrency patch

It sets the spawn limit above 255.

Big Concurrency fix

Fixes a compiler error if you set concurrency higher than 509 in /usr/local/src/netqmail-1.06/conf-spawn.

maildir++ patch

adds maildirquota support to qmail-pop3d and qmail-local.

Better qmail-smtpd Logging patch

Facilitates diagnosing qmail-smtpd logging its actions and decisions (search for a line starting with qmail-smtp:). This is useful for discovering fake IP addresses with bad HELO’s when qmail-smtpd doesn’t log anything.

SMTP HELO/EHLO Greeting delay patch

Reduces spam by adding a user-definable delay after SMTP clients have initiated SMTP sessions, prior to qmail-smtpd responding with “220 ESMTP”. You can control the delay via the environment variable SMTPD_GREETDELAY (was GREETDELAY in the original patch). A value of SMTPD_GREETDELAY=”30” will delay qmail-smtpd’s response for 30 seconds.

DKIM patch

adds DKIM signing & verification support to qmail at both qmail-smtpd and qmail-remote/local level.

This is the page where the DKIM configuration is shortly explained.

EXT-TODO patch

addresses a problem known as the silly qmail (queue)  problem.

BIG-TODO patch

Makes qmail use a hashing mechanism in the todo folder similar to that used in the rest of the queue.

qmail-inject-null-sender patch

Prevents qmail-inject from rewriting the null sender, fixing an issue with sieve vacation/reject messages.

doublebounce-trim patch

Prevents double bounces from hitting your queue a second time provided that you delete the first line from /var/qmail/control/doublebounceto

esmtp-size patch

Enables qmail-smtpd to reject messages if they’re larger than the maximum number of bytes allowed (you can set this value in the /var/qmail/control/databytes control file).

qmail-tap

Provides the ability to archive each email that flows through the system.

qmail-remote CRLF patch

Enables qmail-remote to handle CR (\r) properly, always sending the line breaks as CRLF (\r\n) and avoiding to double the CR (like qmail-remote normally does). This often caused me a broken header when forwarding messages by means of a sieve rule.

Comments

SMTPAUTH

Hi after apply the patch and export auth, CRAM-MD5 is not enabled

220 my.domain.com ESMTP
ehlo
250-my.domain.com
250-STARTTLS
250-PIPELINING
250-8BITMIME
250-AUTH LOGIN PLAIN
250 SIZE 0

Do i need to export CRAM-MD5?

Thanks

Nic

cram-md5 auth

No, take a look to README.auth for details


Many thanks!

Many thanks!

Hi, thank you very much for

Hi, thank you very much for your work. I was wondering if it is possible to have a combined patch including ALL the patches above, EXCEPT for the BIG-TODO one. It is mentioned somewhere, but I couldn't find it.

 

Thanks again!

it should be quite simple to

it should be quite simple to reverse that patch, but for me it's already very time consuming to follow one single patch, so I can't fullfil all requests for changes. anyway I'm always available as advisor :)


Just want to say thank you

Just wanted to say thank you for pulling this all together in one page. It has been very helpful have a signle source location to get what I needed for qmail, your hard work is appreciated!

IPv6 support?

Is this version netqmail, with your patch supports IPv6?
I mean SPF, setting RELAYCIENT and other variables.

I found a patch for IPv6 netqmail-1.06:

But when I tried to put it on the source of your patch, came out a lot of mistakes, which can not cope.


On my server a few weeks, turn on the full support of IPv6, I also found a patch to patch the IPv6 tcpserwer:
http://www.brandonturner.net/blog/2009/08/qmail-ipv6-tcpserver/
It remains to Spamdyke, but that's my problem;)

Cheers;)

No, my combined patch doesn't support IPv6

No, my combined patch doesn't support IPv6. Unfortunately I don't have any IPv6 network to test the patches that are around.

cheers :)


Forcetls

Hi

I improved a little patch Forcetls to Qmail did not propose an authorization when it is not possible, due to lack of TLS encryption:

http://pastebin.com/N4zBQZUu#

Still I would like to improve the correct fragment responsible for:

538 auth not available without TLS (# 5.3.3)
Connection closed by foreign host.

To properly closed the connection, such as MUSTAUTH, or SPFFAIL

-> QUIT
<- 221 example.com
=== Connection closed with remote host.

But I have no idea how to do it .

Cheers ;)

If my understanding

If my understanding of you code is correct, you want to allow the auth with CRAM_MD5 when STARTTLS is not provided. So it's not clear to me why you want to close the door once you decided that it's a user's responsibity to secure the connection with TLS

538 auth not available without TLS (# 5.3.3)
Connection closed by foreign host.

In my opinion it would be a responsibility of the postmaster to forcetls. If not, you may want to rename the "forcetls" label of this patch with something like "skiptls" :)


HI "If my understanding of

HI "If my understanding of you code is correct, you want to allow the auth with CRAM_MD5 when the user does not provide STARTTLS

No, :it's not at all with CRAM-MD5:

swaks -f user@example.com -t postmaster@example.com -s example.com --p 587 -au user@example.com -ap password
=== Trying example.com:587...
=== Connected to example.com.
<- 220 example.com ESMTP
-> EHLO localhost.localdomain
<- 250-wampir7.pl
<- 250-STARTTLS
<- 250-PIPELINING
<- 250-8BITMIME
<- 250-SIZE 67108864
<- 250 X Authorization requires an encrypted SSL or TLS connection
*** Host did not advertise authentication
-> QUIT
<- 221 example.com
=== Connection closed with remote host.

My goal was that the server did not provide authentication, authorization when it is not possible due to lack of TLS encryption:

While the offer, when encryption is enabled:
Like this:

swaks -f user@example.com -t postmaster@example.com -s example.com --p 587 -au user@example.com -ap q --tls
=== Trying example.com:587...
=== Connected to example.com.
<- 220 example.com ESMTP
-> EHLO localhost.localdomain
<- 250-example.com
<- 250-STARTTLS
<- 250-PIPELINING
<- 250-8BITMIME
<- 250-SIZE 67108864
<- 250 X Authorization requires an encrypted SSL or TLS connection
-> STARTTLS
<- 220 ready for tls
=== TLS started w/ cipher DHE-RSA-AES256-SHA
=== TLS peer subject DN="/C=IT/ST=PL/L=TestO=Test/OU=IMAP server/CN=example.com/emailAddress=postmaster@example.com"
~> EHLO localhost.localdomain
<~ 250-example.com
<~ 250-PIPELINING
<~ 250-8BITMIME
<~ 250-SIZE 67108864
<~ 250 AUTH LOGIN PLAIN CRAM-MD5
~> AUTH CRAM-MD5
<~ 334 PDMyNjAwLjEzMzIyNDI3NjhAMD4=
~> dXNlckBleGFtcGxlLmNvbSAwMzFlYjgwNTE4OTcyODgwZWRlOWU5M2U1ZThhZDJjYw==
<~ 235 ok, go ahead (#2.0.0)
~> MAIL FROM:<user@example.com>
<~ 250 ok
~> RCPT TO:<postmaster@exammple.com>
<~ 250 ok
~> DATA
<~ 354 go ahead
~> Date: Tue, 20 Mar 2012 12:26:08 +0100
~> To: postmaster@exammple.com
~> From: user@example.com
~> Subject: test Tue, 20 Mar 2012 12:26:08 +0100
~> X-Mailer: swaks v20111230.0 jetmore.org/john/code/swaks/
~>
~> This is a test mailing
~>
~> .
<~ 250 ok 1332242769 qp 32604
~> QUIT
<~ 221 example.com
=== Connection closed with remote host.


That was my reservation it immediately, and disconnect the test without TLS authentication constitute circumvention of the problem, but it only partially solved.
Here, not about the CRAM-MD5, but here is that the server did not provide authorization for no reason that can not be held, and that in connection with any mail client that does not try to send the password without encryption.


Made sure that the CRAM-MD5 was exclusive, as before. ;)

I meant it to be solved better than Gmail. :D

Cheers ;)

I'm sorry but I'm not sure

I'm sorry but I'm not sure I have understood what you say towards the end of your message..

Anyway, are the tests you provide made using my patch or your modified one?

My goal was that the server did not provide authentication, authorization when it is not possible due to lack of TLS encryption:

This is exactly what my forcetls patch does, right?


Hi This is exactly what my

Hi

This is exactly what my forcetls patch does, right?

Exactly the point, I had to just to authorization was not offered when it is unrealistic due to lack of TLS.

This is to avoid situations where someone set the example in Outlook autoryzaję PLAIN, then this Outlok trying to log in, and the error log.

I prefer a system where the server does not offer authorization (AUTH), if it can not be done, just like in Gmail

Cheers ;)