Shrink Tablespace “problematici”


Se avete intenzione di modificare un TB su un ambiente di produzione prima ancora di pensarlo prendetevi subito e nell’ordine seguente:
1> una vacanza di almeno 7 giorni (occorre sempre e cmq!)
2> una buona dose di tranquillanti (ogni buon dba oracle/sysadmin unix conserva sempre qualcosa di chimico nel cassetto!)
3> un backup full del DB (non vi ho ancora parlato di export data pump e di RMAN vero? Beh lo faro’..intanto sappiate che Google è un vostro amico![cit.])

Bene ho scritto “Tablespace problematici” e non Tablespace.. già perchè spesso il comando da manuale per il resize:
ALTER DATABASE DATAFILE ‘/home/oracle/oradata/tbmaledetto.dbf’ size 10G
indovinate? Non funziona…
i motivi sono tanti e a volte basta semplicemente un PURGE RECYCLEBIN per risolvere
altre volte invece, quando siete tanto ma taanto ma proprio taaaanto sfigatti il vostro db proviene da svariati
porting e durante il suo percorso, di release in release, il tablespace in questione ha sempre più frammentato i suoi dati all’interno fino a rendere praticamente impossibile perdere tempo tra i blocks liberi e fantomatici recuperi “standard”…

Quindi la soluzione è:

1> Create un TS NUOVO con le dimensioni/datafiles utili a contenere il vecchio..dategli un nome PROVVISORIO
(io ho spostato USERS, e mi sono bastati due DATAFILE da 20Gb ciascuno)
create tablespace USERS2 datafile ‘/home/oracle/oradata/user1.dbf’ size 20G autoextend on,’/home/oracle/oradata/user2.dbf’ size 20G autoextend on;
2> muovete tutti gli oggetti del TS “vecchio” spoolando ed eseguendo questo script:
(io l’ho usato per spostare tutti gli oggetti di USERS dentro USERS2.. modificatelo voi stessi secondo quello
che vi serve oppure se siete fighi sostituite USERS e USERS2 con &VARIABILE1 e &VARIABILE2 ;)

set pagesize 2000
set linesize 200
set echo off
set heading off
select ‘Transporting tablespace ‘ || ‘USERS’ || ‘ to tablespace ‘ || ‘USERS2′ from dual;
select ‘Size: ‘ || to_char((sum(ext.bytes) / 1048576), ’9,990.00′) || ‘ MB’
from dba_objects ob
inner join (
select ta.owner, ta.table_name as nom, ta.tablespace_name as tbs, ‘TABLE’ as tipo from dba_tables ta
union
select ind.owner, ind.index_name as nom, ind.tablespace_name as tbs, ‘INDEX’ as tipo from dba_indexes ind
) tb on tb.owner=ob.owner and tb.nom=ob.object_name and tb.tipo=ob.object_type
inner join dba_extents ext on ext.segment_name = ob.object_name
where ob.object_type in (‘INDEX’, ‘TABLE’, ‘LOB’) and (tb.tbs = ‘USERS’);
select ‘alter user ‘ || ob.owner || ‘ quota unlimited on ‘ || ‘USERS2′ || ‘ default tablespace ‘ || ‘USERS2′ || ‘;’
from dba_objects ob
inner join (
select ta.owner, ta.table_name as nom, ta.tablespace_name as tbs, ‘TABLE’ as tipo from dba_tables ta
union
select ind.owner, ind.index_name as nom, ind.tablespace_name as tbs, ‘INDEX’ as tipo from dba_indexes ind
) tb on tb.owner=ob.owner and tb.nom=ob.object_name and tb.tipo=ob.object_type
where ob.object_type in (‘INDEX’, ‘TABLE’, ‘LOB’) and (tb.tbs = ‘USERS’)
group by ob.owner;
select
decode(ob.object_type,
‘TABLE’,
‘alter table “‘ || ob.owner || ‘”.”‘ || ob.object_name || ‘” move tablespace ‘ || ‘USERS2′ || ‘;’,
‘alter index “‘ || ob.owner || ‘”.”‘ || ob.object_name || ‘” rebuild tablespace ‘ || ‘USERS2′ || ‘;’
)
from dba_objects ob
inner join (
select ta.owner, ta.table_name as nom, ta.tablespace_name as tbs, ‘TABLE’ as tipo from dba_tables ta
union
select ind.owner, ind.index_name as nom, ind.tablespace_name as tbs, ‘INDEX’ as tipo from dba_indexes ind
) tb on tb.owner=ob.owner and tb.nom=ob.object_name and tb.tipo=ob.object_type
where ob.object_type in (‘TABLE’) and (tb.tbs = ‘USERS’);
select
‘alter table “‘ || lo.owner || ‘”.”‘ || lo.table_name ||
‘” move lob (“‘ || lo.column_name || ‘”) store as (tablespace ‘ || ‘USERS2′ || ‘);’
from dba_lobs lo
inner join dba_segments se on se.segment_name = lo.segment_name
where se.tablespace_name = ‘USERS’;
select
decode(ob.object_type,
‘TABLE’,
‘alter table “‘ || ob.owner || ‘”.”‘ || ob.object_name || ‘” move tablespace ‘ || ‘USERS2′ || ‘;’,
‘alter index “‘ || ob.owner || ‘”.”‘ || ob.object_name || ‘” rebuild tablespace ‘ || ‘USERS2′ || ‘;’
)
from dba_objects ob
inner join (
select ta.owner, ta.table_name as nom, ta.tablespace_name as tbs, ‘TABLE’ as tipo from dba_tables ta
union
select ind.owner, ind.index_name as nom, ind.tablespace_name as tbs, ‘INDEX’ as tipo from dba_indexes ind
) tb on tb.owner=ob.owner and tb.nom=ob.object_name and tb.tipo=ob.object_type
where ob.object_type in (‘INDEX’) and (tb.tbs = ‘USERS’);

