Cómo enviar correos automáticos con Bash y Postfix en Debian 13: scripts interactivos, alertas, HTML y archivos adjuntos

Serie Postfix — Parte 2 | OPERSLINUX

En el tutorial anterior aprendimos a instalar y configurar Postfix en Debian 13 para enviar correos electrónicos mediante servidores SMTP externos, como HostGator y Gmail.

Ahora vamos a aprovechar esa configuración para desarrollar nuestros propios scripts en Bash y automatizar el envío de mensajes desde Linux.

A diferencia de un script que tiene el destinatario, remitente y mensaje escritos directamente en su código, en este tutorial crearemos una herramienta interactiva que nos preguntará qué queremos enviar, a quién, desde qué dirección, con qué asunto y si deseamos adjuntar algún archivo.

También aprenderemos a enviar mensajes HTML, generar alertas automáticas del sistema y programar notificaciones utilizando cron.

1. Requisitos previos

Para seguir este tutorial necesitaremos:

  • Debian GNU/Linux 13.
  • Postfix instalado y configurado con un servidor SMTP externo.
  • Bash y acceso a la terminal.
  • Una cuenta de correo autorizada para enviar mensajes.
  • Conocimientos básicos sobre comandos de Linux.

Primero comprobamos que Postfix esté instalado:

dpkg -l | grep postfix

Después verificamos su configuración:

sudo postfix check

Consultamos el servidor SMTP configurado:

postconf relayhost

Por ejemplo, si utilizamos Gmail, podríamos encontrar:

relayhost = [smtp.gmail.com]:587

Si utilizamos HostGator, aparecerá el servidor SMTP correspondiente a nuestra cuenta.

También comprobaremos que existe la interfaz compatible con Sendmail:

ls -l /usr/sbin/sendmail

Aunque estamos utilizando Postfix, esta interfaz permite que los scripts entreguen mensajes al sistema de correo local.

2. ¿Cómo funciona el envío de correos desde Bash?

Nuestro programa utilizará el siguiente proceso:

USUARIO
   |
   v
SCRIPT BASH
   |
   | Solicita remitente,
   | destinatario, asunto,
   | mensaje y adjuntos
   |
   v
/usr/sbin/sendmail
   |
   v
POSTFIX
   |
   | SMTP autenticado y TLS
   v
HOSTGATOR / GMAIL
   |
   v
DESTINATARIO

Bash se encargará de preparar el mensaje.

Postfix lo recibirá y lo enviará mediante el servidor SMTP que configuramos anteriormente.

Es importante recordar que la dirección del remitente debe estar autorizada por nuestro proveedor SMTP. El hecho de que nuestro programa permita escribir una dirección no significa que podamos utilizar identidades ajenas.

3. Crear nuestro primer correo desde Bash

Antes de desarrollar el programa interactivo, realizaremos una prueba sencilla.

Ejecutamos:

/usr/sbin/sendmail -t <<'EOF'
To: [email protected]
From: [email protected]
Subject: Prueba de Bash y Postfix
Content-Type: text/plain; charset=UTF-8

Hola.

Este mensaje fue creado desde Bash
y enviado mediante Postfix en Debian 13.
EOF

Debemos sustituir las direcciones por cuentas reales.

Explicación

/usr/sbin/sendmail es la interfaz compatible que Postfix proporciona para recibir mensajes locales.

-t indica que los destinatarios se obtendrán de las cabeceras del mensaje.

<<'EOF' inicia un documento heredado (heredoc) que permite enviar varias líneas de texto al comando.

To: identifica al destinatario.

From: identifica al remitente.

Subject: establece el asunto.

Content-Type: indica el formato del mensaje.

La línea vacía después de las cabeceras separa estas del contenido del correo.

4. Crear nuestro programa interactivo

Ahora desarrollaremos un programa que permita introducir los datos desde la terminal.

Su funcionamiento será parecido al siguiente:

=========================================
       OPERSLINUX - CORREO BASH
=========================================

Correo del remitente:
> [email protected]

Correo del destinatario:
> [email protected]

Asunto:
> Prueba desde Debian 13

Tipo de mensaje:
1) Texto normal
2) HTML

Selecciona una opción:
> 1

Escribe el mensaje.
Para finalizar, escribe FIN en una línea:

Hola.

