Passa al contenuto principale

L'architettura OpenVOS si avvale di diversi sistemi indipendenti: il NIO per la comunicazione X.25, i controller dell'array di dischi Fibre Channel, l'UPS per l'alimentazione, il server di console Internet RSN per RSN su IP e gli switch Ethernet della rete di manutenzione che consentono a tutti questi sistemi di comunicare tramite una rete Ethernet/IP privata. Questi sistemi sono monitorati da vari processi OpenVOS per garantire il loro corretto funzionamento. Tuttavia, alcuni eventi, come gli accessi degli utenti, non vengono monitorati. La console RSN e gli switch di rete hanno la possibilità di inviare un messaggio a un server di registrazione ogni volta che qualcuno effettua l'accesso o tenta di farlo. Poiché gli switch di rete sono collegati solo al Stratus , è logico avere un server di registrazione in esecuzione sul Stratus . A tal fine ho creato un server di registrazione molto semplice, che si limita a scrivere il messaggio ricevuto insieme a un timestamp data-ora e all'indirizzo IP dell'host che ha inviato il messaggio sull'output standard. Eseguendo il server come processo avviato, i messaggi possono essere salvati nel file di output del processo.

Esempi relativi agli switch di rete
È possibile che una persona autorizzata abbia semplicemente avuto difficoltà a digitare la password di root durante l'accesso allo switch di rete come root, oppure forse è semplicemente molto brava a indovinare le password.


02/10/2011 11:55:39 : 10.10.1.75 : >%AAA-W-REJECT: Nuova connessione Telnet da utilizzare
+r root, origine 10.10.1.1 destinazione 10.10.1.75  RIFIUTATA

02/10/2011 11:56:03 : 10.10.1.75 : >%AAA-W-REJECT: Nuova connessione telnet per l'utente
+r root, origine 10.10.1.1 destinazione 10.10.1.75  RIFIUTATA

2011-10-02 11:56:08 : 10.10.1.75 : >%AAA-I-CONNECT: Sessione CLI utente per l'utente ro
+ot tramite telnet , origine 10.10.1.1 destinazione  10.10.1.75 ACCETTATA

Ecco qualcuno che sta cercando di indovinare gli ID utente degli amministratori di sistema


02/10/2011 12:03:13 : 10.10.1.75 : >%AAA-W-REJECT: Nuova connessione Telnet per l'utente
+r admin, origine 10.10.1.1 destinazione 10.10.1.75  RIFIUTATA

2011-10-02 12:03:30 : 10.10.1.75 : >%AAA-W-REJECT: Nuova connessione telnet per l'uso
+r sysadmin, origine 10.10.1.1 destinazione 10.10.1.75  RIFIUTATA

2011-10-02 12:04:39 : 10.10.1.75 : >%AAA-W-REJECT: Nuova connessione telnet per l'uso
+r Amministratore, origine 10.10.1.1 destinazione 10.10.1.75  RIFIUTATA

Oltre agli accessi degli utenti, gli switch di rete segnaleranno ogni volta che la configurazione viene modificata


02/10/2011 15:16:29 : 10.10.1.75 : >%COPY-I-FILECPY: Copia file - URL di origine in esecuzione
+ URL di destinazione flash://startup-config

2011-10-02 15:16:43 : 10.10.1.75 : >%COPY-N-TRAP: L'operazione di copia è stata completata con successo

Inoltre, segnalerà i messaggi relativi all’attivazione e alla disattivazione della connessione, che possono rivelarsi molto utili per risolvere eventuali problemi di comunicazione.


02/10/2011 15:49:17 : 10.10.1.75 : >%LINK-W-Down:  2/e24

02/10/2011 15:49:20 : 10.10.1.75 : >%LINK-I-Up:  2/e24
  Esempi dal server della console Internet RSN
Un utente del modulo si è collegato alla console RSN ed è entrato come root dopo aver digitato due volte una password errata.


