Pagina 1 di 1

Semplice rimpiazzo in bash del comando sendmail

Inviato: sab 15 set 2012, 14:57
da ilmich
Salve a tutti,

sto scrivendo un piccolo demone per la gestione del solo invio di mail tramite il protocollo stmp.
Il perchè non utilizzi mta esterni o ne installi uno ad-hoc, è piu' che altro per un mio esperimento (oltre a non volermi/potermi sobbarcare al momento l'amministrazione di un server smtp che utilizzerei comunque solo per l'invio e non per la ricezione).
Il demone è pronto e funziona anche piuttosto bene pero' ora volevo integrarlo con i servizi piu' blasonati (php/fail2ban e altri) che tipicamente si appoggiano all'eseguibile sendmail per l'invio.. insomma un po' come fanno tutti gli mta che ho superficialmente studiato, avrei bisogno di crearmi un rimpiazzo per il comando sendmail che funzioni secondo le regole del mio demone.

ora, considerando che ho implementato una coda di messaggi su filesystem, il mio clone di sendmail potrebbe essere un semplice script che piazza dei file in una directory ad-hoc.

ad un rapido sguardo l'utilizzo di sendmail non mi pare troppo complesso,(a parte flag e flagghettini vari che affrontero' caso per caso) nel senso che ho visto che viene inviato nello standard input(fino alla pressione di ctrl-d) il messaggio raw con tutti gli header quindi sostanzialmente a me serve redirezionare lo standard input direttamente in un file che decido io.

putroppo non sono un espertone di bash, mi sapete dare qualche dritta su come fare? mi basta un semplice read all'interno dello script per ottenere lo stesso effetto?

spero di essere stato chiaro
ciau

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: sab 15 set 2012, 15:05
da ilmich
mentre scrivevo ho letto che questo tizio ha fatto esattamente quello che serve a me :)

comunque consigli e suggerimenti sono ben accetti :)

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: sab 15 set 2012, 18:17
da targzeta
Esiste il comando 'mail' o non ho capito bene il problema. In pratica invia e riceve posta direttamente utilizzando il demone sendmail.

Se poi vuoi, esiste anche 'mini_sendmail' che è un demone piccolino che rimpiazza sendmail, ovvero si appoggia ad un sendmail attivo su qualche IP e porta, non necessariamente in localhost. Così puoi usare un sendmail di qualche altra macchina :)...sempre che ne trovi una.

Emanuele

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: dom 16 set 2012, 23:14
da ilmich
non ho sicuramente spiegato bene il problema, ma partendo dal tuo suggerimento riguardo al comando mail ho trovato la mia soluzione temporanea che si chiama ssmtp

in pratica riassumendo ho un'applicazione php deployata su un po di server. quest'applicazione deve poter anche inviare delle mail ma vorrei evitare il piu' possibile l'onere di installare un mta ad-hoc.
visto che il sistema standard del php per l'invio delle mail si poggia su sendmail mi serviva una soluzione diversa che pero' fosse anche la piu' "naturale" possibile.

percio' ho chiesto come creare in modo semplice un clone bash al comando sendmail.. ho sviluppato una semplice applicazione java che in soldoni costituisca LA SOLA PARTE DI INVIO di un classico server smtp (dato un indirizzo mail risolve il record mx del dominio, contatta il server smtp, invia la mail secondo il protocollo smtp etc etc etc) in questo modo non installo alcun server smtp, ma tramite un semplicissimo demone invio mail senza dovermi appoggiare nemmeno a mta esterni(questa parte è già testata e funzionante).
mi mancava solo creare il collante fra php e questo software percio' avevo bisogno di un clone di sendmail compatibile.

per ora pero', visto che l'applicazione non è ancora matura in tutte le sue parti, ho deciso di optare per il software che ho trovato, che in pratica dovrebbe essere simile al tuo 'mini_sendmail' dato che si appoggia ad un smtp esterno garantendo pero' la compatibilità con i parametri del comando sendmail.

spero che ora sia riuscito a spiegarmi un po' meglio :D