Este es un mensaje de prueba.
Saludos desde Debian 13.
FIN

¿Deseas adjuntar un archivo? (s/n):
> n

¿Enviar correo? (s/n):
> s

Mensaje aceptado por Postfix.

La ventaja es que podremos ejecutar el mismo script tantas veces como queramos, sin editar su código para cambiar los datos del correo.

5. Crear el archivo enviar-correo.sh

Primero creamos una carpeta para guardar nuestros scripts:

mkdir -p ~/scripts-postfix

Entramos:

cd ~/scripts-postfix

Creamos el archivo:

nano enviar-correo.sh

Agregamos el siguiente código:

#!/usr/bin/env bash

# ==========================================================
# OPERSLINUX
# Programa interactivo de correo con Bash y Postfix
# Debian GNU/Linux 13
# ==========================================================

set -o pipefail

# ----------------------------------------------------------
# 1. COMPROBAR DEPENDENCIAS
# ----------------------------------------------------------

for comando in base64 mktemp basename tr date; do

    if ! command -v "$comando" >/dev/null 2>&1; then
        printf 'Error: falta el comando %s\n' "$comando" >&2
        exit 1
    fi

done

if [[ ! -x /usr/sbin/sendmail ]]; then
    echo "Error: no se encontró /usr/sbin/sendmail."
    exit 1
fi

# ----------------------------------------------------------
# 2. VALIDAR DIRECCIONES DE CORREO
# ----------------------------------------------------------

validar_correo() {

    local correo="$1"

    [[ "$correo" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]

}

leer_correo() {

    local etiqueta="$1"
    local valor

    while true; do

        read -r -p "$etiqueta: " valor || return 1

        if validar_correo "$valor"; then
            printf '%s' "$valor"
            return 0
        fi

        echo "Dirección no válida. Intenta nuevamente." >&2

    done

}

# ----------------------------------------------------------
# 3. MOSTRAR ENCABEZADO
# ----------------------------------------------------------

echo
echo "=========================================="
echo "       OPERSLINUX - CORREO BASH"
echo "=========================================="
echo

# ----------------------------------------------------------
# 4. SOLICITAR REMITENTE Y DESTINATARIO
# ----------------------------------------------------------

REMITENTE=$(leer_correo "Correo del remitente") || exit 1

DESTINATARIO=$(leer_correo "Correo del destinatario") || exit 1

echo

# ----------------------------------------------------------
# 5. SOLICITAR ASUNTO
# ----------------------------------------------------------

while true; do

    read -r -p "Asunto: " ASUNTO || exit 1

    if [[ -n "$ASUNTO" &&
          "$ASUNTO" != *$'\r'* &&
          "$ASUNTO" != *$'\n'* ]]; then
        break
    fi

    echo "El asunto no puede estar vacío."

done

echo

# ----------------------------------------------------------
# 6. ELEGIR EL FORMATO
# ----------------------------------------------------------

echo "Tipo de mensaje:"
echo "1) Texto normal"
echo "2) HTML"
echo

while true; do

    read -r -p "Selecciona una opción [1-2]: " OPCION || exit 1

    case "$OPCION" in

        1)
            TIPO="text/plain"
            NOMBRE_TIPO="Texto normal"
            break
            ;;

        2)
            TIPO="text/html"
            NOMBRE_TIPO="HTML"
            break
            ;;

        *)
            echo "Selecciona 1 o 2."
            ;;

    esac

done

# ----------------------------------------------------------
# 7. CREAR ARCHIVOS TEMPORALES
# ----------------------------------------------------------

umask 077

MENSAJE_TMP=$(mktemp) || exit 1

CORREO_TMP=$(mktemp) || {
    rm -f -- "$MENSAJE_TMP"
    exit 1
}

trap 'rm -f -- "$MENSAJE_TMP" "$CORREO_TMP"' EXIT

# ----------------------------------------------------------
# 8. SOLICITAR EL CONTENIDO
# ----------------------------------------------------------

echo
echo "Escribe tu mensaje."
echo "Para finalizar, escribe FIN en una línea."
echo

while IFS= read -r LINEA; do

    if [[ "$LINEA" == "FIN" ]]; then
        break
    fi

    printf '%s\n' "$LINEA" >> "$MENSAJE_TMP"

done

if [[ ! -s "$MENSAJE_TMP" ]]; then
    echo "Error: el mensaje está vacío."
    exit 1
