qmailAdmin is a free software package that provides a web interface for managing a qmail system with virtual domains. It provides admin for adding/deleting users, Aliases, Forwards, Mailing lists and Autoresponders.

Before installing, you may want to patch qmailadmin with a patch of mine which enables a check for the password strenght. This should avoid unsafe accounts created by domain administrators such as "test 123456". Since my skills on C programming are very low, I preferred to do the check via javascript form validation. Currently only password which contains at list an uppercase character, a digit, a special character and are at least eight characters long are allowed. Of course we have to trust that the domain administrator will not have javascript disabled, but there's no reason to think that he has any interest to do so. You can adjust the javascript file pw_strenght_chk.js inside the html dir to your needs.

We will also apply an additional patch (thanks to Tony) in order to have authentication failures logged. This makes possibile to ban malicious IPs via fail2ban. It is required to create the log file /var/log/qma-auth.log initially and assign write priviledges to apache.

The next patch is the ezmlm-idx 7 compatibility, which restores the compatibility with ezmlm-idx-7 (thanks to J.D. Trolinger for the advice).

Finally the fix to the catchall account (thanks to Luca Franceschini).


cd /usr/local/src
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/tar/qmailadmin-1.2.16.tar.gz
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmailadmin/qmailadmin-1.2.16-pwd-strenght.patch-2015.04.25
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmailadmin/qmailadmin-1.2.16-log.patch
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmailadmin/mailinglist.c.ezmlm7.patch
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmailadmin/qmailadmin-catchall.patch

touch /var/log/qma-auth.log
chgrp apache /var/log/qma-auth.log
chmod g+w /var/log/qma-auth.log

tar xzf qmailadmin-1.2.16.tar.gz
cd qmailadmin-1.2.16
patch -p1 < ../qmailadmin-1.2.16-pwd-strenght.patch-2015.04.25
patch < ../qmailadmin-1.2.16-log.patch
patch < ../mailinglist.c.ezmlm7.patch
patch < ../qmailadmin-catchall.patch
chown -R root.root .

./configure \
  --enable-htmldir=/usr/local/www/htdocs/qmail \
  --enable-cgibindir=/usr/local/www/htdocs/qmail/cgi-bin \
  --enable-cgipath=/cgi-bin/qmailadmin \
  --enable-imagedir=/usr/local/www/htdocs/qmail/qmailadmin/qmailadmin_img \
  --enable-imageurl=/qmailadmin_img \
  --enable-htmllibdir=/usr/local/www/htdocs/qmail/qmailadmin \
  --enable-qmaildir=/var/qmail \
  --enable-domain-autofill \
  --enable-vpopuser=vpopmail \
  --enable-vpopgroup=vchkpw \
  --enable-autoresponder-path=/usr/local/bin \
  --enable-ezmlmdir=/usr/local/bin/ezmlm \
  --enable-modify-quota \
  --disable-ezmlm-mysql \

make install-strip

This installs qmailadmin in /usr/local/www/htdocs/qmail

Be aware the the home graphics middleleft1.png released with qmailadmin has license problems as shown here (thanks to Marc for the hint).

Apache virtual host

<VirtualHost *:443>
        ServerName yourdomain.net
        DocumentRoot /usr/local/www/htdocs/qmail
        ScriptAlias /cgi-bin/ "/usr/local/www/htdocs/qmail/cgi-bin/"
        ErrorLog  "/usr/local/www/logs/qmailadmin_error.log"
        CustomLog "/usr/local/www/logs/qmailadmin_access.log" common
        <Directory "/usr/local/www/htdocs/qmail">
            AllowOverride None
            Order allow,deny
            Allow from all
        <Directory "/usr/local/www/htdocs/qmail/cgi-bin">
            AllowOverride None
            Options ExecCGI
            Order allow,deny
            Allow from all

        Alias /qmailadmin_img/ "/usr/local/www/htdocs/qmail/qmailadmin/qmailadmin_img/"
        <Directory "/usr/local/www/htdocs/qmail/qmailadmin/qmailadmin_img">
            Order allow,deny
            Allow from all

Now browse to https://yourdomain.net/cgi-bin/qmailadmin and login as postmaster:



Hi Roberto,

I'm trying to setup email server based on your blog on Centos 6.5 x64

I manage to get everything to work until Qmailadmin part, when i test the menu "Set catchall email deleted" "Set catchall bounced" and "Set remote catch all account" , the page just show blank screen, even when i refresh (F5) , other menu seems ok.

Do you have any hint about this problem ?


Hi George,

I have the same issue here. It worked in the past. I think it could be a bug... let me know if you solve

it was working before, must be some upgrade to apache, php, bash(?), or who knows what broke this.

surely it does not depend on php because it's not written in php. 

I would try to downgrade qmailadmin to see if it's broken only in the latest version

Hi Roberto,