ciau

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 17 set 2012, 0:12
da targzeta
Sì, tutto chiaro. Dalle specifiche sembra essere proprio uguale a mini_sendmail, che io ho installato qui su Slacky dato che il nostro server apache è in chroot jail e mi serviva un modo per far comunicare php con il vero server sendmail.

Emanuele

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 17 set 2012, 0:28
da ilmich
infatti non so se ho capito male io la home, ma il mini_sendmail non l'ho poi utilizzato perchè apparentemente sembrava volesse collegarsi comunque ad un sendmail.
al momento invece sto utilizzato ssmtp con l'smtp di gmail e devo dire che una volta configurato, un sacco di servizi e servizietti che inviano mail di alert (fail2ban e affini) funzionano out-of-the box.

grazie ancora per gli spunti :thumbright:

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 17 set 2012, 15:10
da ilmich
Offtopic: volevo riportare la mia esperienza con ssmtp scrivendo un micro tutorial qui sul wiki(e magari poi riportarlo pure sulla neonata documentazione ufficiale). se siete d'accordo a chi devo chiedere affinche abbia i diritti giusti per farlo!???!
inoltre non l'ho trovato ma se c'e' un format che è meglio seguire (una traccia o comunque un qualche slacky's way) me la potreste indicare?

ciau

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 17 set 2012, 15:56
da targzeta
Offtopic: Ti ho aggiunto al gruppo wiki del forum. Prova a vedere se riesci a loggarti anche nella homepage di Slacky (stesse credenziali). Ora non ricordo se c'è uno stile ufficiale sulla documentazione. Quando crei un nuovo articolo, però, troverai due link a mediawiki, io in genere seguo quelli.

Unica nota, se vuoi fare riferimenti interni alla wiki, usa [[articolo]] oppure [[articolo|nome alternativo]] e non cose come http://www.slacky....

Emanuele

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 17 set 2012, 16:05
da ilmich
Offtopic: Grazie 1000... funziona :thumbright:
per quanto riguarda le guide seguiro' il tuo consiglio :)

grazie ancora

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 1 ott 2012, 1:35
da ilmich
riprendo questo post per chiedere una mano ai maestri della shell :D
utilizzando ssmtp come rimpiazzo diretto a sendmail ( un brutale link simbolico) la mia applicazione php rallenta il tempo necessario alla transazione smtp(che è di circa un paio di secondi).
percio' riprendendo un po' l'esigenza originale del post ho scritto questo semplice script(prendendo spunto da qui) che andro' a sostituire al binario /usr/sbin/sendmail

Codice: Seleziona tutto

#!/bin/bash

LOGDIR=/tmp/sendmail-sim
NOW=$(date +%Y%m%dT%H%M)
CNT=1
FILENAME="$LOGDIR/$NOW.$CNT.mail"

while [ -f $FILENAME ]; do
    CNT=$(($CNT + 1))
    FILENAME="$LOGDIR/$NOW.$CNT.mail"
done

echo "/usr/sbin/ssmtp $* << EOF" >> $FILENAME
cat - >> $FILENAME
echo "EOF" >> $FILENAME

exit 0
questo script nn fa altro che, ad ogni chiamata al binario sendmail (nel mio caso il php) creare all'interno di una directory temporanea un file con, per esempio, questo contenuto

Codice: Seleziona tutto

/usr/sbin/ssmtp -t -i << EOF
To: xxxxxxx@xxxxx.com
Subject: test
X-PHP-Originating-Script: 1000:functions.inc.php
From: xxxxxxxx@xxxxxx.com
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary = 10983184325068cde89b4454.43655820
This is a MIME encoded message.

--10983184325068cde89b4454.43655820
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: base64


--10983184325068cde89b4454.43655820
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: base64

Q2lhbyBwaXBwbw==


EOF
come potete notare i file cosi' creati sono degli script veri e propri che inviano la mail tramite il binario ssmtp

fatto questo ho messo in cron ogni minuto quest'altro semplicissimo script

Codice: Seleziona tutto

#!/bin/sh