fi

# ----------------------------------------------------------
# 9. SOLICITAR ARCHIVO ADJUNTO
# ----------------------------------------------------------

ADJUNTO=""

echo

read -r -p "¿Deseas adjuntar un archivo? (s/n): " RESPUESTA || exit 1

if [[ "$RESPUESTA" =~ ^[sS]$ ]]; then

    read -r -p "Ruta del archivo: " ADJUNTO || exit 1

    if [[ ! -f "$ADJUNTO" || ! -r "$ADJUNTO" ]]; then
        echo "Error: el archivo no existe o no puede leerse."
        exit 1
    fi

fi

# ----------------------------------------------------------
# 10. MOSTRAR RESUMEN
# ----------------------------------------------------------

echo
echo "=========================================="
echo "             RESUMEN"
echo "=========================================="
echo "Remitente:    $REMITENTE"
echo "Destinatario: $DESTINATARIO"
echo "Asunto:       $ASUNTO"
echo "Formato:      $NOMBRE_TIPO"
echo "Adjunto:      ${ADJUNTO:-Ninguno}"
echo "=========================================="
echo

read -r -p "¿Enviar correo? (s/n): " CONFIRMAR || exit 1

if [[ ! "$CONFIRMAR" =~ ^[sS]$ ]]; then
    echo "Envío cancelado."
    exit 0
fi

# ----------------------------------------------------------
# 11. CONSTRUIR EL MENSAJE MIME
# ----------------------------------------------------------

ASUNTO_B64=$(printf '%s' "$ASUNTO" | base64 -w 0)

BOUNDARY="OPERSLINUX_$(date +%s)_$$_${RANDOM}"

{
    printf 'To: %s\n' "$DESTINATARIO"
    printf 'From: %s\n' "$REMITENTE"
    printf 'Subject: =?UTF-8?B?%s?=\n' "$ASUNTO_B64"
    printf 'MIME-Version: 1.0\n'

    if [[ -n "$ADJUNTO" ]]; then

        printf 'Content-Type: multipart/mixed; boundary="%s"\n' "$BOUNDARY"
        printf '\n'

        printf -- '--%s\n' "$BOUNDARY"
        printf 'Content-Type: %s; charset=UTF-8\n' "$TIPO"
        printf 'Content-Transfer-Encoding: base64\n'
        printf '\n'

        base64 -w 76 "$MENSAJE_TMP"
        printf '\n'

        NOMBRE_ARCHIVO=$(basename -- "$ADJUNTO")

        NOMBRE_SEGURO=$(printf '%s' "$NOMBRE_ARCHIVO" |
            LC_ALL=C tr -c 'A-Za-z0-9._-' '_')

        printf -- '--%s\n' "$BOUNDARY"
        printf 'Content-Type: application/octet-stream\n'
        printf 'Content-Transfer-Encoding: base64\n'
        printf 'Content-Disposition: attachment; filename="%s"\n' "$NOMBRE_SEGURO"
        printf '\n'

        base64 -w 76 "$ADJUNTO"
        printf '\n'

        printf -- '--%s--\n' "$BOUNDARY"

    else

        printf 'Content-Type: %s; charset=UTF-8\n' "$TIPO"
        printf 'Content-Transfer-Encoding: base64\n'
        printf '\n'

        base64 -w 76 "$MENSAJE_TMP"
        printf '\n'

    fi

} > "$CORREO_TMP"

# ----------------------------------------------------------
# 12. ENTREGAR EL MENSAJE A POSTFIX
# ----------------------------------------------------------

echo
echo "Entregando mensaje a Postfix..."

if /usr/sbin/sendmail -oi -t -f "$REMITENTE" < "$CORREO_TMP"; then

    echo "Mensaje aceptado por el sistema local."
    echo "Consulta los registros para verificar su entrega."

else

    echo "Error: no fue posible entregar el mensaje a Postfix."
    exit 1

fi

Nota: este programa es una herramienta educativa para uso local. La validación de direcciones es básica y no cubre todos los formatos admitidos por los estándares de correo. Para producción conviene añadir límites de tamaño, controles de frecuencia y una implementación MIME más completa.

6. Explicación de los elementos principales del script

6.1. ¿Qué significa #!/usr/bin/env bash?

#!/usr/bin/env bash