I cannot find where qmailadmin logs failed login attempts or failed change password attempts. I'd like to work with fail2ban to ban those who attempt too many logins.

Thank you,


Hi Boatner, I know. This is a problem. I doesn't log anything nor to /var/log/maillog nor to mysql

Dear all,

after some testing I found out that it works when downgrading vpopmail to v. 5.4.32 and qmailadmin to 1.2.15.

I also noticed that the compilation of qmailadmin breaks when compiling 1.2.16 over vpopmail 5.4.32, or 1.2.15 over vpopmail 5.4.33.


  • qmailadmin 1.2.16 goes with vpopmail-5.4.33, but this option seems to have the catch-all accounts functionality broken
  • qmailadmin 1.2.15 only goes with vpopmail-5.4.32

this issue is fixed (thanks to Luca Franceschini). Patch

Hello Roberto,

i want to warn you about the risks of using the login picture from qmailadmin. Seriously this is no joke and i couldn't believe it the first time but using qmailadmin with this picture (
middleleft1.png ) had cost me a fine of several hundreds Euro. This has happened: A few weeks ago i've got a letter from the company Getty Images, that i'm using illegal the picture provided in the login form from qmailadmin. Getty Images says that they has the legal rights of this image an i didn't have a license to use the picture and i have to pay this amount of money as an compensation for violating the copy right of this picture and of course i have to remove the picture immediatelly. I googled this thing and found out that this is true and even the guys from inter7 are aware of this thing, that happend to other qmailadmin users too (see the full thread of this post: http://article.gmane.org/gmane.mail.qmail.admin/4804). I contacted a lawyer and he said that under german and EU copyright laws this is true and i violated the copy right because i have to make sure that when i publish on a website a picture i'm responsible to make sure that i don't violate any copyright rules, even when the picture is part of an open source software. Another lawyer told me that i can try to go against it but the uncertain of succes and the costs of an lawyer for this put me to the decision to pay the fine.

So be warned when using the picture and check the copyright laws of your country.


Thanks for the hint Mark. I'm going to write a note asap

I suppose that this is the reason why that image is not shown anymore in the latest version. I thought that it was a bug, but I think this is an explanation.


Thanks for your great works on this guide.  I would like to share the patch for qmailadmin (1.2.16) in order to have auth logging.  The patch shall log the failed login in qmailadmin login page.  The patch as underneath:

--- qmailadmin.c 2011-02-22 22:45:48.000000000 +0800
+++ qmailadmin.c.new 2015-05-11 12:06:58.984316573 +0800
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 #include <unistd.h>
 #include <pwd.h>
 #include <dirent.h>
@@ -109,6 +110,33 @@
 char RealDir[156];
 char Lang[40];
