Rimozione del driver vpopmail-auth di Dovecot

14 gennaio 2021 Roberto Puzzanghera0 commenti

Coloro che ancora stanno utilizzando il driver vpopmail di Dovecot per fare l'autentucazione, dovrebbero prendere in considerazione la migrazione al driver sql, poichè il 17 marzo il Team di sviluppo di Dovecot ha annunciato la sua rimozione probabilmente già dalla prossima v2.3.11. Vedere qui per informazioni aggiuntive sulle componenti obsolete che saranno presto rimosse.

  • 13 gennaio 2021:
    - aggiunto il supporto sql a aliasdomain
  • 4 gennaio 2021
    - è stato rilasciato dovecot-2.3.13 e con esso è stato rimosso il driver vpopmail. Maggiori informazioni qui.

Aggiungere vpopmail's aliasdomains a mysql

Come qualcuno ha già messo in evidenza nei commenti, passare a dovecot's sql  può essere doloroso se si devono gestire degli aliasdomains. Mostrerò qui sotto come fare in modo che dovecot dovecot sia a conoscenza deglii aliasdomains di vpopmail, di modo che un utente che si logga coun domain alias possa superare la fase di autenticazione.

L'idea è quella di salvare le coppie alias/domain in una nuova "aliasdomains" tabella per mezzo un vaddaliasdomain wrapper script, e modificare la query sql di dovecot al fine di selezionare il dominio utente da questa tabella.

Creare la tabella

Aprire il proprio prompt di mysql e lanciare la seguente query per creare la tabella aliasdomains