Esta línea se conoce como shebang.

Indica que el archivo debe ejecutarse utilizando el intérprete Bash.

6.2. ¿Para qué sirve read?

read -r -p "Asunto: " ASUNTO

El comando read permite solicitar información al usuario.

El parámetro -r evita que las barras invertidas sean interpretadas como caracteres especiales.

El parámetro -p muestra un mensaje antes de solicitar la entrada.

La variable ASUNTO almacena el valor introducido.

6.3. ¿Qué son las variables?

Una variable permite almacenar información.

Por ejemplo:

DESTINATARIO="[email protected]"

Para consultar su contenido:

echo "$DESTINATARIO"

Las comillas dobles ayudan a conservar correctamente los espacios y caracteres del valor.

6.4. ¿Cómo funcionan las condiciones?

Nuestro programa utiliza condiciones como:

if [[ -f "$ADJUNTO" ]]; then
    echo "El archivo existe."
fi

if inicia la condición.

[[ ... ]] evalúa una expresión.

-f comprueba si existe un archivo regular.

then indica qué instrucciones ejecutar.

fi finaliza la condición.

6.5. ¿Cómo funcionan los ciclos?

También utilizamos:

while true; do

    read -r -p "Asunto: " ASUNTO

    [[ -n "$ASUNTO" ]] && break

done

Este ciclo solicita un asunto hasta que el usuario introduzca un valor no vacío.

while permite repetir instrucciones.

do inicia el bloque.

done lo finaliza.

break interrumpe el ciclo.

7. Dar permisos y ejecutar el programa

Guardamos el archivo y ejecutamos:

chmod 700 enviar-correo.sh

Esto permite que el propietario lea, modifique y ejecute el script, mientras que los demás usuarios no tendrán permisos.

Ahora lo ejecutamos:

./enviar-correo.sh

El programa solicitará los datos del correo.

8. Primera práctica: enviar un mensaje de texto

Ejecutamos:

./enviar-correo.sh

Introducimos el remitente y destinatario.

Después escribimos el asunto.

Seleccionamos:

1) Texto normal

Escribimos:

Hola.

Este es mi primer correo interactivo
utilizando Bash y Postfix.

Saludos desde Debian 13.
FIN

Cuando el programa pregunte si queremos adjuntar un archivo, respondemos n.

Finalmente confirmamos el envío.

Si el mensaje es aceptado por Postfix, el programa mostrará una confirmación local.

Para comprobar el transporte:

postqueue -p

También consultamos los registros:

sudo journalctl --since "10 minutes ago" --no-pager | grep -i postfix

9. Segunda práctica: enviar un correo HTML

Los mensajes HTML permiten incorporar títulos, colores, tablas y enlaces.

Ejecutamos nuevamente:

./enviar-correo.sh

Seleccionamos:

2) HTML

Introducimos:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Correo de prueba</title>
</head>
<body style="font-family: Arial, sans-serif;">

    <h1 style="color: #008a45;">
        Notificación desde Debian 13
    </h1>

    <p>
        Este mensaje fue enviado utilizando
        <strong>Bash y Postfix</strong>.
    </p>

    <p>
        Saludos desde OPERSLINUX.
    </p>

</body>
</html>
FIN

El script establecerá el tipo de contenido:

Content-Type: text/html; charset=UTF-8

Esto permite que el cliente de correo interprete el mensaje como HTML.

Para correos electrónicos es recomendable utilizar estilos sencillos en línea, ya que algunos clientes de correo no admiten todas las características de CSS.

10. Tercera práctica: enviar un archivo adjunto

Primero creamos un archivo de prueba:

printf 'Reporte de prueba\nServidor Debian 13\n' > reporte.txt

Ejecutamos:

./enviar-correo.sh

Cuando aparezca:

¿Deseas adjuntar un archivo? (s/n):

Respondemos:

s

Indicamos la ruta:

./reporte.txt

El programa comprobará que el archivo exista y sea legible.

Después lo incorporará al mensaje utilizando MIME.

¿Qué es Base64?

Base64 permite representar datos binarios mediante caracteres de texto.

En nuestro programa utilizamos:

base64 -w 76 "$ADJUNTO"

Esto codifica el archivo y divide la salida en líneas de hasta 76 caracteres.

El cliente de correo podrá interpretar esa sección como un archivo adjunto.

