SMTP con Postfix 3.10.12
Este laboratorio utiliza Postfix 3.10.12. Comprueba que una misma sesión:
- anuncia capacidades ESMTP mediante
EHLO - acepta un usuario local conocido
- rechaza un usuario local inexistente
- rechaza un destinatario externo cuando el origen no pertenece a
mynetworks - vuelve a estado inicial después de retirar el contenedor
La prueba no envía DATA, no entrega mensajes y no valida AUTH, STARTTLS, submission, cola, SPF, DKIM, DMARC, catch-all ni greylisting.
Aprovisionamiento
Sección titulada «Aprovisionamiento»El contenedor usa Debian 13.1 y publica Postfix solo en 127.0.0.1:2525. La instalación se realiza dentro del recurso desechable:
docker run -d --name offsec-kb-smtp-lab \ -p 127.0.0.1:2525:25 debian:13.1-slim sleep infinityInstala Postfix sin preguntas interactivas. Después crea el usuario local valid, fija el dominio y arranca el servicio:
docker exec offsec-kb-smtp-lab sh -lc ' export DEBIAN_FRONTEND=noninteractive apt-get update echo "postfix postfix/mailname string example.test" | debconf-set-selections echo "postfix postfix/main_mailer_type string Internet Site" | debconf-set-selections apt-get install -y postfix useradd -M valid postconf -e "myhostname = smtp-lab.example.test" postconf -e "mydomain = example.test" postconf -e "mydestination = example.test, localhost" postconf -e "mynetworks = 127.0.0.0/8" postconf -e "smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination" postfix start'local_recipient_maps conserva el valor de Postfix proxy:unix:passwd.byname $alias_maps. Por eso valid@example.test corresponde al usuario creado y invalid@example.test no.
Diálogo y controles
Sección titulada «Diálogo y controles»Ncat o Netcat permiten ver cada respuesta. Postfix anuncia PIPELINING después de EHLO, pero el ejemplo añade una pausa para que el registro mantenga el orden:
{ sleep 0.3 printf 'EHLO operator.example.test\r\n' sleep 0.3 printf 'MAIL FROM:<sender@source.test>\r\n' sleep 0.3 printf 'RCPT TO:<valid@example.test>\r\n' sleep 0.3 printf 'RSET\r\n' sleep 0.3 printf 'MAIL FROM:<sender@source.test>\r\n' sleep 0.3 printf 'RCPT TO:<invalid@example.test>\r\n' sleep 0.3 printf 'RSET\r\n' sleep 0.3 printf 'MAIL FROM:<sender@source.test>\r\n' sleep 0.3 printf 'RCPT TO:<external@destination.test>\r\n' sleep 0.3 printf 'QUIT\r\n'} | nc 127.0.0.1 2525Resultado saneado:
220 smtp-lab.example.test ESMTP Postfix (Debian)250-smtp-lab.example.test250-PIPELINING250-SIZE 10240000250-VRFY250-ETRN250-STARTTLS250-ENHANCEDSTATUSCODES250-8BITMIME250-DSN250-SMTPUTF8250 CHUNKING250 2.1.0 Ok250 2.1.5 Ok250 2.0.0 Ok250 2.1.0 Ok550 5.1.1 <invalid@example.test>: Recipient address rejected: User unknown in local recipient table250 2.0.0 Ok250 2.1.0 Ok554 5.7.1 <external@destination.test>: Relay access denied221 2.0.0 ByeLos tres códigos prueban decisiones de la fase RCPT TO. No prueban entrega final. RSET descarta el envelope anterior y permite comparar los casos en la misma conexión.
Versión y configuración relevante
Sección titulada «Versión y configuración relevante»docker exec offsec-kb-smtp-lab postconf \ mail_version myhostname mydestination \ local_recipient_maps smtpd_relay_restrictionsLa reproducción registró Postfix 3.10.12, mydestination = example.test, localhost y permit_mynetworks, reject_unauth_destination.
Fallo del laboratorio
Sección titulada «Fallo del laboratorio»La primera ejecución envió todos los comandos al conectar, antes de leer el banner y negociar EHLO. Postfix respondió 554 5.5.0 Error: SMTP protocol synchronization. El fallo pertenecía al cliente de prueba, no a la política de destinatarios. Las pausas permitieron observar las fases en orden.
Cleanup
Sección titulada «Cleanup»docker rm -f offsec-kb-smtp-labnc -zv 127.0.0.1 2525El control final devolvió Connection refused. No quedó listener en loopback. La imagen local no contiene datos del entorno y puede retirarse más tarde mediante el procedimiento normal de mantenimiento de Docker.