02/10/2011 12:11:03 : 10.10.1.200 : in.telnetd[2942]: connessione da 10.10.1.1 (10+
.10.1.1)
2011-10-02 12:11:03 : 10.10.1.200 : telnetd[2942]: deve: getaddrinfo: Errore temporaneo\
+nella risoluzione del nome
2011-10-02 12:11:07 : 10.10.1.200 : login[2943]: password non valida per `root' su
+`ttyp0' da `10.10.1.1'
2011-10-02 12:11:15 : 10.10.1.200 : login[2943]: password non valida per `root' su
+`ttyp0' da `10.10.1.1'
02/10/2011 12:11:35 : 10.10.1.200 : login[2945]: accesso root su `ttyp0' da `10.10.1.1'

Si noti che la console RSN segnalerà un ID utente «UNKNOWN» se si effettua un tentativo con un ID utente non valido.


02/10/2011 12:12:31 : 10.10.1.200 : in.telnetd[2946]: connessione da 10.10.1.1 (10+
.10.1.1)
2011-10-02 12:12:32 : 10.10.1.200 : telnetd[2946]: deve: getaddrinfo: Errore temporaneo
+nella risoluzione del nome
2011-10-02 12:12:37 : 10.10.1.200 : login[2947]: password non valida per `UNKNOWN'
+su `ttyp0' da `10.10.1.1'
2011-10-02 12:12:45 : 10.10.1.200 : login[2947]: password non valida per `UNKNOWN'
+su `ttyp0' da `10.10.1.1'
2011-10-02 12:12:54 : 10.10.1.200 : login[2947]: password non valida per `UNKNOWN'
+su `ttyp0' da `10.10.1.1'

La console RSN non segnalerà l'accesso effettuato con l'ID utente valido rsn_admin. Tuttavia, la connessione risulterà comunque visibile. L'ID utente rsn_admin non ha il permesso di modificare alcun file di configurazione di sistema. Se l'utente rsn_admin tenta di passare all'account root con il comando su, l'operazione verrà registrata.


02/10/2011 12:15:37 : 10.10.1.200 : in.telnetd[2957]: connessione da 10.10.1.1 (10\
+.10.1.1)
2011-10-02 12:15:38 : 10.10.1.200 : telnetd[2957]: deve: getaddrinfo: Errore temporaneo\
+nella risoluzione del nome
2011-10-02 12:15:54 : 10.10.1.200 : su[2959]: + ttyp0 rsn_admin-root
2011-10-02 12:15:54 : 10.10.1.200 : PAM_unix[2959]: (su) sessione aperta per l'utente\
+ root da rsn_admin(uid=500)

Così come i tentativi che falliscono.


02/10/2011 12:19:50 : 10.10.1.200 : PAM_unix[2972]: errore di autenticazione; rsn_
+admin(uid=500) -> root per il servizio su
2011-10-02 12:19:52 : 10.10.1.200 : su[2972]: pam_authenticate: Autenticazione f
+allata
2011-10-02 12:19:52 : 10.10.1.200 : su[2972]: - ttyp0 rsn_admin-root

 

Per configurare lo switch di rete in modo che invii i messaggi di log al modulo OpenVOS, è necessario accedere allo switch come root, eseguire il comando di registrazione dei log e quindi salvare la nuova configurazione:

telnet 10.10.1.75                                       
Tentativo in corso...
Connesso a 10.10.1.75.
Il carattere di escape è '^]'.

Nome utente: root
Password: ******

console# config
console(config)# logging 10.10.1.1
console(config)#

console# copy running-config startup-config

 

Per configurare la console RSN in modo che invii i messaggi di log al modulo OpenVOS, è necessario accedere alla console come root e avviare il processo syslogd con il comando «syslogd –R 10.10.1.1:514». Per garantire che il processo syslogd venga avviato dopo un riavvio, è necessario modificare il file /etc/tc.d/rc.local.

telnet 10.10.1.200
Trying...
Connected to 10.10.1.200.
Escape character is '^]'.

Moxa Embedded Linux, Professional Edition
Linux/armv5teb 2.4.18_mvl30-ixdp425

