venerdì 3 aprile 2015

Cron fork crash

Un amico mi ha contattato perche' la sua macchina di acquisizione dati (Ubuntu 14.04 su una macchina DELL certificata Linux) nella notte ha crashato con reboot e perdita di dati
La macchina e' esposta con indirizzo pubblico su Internet ma non ha servizio Web (solo SSH ed altri sistemi di controllo remoto)

I sintomi dal syslog sono una serie di errori
-----------------------------------------------------
Mar 10 06:38:01 apollo CRON[2745]: (apollo) CMD (/home/apollo/xxxxxxxxx)
Mar 10 06:38:01 apollo CRON[28701]: (apollo) MAIL (mailed 1 byte of output; but got status 0x00ff, #012)
Mar 10 06:34:01 apollo CRON[16435]: (apollo) CMD (/home/apollo/xxxxxx)
Mar 10 06:39:01 apollo CRON[18558]: (CRON) error (can't fork)
Mar 10 06:39:01 apollo CRON[16435]: (CRON) error (can't fork)
-----------------------------------------------------

con l'ultimo messaggio prima di fare reboot
-----------------------------------------------------
Mar 10 08:49:27 apollo xinetd[27808]: service telnet: too many consecutive fork failures
Mar 10 09:22:16 apollo xinetd[27808]: telnet: fork failed: Cannot allocate memory (errno = 12)
Mar 10 09:22:36 apollo xinetd[27808]: message repeated 4 times: [ telnet: fork failed: Cannot allocate memory (errno = 12)]
Mar 10 09:22:36 apollo xinetd[27808]: service telnet: too many consecutive fork failures
-----------------------------------------------------

mi viene detto che e' stato installato il servizio telnet perche' la macchina non era piu' raggiungibile via SSH (insieme a telnet erano stati installati ShellInABox, Vino e NoMachine)
Nei log erano presenti connessioni da tutto il mondo su telnet

-----------------------------------------------------
Mar 10 05:32:40 apollo in.telnetd[28701]: connect from xx.xxx.x.xxx (xx.xxxx.x.xxx)
-----------------------------------------------------

il primo consiglio e' stato quello di spengere tutti i servizi non necessari, in particolare telnet (al giorno d'oggi e' sostanzialemente obsoleta)

Il mattino dopo la macchina presentava un normale traffico di rete solo sulla rete interna ma nella notte era andata di nuovo in crash con un ultimo messaggio
-----------------------------------------------------
Mar 11 03:34:01 apollo cron[1163]: (CRON) error (can't fork)
-----------------------------------------------------
di nuovo un crash su un fork

a questo punto e' partita la ricerca sul colpevole. La macchina lavorava al 5% della CPU con la Swap libera quindi in condizioni sostanzialmente ottimali ed eseguiva uno script una volta al minuto che elabora dei dati acquisiti e invia i risultati ad un'altra macchina. Lo script era costituito da diverse fasi la somma dei tempi di ciascun passo era nettamente inferiore ad un minuto, non era quindi possibile la sovrapposizione di piu' lavori in cron che potessero generare una fork bomb

Guardando meglio e' emerso pero' che l'ultimo passo copiava i dati sulla macchina remota mediante un comando rsync un solo file (peraltro sempre dello stesso nome) ed e' stato visto che la directory di arrivo era costituita da una moltitudine di file. Il numero dei file nel server di arrivo rendevano rsync molto lenta e cio' creava il sovrapporsi dei cron ogni minuto per arrivare a saturare le risorse acccumulandosi lavoro con il tempo

Sostituito il comando rsync con scp la macchina ha ripreso a lavorare senza interruzioni