L'architettura OpenVOS si avvale di diversi sistemi indipendenti; il NIO per la comunicazione X25, i controller disk array di canali in fibra, l'UPS per l'alimentazione, l'RSN Internet Console Server per RSN su IP e gli switch Ethernet della rete di manutenzione che permettono a tutti questi sistemi di comunicare su una rete privata Ethernet/IP. Questi sistemi sono monitorati da vari processi OpenVOS per assicurarsi che funzionino correttamente. Ma alcuni eventi come i login degli utenti non sono monitorati. La console RSN e gli switch di rete hanno la possibilità di inviare un messaggio ad un server di registrazione ogni volta che qualcuno effettua il login o tenta di effettuare il login. Poiché gli switch di rete sono collegati solo al modulo Stratus , ha senso far funzionare un server di logging sul modulo Stratus . A tal fine ho creato un logging server molto semplice, che scrive semplicemente il messaggio che riceve insieme alla data e all'ora e all'indirizzo IP dell'host che ha inviato il messaggio all'output standard. Eseguendo il server come processo avviato, i messaggi possono essere salvati nel file di uscita del processo.
Esempi dagli switch di rete |
È possibile che qualcuno che era autorizzato abbia avuto problemi a digitare la password di root quando si è connesso allo switch di rete come root, ma forse è anche vero che è molto bravo a indovinare le password.
2011-10-02 11:55:39 : 10.10.1.75 : >%AAA-W-RIFIUTO: Nuova connessione telnet per l'uso
+r radice, fonte 10.10.1.1.1 destinazione 10.10.1.75 RIFIUTATO
2011-10-02 11:56:03 : 10.10.1.75 : >%AAA-W-RIFIUTO: Nuova connessione telnet per l'uso
+r radice, fonte 10.10.1.1.1 destinazione 10.10.1.75 RIFIUTATO
2011-10-02 11:56:08 : 10.10.1.75 : >%AAA-I-CONNECT: Sessione CLI utente per l'utente ro
+ot su telnet , sorgente 10.10.1.1.1 destinazione 10.10.1.75 ACCETTA
Ecco qualcuno che indovina gli ID utente dell'amministratore di sistema
2011-10-02 12:03:13 : 10.10.1.75 : >%AAA-W-RIFIUTO: Nuova connessione telnet per l'uso
+r admin, fonte 10.10.1.1.1 destinazione 10.10.1.75 RIFIUTATO
2011-10-02 12:03:30 : 10.10.1.75 : >%AAA-W-RIFIUTO: Nuova connessione telnet per l'uso
+r sysadmin, fonte 10.10.1.1.1 destinazione 10.10.1.75 RIFIUTATO
2011-10-02 12:04:39 : 10.10.1.75 : >%AAA-W-RIFIUTO: Nuova connessione telnet per l'uso
+r Amministratore, fonte 10.10.1.1.1 destinazione 10.10.1.75 RIFIUTATO
Oltre al login dell'utente, gli switch di rete segnalano quando la configurazione è stata modificata
2011-10-02 15:16:29 : 10.10.1.75 : >%COPY-I-FILECPY: Copia file - URL sorgente eseguito
+ning-config destinazione URL flash://startup-config
2011-10-02 15:16:43 : 10.10.1.75 : >%COPY-N-TRAP: L'operazione di copia è stata completata
+ed con successo
E riporterà anche messaggi di link up e down che possono essere molto utili per la risoluzione dei problemi di comunicazione.
2011-10-02 15:49:17 : 10.10.1.75 : >%LINK-W-Down: 2/e24
2011-10-02 15:49:20 : 10.10.1.75 : >%LINK-I-Up: 2/e24
|
Esempi dal server RSN Internet Console Server |
Qualcuno del modulo si è collegato alla console RSN e ha effettuato il login come root, dopo aver digitato la password in modo errato per due volte.
2011-10-02 12:11:03 : 10.10.1.200 : in.telnetd[2942]: collegarsi dal 10.10.1.1 (10
+.10.1.1)
2011-10-02 12:11:03 : 10.10.1.200 : telnetd[2942]: doit: getaddrinfo: Temporaneo
+fallimento 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' 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' da `10.10.1.1'.
2011-10-02 12:11:35 : 10.10.1.200 : login[2945]: login root su `ttyp0' da `10
+.10.1.1'
Si noti che la console RSN segnalerà un ID utente di UNKNOWN se viene effettuato un tentativo con un ID utente non valido.
2011-10-02 12:12:31 : 10.10.1.200 : in.telnetd[2946]: collegarsi dal 10.10.1.1 (10
+.10.1.1)
2011-10-02 12:12:32 : 10.10.1.200 : telnetd[2946]: doit: getaddrinfo: Temporaneo
+fallimento 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.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.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.1'.
La console RSN non segnalerà quando l'ID utente rsn_admin valido viene utilizzato per il login. Tuttavia, si vedrà comunque la connessione. L'ID utente rsn_admin non ha accesso per modificare i file di configurazione del sistema. Se l'utente rsn_admin tenta di passare a root con il comando su, verrà registrato.
2011-10-02 12:15:37 : 10.10.1.200 : in.telnetd[2957]: collegarsi dal 10.10.1.1 (10
+.10.1.1)
2011-10-02 12:15:38 : 10.10.1.200 : telnetd[2957]: doit: getaddrinfo: Temporaneo
+fallimento 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
+ radice per rsn_admin(uid=500)
Così come i tentativi che falliscono.
2011-10-02 12:19:50 : 10.10.1.200 : PAM_unix[2972]: errore di autenticazione; rsn_ 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
+tempo libero
2011-10-02 12:19:52 : 10.10.1.200 : su[2972]: - ttyp0 rsn_admin-root
|
Per configurare lo switch di rete in modo da inviare messaggi di log al modulo OpenVOS è necessario accedere allo switch come root, eseguire il comando di logging e poi salvare la nuova configurazione:
telnet 10.10.1.75 Provare... Collegato a 10.10.1.75. Il carattere di fuga è '^]'. Nome utente: root Password:****** console# config console(config)# logging 10.10.1.1 console(config)# console# copy run-config startup-config |
Per configurare la console RSN in modo da inviare 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 essere sicuri che il processo syslogd sia avviato dopo un riavvio, il file /etc/tc.d/rc.local deve essere cambiato.
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# |
Supponendo di ottenere lo stesso output come mostrato sopra è possibile cancellare il file rc.local.bak con "rm rc.local.bak".
Una volta che la registrazione è stata impostata sui dispositivi è necessario eseguire il programma logd sul modulo Stratus . Suggerisco di avviare il programma con la seguente macro di comando. Il file di log si chiamerà logd.(data).(ora).out. Se per qualche motivo un file con quel nome esiste già, viene rinominato in logd.(date).(time).old.out. Se esiste già un file con il suffisso .old.out viene cancellato. Dato che il timbro temporale è al secondo, questo è improbabile. Il file out ha un blocco implicito, quindi il file può essere letto in qualsiasi momento. Si noti che il file out crescerà per sempre, quindi sarà necessaria una certa manutenzione da parte vostra o potete modificare il programma per renderlo più intelligente nella gestione dell'output.
e start_logd.cm inizia qui
&
& Versione 1.00 11-11-02
& [email protected]
&
& Questo script crea un file di log, imposta il blocco implicito e avvia il logd
e processo. Il processo non terminerà normalmente e il file di registro ha il file di log
e il potenziale per crescere molto grande.
&
&
& Questo software viene fornito "così com'è", SENZA ALCUNA GARANZIA O
E QUALSIASI TIPO DI SUPPORTO DI QUALSIASI TIPO. L'AUTORE DISCLAUDE SPECIFICAMENTE QUALSIASI IMPLICITA
E GARANZIE DI COMMERCIABILITÀ O IDONEITÀ PER QUALSIASI SCOPO PARTICOLARE.
& La presente clausola di esclusione di responsabilità si applica, nonostante le dichiarazioni verbali di qualsiasi
e gentile da parte dell'autore o di chiunque altro.
&
&set DT (data).(ora)
&if (esiste logd.&DT&.out)
e poi rinominare logd.&DT&.out logd.&DT&.old.out -cancellare
crea_file logd.&DT&.out
impostare_implicare_il_blocco.logd.&DT&.out
start_process logd -output_path logd.&DT&.out -privilegiato -process_name logd
&
e inizio_logd.cm finisce qui
|
Finalmente ecco 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 */
|