Debemos recordar que Base64 aumenta el tamaño de los datos aproximadamente un 33 %, por lo que conviene evitar archivos demasiado grandes.

11. ¿Qué es MIME?

MIME significa Multipurpose Internet Mail Extensions.

Permite incorporar diferentes tipos de contenido dentro de un correo electrónico.

Por ejemplo:

MENSAJE MIME
│
├── Cabeceras
│
├── Contenido HTML
│
└── Archivo adjunto

Cuando un mensaje contiene varias partes utilizamos:

Content-Type: multipart/mixed

Las partes se separan mediante un identificador llamado boundary.

Nuestro script genera ese identificador automáticamente.

12. Crear alertas automáticas del almacenamiento

Hasta ahora hemos desarrollado un programa interactivo.

Pero Bash también permite enviar correos automáticamente cuando ocurre determinada condición.

Por ejemplo, podemos crear una alerta cuando el almacenamiento de nuestro servidor supere el 80 %.

Creamos:

nano alerta-disco.sh

Agregamos:

#!/usr/bin/env bash

# ==========================================
# OPERSLINUX - ALERTA DE DISCO
# ==========================================

DESTINATARIO="[email protected]"
REMITENTE="[email protected]"

LIMITE=80

USO=$(df -P / | awk 'NR==2 {
    gsub("%", "", $5);
    print $5
}')

if [[ ! "$USO" =~ ^[0-9]+$ ]]; then
    echo "Error al consultar el uso del disco." >&2
    exit 1
fi

if (( USO >= LIMITE )); then

    ASUNTO="Alerta: almacenamiento al ${USO}%"

    /usr/sbin/sendmail -oi -t -f "$REMITENTE" <<EOF
To: $DESTINATARIO
From: $REMITENTE
Subject: $ASUNTO
Content-Type: text/plain; charset=UTF-8

ALERTA DEL SISTEMA

La partición raíz ha alcanzado el ${USO}%.

Límite configurado: ${LIMITE}%.

Servidor: $(hostname)

Revisa el espacio disponible.
EOF

fi

Debemos sustituir las direcciones por cuentas reales.

Explicación

La instrucción:

df -P /

consulta el uso de almacenamiento del sistema de archivos que contiene /.

Después:

awk 'NR==2 {gsub("%", "", $5); print $5}'

extrae el porcentaje de uso.

Si el valor es igual o superior al límite, el script construye y envía una alerta.

Por ejemplo:

Uso actual: 85%
Límite: 80%

Resultado: enviar alerta.

Si el uso es inferior al límite, no enviará ningún mensaje.

13. Programar las alertas con cron

Cron permite ejecutar tareas periódicamente sin intervención del usuario.

Comprobamos si está instalado:

systemctl status cron --no-pager

Si no lo tenemos:

sudo apt install cron

Lo habilitamos:

sudo systemctl enable --now cron

Damos permisos al script:

chmod 700 alerta-disco.sh

Abrimos la configuración de cron:

crontab -e

Agregamos:

*/30 * * * * /home/usuario/scripts-postfix/alerta-disco.sh

Debemos sustituir la ruta por la ubicación real del archivo.

¿Qué significa */30 * * * *?

Los cinco campos representan:

MINUTO HORA DÍA MES DÍA_SEMANA

La expresión */30 en el campo de minutos indica que el programa se ejecutará cada 30 minutos.

Si el almacenamiento continúa por encima del límite, el script enviará una alerta en cada ejecución. Para producción conviene agregar un control que evite notificaciones repetitivas.

14. Enviar notificaciones de respaldos

Otra aplicación útil es enviar un correo cuando termina una copia de seguridad.

Creamos:

nano respaldo-notificacion.sh

Agregamos:

#!/usr/bin/env bash

DESTINATARIO="[email protected]"
REMITENTE="[email protected]"

DESTINO="$HOME/Respaldos"

mkdir -p "$DESTINO" || exit 1

ARCHIVO="$DESTINO/respaldo-$(date +%F).tar.gz"

if tar -czf "$ARCHIVO" -C "$HOME" Documentos; then

    ESTADO="CORRECTO"
    DETALLE="El respaldo finalizó correctamente."

else

    ESTADO="ERROR"
    DETALLE="El respaldo presentó un problema."

fi

