🛡️ Cómo usar Wrappers en C para gestionar Asterisk, Servidores de Correo e Inteligencia Artificial desde la Web
Cuando desarrollamos sistemas que necesitan interactuar con Asterisk (PBX), servidores de correo como Postfix/Dovecot, o incluso ejecutar modelos de inteligencia artificial, muchas veces nos encontramos con una limitación importante:
🔒 PHP o tu app web no puede ejecutar comandos privilegiados directamente.
Por temas de seguridad, el usuario www-data
de Apache/Nginx no tiene permisos para borrar correos, reiniciar servicios o ejecutar modelos de IA desde el sistema. ¿La solución? ➤ Un wrapper en C controlado con sudo
.
🧩 ¿Qué es un wrapper en este contexto?
Un wrapper es un programa en C (o Bash/Python) que actúa como intermediario seguro entre tu aplicación web y el sistema operativo. Lo usas para:
- Borrar buzones de forma segura
- Ejecutar comandos como
postmap
,dovecot reload
, etc. - Recargar configuraciones de Asterisk (
module reload
,dialplan reload
) - Ejecutar modelos de IA (como un clasificador en Python o C++)
🛠️ Proyecto completo: sistema_wrapper.c
Este wrapper más avanzado permite ejecutar diferentes operaciones del sistema de forma controlada:
📦 Funcionalidades del wrapper:
- ✅ Eliminar un buzón de correo
- ✅ Recargar Asterisk
- ✅ Ejecutar un modelo IA
- ✅ Registrar todo en un log seguro
- ✅ Validar argumentos
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
const char *LOG_PATH = "/var/log/sistema_wrapper.log";
void registrar_log(const char *operacion, const char *detalle) {
FILE *log = fopen(LOG_PATH, "a");
if (log) {
time_t ahora = time(NULL);
char *tiempo = ctime(&ahora);
tiempo[strcspn(tiempo, "\n")] = 0;
fprintf(log, "[%s] [%s] %s\n", tiempo, operacion, detalle);
fclose(log);
}
}
void eliminar_buzon(const char *email) {
if (strstr(email, "..") || strchr(email, ';')) {
registrar_log("ERROR", "Entrada maliciosa en email");
printf("Entrada inválida.\n");
return;
}
char comando[512];
snprintf(comando, sizeof(comando), "rm -rf /var/mail/vhosts/%s", email);
int r = system(comando);
if (r == 0) {
registrar_log("BUZON", email);
printf("Buzón %s eliminado.\n", email);
} else {
registrar_log("ERROR", "Fallo al eliminar buzón.");
printf("Error al eliminar buzón.\n");
}
}
void recargar_asterisk() {
int r = system("asterisk -rx 'module reload'");
if (r == 0) {
registrar_log("ASTERISK", "Recarga de módulos completada");
printf("Asterisk recargado.\n");
} else {
registrar_log("ERROR", "Fallo al recargar Asterisk");
printf("Error recargando Asterisk.\n");
}
}
void ejecutar_modelo_ia() {
int r = system("python3 /opt/ia/clasificador.py /tmp/mensaje.txt >> /tmp/resultado.txt");
if (r == 0) {
registrar_log("IA", "Modelo ejecutado con éxito");
printf("Modelo IA ejecutado.\n");
} else {
registrar_log("ERROR", "Fallo al ejecutar IA");
printf("Error en ejecución de IA.\n");
}
}
void mostrar_uso() {
printf("Uso: sistema_wrapper [comando] [argumento]\n");
printf("Comandos:\n");
printf(" eliminar-buzon email@dominio.com\n");
printf(" recargar-asterisk\n");
printf(" ejecutar-ia\n");
}
int main(int argc, char *argv[]) {
if (argc < 2) {
mostrar_uso();
return 1;
}
if (strcmp(argv[1], "eliminar-buzon") == 0 && argc == 3) {
eliminar_buzon(argv[2]);
} else if (strcmp(argv[1], "recargar-asterisk") == 0) {
recargar_asterisk();
} else if (strcmp(argv[1], "ejecutar-ia") == 0) {
ejecutar_modelo_ia();
} else {
mostrar_uso();
return 1;
}
return 0;
}
⚙️ Compilación y permisos
gcc -o /usr/local/bin/sistema_wrapper sistema_wrapper.c
chmod +x /usr/local/bin/sistema_wrapper
🔐 Seguridad vía sudoers
sudo visudo
Agrega esta línea:
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/sistema_wrapper
🌐 Llamada desde Laravel o PHP
// Eliminar buzón
shell_exec("sudo /usr/local/bin/sistema_wrapper eliminar-buzon jose@midominio.com");
// Recargar Asterisk
shell_exec("sudo /usr/local/bin/sistema_wrapper recargar-asterisk");
// Ejecutar modelo IA
shell_exec("sudo /usr/local/bin/sistema_wrapper ejecutar-ia");
📊 Log generado
Contenido típico en /var/log/sistema_wrapper.log
:
[2025-07-17 10:23:44] [BUZON] jose@midominio.com
[2025-07-17 10:24:01] [ASTERISK] Recarga de módulos completada
[2025-07-17 10:25:05] [IA] Modelo ejecutado con éxito
🚀 Conclusión
Los wrappers en C son herramientas extremadamente útiles para permitir que tu sistema web realice tareas privilegiadas de forma controlada, segura y auditada. Ya sea para administrar Asterisk, Postfix o ejecutar modelos IA, puedes confiar en este enfoque cuando los permisos o la seguridad del sistema sean una prioridad.
No hay comentarios:
Publicar un comentario