Desarrollo y bases de datos

Desarrollando y automatizando vía API de cPanel

Revisado el 14 min de lectura cpanel api automatizacion

La API de cPanel es una gran desconocida para el usuario final, a día de hoy esta interfaz da acceso a absolutamente todas las funciones de cPanel, permitiendo controlar y automatizar cualquier necesidad que se tenga, desde aquellas más básicas como crear cuentas de correo desde una herramienta externa (por ejemplo para facilitar el onboarding de nuevos usuarios o empleados), crear redirecciones, copias de seguridad, obtener estadísticas y en general cualquier función que necesites.

Esta API tiene la versatilidad de permitir el acceso por diferentes vías, por ejemplo a nivel local se puede usar vía SSH sin requerir autenticación de ningún tipo, o haciendo llamadas (ej desde cURL o un cliente http) a la URL de cPanel usando autenticación vía token.

Aunque la API de cPanel cuenta con una extensa documentación, para reducir las barreras de entrada, vamos a mostrar varios ejemplos prácticos para las diferentes formas de autenticación y uso.

Acceso a la API vía terminal, comando uapi

Si el uso de la API será desde el propio servidor que aloja la cuenta, cPanel no requerirá ningún tipo de autenticación, pudiendo hacer uso de forma libre de la API.

Ejemplo de uso, creando una redirección vía terminal

Si tienes experiencia con el uso de SSH y línea de comandos, esta vía es probablemente la más rápida para embarcarte en el uso de la API, para ello dispondríamos del comando uapi que hace de punto de entrada.

En este caso ejemplo vamos a añadir una redirección para uno de los dominios configurados, esto lo haremos por medio de la llamada Mime add_redirect.

Siguiendo con el ejemplo, si queremos redireccionar dominio1.com a dominio2.com, con una redirección de tipo 301 (permanente) tanto para www como sin estas, los parámetros necesarios serían que deberemos transmitir a la llamada a la API serían:

  • domain: dominio1.com
  • redirect: https://dominio2.com
  • type: permanent
  • redirect_www: 0

Con lo que el comando a ejecutar quedaría de la siguiente forma:

/usr/local/cpanel/bin/uapi --output=jsonpretty \
  Mime \
  add_redirect \
  domain='dominio1.com' \
  redirect='https://dominio2.com/' \
  redirect_www=0 \
  type="permanent"

Tras ejecutar el comando recibiremos confirmación en formato json tabulado (jsonpretty), informando si se añadió correctamente o de cualquier error que pudiese ocurrir.

En el valor de --output= definimos en que formato queremos la respuesta, puede ser json, jsonpretty o yaml

Ejemplo de uso, obteniendo un listado de cuentas de correo

Lo primero sería localizar la función que necesitamos para obtener el listado de todas las cuentas de correo existentes en nuestro servicio, para ello usaremos Email list_pops, que tal como indica la documentación, devuelve un listado de todos los emails.

Ejecutar esta operación es tan fácil como ejecutar /usr/local/cpanel/bin/uapi Email list_pops, obteniendo un resultado tipo:

apiversion: 3
func: list_pops
module: Email
result:
  data:
    -
      email: account@domain.com
      login: Main Account
      suspended_incoming: 0
      suspended_login: 0
  errors: ~
  messages: ~
  metadata:
    transformed: 1
  status: 1
  warnings: ~

Dado que queremos un listado de las cuentas y en la respuesta tenemos información que en este caso práctico no necesitamos, podemos combinar varios filtros para limpiar el resultado:

/usr/local/cpanel/bin/uapi Email list_pops | grep email | awk -F ":" '{print $2}'| sed 's/^[[:space:]]*//'

Este comando devolvería el listado de cuentas de correo, uno por línea y sin más información de la respuesta de la API, en la primera parte ejecutamos la llamada a la API, y el resultado lo filtramos para los campos que aparezca "email", por último con la ayuda de los comandos awk y sed, limpiamos la salida, con lo que tendríamos.

cuenta1@dominio.com
cuenta2@dominio.com
cuenta3@dominio.com

Si queremos guardar el listado en un fichero, simplemente añadimos al final del comando > fichero.txt, esta adición redirecciona la salida para que en vez de en pantalla se envíe a un fichero.txt (si el fichero no existe es creado automáticamente).

El uso de la API por medio del comando uapi es bastante sencillo a la vez que pontente, incluso si tenemos programas en el servidor, podrían usar estos comandos haciendo la llamada desde PHP por medio de una función como shell_exec.

Autenticación con la API desde servidor externo

Para acceder a la API desde un servidor externo, deberemos autenticarnos para que la operación sea permitida por el servidor, para ello necesitaremos un token de acceso.

Los token se pueden crear y gestionar desde cPanel, sección Manage API tokens. Crea uno exclusivo para cada automatización, con caducidad y con el menor alcance que permita la tarea; no reutilices la contraseña de cPanel ni un token compartido por varios sistemas.

El sistema generará una cadena de texto aleatoria que sería el token y solo se mostrará una vez. Guárdalo en el gestor de secretos de la aplicación o en un fichero de configuración fuera de la raíz web, propiedad del usuario y con permisos 0600. No lo escribas directamente en un comando: quedaría en el historial de la shell y podría aparecer en listados de procesos o registros.

Ya con nuestro token a buen recaudo, podremos hacer llamadas a la API. Por ejemplo, guarda la cabecera en ~/.config/cpanel-api/curl.conf, protege el fichero con chmod 600 ~/.config/cpanel-api/curl.conf y úsalo desde cURL sin incluir el token en el comando:

curl --config "$HOME/.config/cpanel-api/curl.conf" \
'https://example.com:2083/execute/Module/function?parameter=value'

El contenido del fichero protegido sería header = "Authorization: cpanel username:APITOKEN". Revoca el token al terminar la integración o en cuanto deje de ser necesario.

  • username: sería tu usuario de cPanel.
  • APITOKEN: el token que hemos creado.
  • example.com: tu dominio, puede ser cualquiera de los dominios alojados en tu cuenta.

Puedes ver que el formato de la dirección que continúa es execute/Module/function?parameter=value, seguiría la siguiente sintaxis:

  • Module: el módulo de la llamada a la API
  • function: la función de la llamada a la API.
  • parameter: sería cualquier parámetro que queramos pasar a la llamada, siguiendo el formato parameter=value y encadenando varios con &.

Tomando el ejemplo anterior del listado de cuentas de correo vemos que la documentación indica que la llamada de tipo GET se debe realizar sobre /Email/list_pops y que no requiere ningún parámetro adicional obligatorio, por lo que la URL a la que llamar quedaría de la siguiente forma:

https://tudominio.com:2083/execute/Email/list_pops

Ejemplo de uso, vaciando la bandeja de SPAM

Continuando con los ejemplos, queremos automatizar el vaciado de la bandeja de SPAM de todas nuestras cuentas de correo. La operación clear_spam_box elimina el contenido de la carpeta Spam de todas las direcciones de la cuenta, incluida la cuenta principal. Es una acción destructiva: revisa primero el alcance y confirma que no necesitas recuperar ningún mensaje.

Siguiendo el ejemplo anterior la llamada usando cURL sería (para las pruebas recomendamos usar un cliente REST como Insomnia):

curl --config "$HOME/.config/cpanel-api/curl.conf" \
'https://example.com:2083/execute/SpamAssassin/clear_spam_box'

Esta misma llamada desde cPanel se podría realizar de la siguiente forma:

$username = "USUARIO_CPANEL";
$token = getenv('CPANEL_API_TOKEN');
$domain = "DOMINIOCPANEL.COM";
 
$query = 'https://'.$domain.':2083/execute/SpamAssassin/clear_spam_box';
 
$curl = curl_init();
curl_setopt($curl, CURLOPT_HEADER,0);               
curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);       
$header[0] = "Authorization: cpanel " . $username.":".$token . "\n\r";
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);    
curl_setopt($curl, CURLOPT_URL, $query);          
$result = curl_exec($curl);
if ($result == false) {
    error_log("curl_exec threw error \"" . curl_error($curl) . "\" for $query");   
                                                   
}
curl_close($curl);
 
print $result;

Si usas un framework PHP o Composer, tienes acceso a librerías como Guzzle que simplifican las llamadas GET y POST. En Laravel puedes usar su cliente HTTP.

use Illuminate\Support\Facades\Http;

$username = "CPANEL_USUARIO";
$token = getenv('CPANEL_API_TOKEN');
$domain = "DOMINIO";
 
$url = 'https://'.$domain.':2083/execute/SpamAssassin/clear_spam_box';
$response = Http::withToken($username . ':' . $token, 'cpanel')->get($url);
$response->json();

Ejemplo de uso, listando las cuentas FTP desde PHP

Si queremos obtener un listado de las cuentas FTP creadas, tras indagar en la documentación damos con /Ftp/list_ftp, por lo que nuestro ejemplo anterior nos valdría para hacer la llamada desde Laravel, modificando la url:

use Illuminate\Support\Facades\Http;

$username = "CPANEL_USUARIO";
$token = getenv('CPANEL_API_TOKEN');
$domain = "DOMINIO";
 
$url = 'https://'.$domain.':2083/execute/Ftp/list_ftp';
$response = Http::withToken($username . ':' . $token, 'cpanel')->get($url);
$response->json();

Ejemplo de uso, creando cuenta de correo desde PHP

La operación histórica para crear una cuenta es /Email/add_pop, aunque cPanel recomienda usar UserManager::create_user en integraciones nuevas. La contraseña del buzón nunca debe ir en una URL ni en una petición GET: las URLs quedan habitualmente en historiales, registros y herramientas de monitorización. Envíala en el cuerpo de una petición POST y obtén tanto esta contraseña como el token desde un almacén de secretos protegido.

use Illuminate\Support\Facades\Http;

$username = "CPANEL_USUARIO";
$token = getenv('CPANEL_API_TOKEN');
$domain = "DOMINIO";

$url = 'https://'.$domain.':2083/execute/Email/add_pop';
$response = Http::withToken($username . ':' . $token, 'cpanel')
    ->asForm()
    ->post($url, [
        'email' => 'cuenta@tudominio.com',
        'password' => getenv('MAILBOX_INITIAL_PASSWORD'),
    ]);
$response->json();

No registres el cuerpo de esta petición y elimina o rota la contraseña inicial después de entregarla por un canal seguro al titular del buzón.

Los expuestos son ejemplos básicos para que puedas familiarizarte con rapidez con la API de cPanel, no obstante todas las llamadas se pueden combinar formando flujos complejos para automatizar tareas tediosas, o incluso integrar con otros programas de los que disponga la empresa o startup.

También te puede ayudar

¿Algo no cuadra o ha cambiado? Cuéntanoslo y lo revisamos.