/usr/sbin/sendmail -oi -t -f "$REMITENTE" <<EOF
To: $DESTINATARIO
From: $REMITENTE
Subject: Respaldo - $ESTADO
Content-Type: text/plain; charset=UTF-8

NOTIFICACIÓN DE RESPALDO

Estado: $ESTADO

$DETALLE

Archivo previsto:
$ARCHIVO

Fecha: $(date)

Servidor: $(hostname)
EOF

Este ejemplo supone que existe la carpeta ~/Documentos.

Debemos ajustar las rutas y direcciones a nuestro sistema.

También conviene comprobar la integridad de los respaldos y conservar copias fuera del servidor original.

15. Recomendaciones de seguridad

Al utilizar Bash y Postfix debemos considerar algunos aspectos.

No guardar contraseñas SMTP en los scripts. Postfix ya tiene configuradas las credenciales necesarias para conectarse al proveedor.

Utilizar remitentes autorizados. El programa interactivo permite escribir el remitente, pero debemos respetar las identidades permitidas por nuestro servidor SMTP.

Validar los datos. Las cabeceras y direcciones deben revisarse para reducir errores y riesgos de inyección.

Limitar los adjuntos. Los archivos grandes pueden superar las restricciones del proveedor y consumir recursos innecesariamente.

Proteger los scripts. Podemos utilizar permisos restrictivos cuando contengan rutas, configuraciones o información privada.

Evitar envíos repetitivos. Las alertas programadas deben incorporar controles para no saturar los buzones.

16. Solucionar problemas frecuentes

El correo no llega

Consultamos la cola:

postqueue -p

Después revisamos los registros:

sudo journalctl --since "15 minutes ago" --no-pager | grep -i postfix

No existe /usr/sbin/sendmail

Comprobamos:

ls -l /usr/sbin/sendmail

Y:

dpkg -l | grep postfix

Si Postfix no está instalado, debemos completar el primer tutorial de la serie.

Permission denied

Puede indicar que el script no tiene permisos de ejecución.

Ejecutamos:

chmod 700 enviar-correo.sh

Después:

./enviar-correo.sh

El correo HTML aparece como texto

Debemos comprobar que el mensaje tenga la cabecera:

Content-Type: text/html; charset=UTF-8

También debemos verificar que exista una línea vacía entre las cabeceras y el contenido.

El adjunto no aparece

Comprobamos que el archivo exista:

ls -lh reporte.txt

También debemos verificar que el usuario tenga permisos para leerlo y que la estructura MIME sea válida.

Cron no ejecuta el script

Comprobamos:

systemctl status cron --no-pager

Y:

crontab -l

Debemos utilizar rutas absolutas y recordar que cron puede ejecutar los programas con un entorno más limitado que nuestra terminal habitual.

17. Ejercicios para practicar

Una vez que el programa funcione podemos realizar las siguientes prácticas:

  1. Enviar un correo de texto utilizando el programa interactivo.
  2. Enviar un mensaje HTML con títulos, colores y enlaces.
  3. Adjuntar un archivo PDF o CSV.
  4. Crear una alerta de almacenamiento y comprobar su funcionamiento.
  5. Programar una tarea mediante cron.
  6. Desarrollar un script que avise cuando un servicio deje de funcionar.

Estos ejercicios permiten aplicar variables, condiciones, ciclos, lectura de datos y automatización en situaciones reales.

Conclusión

En esta segunda parte de nuestra serie sobre Postfix aprendimos a utilizar Bash para enviar correos electrónicos desde Debian 13.

Comenzamos con una prueba sencilla mediante la interfaz compatible con Sendmail y después desarrollamos un programa interactivo que solicita el remitente, destinatario, asunto, mensaje y archivo adjunto.

También aprendimos a construir mensajes HTML, utilizar MIME, generar alertas del sistema y programar tareas mediante cron.

La ventaja principal es que Bash se encarga de preparar el contenido y Postfix se encarga del transporte del correo.

Gracias a esta separación podemos crear herramientas de automatización sin almacenar contraseñas SMTP dentro de nuestros scripts.

En la siguiente parte de nuestra serie aprenderemos a utilizar PHP puro con Postfix para desarrollar formularios HTML, validar información y enviar mensajes desde aplicaciones web.

OPERSLINUX — Aprende Linux, servidores y programación mediante la práctica.

Deja un comentario