azvos login: root
Password:
Welcome to

    ___  _____  __        _______    _____                   __
   / _ / __/ |/ / ____  /  _/ _   / ___/__  ___  ___ ___  / /__
  / , _/ /    / /___/ _/ // ___/ / /__/ _ / _ (_-</ _ / / -_)
 /_/|_/___/_/|_/       /___/_/     ___/___/_//_/___/___/_/__/ 

 Authorized Users Only!

root@azvos:~# syslogd -R 10.10.1.1:514
root@azvos:~# 
root@azvos:~# 
root@azvos:~# 
root@azvos:~# cd /etc/rc.d
root@azvos:/etc/rc.d# cp rc.local rc.local.bak
root@azvos:/etc/rc.d# echo syslogd -R 10.10.1.1:514 >> rc.local
root@azvos:/etc/rc.d# tail rc.local
fi
/etc/init.d/ssh start
/etc/init.d/apache stop
/etc/init.d/portmap stop
rm -f /rsn/call.log
/rsn/callhome &
lcmmessage -c -m "   Welcome to   " -l
lcmmessage -m " RSN-IP Console " -l
cat /etc/motd
syslogd -R 10.10.1.1:514
root@azvos:/etc/rc.d#

 

Se ottieni lo stesso risultato mostrato sopra, puoi eliminare il file rc.local.bak con il comando “rm rc.local.bak”.

Una volta configurata la registrazione sui dispositivi, è necessario eseguire il programma logd sul Stratus . Suggerisco di avviare il programma con la seguente macro di comando. Il file di log avrà il nome logd.(data).(ora).out. Se per qualche motivo esiste già un file con quel nome, verrà rinominato in logd.(data).(ora).old.out. Se esiste già un file con il suffisso .old.out, questo verrà eliminato. Dato che il timestamp è preciso al secondo, ciò è improbabile. Il file di output ha un blocco implicito, quindi può essere letto in qualsiasi momento. Si noti che il file di output crescerà all'infinito, quindi sarà necessaria una certa manutenzione da parte vostra oppure potrete modificare il programma per renderlo più efficiente nella gestione dell'output.



& start_logd.cm inizia qui\
&\
& Versione 1.00 11-11-02\
&stratus
&\
& Questo script crea un file di log, imposta il blocco implicito e avvia il processo logd\
&. Il processo normalmente non termina e il file di log può\
& raggiungere dimensioni molto grandi.
&
&
& Questo software viene fornito "COSÌ COM'È", SENZA ALCUNA GARANZIA O
& ALCUN TIPO DI SUPPORTO. L'AUTORE DECLINA SPECIFICAMENTE QUALSIASI GARANZIA IMPLICITA
& DI COMMERCIABILITÀ O IDONEITÀ PER UN PARTICOLARE SCOPO.
& La presente esclusione di responsabilità si applica, nonostante qualsiasi dichiarazione verbale di qualsiasi tipo fornita dall'autore o da chiunque altro.
&
&
&set DT (data).(ora)
&if (esiste logd.&DT&.out)
&then !rinomina logd.&DT&.out logd.&DT&.old.out -elimina
!crea_file logd.&DT&.out
!imposta_blocco_implicito logd.&DT&.out
avvia_processo logd -percorso_di_output logd.&DT&.out -privilegiato -nome_processo logd
&
& start_logd.cm termina qui

 

Ed ecco finalmente il programma.



/* logd.c starts here

   Version 1.00 11-11-02
   [email protected]

   This software is provided on an "AS IS" basis, WITHOUT ANY WARRANTY OR
   ANY SUPPORT OF ANY KIND. The AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE.
   This disclaimer applies, despite any verbal representations of any
   kind provided by the author or anyone else.
*/

#define _POSIX_SOURCE

#include <sys/select.h>
#include <prototypes/inet_proto.h>
#include <stdlib.h>
#include <string.h>
#include <c_utilities.h>
#include <errno.h>
#include <time.h>

#define BUFFERLEN 10000
#define bzero(s, len)             memset((char *)(s), 0, len)