for i in `ls *.mail`
do
    (
	name=`basename $i .mail`
	echo "send mail $i"
        /bin/sh $i 2>$name.error
        RETVAL=$?
        [ $RETVAL -eq 0 ] && echo "ok" && rm $name.error && mv $i $i.sent
        [ $RETVAL -ne 0 ] && echo "failed"
    ) &
done
che nn fa altro che scansionare la directory con tutti gli script mail creati e li esegue in background.
ho fatto un po' di prove e il tutto funziona 'onestamente'.. pero' chiedo il vostro aiuto per lo spooler (l'ultimo script per intenderci) per

1) limitare il numero di processi lanciati in background in modo che se ci sono 10..100..1000 mail non si ingolfi il sistema. avevo pensato ad un

Codice: Seleziona tutto

ps aux | grep ssmtp | wc -l
da utilizzare per contare i processi già forkati ma non saprei se è la strada migliore

2) loggare su un file in un formato simile a quelli utilizzato per i log di sistema (ho dato uno sguardo al binario logger, ma mi pare che quello loggi sul log di sistema, a me invece servirebbe un log ad-hoc)

3) eventuali accorgimenti / miglioramenti tenendo conto che soprattutto l'ultimo script è ancora una bozza

grazie in anticipo

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 1 ott 2012, 3:18
da ilmich
ci ho giocato ancora un po' ed ecco lo script finale che scoda da filesystem con controllo di numero massimo di processi

Codice: Seleziona tutto

#!/bin/sh

. /etc/ssmtpooler

MAILDIR=$BASEDIR/out-queue
PROCDIR=$BASEDIR/proc-queue/$$

for i in 1 2 3 4 5 6 7 8 9 10
do
    if [ ! -f $BASEDIR/lock ]; then
	touch $BASEDIR/lock #simple lock to avoid concurrency during moving mails to process queue
	mkdir -p $PROCDIR
	mails=`ls $MAILDIR/*.mail`
	#move mail to process queue
	for i in $mails
	do
	    mv $i $PROCDIR/`basename $i`
	done
	rm $BASEDIR/lock # release lock
	
	#process queue
	for x in $mails
	do
	    (
		name=`basename $x`
		# copy mail to temporary file
		tmp=`mktemp /tmp/ssmtpooler.XXXXXX`
		cat $PROCDIR/$name > $tmp

		# send mail
	        /bin/sh $tmp
	        RETVAL=$?
	        [ $RETVAL -eq 0 ] && echo "ok"
	        [ $RETVAL -ne 0 ] && echo "failed" && mv $tmp $MAILDIR/$name # in case of error move again to original queue	        
	        [ -f $tmp ] && rm $tmp
	    ) &

    	    nfork=`ps aux | grep ssmtp | grep -v grep | wc -l`
            while [ $nfork -gt 10 ]
	    do
		sleep 1
		nfork=`ps aux | grep ssmtp | grep -v grep | wc -l`
	    done
        done
        #clean process queue
        rm -r $PROCDIR
        exit 0;
    fi
    sleep 1
done

exit 1
il controllo dei processi l'ho fatto utilizzando ps e contando le linee risultanti.
lo script dovrebbe essere thread safe in quanto ad ogni lancio viene creata una nuova directory in base al PID, all'interno della quale vengono poi spostate le mail presenti in quel momento nella coda. per garantire l'esclusività di questa operazione viene creato un file di lock.
percio' se per caso lo script impiega piu' tempo del dovuto e ne dovesse partire un altro (ricordo che questo script è in cron periodico) non si dovrebbero intrecciare e inviare mail doppie.

mi resta solo da trovare un modo decente per loggare le attività e gli errori e dovrebbe essere grosso modo finito

come posso fare?

ciau

Re: Semplice rimpiazzo in bash del comando sendmail

Inviato: lun 1 ott 2012, 11:41
da ilmich
miklos ha scritto:mi resta solo da trovare un modo decente per loggare le attività e gli errori e dovrebbe essere grosso modo finito

come posso fare?
ho risolto. in pratica utilizzo il binario logger e configuro il demone syslog per redirezionare i logs dello script su un file separato \:D/

prevedo un nuovo articolo sul wiki :)