+static void
+log_auth(char *msg)
+    FILE *fp = NULL;
+    if ((fp = fopen("/var/log/qma-auth.log", "a")) == NULL) {
+ exit(-1);
+    }
+    const char *ip_addr = getenv("REMOTE_ADDR");
+    if (!ip_addr)
+        ip_addr = "";
+    time_t tv;
+    struct tm tm;
+    char time_buf[64];
+    time(&tv);
+    localtime_r(&tv, &tm);
+    strftime(time_buf, sizeof(time_buf) - 2, "%Y/%m/%d %H:%M:%S", &tm);
+    fprintf(fp, "%s user:%s@%s ip:%s auth:%s\n", time_buf, Username, Domain, ip_addr, msg);
+    if (fclose(fp) != 0) {
+        exit(-1);
+    }
 void qmailadmin_suid (gid_t Gid, uid_t Uid)
   if ( geteuid() == 0 ) {
@@ -195,6 +223,11 @@
     if (*Username && (*Password == '\0') && (*Password1 || *Password2)) {
       /* username entered, but no password */
       snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[198]);
+      char log_buf[3 * MAX_BUFF];
+      memset(log_buf, 0x0, sizeof(log_buf));
+      snprintf(log_buf, sizeof(log_buf) - 2, "failed [%s@%s]", Newu, Domain);
+      log_auth(log_buf);
     } else if (*Username && *Password) {
       /* attempt to authenticate user */
       vget_assign (Domain, RealDir, sizeof(RealDir), &Uid, &Gid);
@@ -208,6 +241,11 @@
       if ( *Domain == '\0' ) {
         snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[198]);
+        char log_buf[3 * MAX_BUFF];
+        memset(log_buf, 0x0, sizeof(log_buf));
+        snprintf(log_buf, sizeof(log_buf) - 2, "failed [%s@%s]", Newu, Domain);
+        log_auth(log_buf);
       } else {
@@ -215,6 +253,11 @@
         pw = vauth_user( User, Domain, Password, "" );
         if ( pw == NULL ) {
           snprintf (StatusMessage, sizeof(StatusMessage), "%s", html_text[198]);
+          char log_buf[3 * MAX_BUFF];
+          memset(log_buf, 0x0, sizeof(log_buf));
+          snprintf(log_buf, sizeof(log_buf) - 2, "failed [%s@%s]", Newu, Domain);
+          log_auth(log_buf);
         } else if (pw->pw_flags & NO_PASSWD_CHNG) {
           strcpy (StatusMessage, "You don't have permission to change your password.");
         } else if (strcmp (Password1, Password2) != 0) {
@@ -264,6 +307,12 @@
          pw = vauth_user( Username, Domain, Password, "" );
          if ( pw == NULL ) {
            snprintf (StatusMessage, sizeof(StatusMessage), "%s\n", html_text[198]);
+           char log_buf[3 * MAX_BUFF];
+           memset(log_buf, 0x0, sizeof(log_buf));
+           snprintf(log_buf, sizeof(log_buf) - 2, "failed [%s@%s]", Newu, Domain);
+           log_auth(log_buf);

It is required to created the log file /var/log/qma-auth.log initially.  Then we can use the log in fail2ban with the underneath filter:

failregex = ip:<HOST> auth:failed

ignoreregex =

Hope the patch is helpful.


verrry much appreciated, as this is one thing I was looking for. At the moment I have an apache authentication before the web page is displayed, just to record the failures in the apache log.

Tony, I added your patch to the present guide. Thanks a lot


The password qmailadmin-1.2.16-pwd-strenght.patch-2015.04.25 patch does not work for me. I am able to use simple password like 1234.

Anyone also encounter this?



and you can open the js file with your browser?

Hi Roberto,

Sadly to say, i dont know the path to it even.

Sorry and thanks


Probably you installed the pwd_strenght_chk.js file in the wrong path. Just navigate to the "add new user" page, right click to look at the html code and click over the javascript file. The file must be accessible by your web server.


The absolute path of add user


The path of the javascript


Cgi-bin path



./configure --enable-help \
--enable-domain-autofill \
--enable-htmldir=/var/www/html \
--enable-imagedir=/var/www/html/images/qmailadmin \
--enable-imageurl=http://domain.com/images/qmailadmin \
--enable-cgibindir=/var/www/cgi-bin \
--disable-ezmlm-mysql \
--enable-modify-quota \

Can you help me to spot any mistake.

Many thanks again


It depends on your web server configuration as well. Try to check if the webserver can access that file as suggested in my previous post


I can see the source.

<script language="Javascript" type="text/javascript" src="/qmailadmin/html/pwd_strenght_chk.js"></script>
        <body bgcolor="#ffffff" onload="init();">

But if i goto http://domain.com/cgi-bin/qmailadmin/html/pwd_strenght_chk.js i will just be directed to http://domain.com/cgi-bin/qmailadmin/



Nic, your web server looks for the script in this path http://domain.com/qmailadmin/html/pwd_strenght_chk.js. Note that the dir is different. Try again and if it fails double check your web server config as far the qmailadmin virtual domain is concerned and also that apache can actually access that file

Thanks Roberto.

All the functions in /html folder are working. I even edited the footer.html and it is also reflected in qmailadmin pages. I just don't know why the js file is not called.



perhaps you have javascript disabled in your browser?


I had checked. javascript.enabled is true and i did a "Do i have java" on Java.com

Thanks for leading me this far. I think its up to myself to look for the broken link.





I cannot find where is the broken link, or how it is broken. But i copy the js file into a public folder and edit the path of add_user.html, change_password.html and mod_user.html to URL of the new js file location.

All working now.




I guess you have some apache permissions problems.. try to browse to that js file with your browser and look at the error you get

The qmailadmin-1.2.16 with ezmlm-idx-7.2.2  needs a patch in order to manage the mailing lists.  I had had to add this patch to my src directory then re-compile.  

patch < ../mailinglist.c.ezmlm7.patch

I also use your qmailadmin-1.2.16-pwd-strenght.patch-2015.04.25 and qmailadmin-1.2.16-log.patch with this patch.

I am not sure if this is in your patch list Roberto.  There are a few sources and I am not sure which one to post. 


John D. Trolinger


Thanks for the advise, John. I was not aware of this patch, but I found it in the qmailrocks site. Tomorrow I'm going to study the idea behind it and eventually I'll add it to my qmailadmin. 

Can you report what kind of error you get when the patch is not applyed?

Before the patch I had to use the command line to add moderators.  Also I could not change settings for the various mailing lists.  

This may not be typical; I had migrated from another server  running older versions of qmailadmin and ezmlm.

Best Regards

I added mailinglist.c.ezmlm7.patch to the patch list

I have followed your guide and I am at the point of logging into Qmailadmin.

The page comes up perfectly but after entering postmaster, domain and password, it gives a blank screen.

I checked all the error logs and there are no entries pointing to a reason for this behaviour.

Using the following versions:

qmailadmin 1.2.16
vpopmail 5.4.33

did you check the syslog to look for a segfault? Anyway.. I would try to recompile qmailadmin