int errno;

getCurrentDateTime (char * szDT)
{
time_t tTime;
struct tm *tmLT;

tTime = time ((time_t *) 0);
tmLT = localtime (&tTime);

sprintf (szDT, "%4ld-%02ld-%02ld %02ld:%02ld:%02ld",
          tmLT -> tm_year+1900,
          tmLT -> tm_mon,
          tmLT -> tm_mday,
          tmLT -> tm_hour,
          tmLT -> tm_min,
          tmLT -> tm_sec);
}

main (argc, argv)
int    argc;
char   *argv [];

{
 struct sockaddr_in serv_addr;
 struct sockaddr_in cli_addr;
 int clilen = sizeof (cli_addr);

 int zeroCount = 0;
 int socks0;
 int recvBytes;

 char szSender [16];
 char  szDateTime [32];
 char szMessage [BUFFERLEN];
 short portNumber;

 if (argc == 1)  /* no arguments - use the default of 514 */
    {
    portNumber = 514;
    }
 else
 if (argc == 2) /* one argument, must be the expected port number */
    {
    portNumber = atoi (argv [1]);
    if (portNumber == 0)
       {
       printf ("nn%s argument was not the expected port number", argv [1]);
       printf ("nUsage: logd [port number, default = 514]n");
       exit (-1);
       }
    }
 else /* more than one argument gets a usage message */
    {
    printf ("nnToo many arguments");
    printf ("nUsage: logd [port number, default = 514]n");
    exit (-1);
    }

/* Leting you know what argument values will actually be used */

 printf ("logd %dnn", portNumber);

 if ((socks0 = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
    {
    perror ("logd: can't create dgram socket");
    exit (errno);
    }

/* build a sockaddr structure holding the address we will bind to. The IP
   address is INADDR_ANY meaning we will listen on all active IP addresses */

 bzero ( (char *) &serv_addr, sizeof (serv_addr));
 serv_addr.sin_family        = AF_INET;
 serv_addr.sin_addr.s_addr   = htonl (INADDR_ANY);
 serv_addr.sin_port          = htons (portNumber);

/* now bind to the address and port */

 if (bind (socks0, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
    {
    perror ("logd: can't bind local address");
    exit (errno);
    }

/* main loop just does a recv, blocking until something is available to read.
   Assuming we receive at least 1 byte we get the current date-time,
   convert the senders IP address to a printable string and print the
   date-time, address and message starting at the 5th character position.
   The first four characters of a syslog message are <NN> where NN is a
   severity and facility code. These can be used for message filtering. Since
   this program doesn't do any filtering I just skip them. */
 while (1)
   {
    recvBytes=recvfrom(socks0,szMessage, BUFFERLEN, 0,
          (struct sockaddr *) &cli_addr, &clilen);
    if (recvBytes > 0)
       {
       getCurrentDateTime ((char *) &szDateTime);
       strcpy (szSender, inet_ntoa ((struct in_addr) cli_addr.sin_addr));
       szMessage [recvBytes] = 0;
       printf ("%s : %s : %sn", szDateTime, szSender, &szMessage[4]);
       zeroCount = 0;
       }
    else
    if (recvBytes < 0) /* in the event of an error report it and exit */
       {
       getCurrentDateTime ((char *) &szDateTime);
       printf ("%s : Error %d returned - exitingn", szDateTime, errno);
       exit (errno);
       }
    else  /* I can't think of any reason we would be getting null messages */
       {  /* but if we get a stream of them we would silently loop. This */
       zeroCount++;          /* forces out a message if we get 100 null */
       if (zeroCount > 99)   /* messages in a row */
          {
          getCurrentDateTime ((char *) &szDateTime);
          strcpy (szSender, inet_ntoa ((struct in_addr) cli_addr.sin_addr));
          printf ("%s : %s %sn", szDateTime,
               "We have received 100 null messages, the last one from",
               szSender);
          zeroCount = 0;
          }
       }
   }
}

/* logd.c ends here */