Esta es una entrada dentro de la serie para la instalación de un servidor de correo completo. Índice completo de contenidos pincha aquí.
Dovecot ofrece la posibilidad de activar una funcionalidad experimental, a partir de su versión v2.2.22, que permite interactuar con comandos doveadm utilizando una serie de APIs vía HTTP. Esto nos permite ejecutar sus comandos mediante el uso de la herramienta CURL.
Esta nueva característica nos brinda la oportunidad de realizar nuestros propios programas, scripts, paneles de adminsitración de buzones, etc sin necesidad de utilizar un usuario del sistema con privilegios. Símplemente debemos de tener o las credenciales del usuario de doveadm o el Token que nos permita lanzar peticiones HTTP desde el exterior o desde la misma máquina local.
Son muchos los comandos que podremos ejecutar, cubriendo cualquier necesidad que podamos tener en la administración de este Backend para buzones de correo electrónico.
Esta entrada se suma a nuestro manual para la configuración de un compelto servidor de correo electróncio, indicado al comienzo, pero es extensible a cualquier instalación de Dovecot que cumpla con la versión mínima requerida o superior.
En el momento en el que se redactó esta entrada del blog disponíamos de la versión Dovecot v2.22.27.
Vamos al lío!!!
Tabla de contenidos
Consideraciones
La configuración de esta funcionalidad nunca debe ser accesible desde cualquier origen. Debemos ser muy cuidadosos con su uso y los permisos de acceso, ya que de lo contrario pondremos en riesgo todo nuestro sistema de buzones, exponiendo su información, configuración y contenido.
Es recomendable activarla para su uso interno, bien para el desarrollo de algún proceso, automatismo, panel de administración Web, … De tener que publicarlo se debería de filtrar por origen al que se precisa conceder acceso, pero nunca publicarlo sin restricción alguna.
Configuración del servicio
Para realizar la configuración solo debemos de agregar unas líneas a nuestro archivo de configuración global para Dovecot, salvo que queramos activar el servicio SSL lo cual nos requiere tener previamente configurado este servicio en nuestra instalación.
Sin SSL
Si vamos a utilizar las APIs para consultas internas desde el mismo sistema podemos prescindir del servicio SSL, ya que la información no saldrá al exterior.
Solo será necesario configurar las siguientes líneas del listener en el archivo dovecot.conf, que en mi caso se encuentra en la ruta /etc/dovecot:
doveadm_password = nuestra_pwd
doveadm_api_key = nuestra_pwd
service doveadm {
inet_listener http {
port = 8080
#ssl = yes
}
}
Reiniciamos el servicio y estaría listo:
sudo service dovecot restart
El puerto configurado quedaría levantado:
netstat -an | grep 8080
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
tcp6 0 0 :::8080 :::* LISTEN
Con SSL
En mi caso prefiero configurar el servicio con SSL para cifrar cualquier tipo de información que circule por la red, lo que requiere tener el servicio configurado en nuestra instalación global. En la entrada Servidor de correo – Configuración Dovecot, SIEVE, ManageSIEVE (parte 7) se explica como hacerlo.
Una vez lo tengamos configuardo, debemos de habilitar el servicio SSL en nuestro listener para la API de Dovecot:
doveadm_password = nuestra_pwd
doveadm_api_key = nuestra_pwd
service doveadm {
inet_listener http {
port = 8080
ssl = yes
}
}
Reiniciamos el servicio y estaría listo:
sudo service dovecot restart
El puerto configurado quedaría levantado:
netstat -an | grep 8080
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
tcp6 0 0 :::8080 :::* LISTEN
Hay que tener en cuenta que para cualquier consulta que lancemos tendremos que utilizar el protocolo HTTPS y el nombre de host configurado en el certificado, en mi caso correu2.yeloquehay.com, como veremos más adelante.
Comandos de la API
Para poder enviar comandos de la API podemos usar tanto el Token como las credenciales user:pwd, pero en cualquiera de los casos debemos de obtener su valor en Base64.
Credenciales en Base64
Para obtener el valor de las credenciales encriptado en Base64 podemos hacer uso de un servicio online, o usar el siguiente código en Python3 y la librería base64:
>>> import base64
>>>
>>> token = 'nuestra_pwd'
>>> credentials = 'doveadm:nuestra_pwd'
>>>
>>> # TOKEN
>>> message_bytes = token.encode('ascii')
>>> base64_bytes = base64.b64encode(message_bytes)
>>> base64_message = base64_bytes.decode('ascii')
>>> print(base64_message)
bnVlc3RyYV9wd2Q=
>>>
>>> # USER:PWD
>>> message_bytes = credentials.encode('ascii')
>>> base64_bytes = base64.b64encode(message_bytes)
>>> base64_message = base64_bytes.decode('ascii')
>>> print(base64_message)
ZG92ZWFkbTpudWVzdHJhX3B3ZA==
>>>
El código resultante es el que usaremos para lanzar los comandos vía CURL.
Listado de comandos
Podemos obtener todos los comandos disponibles de la siguiente forma, usando HTTP o HTTPS dependiendo de la configuración que hubieramos realizado en el paso anterior:
- Con usuario:contraseña:
curl -H "Authorization: Basic ZG92ZWFkbTpudWVzdHJhX3B3ZA==" https://correu2.yeloquehay.com:8080/doveadm/v1
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0[
{"command":"serviceStop", "parameters":[
{"name":"service","type":"array"}
]},
{"command":"serviceStatus", "parameters":[
{"name":"service","type":"array"}
]},
{"command":"processStatus", "parameters":[
{"name":"service","type":"array"}
]},
{"command":"stop", "parameters":[]},
{"command":"reload", "parameters":[]},
{"command":"statsDump", "parameters":[
{"name":"socketPath","type":"string"},
{"name":"type","type":"string"},
{"name":"filter","type":"string"}
]},
...
- Con Token:
curl -H "Authorization: X-Dovecot-API ZG92ZWFkbTpudWVzdHJhX3B3ZA==" https://correu2.yeloquehay.com:8080/doveadm/v1
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0[
{"command":"serviceStop", "parameters":[
{"name":"service","type":"array"}
]},
{"command":"serviceStatus", "parameters":[
{"name":"service","type":"array"}
]},
{"command":"processStatus", "parameters":[
{"name":"service","type":"array"}
]},
{"command":"stop", "parameters":[]},
{"command":"reload", "parameters":[]},
{"command":"statsDump", "parameters":[
{"name":"socketPath","type":"string"},
{"name":"type","type":"string"},
{"name":"filter","type":"string"}
]},
...
La lista es muy extensa, por lo que es recomendable dedicarle un tiempo para buscar el que más se ajuste a nuestras necesidades y probarlo.
Ejemplo desde BASH
Un ejemplo de comando sería obtener la quota utilizada y disponible de un buzón, el cual podemos obtener con el siguiente comando desde BASH. Los valores vienen dados en KB:
curl -H "Authorization: X-Dovecot-API ZG92ZWFkbTpudWVzdHJhX3B3ZA==" -H "Content-Type: application/json" -d '[["quotaGet", { "user": "email@email.com"}, "c01"]]' https://correu2.yeloquehay.com:8080/doveadm/v1
[["doveadmResponse",[{"root":"User quota","type":"STORAGE","value":"497713","limit":"10485760","percent":"4"},{"root":"User quota","type":"MESSAGE","value":"11116","limit":"-","percent":"0"}],"c01"]]
En la respuesta doveadmResponse podemos ver la capacidad utilizada, el límite máximo y el porcentaje utilizado, tanto para el tamaño STORAGE como de número de mensajes MESSAGE.
Si recibiéramos un error sería similar al siguiente resultado:
[["error",{"type":"exitCode", "exitCode":67},"c01"]]
Ejemplo desde Python
Desde Python podemos ejecutar el comando anterior con la librería requests, la cual no viene por defecto y hay que instalarla:
python3 -m pip install requests
>>> import requests
>>> url = 'https://correu2.yeloquehay.com:8080/doveadm/v1'
>>> headers = {'Authorization':'X-Dovecot-API ZG92ZWFkbTpudWVzdHJhX3B3ZA==', 'Content-Type':'application/json'}
>>> payload = '[["quotaGet", { "user": "email@email.com"}, "c01"]]'
>>> r = requests.post(url, data=payload, headers=headers)
El resultado lo podríamos ver de la siguiente forma:
>>> r.content
b'[["doveadmResponse",[{"root":"User quota","type":"STORAGE","value":"491169","limit":"10485760","percent":"4"},{"root":"User quota","type":"MESSAGE","value":"10960","limit":"-","percent":"0"}],"c01"]]'
>>> response = r.json()
>>> print(response[0])
['doveadmResponse', [{'value': '491169', 'limit': '10485760', 'percent': '4', 'type': 'STORAGE', 'root': 'User quota'}, {'value': '10960', 'limit': '-', 'percent': '0', 'type': 'MESSAGE', 'root': 'User quota'}], 'c01']
>>> print(response[0][1])
[{'value': '491169', 'limit': '10485760', 'percent': '4', 'type': 'STORAGE', 'root': 'User quota'}, {'value': '10960', 'limit': '-', 'percent': '0', 'type': 'MESSAGE', 'root': 'User quota'}]
>>> print(response[0][1][1])
{'value': '10960', 'limit': '-', 'percent': '0', 'type': 'MESSAGE', 'root': 'User quota'}
Una forma más visual de mostrar los datos:
>>> storage = response[0][1][0]
>>> for key in storage.keys():
... print('%s - %s' % (str(key),str(storage[key])))
...
value - 491169
limit - 10485760
percent - 4
type - STORAGE
root - User quota
Y con la librería de Python humanfriendly podemos ver el resultado en formato más amigable, pero debemos de instalarla. Los valores vienen dados en KB, por lo que tendremos que multiplicar x1000 el resultado obtenido para ver el dato correcto:
python3 -m pip install humanfriendly
>>> import humanfriendly
>>>
>>> used = humanfriendly.format_size(storage['value'] * 1000)
>>> max_limit = humanfriendly.format_size(storage['limit'] * 1000)
>>>
>>> print('value - %s\nlimit - %s\npercent - %s\%\ntype - %s\nroot - %s' % (str(used), str(max_limit), str(storage['percent']), str(storage['type']), str(storage['root'])))
value - 491.2 MB
limit - 10.05 GB
percent - 4%
type - STORAGE
root - User quota
Conclusiones
Con esta nueva funcionalidad de Dovecot podemos interactuar con los comandos Doveadm sin necesidad de usuario de sistema, ni de estar dentro de la consola de nuestro servidor, pero mucho cuidado con la seguridad ya que estamos exponiendo un acceso directo a la administración de nuestros buzones y su contenido.
Enlaces de interés
Oficial configuración Dovecot API
Servidor de correo – Configuración Dovecot, SIEVE, ManageSIEVE (parte 7)