Adesso il vecchio TS è vuoto… cancellatelo e insultatelo quanto volete:
DROP TABLESPACE users INCLUDING CONTENTS AND DATAFILES;
(PS: se il TS è il DEFAULT USER settate come DEFAULT USERS quello nuovo così:
ALTER database default tablespace users2; )
e rinominate il nuovo con:
ALTER TABLESPACE users2 RENAME TO users;
Finalmente avete risparmiato lo spazio che desideravate e in più avete il vostro bel TS
con i dati frammetati e quindi resizzabile quando e quanto credete.
Amen

Posted in oracle, Unix | Leave a comment

Ricreare la TABLESPACE TEMPORANEA su ORACLE


A volte, nelle giornate peggiori, quando magari determinate congiunzioni astrali non ci sono particolarmente favorevoli puo’ capitare che una TABLESPACE se ne vada a puttane, quando questa TABLESPACE poi è quella TEMPORANEA, dopo aver bestemmiato abbondantemente cominciate a ordinare nella vostra mente le persone alle quali recentemente avete fatto del male filtrando quali tra queste possano centrarci qualcosa con il voodoo, la macumbaa e la stregoneria in generale
ma tralasciamo adesso l’ astrologia, l’ alchimia e le scienze magiche e tornaniamo su sqlplus e al nostro db… :D
la rottura della TS TEMP fortunatamente non capita spesso, puo’ capitare successivamente ad un ripristino o a qualche operazione particolare nel db (*).
Vediamo come è possibile uscirne vivi:
La nostra TS TEMP principale del db è:
SQL> select PROPERTY_VALUE from database_properties
where property_name = ‘DEFAULT_TEMP_TABLESPACE’;

PROPERTY_VALUE
——————————————————————————–
TEMP
E ovviamente se proviamo a fare la cosa più normale in questi casi, e cioè dropparla e rigenerarla, essendo la TEMP globale del db otterremo un errore ORA-12906:
SQL> drop tablespace temp;
drop tablespace temp
*
ERROR at line 1:
ORA-12906: cannot drop default temporary tablespace

Per risolvere il problema dobbiamo quindi creare una nuova TS temporanea provvisoria così:
SQL> create temporary tablespace temp2 tempfile ‘/oradata2/temp2.dbf’ size 10M;
Tablespace created.

Definirla come temporanea principale:
SQL> alter database default temporary tablespace temp2;
Database altered.