USE vpopmail;
CREATE TABLE `aliasdomains` (
`alias` varchar(100) NOT NULL,
`domain` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `aliasdomains`
ADD PRIMARY KEY (`alias`);

Scaricare lo shell script

Scaricare lo script da usare quando si creano nuovi aliasdomains e assegnargli privilegi +x

cd /usr/local/bin
wget https://notes.sagredo.eu/files/hacks/qmail/vpopmail/my_vaddaliasdomain
chmod +x my_vaddaliasdomain

Questo è il contenuto dello script

#!/bin/bash 
# 
# v. 2021.01.13 
# vpopmail/vaddaliasdomain wrapper script 
# by Roberto Puzzanghera 
# More info here https://notes.sagredo.eu/en/qmail-notes-185/dovecot-vpopmail-auth-driver-removal-241.html 
# 
# Adds/delete vpopmail's aliasdomains recording the newly created alias in mysql 
# This gets dovecot's sql auth driver working with vpopmail's aliasdomains as well 
# 

# Config and executables path 
VPOPMAIL_MYSQL_CONFIG="/home/vpopmail/etc/vpopmail.mysql" 
VADDALIASDOMAIN="/home/vpopmail/bin/vaddaliasdomain" 
VDELDOMAIN="/home/vpopmail/bin/vdeldomain" 

# Extract mysql params 
HOST=$(sed -n 's/^\(.*\)|0|vpopmail.*/\1/p' $VPOPMAIL_MYSQL_CONFIG) 
USER=vpopmail 
PWD=$(sed -n 's/.*|vpopmail|\(.*\)|.*/\1/p' $VPOPMAIL_MYSQL_CONFIG) 

function create() { 
       # Output the query to a file that we want to run 
       # The real domain will be alias of itself. It'll be inserted just the first time the query is executed. 
       cat << EOF > /tmp/query.sql; 
       USE vpopmail; 
       INSERT IGNORE INTO aliasdomains (domain,alias) VALUES ("$1","$1"); 
       INSERT IGNORE INTO aliasdomains (domain,alias) VALUES ("$1","$2"); 
EOF 
       # Execute the query 
       mysql -h $HOST -u $USER -p$PWD -N -A < /tmp/query.sql 
} 

function delete() { 
       # Output the query to a file that we want to run 
       cat << EOF > /tmp/query.sql; 
       USE vpopmail; 
       DELETE FROM aliasdomains WHERE alias="$1"; 
EOF 
       # Execute the query 
       mysql -h $HOST -u $USER -p$PWD -N -A < /tmp/query.sql 
} 


if [ "$2" = 'delete' ]; then 

   echo 
   echo -n "Are you sure you want to delete $2 aliasdomain y/N? [N] " 
   read VAR_DELETE 

   if [ "$VAR_DELETE" = 'y' ]; then 

       # Delete aliasdomain 
       echo "Deleting $1" 
       # Delete vpopmail aliasdomain 
       $VDELDOMAIN $1 
       # Delete mysql record 
       delete $1 

   else 
       exit 0 

   fi 

elif [ "$2" != '' ]; then 

   echo "Creating $2 as alias of $1" 
   # Create mysql record     
   # Create vpopmail's aliasdomain only if $1 not equal to $2 
   # (alias and domain should be different for vpopmail but is needed for the dovecot's sql auth) 
   if [ $1 != $2 ]; then 
        $VADDALIASDOMAIN $1 $2 
   fi
   create $1 $2 

elif [ "$1" = '' ] || [ "$2" = '' ]; then 

   # Usage 
   echo 
   echo "Usage" 
   echo 
   echo "Creating an aliasdomain:" 
   echo "$0 <real_domain> <alias_domain>" 
   echo 
   echo "Deleting an aliasdomain:" 
   echo "$0 <alias_domain> delete" 
   echo 
fi 

exit 0

Lo script chiama il programma vaddaliasdomain e aggiunge il record al database.

Usarlo in questo modo per creare un aliasdomain

my_vaddaliasdomain domain.net alias.net

Questo comando scrive due record nella tabella:

MariaDB [vpopmail]> SELECT * FROM aliasdomains; 
+----------------------+----------------------+ 
| alias                | domain               | 
+----------------------+----------------------+ 
| alias.net            | domain.net           | 
| domain.net           | domain.net           |  
+----------------------+----------------------+

Come si può notare domain.net deve pure essere aggiunto conme un alias di sè stesso per consentire l'atenticazione del dominio domain.net.

Usare in questo modo per cancellare un aliasdomain

my_vaddaliasdomain alias.net delete

MariaDB [vpopmail]> SELECT * FROM aliasdomains; 
+----------------------+----------------------+ 
| alias                | domain               | 
+----------------------+----------------------+ 
| domain.net           | domain.net           | 
+----------------------+----------------------+

Tenere presente che l'alias record domain.net deve essere sempre presente anche per i domini che non hanno alias. Pertanto, se si ha in mente di usare in futuro aliasdomain e passare al driver sql, è necessario creare un record per ogni dominio, per esempio:

my_vaddaliasdomain domain.net domain.net

Modificare la query sql

Infine è necessario modificare il file dovecot-sql.conf.ext come segue (scarica). Notare le variazioni in password_query e userdb_query.

# Database driver: mysql, pgsql, sqlite 
driver = mysql 

# Database connection string. This is driver-specific setting. 
# 
# mysql: 
#   Basic options emulate PostgreSQL option names: 
#     host, port, user, password, dbname 
# 
#   But also adds some new settings: 
#     client_flags           - See MySQL manual 
#     connect_timeout        - Connect timeout in seconds (default: 5) 
#     read_timeout           - Read timeout in seconds (default: 30) 
#     write_timeout          - Write timeout in seconds (default: 30) 
#     ssl_ca, ssl_ca_path    - Set either one or both to enable SSL 
#     ssl_cert, ssl_key      - For sending client-side certificates to server 
#     ssl_cipher             - Set minimum allowed cipher security (default: HIGH) 
#     ssl_verify_server_cert - Verify that the name in the server SSL certificate 
#                              matches the host (default: no) 
#     option_file            - Read options from the given file instead of 
#                              the default my.cnf location 
#     option_group           - Read options from the given group (default: client) 
#  
connect = host=localhost dbname=vpopmail user=vpopmail password= 

# Default password scheme. 
# 
# List of supported schemes is in 
# http://wiki2.dovecot.org/Authentication/PasswordSchemes 
# 
default_pass_scheme = MD5-CRYPT 

# passdb query to retrieve the password. It can return fields: 
#   password - The user's password. This field must be returned. 
#   user - user@domain from the database. Needed with case-insensitive lookups. 
#   username and domain - An alternative way to represent the "user" field. 
# 
# The "user" field is often necessary with case-insensitive lookups to avoid 
# e.g. "name" and "nAme" logins creating two different mail directories. If 
# your user and domain names are in separate fields, you can return "username" 
# and "domain" fields instead of "user". 
# 
# The query can also return other fields which have a special meaning, see 
# http://wiki2.dovecot.org/PasswordDatabase/ExtraFields 
# 
# Commonly used available substitutions (see http://wiki2.dovecot.org/Variables 
# for full list): 
#   %u = entire user@domain 
#   %n = user part of user@domain 
#   %d = domain part of user@domain 
# 
# Note that these can be used only as input to SQL query. If the query outputs 
# any of these substitutions, they're not touched. Otherwise it would be 
# difficult to have eg. usernames containing '%' characters. 
# 
# Example: 
#   password_query = SELECT userid AS user, pw AS password \ 
#     FROM users WHERE userid = '%u' AND active = 'Y' 
# 
password_query = SELECT \ 
       CONCAT(vpopmail.pw_name, '@', aliasdomains.domain) AS user, \ 
               vpopmail.pw_passwd AS password, \ 
               vpopmail.pw_dir as userdb_home, \ 
               89 AS userdb_uid, \ 
               89 AS userdb_gid \ 
       FROM `vpopmail` \ 
       INNER JOIN aliasdomains ON \ 
               aliasdomains.alias='%d' \ 
       WHERE \ 
               vpopmail.pw_name = '%n' \ 
               AND \ 
               vpopmail.pw_domain = aliasdomains.domain 

# userdb query to retrieve the user information. It can return fields: 
#   uid - System UID (overrides mail_uid setting) 
#   gid - System GID (overrides mail_gid setting) 
#   home - Home directory 
#   mail - Mail location (overrides mail_location setting) 
# 
# None of these are strictly required. If you use a single UID and GID, and 
# home or mail directory fits to a template string, you could use userdb static 
# instead. For a list of all fields that can be returned, see 
# http://wiki2.dovecot.org/UserDatabase/ExtraFields 
# 
# Examples: 
#   user_query = SELECT home, uid, gid FROM users WHERE userid = '%u' 
#   user_query = SELECT dir AS home, user AS uid, group AS gid FROM users where userid = '%u' 
#   user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u' 
# 
user_query = \ 
       SELECT \ 
               vpopmail.pw_dir AS home, \ 
               89 AS uid, \ 
               89 AS gid, \ 
               CONCAT('*:bytes=', REPLACE(SUBSTRING_INDEX(vpopmail.pw_shell, 'S', 1), 'NOQUOTA', '0')) AS quota_rule \ 
       FROM vpopmail \ 
       INNER JOIN aliasdomains ON \ 
               aliasdomains.alias='%d' \ 
       WHERE \ 
               vpopmail.pw_name = '%n' \ 
               AND \ 
               vpopmail.pw_domain = aliasdomains.domain \ 
               AND \ 
               ('%a'!='995' or !(vpopmail.pw_gid & 2)) \ 
               AND \ 
               ('%r'!='localhost' or !(vpopmail.pw_gid & 4)) \ 
               AND \ 
               ('%r'='localhost' or '%a'!='993' or !(vpopmail.pw_gid & 8)) 

# If you wish to avoid two SQL lookups (passdb + userdb), you can use 
# userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll 
# also have to return userdb fields in password_query prefixed with "userdb_" 
# string. For example: 
#password_query = \ 
#  SELECT userid AS user, password, \ 
#    home AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \ 
#  FROM users WHERE userid = '%u' 

# [WEBMAIL-IP] is the IP of your webmail web server. 
# I'm assuming that the imap connection is only on port 993 and the pop3 connection is on port 955. 
# Adjust to your needs 
# 
# logically this means: 
# SELECT user 
# WHEN POP is not disabled for that user connecting on port 995 (995 is the pop3s port allowed from remote in my configuration) 
# AND WHEN webmail access is not disabled for that user when connecting from [WEBMAIL-IP] 
# AND WHEN IMAP is not disabled for that user connecting on port 993 (993 is the imap port allowed from remote  
# in my configuration) unless his remote ip the one belonging to the webmail 

# Query to get a list of all usernames. 
#iterate_query = SELECT username AS user FROM users 
iterate_query = SELECT CONCAT(pw_name,'@',pw_domain) AS username FROM `vpopmail`

Migrare gli account al formato sql

Questa soluzione richiede che gli account siano già in formato sql. Per convertire dal formato cdb a sql usare il programma vconvert di vpopmail:

vconvert: usage 
The first option sets which format to convert FROM, 
the second option sets which format to convert TO. 
-e = etc format 
-c = cdb format 
-m = sql format 
-S = set sqwebmail passwords 
-v = version 
-d = debug info

Se invece si vuole passare a postgres, dare un'occhiata a questa soluzione di erdgeist qui.

Aggiungi un commento