Per confermare che sia la TS che vogliamo diamo un:
SQL> select username, temporary_tablespace from dba_users where username in (‘utente1′,’SCOTT’,'utente2′);

USERNAME TEMPORARY_TABLESPACE
—————————— ——————————
utente1 TEMP2
PROD TEMP2
utente2 TEMP2

A questo punto finalmente cancelliamo la TS temporanea ex-di-default
SQL> drop tablespace temp;
Tablespace dropped.

Cancelliamo il datafile corrispondente nel filesystem mi raccomando e infine riprocediamo come sopra
ma stavolta per la TS TEMP definitiva.
Amen

Posted in oracle, Unix | Tagged | 1 Comment

2 Metodi “sicuri” per il cambio del SID su un db ORACLE 11g


Recentemente, dopo un urgente ripristino di un db su un ambiente diverso da quello sorgente (un ambiente di produzione su uno di collaudo), mi sono ritrovato a imprecare doverne cambiare il nome e diversi altri parametri.
L’ operazione delicata in questi casi è proprio quella del cambio del SID. Esistono due modi che ho sperimentato con esito positivo, il primo è più semplice e consiste nel usare l’ utility DBNEWID.
Dopo il ripristino ho dovuto tirarmi provvisoriamente su l’ istanza in modalità mount e per farlo, nel mio caso, ho in ordine:
* cambiato il sid sul bash_profile dell’utenza unix usata (e ovviamente reso attivo, con il comando source o con login o con su - etc. etc.);
* editato il file init.ora (solitamente initSID.ora) cambiandone il nome (appunto initNUOVOSID.ora) e tutti riferimenti al vecchio SID (dbname, path flashback/logs etc.);
* restartartato il listener (nel mio caso ho lasciato intatto il file listener.ora, visto che il vecchio SID sarà stato successivamente proprio quello che volevo riconfermare);
* SQL> startup mount exclusive ;
* nid target=sys/password DBNAME=nuovoSID SETNAME=Y ;
In questa maniera lo scopo è stato raggiunto e per tirare su il “nuovo” db ho dovuto solo:
* Ricambiare il sid sul enviroment dell’ utente di sistema per oracle;
* Spegnere il db.
* Ricreare l’ SPFILE con un:
SQL> create spfile from pfile=puntando al path di quello nuovo (initNUOVOSID.ora)
* SQL> startup
FINE.

————————————————-

Il secondo metodo come vi dicevo è piu complesso e lungo, consiste nel rifare la procedura a mano x la creazione del controlfile:
Bisogna innanzitutto ricordarsi il PATH settato x files di trace del db:
* SQL> show parameter USER_DUMP_DEST ;
Questo PATH ci servirà a prendere il trace generato dal comando:
* SQL> alter database backup controlfile to trace;
Come vedete dal comando in questa maniera avremmo il ddl per la creazione del cf all’interno del file trace
appena creato.
* Spegniamo il db appena ripristinato:
SQL> shutdown immediate ;
e dalla directory DUMPDEST preleviamo il trc-file corrispondente al controlfileToTrace;
* Editiamolo cominciando a eliminare tutte le righe prima della fase 2 ( Set #2. RESETLOGS case )
* Aggiungiamo un “REUSE” davanti il “SET” della riga: “create controlfile….” modificando il SID vecchio col nuovo, otterremo: “CREATE CONTROLFILE REUSE SET DATABASE “NUOVOSID” ……..
* Cancelliamo tutto quello che viene dopo “CHARACTER SET…”
* Salviamo il nostro file come script sql (.sql)
* Rinominiamo adesso il file initVECCHIOSID.ora in initNUOVOSID.ora (e modifichiamo all’interno i riferimenti al vecchio SID);
* Settiamo l’enviroment x l’ utenza unix e carichiamola.
* SQL> startup nomount ;
* lanciamo il file precedentemente modificato per la creazione del nuovo controlfile ;
* SQL> alter database open resetlogs (occhio alle dir nuove per i logs, il nome sarà il nuovo SID, ci sono già?)
* SQL> alter database rename global_name to
* SQL> alter database open;
* Ricreiamo la TABLESPACE temporanea.

Posted in oracle, Unix | Tagged | 1 Comment

Gather stats for only lastAnalyzed apps Tables (appunti grezzi)


#!/bin/sh
cd /home/oracle/script/
. /home/oracle/.env11g
/home/oracle/app/product/11.2.0/bin/sqlplus -s /nolog < set feed off pages 1000 lines 120 echo off verify off
connect userDBA/passwd;
spool on
spool statLast.sql
select 'exec dbms_stats.gather_table_stats('''||OWNER|| ''',''' ||table_name|| ''',cascade => TRUE);’ from dba_all_tables where OWNER not like ‘%SYS%’ AND OWNER not like ‘SCOTT’ and OWNER not like ‘XXXX’ AND LAST_ANALYZED is not null AND last_analyzed > (sysdate-NUMdays) order by last_analyzed;
spool off
EOF
#lavora lo spool sql in modo da togliere intestazione della query
/bin/sed /OWNER/d statLast.sql > statLast2.sql
/bin/sed /—–/d statLast2.sql > statLast3.sql
#esegue lo script dinamico creato per le stats specifiche + uno spool per eventuali
/home/oracle/app/product/11.2.0/bin/sqlplus -s /nolog < set feed off pages 1000 lines 120 echo off verify off
connect userDBA/passwd;
spool on
spool ESITOSTATS.TXT
@statLast3
spool off
EOF
exit 0

Posted in oracle, Unix | Tagged | Leave a comment

Juniper/Linux – in VPN con Network connect da linux


PREPARAZIONE DEL CLIENT (1 sola volta)
- effettuare una prima connessione completa al sito del network connect di juniper https://extranet.dominio.net, in questa maniera verrà scaricato il client nella propria $home creando cosi /home/utente/.juniper_networks/network_connect

- compilare dentro $HOME/.juniper_networks/network_connect/ l’eseguibile ncui così:
gcc -m32 -Wl,-rpath,`pwd` -o ncui libncui.so

- prendiamo adesso il certificato ssl dal host con:
echo | openssl s_client -connect extranet.dominio.net:443 2>&1 |sed -ne ‘/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p’ |openssl x509 -outform der > ssl.crt

CONNESSIONE
- Da questo momento per ogni connessione alla VPN faremo il login sul frontend web del network connect https://extranet.dominio.net e preleveremo il DSID cookie tramite il browser con il comando:

javascript:alert(document.cookie)

in questa maniera successivamente potremmo far partire il client con:
(cd /root/.juniper_networks/network_connect; )
./ncui -h extranet.sace.it -c “DSID=733f7719f6f92672b63bea541f24c73b” -f ssl.crt

Posted in Networking, Unix | Tagged , , , , , , | 2 Comments

MailServer IMAP/POP3/SMTP(SSL) + ASPAM/postGREY


Questa guida intende descrivere come installare e configurare un semplice server di posta Imap/pop3/smtp con auth ssl e antispam+postgrey su linux (archlinux).
Cominciamo col generare i certificati che useremo per le autenticazioni:

cd /etc/ssl/certs & openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout mail.key -out mail.crt
openssl rsa -in mail.key -out mail.key & mv mail.key /etc/ssl/private

Assicuriamoci che l’utenza di sistema che mapperemo con quella per l’email appartenga al gruppo “mail” e cominciamo con le installazioni:

pacman -S postfix procmail dovecot spamassassin
configuriamo spamassassin:
groupadd -g 5001 spamd
useradd -u 5001 -g spamd -s /sbin/nologin -d /var/lib/spamassassin -m spamd
chown spamd:spamd /var/lib/spamassassin

tuniamo un po’ abbassando ad 1 il valore del parametro max-children (default=5), cio’ ci fara risparmiare parecchia ram:
vi /etc/conf.d/spamd

SAHOME=”/var/lib/spamassassin/”
SPAMD_OPTS=”-c –max-children 1 –username spamd -H ${SAHOME} -s ${SAHOME}spamd.log –pidfile /var/run/spamd.pid”

Configuriamo adesso DOVECOT per l’ IMAPssl e il pop3dssl con:
vim /etc/dovecot/dovecot.conf

protocols = imaps pop3s

disable_plaintext_auth = yes
log_timestamp = “%b %d %H:%M:%S ”

#ssl_disable = no

#i nostri certificati precedentemente creati
ssl_cert_file = /etc/ssl/certs/mail.crt
ssl_key_file = /etc/ssl/private/mail.key

mail_location = maildir:~/Maildir
mail_access_groups = mail
auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@

protocol imap {
imap_client_workarounds = delay-newmail tb-extra-mailbox-sep
}

protocol pop3 {
pop3_uidl_format = %08Xu%08Xv
#pop3_client_workarounds =
}

auth default {
mechanisms = plain login
passdb pam {
}
userdb passwd {
}
user = root
socket listen {
client {
path = /var/run/dovecot/auth-client
user = postfix
group = postfix
mode = 0660
}
}
}

Passiamo adesso alla configurazione di POSTFIX, (

cd /etc/postfix/

) cominciamo dal file principale:
vi main.cf


# Paths
queue_directory = /var/spool/postfix
daemon_directory = /usr/lib/postfix
command_directory = /usr/sbin
mail_owner = postfix
# Domain settings
myhostname = mail.nostrodominio.com
myorigin = nostrodominio.com
mydestination = $myhostname, localhost.$mydomain, localhost
# Timeout settings and other limits
delay_warning_time = 4h
unknown_local_recipient_reject_code = 450
minimal_backoff_time = 300s
maximal_backoff_time = 1200s
maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d
smtp_helo_timeout = 60s
smtpd_soft_error_limit = 3
smtpd_hard_error_limit = 12
# SMTP settings
smtpd_tls_cert_file=/etc/ssl/certs/mail.crt
smtpd_tls_key_file=/etc/ssl/private/mail.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
smtpd_tls_loglevel = 1
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination,
#postgrey
check_policy_service inet:127.0.0.1:10030
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks
smtpd_sasl_security_options = noanonymous
# SASL
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/run/dovecot/auth-client

# Network settings
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 127.0.0.0/8
relayhost =
# Email and mailbox settings
alias_maps = hash:/etc/postfix/aliases
alias_database = $alias_maps
home_mailbox = Maildir/
virtual_alias_domains = miodominio.com eventualealtrodominio.org
virtual_alias_maps = hash:/etc/postfix/virtual
mailbox_size_limit = 0

# Misc
mailbox_command = /usr/bin/procmail
smtpd_banner = $myhostname ESMTP banner_che_vogliamo
biff = no
append_dot_mydomain = no
debug_peer_level = 2
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/man
sample_directory = /etc/postfix/sample
readme_directory = no
recipient_delimiter = +

Mappiamo adesso utenza sys/utenza email inserendo le informazioni opportune con:
vi /etc/postfix/virtual


utenteemail@dominiomio.com utentesistema@localhost
utente2mail@altrodominio.org utentesistema2@localhost
#etc.

lanciamo adesso il comando:

postmap /etc/postfix/virtual

alliniamo adesso a spamassassin postfix configurando il suo vero motore principale:
vi master.cf e aggiungiamo/modifichiamo


smtp inet n – n – – smtpd
-o content_filter=spamassassin
spamassassin unix – n n – – pipe
user=spamd argv=/usr/bin/perlbin/vendor/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}

Configuriamo spamassassin:
vi /etc/mail/spamassassin/local.cf

rewrite_header Subject *****SPAM*****
required_score 3
report_safe 0 #1
use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1

Diciamo adesso a procmail come istruire le emails marchiate da spamassassin:
vi /etc/procmailrc


DROPPRIVS=yes
DEFAULT=$HOME/Maildir/
MAILDIR=$HOME/Maildir/
:0:
* ^X-Spam-Status: Yes
.Junk/

Postgrey:
yaourt -S postgrey
configuriamo con
vi /etc/conf.d/postgrey


POSTGREY_TYPE=”inet”
POSTGREY_HOST=”127.0.0.1″
POSTGREY_PORT=”10030″
POSTGREY_SOCKET=”/var/spool/postfix/private/postgrey”
POSTGREY_OPTS=”–delay=60″

Infine creiamo la Maildir per l’utente:

cd ~utente
umask 077
mkdir -p Maildir/{cur,new,tmp}
mkdir -p Maildir/.Drafts/{cur,new,tmp}
mkdir -p Maildir/.Sent/{cur,new,tmp}
mkdir -p Maildir/.Trash/{cur,new,tmp}
chmod -R 0700 Maildir
chown -R utente:users *

Riavviamo adesso tutti i servizi legati al mail server

/etc/rc.d/postgrey start
/etc/rc.d/spamd start
/etc/rc.d/dovecot start
/etc/rc.d/postfix start

..e configuriamoci i nostri clients di posta.

Posted in Networking, Unix | Tagged | Leave a comment

AutoTrace UserTrigger Oracle (appunti grezzi)

SQL> CREATE OR REPLACE TRIGGER trace_logon
2 after logon on database
3 begin
4 if ( sys_context(‘USERENV’, ‘SESSION_USER’) in (‘N00b1′, ‘Noob2′))
5 then
6 execute immediate ‘alter session set timed_statistics=true’;
7 execute immediate ‘alter session set max_dump_file_size=10000′;
8 execute immediate ‘alter session set tracefile_identifier=”Noobs”;
9 execute immediate ‘alter session set events ”10046 trace name context forever, level 12”’;
10 end if;
11 end;
12 /

SQL> CREATE OR REPLACE TRIGGER trace_logoff before logoff on database
2 begin
3 if ( sys_context(‘USERENV’, ‘SESSION_USER’) in (‘N00b1′,’Noob2′))
4 then
5 execute immediate ‘alter session set events ”10046 trace name context off”’;
6 end if;
7 end;
8

PS:
tkprof $ORACLE_BASE/diag/rdbms/prod/prod/trace/*Noobs….* $ORACLE_HOME/*Noob….*.out sys=no print=10 sort=fchela

Posted in oracle | Tagged | 1 Comment

Rebuild index oracle (appunti grezzi)

#!/bin/sh
#rebuilder script
#trova indici e ricostruisce
. /home/oracle/.env11g
SCRIPT_DIR=/home/oracle/script
/home/oracle/app/product/11.2.0/bin/sqlplus -s /nolog < set feed off pages 1000 lines 120 echo off verify off
connect system/"password"
spool ${SCRIPT_DIR}/allIndex.sql
select 'ALTER INDEX "' || table_owner ||'"."'|| index_name || '" REBUILD;' from all_indexes;
spool off
EOF
/bin/sed /TABLE_OWNER/d allIndex.sql > allIndex2.sql
/bin/sed /———–/d allIndex2.sql > allIndex3.sql
/home/oracle/app/product/11.2.0/bin/sqlplus -s /nolog< connect SYSTEM/"password"
spool ${SCRIPT_DIR}/risultato.out select to_char(sysdate,'DD/MM/YYYY HH24:MI:SS') from dual;
@${SCRIPT_DIR}/allIndex3.sql
select to_char(sysdate,'DD/MM/YYYY HH24:MI:SS') from dual;
spool off
EOF
exit 0

Posted in oracle | Tagged , , , , , , , | Leave a comment

Logging centralizzato e sicuro


Se volete anche voi risparmiare qualche migliaio di € , evitando l’acquisto di costose appliance che fanno più o meno la stessa cosa, questo sistema di logging centralizzato, che ho ideato un annetto fa circa, dovrebbe rispondere fedelmente alle direttive del decreto sulle “misure e accorgimenti prescritti ai titolari dei trattamenti effettuati con strumenti elettronici relativamente alle attribuzioni delle funzioni di amministratore di sistema” del 27 novembre 2008 – (G.U. n. 300 del 24 dicembre 2008).

L’aspetto fondamentale che questo sistema dovrà esaudire è cio’ che viene prescritto nel capitolo 4.5:
sulla “Registrazione degli accessi”
Devono essere adottati sistemi idonei alla registrazione degli accessi logici (autenticazione informatica) ai sistemi di elaborazione e agli archivi elettronici da parte degli amministratori di sistema. Le registrazioni (access log) devono avere caratteristiche di completezza, inalterabilità e possibilità di verifica della loro integrità adeguate al raggiungimento dello scopo di verifica per cui sono richieste.”

Il sistema infatti si occuperà di delegare verso un unico server tutti gli accessi degli amministratori (root per macchine UNIX/LINUX e administrator su Domain controller e/o servers Windows ) della vostra rete, utilizzando un syslog centralizzato e un sistema di memorizzazione a scelta tra:
- i piu costosi devices WORM (Write Once Read Many);
- il gratuito UDF (anche lui scrivibile una sola volta come sui sistemi WORM…. anzi in realtà il 99% dei device WORM usano proprio UDF eheheh );
- ISO9660 magari incapsulandolo in una comunissima immagine ISO;
- o addirittura il performantissimo e almeno per me “nuovo” NILFS (che uso ultimamente sulle /etc dei miei servers linux) , un filesystem a snapshot continui ( http://www.nilfs.org/en/ – “NILFS is a log-structured file system supporting versioning of the entire file system and continuous snapshotting which allows users to even restore files mistakenly overwritten or destroyed just a few seconds ago.”);
Il tutto “accompagnato” magari da un bel HASH corrispondente ;)

Partiamo subito con qualche specifica:
Il sistema potrà essere composto da un normalissimo pc i386 (non servono grossi requisiti hardware) con installata una qualsiasi distribuzione linux totalmente hardenizzata..
io per ulteriore sicurezza ho utilizzato un kernel 2.6.27-10 patchato con grsecurity/pax in modo da limitare (attraverso apposite ACL) perfino le operazioni di root (quando avro’ tempo magari vi parlero’ di grsec :D ) e non ho lasciato, nessun servizio in ascolto (ovviamente nemmeno sshd).
Il servizio di logs centralizzato è servito dal demone syslog che riceve sulla porta 514 UDP i logs delle autenticazioni
da tutte le macchine del nostro CED (nel mio caso gli os maggiormente usati: tru64, hpux e windows).
Il file di configurazione del syslog centralizzato sarà quindi:

#
# /etc/syslog.conf
#

*.emerg *
*.err /var/log/errors
kern.* /var/log/kernel
authpriv.* /var/log/auth
mail.* /var/log/mail
*.!err;mail,kern.none /var/log/messages
auth.info /var/log/SERVERSlogs/auth.info
# Log everything to vc12
# *.* /dev/vc/12

# End of file

In questo post in merito alla fase della memorizzazione dei logs utilizzero’ il filesystem Iso9660 incapsulato in un immagine ISO (inalterabile nel contenuto come vuole il decreto) e sopratutto “depositata” corrispondentemente ad un HASH (ho usato SHA256).

[Piu' avanti, in merito alla memorizzazione dei logs, se avro' tempo magari vi descrivero' altri metodi utilizzando per esempio UDF, WORM o sopratutto NILFS....]

Tale filesystem è stato scelto sia per la sua particolare caratteristica “WORM” ( Write Once Read Many ) sia per la sua compatibilità a sistemi operativi diversi sia ,non meno, alla possibilità di organizzare ogni 6 mesi o prima (come descrive il decreto stesso) una masterizzazione su CD/DVD..
(Io ho preferito utilizzare le immagini ISO ma potremmo perfettamente scrivere direttamente sul DVD senza passare per le ISO utilizzando il già citato UDF e considerando che per aggiungere dati ad un dvd contente altri dati possiamo usare il comando:

# growisofs -M /dev/dvd /tmp/file_da_aggiungere

;) )

..ecco gli scripts che opportunamente inseriti in crontab si occuperanno di fare cio’ che ho descritto:
(PS: occupatevi di crearvi prima le directory :P )

#!/bin/bash
chattr -i -R /root/StoricoLogs
mv /var/log/SERVERSlogs/auth.info /root/StoricoLogs/complauth.info
egrep ‘(dmin|root)’ /root/StoricoLogs/complauth.info > /root/StoricoLogs/`date +%Y%h%d_%H%M`
shasum /root/StoricoLogs/`date +%Y%h%d_%H%M` > /root/StoricoLogs/hashlog`date +%Y%h%d_%H%M`
rm /root/StoricoLogs/complauth.info
chattr +i -R /root/StoricoLogs/*
/etc/rc.d/syslogd restart

questo catalogherà i logs ricevuti su syslog, li filtrerà (prenderà tutto cio’ che riguarda l’auth di utenti root e administrator) e infine creerà un HASH corrispondente allo STEP attuato, riavviando successivamente syslog..

#!/bin/bash
chattr -i /root/StoricoLogs/*
mkisofs -input-charset=utf-8 -J -l -V “`date +%Y%h%d`_Log” -o /root/IsoLogs/`date +%Y%h%d`.iso /root/StoricoLogs/
rm /root/StoricoLogs/*
rm /root/auth

Quest’altro produrrà l’ISO corrispondente allo “STEPlogs” in corso utilizzando come “etichetta” la data/orario di produzione e cancellando successivamente le tracce in modo da ricominciare con un nuovo STEP successivo.

Passiamo adesso alla configurazione dei Client da dove prelevare i logs:
ovviamente @Logserver è l’host corrispondente al nostro serverlogs (inserite la corrispondenza host->ip sul file /etc/hosts oppure nello script inserite @ip)

HPUX 11.x o Linux:

# @(#)B11.23_LR
#
# syslogd configuration file.
#
# See syslogd(1M) for information about the format of this file.
#
mail.debug /var/adm/syslog/mail.log
*.info;mail.none /var/adm/syslog/syslog.log
*.alert /dev/console
*.alert root
*.emerg *
auth.info @logserver

Tru64 4*:

#
# @(#)$RCSfile: syslog.conf,v $ $Revision: 4.1.8.1 $ (DEC) $Date: 2000/10/19 19:13:52 $
#
#
# syslogd config file
#
# facilities: kern user mail daemon auth syslog lpr binary
# priorities: emerg alert crit err warning notice info debug
kern.debug /var/adm/syslog.dated/kern.log
user.debug /var/adm/syslog.dated/user.log
mail.debug /var/adm/syslog.dated/mail.log
daemon.debug /var/adm/syslog.dated/daemon.log
auth.debug /var/adm/syslog.dated/auth.log
auth.info;auth.debug @logserver
*.info;syslog.debug /var/adm/syslog.dated/syslog.log
lpr.info /var/adm/syslog.dated/lpr.log

msgbuf.err /var/adm/crash/msgbuf.savecore

kern.debug /var/adm/messages
*.alert;kern.debug /dev/console
*.emerg *

e infine lo “zoccolo duro” ehhmmm scherzo :P WINDOWS:
Per windows (nel mio caso 2003 server e) dovremmo trovare un buon prodotto in grado di “tradurre”
il sistema dei logs microsoft (EVENTLOGS) per il nostro sistema (SYSLOG)..
esistono diverse possibilità, io ho optato per questa: https://engineering.purdue.edu/ECN/Resources/Documents/UNIX/evtsys
installatelo e configuratelo seguendo queste semplicissime istruzioni http://eventlog-to-syslog.googlecode.com/files/Readme_4.1.rtf ;)

il sistema è pronto per l’uso date la passwd di root al vostro incaricato e ditegli di cambiarla:
da questo momento solo lui, sarà in grado di visualizzare/conservare (ma non modificare) i logs accedendo esclusivamente fisicamente alla console della macchina..
io ho installato una GUI minimale (lxkde) e un frontend di masterizzazione (k3b o brasero) per rendergli le operazioni piu’ semplici ;)
ciao!

Posted in Unix | Tagged , , , | Leave a comment

DRBD e Heartbeat


Dopo le esperienze con i prodotti commerciali di HP e SUN per i filesystem condivisi, l’alta disponibilità, clusters, LB etc. etc. (nel mio caso: service guard, vpars, fs veritas, ldoms e altre diavolerie in ambito HPUX e Sun SOLARIS..) ritorno con piacere alla reatà che preferisco di linux e del software open-source e sopratutto alla facilità ed immediatezza della tastiera/console abbandonando almeno per un po’ :P quelle maledette freccette, i drags and drops, le caselline introvabili e le acrobazie del mouse su quei costosissimi e sempre uguali web_services_java_based che fanno tutto e di più..

apparte le mie paranoie digitali quindi :P cominciamo subito con lo scegliere cosa usare per condividere ai nodi del nostro cluster un unico filesystem..

per realizzare cio’ ho optato per DRBD (dovrebbe essere l’acronimo di distribuited
replicated block device”)..praticamente non è altro che un RAID1 (un mirror)
tra due dispositivi di rete: il suo lavoro è quello di propagare dati da un nodo all’altro(sincronizzare praticamente)..

Partizioniamo su ogni nodo la “parte” che dedicheremo al nostro sistema (non vi dico come si fa, lo sapete già questo) questa partizione verà “letta” dal DRBD che abbiamo installato sul nodo e verà cosi creato il device /dev/drbd*..
lo stesso DRBD poi, attraverso il suo file di configurazione /etc/drbd.conf stabilirà se scrivere o meno sul device in questione (questo in base ai criteri del nodo, se questo è primario allora potrà montare il device in +w).

Per avere una più affidabile configurazione del nostro cluster sarà meglio utilizzare 2 schede di rete ridondanti per ogni nodo, per farlo basterà abilitare il modulo “bonding” del kernel (trovate il modulo sotto “NEtwork device” nel menuconf del kernel) e quindi per ogni nodo del cluster dare:

#modprobe bonding {attiviamo il modulo del kernel linux per il bonding}
#ifconfig bind0 “ip” up {attiviamo l’interfaccia di bonding}
#ifenslave bond0  eth0 eth1 {creiamo il channel bonding nel nostro nodo}

..creeremo quindi anche uno script che faccia il tutto ad ogni riavvio della macchina
in /etc/rc.d/net.bond0 configurando anche /etc/rc.d/ifenslave
(i path ovviamente possono variare a secondo della distribuzione linux che usate ;)

perfetto, dando adesso per scontato che abbiate “fisicamente” predisposto il cluster
[cavo cross tra le schede di rete] [poi vedremo anche di usare un cavo seriale tra
le due porte seriali ;) ] e partizionato le 2 porzioni di fs dedicate a DRBD su ogni nodo.

Configurate DRBD [/etc/drbd.conf] seguendo il solito file di configurazione di esempio
e create quindi il famoso device con:

#mknod -m 0760 /dev/drbd0 b 147 0

avviamo il servizio:

#/etc/rc.d/drbd start

montiamo adesso sul primo nodo il device come master:

#drbdadm — –do-what-I-say primary shared

in questa maniera il device è già su ed è possibile,
dal nodo primario, montare su /shared la nostra partizione condivisa con DRBD..
ovviamente se volete potrete anche utilizzare LVM sui due nodi creando il volume
corrispondente al device di DRBD /dev/drbd0 su ogni macchina del cluster.

per poter gestire adesso il failover del nostro servizio nel nostro cluster useremo Heartbeat:
prima di tutto configuriamo sui due nodi, seguendo il solito esempio, il file ha.cf

## /etc/ha.d/ha.cf
keepalive 1
deadtime 20
warntime 3
initdead 20
serial /dev/ttyS0
bcast eth1
auto_failback yes
node host_del_nodo1
node host_del_nodo2
crm no

successivamente configuriamo /etc/ha.d/haresources sui due nodi inserendo le risorse che migreremo tra le due macchine (quindi nel nostro caso l’unico servizio per il failover è quello di drbd):

hostnodo1 drbddisk::shared script_avvio_lvm Filesystem::/dev/drbd0::/shared0::fs_scelto

(se non lo avete fatto: attivate il supporto a watchdog del kernel e create il corrispondente device:

#mknod /dev/watchdog c 10 130 )

per una maggiore sicurezza infine nel file /etc/ha.d/authkeys impostiamo la crittografia dei dati
tra i nodi:

## /etc/ha.d/authkeys
auth 1
1 sha HeartbeatPassword

diamo i permessi:

# chmod 600 /etc/ha.d/authkeys

e infine riconfiguriamo l’altro nodo con le stesse impostazioni oppure
piu semplicemente:

#scp /etc/ha.d/authkeys root@nodo2:/etc/ha.d/

prima di concludere il tutto vi consiglio un breve periodo di test ed infine un buon tuning per
una piu’ appropiriata scelta dei deadtimes di heartbeat e di tutti gli altri parametri e/o dei filesystem per le partizioni di drdb ;)

PS: Appena avro’  tempo scrivero’ qualche altro appunto in merito alla possibilita’ del load-balancing su linux

utilizzando un unico host con LVS e i nodi linux-director ;)

Saluti! :)

Posted in Unix | Tagged , , , , , | Leave a comment