Virtualització de servidors
Mar 23
Quan tens més de dos servidors, virtualitzar-los és una bona manera de reduir les despeses de hosting. Es tracta de contractar una màquina potent i instal·lar-hi màquines virtuals que substituiran els servidors actuals: una màquina amb molta RAM, per poder-la repartir entre els servidors virtuals, i una bona CPU.
Hi ha moltes companyies de hosting que ofereixen màquines amb aquestes característiques i aquí hi ha un bon llistat de les que ofereixen Debian. Nosaltres, en aquest cas, hem escollit Hetzner.de que té preus molt competitius.
Amb el servidor ex4s tindrem una màquina de 32 GB de RAM, amb un processador Intel i7 i un RAID1 de 3TB per 59€ al més, IVA inclòs. Com que necessitem més IP’s per les màquines virtuals, demanarem una subxarxa de 6 IP, que costa 5,40€. Per poder demanar les IP cal pagar una cosa que han batejat com a “flexi pack” i que ens costarà 15€ cada més. Al contractar el servidor també haurem de pagar 149€ en concepte de posada apunt. Fent la suma, apart dels 149€ inicials, el cost mensual serà d’uns 80€, realment és un preu molt competitiu per un servidor d’aquestes característiques.
Un cop demanat, en un o dos dies ja tenim el servidor instal·lat amb el sistema operatiu que hagem escollit, que en el nostre cas és “Debian 6.0 minimal”. Entrem per SSH i instal·lem el Puppet que ens configura automàticament les alertes de Nagios, gràfiques de Munin, etc.. i ja podem centrar-nos en la virtualització.
Discs
Per defecte tot el disc està particionat i muntat, si volem fer servir volums LVM cal desmuntar una de les particions i configurar-lo amb LVM.
Escollim la partició a eliminar, en aquest cas /home
Filesystem Size Used Avail Use% Mounted on
/dev/md2 1016G 281G 684G 30% /
tmpfs 7.8G 0 7.8G 0% /lib/init/rw
proc 0 0 0 - /proc
sysfs 0 0 0 - /sys
udev 7.8G 168K 7.8G 1% /dev
tmpfs 7.8G 0 7.8G 0% /dev/shm
devpts 0 0 0 - /dev/pts
/dev/md1 496M 38M 434M 8% /boot
/dev/md3 1.7T 196M 1.6T 1% /home
La desmuntem (si volem conservar-ne les dades caldrà copiar-les a una altre partició) i configurem l’LVM
pvcreate /dev/md3
vgcreate vg0 /dev/md3
Cal treure l’entrada que munta /home del fitxer /etc/fstab.
A partir d’aquí podrem afegir un “storage pool” del tipus “LVM Volume Group” fent servir el virt-manager
KVM
KVM (Kernel Based Virtual Machine) és el software que farem servir per la virtualització. L’instal·lem amb l’apt:
Quan tinguem corrent el dimoni libvirt-bin, ens hi podrem connectar per crear màquines virtuals i gestionar-les. Podem fer servir virtinst a la línia de comandes o bé una aplicació d’escriptori que es diu virt-manager.
També podem migrar els servidors actuals a màquines virtuals seguint el mètode d’aquest post.
Configuració de xarxa
Hem seguit aquesta pàgina (en alemany) del wiki de Hetzner. També hi ha aquesta pàgina on s’explica una altre manera de configurar la xarxa, un pèl més complicada.
Bridge
Per poder assignar IP’s públiques a les màquines virtuals, configurarem un bridge, un dispositiu virtual que agafa els paquets d’una interfície i els enruta cap a una altre de manera transparent. La idea és fer el bridge i connectar-hi la eth0 i les màquines virtuals, tal com si estiguessin totes connectades al mateix switch de xarxa, per configurar el bridge de manera permanent hem de modificar /etc/network/interfaces:
auto eth0
iface eth0 inet manual
auto br0
iface br0 inet static
address 1.2.3.174
broadcast 1.2.3.191
netmask 255.255.255.224
gateway 1.2.3.161
pointopoint 1.2.3.161
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
# si ho fessim amb route add -net perdriem 2 IP's:
up route add -host 3.4.5.216 dev br0
up route add -host 3.4.5.217 dev br0
up route add -host 3.4.5.218 dev br0
up route add -host 3.4.5.219 dev br0
up route add -host 3.4.5.220 dev br0
up route add -host 3.4.5.221 dev br0
up route add -host 3.4.5.222 dev br0
up route add -host 3.4.5.223 dev br0
Hem deixat eth0 sense IP i li hem donat al bridge br0 la IP principal (1.2.3.174). Afegim una ruta per cada host de la subxarxa que ens ha tocat. Es podria fer amb una sola línia amb “route add -net” però no podríem usar les IP de xarxa i de broadcast, fent-ho host per host aprofitem les 8 IP.
Creem el fitxer /etc/sysctl.d/10-no-icmp-redirects.conf i hi afegim:
# Because of our network setup, the Host machine could send ICMP
# "redirect" messages to all guests, telling them to find the Hetzner
# gateway directly. That is impossible: Hetzner would throw away the
# traffic from the virtual interfaces because of their non registered
# MAC addresses (ie different from the main interface).
net.ipv4.conf.eth0.send_redirects=0
net.ipv4.conf.br0.send_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
Podem aplicar-ho amb:
/sbin/sysctl -w net.ipv4.conf.br0.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.all.send_redirects=0
/sbin/sysctl -w net.ipv4.conf.default.send_redirects=0
també cal activar l’ip_forward però això ho farem amb el Shorewall.
Tallafocs
Per configurar les regles de tallafocs farem servir Shorewall. Els fitxers de configuració estaran a /etc/shorewall. Hi podem copiar els exemples de /usr/share/doc/shorewall/default-config/ , ja que per defecte /etc/shorewall és buit.
Al fitxer zones podem separar conceptualment la xarxa en varies zones: la zona local (el tallafocs, fw), Internet (net) i les màquines virtuals (kvm). Com que net i kvm estan a br0, tenim dues zones a la mateixa interfície. Per separar aquestes zones hem d’especificar quins hosts pertanyen a cada zona, tal com s’explica aquí. El fitxer zones queda així:
##############################################################################
#ZONE TYPE OPTIONS IN OUT
# OPTIONS OPTIONS
fw firewall
net ipv4
kvm:net ipv4
La zona kvm està inclosa a la zona net, per especificar quins hosts pertanyen a kvm cal indicar-ho al fitxer hosts, així tot el que estigui a la zona net i dins els rangs de xarxa 3.4.5.216/29 i 192.168.1.0/24 (el rang que configurarem al dhcp) serà de la zona kvm, la resta serà net.
##############################################################################
#ZONE HOST(S) OPTIONS
kvm br0:3.4.5.216/29,192.168.1.0/24 -
A interfaces és on assignem les interfícies a una zona, en aquest cas estem assignant br0 a la zona net
##############################################################################
#ZONE INTERFACE BROADCAST OPTIONS
net br0 detect tcpflags,nosmurfs,routeback,blacklist,dhcp
A policy definim les polítiques per defecte, hem configurat que s’accepti tot el trànsit de sortida del tallafocs i de la zona kvm, la resta es denega (drop).
##############################################################################
#SOURCE DEST POLICY LOG LIMIT: CONNLIMIT:
# LEVEL BURST MASK
$FW all ACCEPT
kvm net ACCEPT
net kvm DROP info
all all DROP info
A rules definim polítiques específiques que sobreescriuen les anteriors, aquí estem definint que s’acceptin les connexions SSH entrants i els ping, però cap a kvm només els pings:
####################################################################################################################################################
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME
# PORT PORT(S) DEST LIMIT GROUP
#SECTION ESTABLISHED
#SECTION RELATED
SECTION NEW
# transit cap al FW
SSH/ACCEPT net $FW
SSH/ACCEPT kvm $FW
Ping/ACCEPT net $FW
Ping/ACCEPT kvm $FW
# transit cap a KVM
Ping/ACCEPT net kvm
També hem modificat shorewall.conf per activar l’ip_forward:
#IP_FORWARDING=Keep
IP_FORWARDING=Yes
Configuració de xarxa de la màquina virtual
Configurem una IP de la subxarxa que ens han assignat i posem la IP principal de la màquina host com a porta d’enllaç, cal posar el pointopoint per indicar que tot el trànsit ha de passar per 1.2.3.174, cal tenir en compte que la màquina virtual no pot parlar directament amb el gateway de Hetzner, ja que l’adreça MAC de la màquina virtual és desconeguda i la rebutgen.
auto eth0
iface eth0 inet static
address 3.4.5.216
netmask 255.255.255.255
gateway 1.2.3.174
pointopoint 1.2.3.174
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 213.133.98.98 213.133.99.99
Configuració DHCP
Ens pot resultar útil tenir un servidor DHCP per instal·lar noves màquines virtuals sense haver de configurar manualment la xarxa. Configurar-lo ha sigut una mica complicat: el que hem fet és afegir una IP d’un rang privat al bridge br0.
auto br0:0
iface br0:0 inet static
address 192.168.1.1
broadcast 192.168.1.255
netmask 255.255.255.0
Al dhcpd.conf hem afegit aquesta declaració:
subnet 0.0.0.0 netmask 0.0.0.0 {
range 192.168.1.10 192.168.1.200 ;
option routers 192.168.1.1;
option subnet-mask 255.255.255.0;
option domain-name-servers 213.133.99.99, 213.133.100.100, 213.133.98.98;
}
Hem provat de configurar-ho amb “subnet 192.168.1.0 netmask 255.255.255.0” però sembla que al dhcpd no li agrada que li configuris el rang de l’àlies br0:0 i fallava l’arrencada amb aquest error:
Només queda configurar el NAT al Shorewall perquè enruti el trànsit de 192.168.1.0/24:
##############################################################################
#INTERFACE SOURCE ADDRESS PROTO PORT(S) IPSEC MARK USER/
# GROUP
br0 192.168.1.0/24
Conclusions
El preu d’una màquina virtual auto-gestionada d’aquesta manera és molt més baix que qualsevol altre màquina virtual de proveïdors com Linode, Rackspace o Amazon. Per exemple, una màquina virtual de 1 GB de Linode val 30€ i en el que hem muntat n’hi caben 30. El cost és 10 vegades menor.
El sistema de virtualització KVM, Linux i tot el software que hem utilitzat és lliure i no està subjecte a costoses llicències. Així doncs en el preu no hi hem de sumar cap llicència, cosa que si que hauríem de fer en el cas d’haver triat fabricants com Microsoft i VMware.
Com a contrapartida si la màquina física falla, fallen totes les màquines virtuals. Així doncs és aconsellable tenir, com a mínim, dos servidors per si un falla poder arrencar un backup de la màquina virtual a l’altre.
Accelerar el temps de càrrega de les aplicacions RubyOnRails
Mar 23
A vegades quan accedim a una aplicació RubyOnRails notem que la primera petició triga molt i després ja va més fluït. Això passa perquè a la primera connexió el Passenger ha de carregar l’aplicació en memòria, quan es deixen de rebre peticions durant un cert temps, el Passenger la descarrega i a la següent petició caldrà tornar a aixecar-la.
Podem evitar aquesta espera si mantenim sempre una o més instàncies de l’aplicació aixecades. Passenger ens permet configurar-ho amb el paràmetre PassengerMinInstances
PassengerPoolIdleTime 10
<VirtualHost *:80>
ServerName foobar.com
DocumentRoot /webapps/foobar/public
PassengerMinInstances 3
</VirtualHost>
amb aquesta configuració tindrem com a mínim sempre tres instàncies aixecades per servir peticions, excepte quan acabem d’engegar l’Apache, ja que per defecte el Passenger no carregarà les instàncies. Podem fer que es carreguin a l’engegar l’Apache amb PassengerPreStart:
PassengerPoolIdleTime 10
<VirtualHost *:80>
ServerName foobar.com
DocumentRoot /webapps/foobar/public
PassengerMinInstances 3
</VirtualHost>
PassengerPreStart http://foobar.com/
Així en arrencar l’Apache es farà una petició a la URL indicada i es carregaran les instàncies de Passenger.
Al comprovar la nova configuració, ens surt aquest error:
Syntax error on line 4 of /etc/apache2/sites-enabled/foobar.com.conf:
Invalid command 'PassengerMinInstances', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.
és perquè la versió de Passenger que porta Debian Squeeze (2.2.11debian), encara no suporta PassengerMinInstances, desinstal·lem el paquet libapache2-mod-passenger i instal·lem el Passenger amb Rubygems:
<IfModule mod_passenger.c>
PassengerRoot /var/lib/gems/1.8/gems/passenger-3.0.11
PassengerRuby /usr/bin/ruby1.8
</IfModule>
LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-3.0.11/ext/apache2/mod_passenger.so
[root@webserver ~]# /etc/init.d/apache2 restart
Estacions de treball Linux per usuaris de Windows
Feb 28
Aquests dies hem estat enfeinats amb el projecte pilot d’una migració d’escriptoris Windows XP cap a Linux. L’objectiu és eliminar totes les instal·lacions de Windows del parc de PCs.
La distribució de Linux que hem escollit és LMDE, l’Edició Debian de Linux Mint. Es tracta d’una rolling release de Debian testing, que porta un escriptori més atractiu que el Gnome 2 pelat de Debian Squeeze.
Aquests són alguns apunts de les coses que hem anat fent.
LMDE Update pack 3
Una vegada instal·lat el LMDE 201109 Gnome 64-bit cal actualitzar-lo amb l’Update Pack 3. Per fer-ho hem de modificar el /etc/apt/sources.list així:
deb http://packages.linuxmint.com/ debian main upstream import
deb http://debian.linuxmint.com/latest testing main contrib non-free
deb http://debian.linuxmint.com/latest/security testing/updates main contrib non-free
deb http://debian.linuxmint.com/latest/multimedia testing main non-free
i fer
si el procés es queda encallat amb aquest error
cal forçar la instal·lació del paquet gstreamer0.10-plugins-bad a mà
sudo apt-get install
sudo apt-get dist-upgrade
Wine
Com que a Debian Wheezy no hi ha wine, i la versió d’Squeeze és una mica antiga, hem optat per instal·lar-lo des de lamaresh.net seguint el seu repositori:
deb http://www.lamaresh.net/apt squeeze main
i l’instal·lem amb
sudo defoma-app purge libwmf0.2-7 # (recomanat pel dpkg)
AutoCAD
Com a alternativa gratuïta a l’AutoCAD instal·lem el DraftSight per Linux de Dassault Systèmes. No és programari lliure i requereix que l’usuari es registri per obtenir una llicència d’ús gratuïta, però permet treballar amb arxius DWG i és força similar per l’usuari.
Firefox
El Firefox que porta el Mint ens dóna molts problemes, decidim instal·lar l’Iceweasel de l’equip Mozilla de Debian, que sempre està a la última versió i funciona millor. Seguim el seu repositori:
deb http://backports.debian.org/debian-backports squeeze-backports main
deb http://mozilla.debian.net/ squeeze-backports iceweasel-release
eliminem el Firefox de LMDE i instal·lem el Iceweasel:
apt-get install -t squeeze-backports iceweasel iceweasel-l10n-ca
Internet Explorer
La part que ens ha donat més problemes ha sigut fer anar una aplicació web dissenyada per funcionar únicament amb Internet Explorer i Jinitiator. Hem provat totes aquestes estratègies:
- Executar el Internet Explorer 6 amb Wine mitjançant winetricks. Aquesta opció no permet instal·lar certificats de client.
- Executar el Internet Explorer 6 amb Wine mitjançant l’instal·lador ie4linux. Aquesta permet instal·lar certificats, però el Jinitiator no s’instal·la.
- Fer varis hacks al Firefox perquè es comporti com un Internet Explorer: modificar el ‘User-agent’, utilitzar Java en comptes de Jinitiator, fer compatibles les pàgines que genera el servidor amb un script de greasemonkey, etc.
Malauradament cap d’elles ha funcionat al 100%. Això vol dir, en resum, que necessitarem almenys una llicència de Windows. I tot gràcies a una aplicació web que només funciona amb el navegador Internet Explorer.
Accedir a Windows XP amb Seamless RDP
Així doncs ens veiem obligats a mantenir un màquina amb Windows XP amb l’únic objectiu de fer funcionar un Internet Explorer. Com que el client disposa d’un servidor Linux amb KVM, decidim posar un Windows XP virtualitzat al sevidor Linux. Així no cal carregar la màquina virtual al PC de l’usuari cada vegada que aquest vulgui fer servir el Internet Explorer. La màquina virtual està sempre engegada i a punt per rebre connexions. Des del Linux accedirem al Internet Explorer de la màquina virtual Windows XP mitjançant el protocol RDP (Remote Desktop Services, abans conegut com a Terminal Services) de Microsoft amb el client rdesktop.
El concepte d’accedir a una sola finestra del Internet Explorer, i no a tot l’escriptori del Windows, s’anomena “seamless RDP”. Per aconseguir-ho, al Windows XP, descarreguem el SeamlessRDP i el descomprimim a C:\seamlessrdp. També és necessari que els usuaris es puguin connectar de forma remota activant-ho a “Mi PC -> Propiedades -> Remoto -> Permitir que los usuarios se conecten de manera remota”.
Ara ja podem obrir l’Internet Explorer des de Linux amb la comanda rdesktop:
Tunning del Seamless RDP a Debian
La versió de rdesktop que porta el LMDE, està afectada per un bug que fa que es mostri un doble marc de finestra (el de Windows i el de Linux al voltant). Inclús es mostra un marc al desplegar els menús de les aplicacions. Per solucionar-ho provem d’instal·lar el rdesktop de Debian Squeeze, que és una versió anterior que no està afectada pel bug, però falla molt sovint. Finalment fem servir un solució alternativa del bug que implica configurar i utilitzar el Compiz com a gestor de finestres.
A l'”editor de la configuració de compiz” activar “regex matching”. Activar també “decoració de la finestra” i al camp “Decoration Windows” hi posem:
Per últim, activem el compiz amb:
Windows XP amb vàries sessions RDP concurrents
Si volem fer servir l’Internet Explorer des de varis PC ens trobarem amb el problema de que Windows XP, senzillament, no permet connexions concurrents. Així doncs si un usuari inicia sessió al Windows XP es tancaran totes les sessions RDP que hi pogués haver obertes en aquells moments. Tot i ser un sistema multi-usuari i ser tècnicament possible, el Windows XP te aquesta política de només permetre una única sessió RDP simultània.
Seria possible saltar-se aquesta limitació aplicant aquest pegat de termsrv.dll. Es tracta d’unes modificacions que Microsoft va publicar per error en una beta del SP2 de Windows XP i que elimina la limitació d’una única sessió RDP simultània. Amb aquesta modificació, amb una sola instal·lació Windows XP es podria donar servei RDP a tots els usuaris Linux de la xarxa local.
Impressora Canon MP620
Per fer funcionar una Canon MP620 ens hem valgut d’aquest script. Amb això pot fer tant d’impressora com de scanner.
chmod +x mp620-630univ
sudo ./mp620-630univ
DOSBox
Com a part de la migració des de Windows XP hem hagut de fer anar un programa de MS-DOS. Afortunadament tenim l’emulador DOSBox als repositoris de Debian. Una vegada instal·lat el DOSBox, configurem alguns paràmetres al nostre gust a ~/.dosbox/dosbox-0.74.conf, per exemple que engegui a pantalla complerta i tingui el teclat ben configurat:
fullscreen=true
# el teclat
keyboardlayout=es
[autoexec]
# fer que la c:\ sigui ~/dosbox_c
mount c /home/user/dosbox_c
Conclusions
Els usuaris accepten amb naturalitat el canvi si tot funciona perfectament: impressores, escànners, accés als servidors, resolució de la pantalla, etc. fins al mínim detall. L’acceptació és major en els usuaris que ja utilitzaven Firefox, Thunderbird i LibreOffice o OpenOffice.
La substitució dels escriptoris Windows per escriptoris Linux és fàcil si s’accepta que no pot ser una substitució complerta. El 90% de les aplicacions Windows tenen un equivalent en Linux o bé poden funcionar sobre Wine, però el 10% no. Això no es cap problema si acceptem mantenir una màquina amb Windows per posar-hi les aplicacions que no funcionen de cap manera en Linux.
Passar de n escriptoris amb Windows a un de sol permet estalviar llicències i despeses de manteniment.
Les aplicacions que no funcionen sobre Linux son, irònicament, aplicacions web.
Presentació comercial 2012
Feb 6
Presentació dels nostres productes en el Primer Simpòsium que es va fer a Vilafranca del Penedès, Barcelona, el dia 3 de febrer de 2012.
De màquina física a virtual tirant pel dret
Jan 20
Aquest és el mètode P2V que hem usat per transformar un servidor Linux físic a una màquina virtual que corri sobre KVM. Es tracta d’un mètode de virtualizació expeditiu que consisteix en bolcar el contingut de tot el disc al servidor on allotjarem la nova màquina virtual. Per anar bé el servidor origen s’hauria d’aturar i arrancar-lo en mode rescue, per així fer la còpia amb els sistemes d’arxius desmuntats, però en el nostre cas no podíem apagar el servidor origen. Amb aquest procediment es pot moure la màquina sense problemes.
Còpia del disc físic
Al servidor destí, deixem el netcat escoltant a un port (a l’exemple, 43333), redirigint tot el que es rebi cap a un fitxer. Podem deixar les comandes en un screen i així podrem tancar la sessió si tarda massa.
Al servidor origen (el que volem virtualitzar) amb la comanda dd bolquem el contingut del disc, el comprimim i amb nc l’enviem cap al port 43333, on escolta el servidor destí amb la comanda anterior. La comanda gzip comprimeix les dades i redueix el volum a transferir. Aquest disc era de 72 GB i va tardar 4 hores a 10 Mbps, passant per Internet.
La sintaxi de la comanda nc pot variar segons el paquet que tinguem instal·lat (les de l’exemple són amb netcat-openbsd)
Revisió dels sistemes d’arxius
Un cop acabada la transferència tenim una imatge del disc a disk.raw. Però com que el servidor origen estava engegat mentre la fèiem, cal fer un fsck de les dades. A Linux podem configurar un fitxer per a que sigui tractat com a un dispositiu, assignant-lo a un dispositiu loop:
Comprovem quin és el següent dispositiu loop lliure:
/dev/loop0
Assignem disk.raw a loop0, així accedit al dispositiu /dev/loop0 estarem accedint al fitxer disk.raw
Ara cal llegir les particions de loop0 i crear-ne els dispositius oportuns per a poder-hi accedir, ens servim de kpartx
Ja tenim les particions accessibles a /dev/mapper/loop0pX i ja podem fer un fsck
fsck.ext3 -f /dev/mapper/loop0p2
...
En aquest punt també podem muntar les particions per comprovar que els arxius hi son i aprofitar per corregir els noms dels dispositius a /etc/fstab.
Abans d’engegar la màquina virtual, cal desfer aquest procés per evitar danys al sistema de fitxers
losetup -d /dev/loop0
Creació de la màquina virtual
Creem la màquina virtual al KVM, li assignem el disc i provem d’arrencar-la.
És possible que no arranqui perquè hagi canviat el nom del dispositiu del disc i no trobi el sistema de fitxers arrel. Mitjançant la consola de KVM haurem d’arreglar la línia al GRUB o al LILO, corregint la opció root= de la línia del kernel, i un cop engegada, modificar el fitxer /etc/fstab.
En el nostre cas /dev/cciss/c0d0p[n] passa a ser /dev/hda[n]
Retocs finals
Cal configurar la nova interfície virtual de xarxa i comprovar que els serveis funcionin correctament.
Durant el temps que hem tardar a fer la virtualització, les dades del servidor físic original han canviat. S’han de sincronitzar abans de fer el canvi. Així doncs aturem el servei dins una finestra d’actuació, sincronitzem les dades i ja podem canviar les zones DNS. El temps en que els usuaris han estat sense servidor ha estat mínim.

Recuperació d’un Software Linux RAID 5
Dec 3
Aquesta és una història d’una matriu de discs que contenia una instal·lació de Zimbra amb uns 100 usuaris. És una història amb final feliç, perquè les dades s’acaben recuperant, però a la vegada és una tragicomèdia sobre les misèries de l’administració de sistemes.
El problema
Hi havia una vegada un servidor HP ProLiant ML310 G3 que tenia un disc de sistema (/dev/sda) de 80 GB i un RAID 5 de dades (/dev/md0) format per 3 discs de 160 GB (/dev/sd[bcd]1). Tot va anar bé fins que el servidor es va quedar durant un temps al passadís (!) i els discs van estar-se sis mesos a 60 graus. A més a més la persona que se’n encarregava va considerar que la millor manera de que estiguessin més fresquets era treure la tapa lateral al servidor. Això només va fer que empitjorar el problema, perquè el flux d’aire que injecten els ventiladors posteriors, tant bon punt entra a la torre surt per el lateral i no passa per la cabina de discos.
No es d’estranyar que aviat un dels tres discs de la matriu (el /dev/sdd) comencés a donar avisos SMART de que tenia problemes:
(...)
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Short offline Completed: read failure 60% 42169 312570497
# 2 Short offline Completed: read failure 60% 42145 312570998
# 3 Extended offline Completed: read failure 10% 42121 312570999
(...)
Es va demanar un disc de recanvi que mai va arribar. No es va insistir prou? No ho sé. La qüestió és que al cap de quatre mesos un dels altres discs va deixar de funcionar de sobte, sense cap avís. El SMART va avisar després que /dev/sdb comencés a donar I/O errors.
El kernel de seguida va treure el disc de la matriu i llavors nosaltres intentem treure’l i tornar-lo a posar a dins (què!? a vegades funciona):
Personalities : [raid5]
md0 : active raid5 sdb1[3] sdd1[2] sdc1[1]
312576512 blocks level 5, 256k chunk, algorithm 2 [3/2] [_UU]
[>....................] recovery = 0.0% (147328/156288256) finish=353.1min speed=7366K/sec
però en aquest cas no funciona perquè el disc sdb està realment KO:
Nov 25 09:51:42 arxiver023 kernel: end_request: I/O error, dev sdb, sector 510663
Aquest cop demanem un disc que sí que arriba. Així doncs canviem el disc sdb per el nou i tot arreglat, no? La matriu es reconstruirà utilitzant la informació de paritat que hi ha a sdc i sdd. Com que no tenim una controladora hot swap hem de parar el servidor, canviar el disc sdb, i tornar a engegar el sistema que per cert és un CentOS 4.9.
Però no és així perquè el disc sdd te sectors que no es poden llegir!
Dec 1 20:30:33 arxiver023 kernel: end_request: I/O error, dev sdd, sector 312570439
...
La matriu queda en una situació llastimosa en la que es nega a engegar-se. Ah! i el millor és que no hi ha copia de seguretat. FAIL!
La solució
Tal com diu la Guia de l’Autoestopista Galàctic: “Don’t Panic!”. Aquest és el check list d’emergència:
- Comunicar als usuaris que s’estaran una bona estona sense accés al servei
- Fer una copia de seguretat del que queda dels discos
- Engegar el que queda de la matriu i treure’n les dades que es pugui
- Tornar a crear la matriu amb discos bons
- Posar-hi les dades del punt #3 altre cop a dins
Backup dels discos
Amb dd fer una còpia dels discos que formen el RAID 5, perquè mai se sap què li pot passar als discos mentre intentem refer la matriu:
dd if=/dev/sdc1 of=/mnt/usb/sdc1.dd bs=4k
dd if=/dev/sdd1 of=/mnt/usb/sdd1.dd bs=4k
En el sdd dóna errors de lectura “dd reading `/dev/sdd1′: Input/output error” i el fitxer sdd1.dd és més petit. En cas de que en els passos posteriors féssim malbé algun disc podríem crear els dispositius de blocks amb els fitxers
Recrear la matriu
Donar un cop d’ull a les instruccions per recuperar un RAID de kernel.org que aplicades al nostre cas:
mdadm: /dev/sdc1 appears to be part of a raid array:
level=5 devices=3 ctime=Sat Dec 3 09:45:25 2011
mdadm: /dev/sdd1 appears to be part of a raid array:
level=5 devices=3 ctime=Sat Dec 3 09:45:25 2011
Continue creating array? y
mdadm: array /dev/md0 started.
Això substituirà les metadades md que hi ha als discos i assumirà que el que contenen és el que li diem nosaltres, és a dir un RAID 5 amb chunk size de 256k. És important posar el chunk size que toqui. També és important posar un dispositiu missing, ja que si els posem tots tres de seguida es posa a reconstruir la matriu i això no ho volem perquè el disc sdd te sectors defectuosos.
Si hem encertat l’estructura a /dev/md0 hauria d’haver-hi el sistema d’arxius o, com en el nostre cas, el LVM. Per muntar-ho fem:
lvchange -a y /dev/vg1/data # activar el volume group
mount /dev/mapper/vg1-data /mnt/array/ -o ro
rsync -a -v /mnt/array /mnt/usb/ # salvar les dades
Amb això copiem les dades a un altre sistema d’arxius, en el nostre cas un disc USB. Si hi ha sort els sectors defectuosos no afectaran a l’estructura del ext3 ni a cap de les dades que conté. En tot cas el més probable és que algun fitxer no es pugui recuperar.
A partir d’aquí només queda tornar a crear una matriu, fer un rsync de les dades cap a dins la matriu i tornar a engegar els serveis. En el nostre cas hem hagut de prescindir del RAID 5 i fer un RAID 0 (amb LVM) perquè no tenim cap disc de recanvi.
Conclusions
Fer copia de seguretat. Si el client no ho vol: insistir. Cap RAID pot evitar la pèrdua de dades. Insisteixo: fer copia de seguretat.
Substituir de seguida qualsevol disc amb errors al SMART. Especialment si és part d’un RAID 5.
Fer un check periòdic del RAID per evitar que els sectors defectuosos passin desapercebuts. Versions més noves de mdadm ja porten un cron per fer-ho. Per exemple a Debian /etc/cron.d/mdadm executa /usr/share/mdadm/checkarray cada primer diumenge de mes.
El rendiment d’escriptura d’un RAID 5 és patètic. Un cop tret el RAID 5 el sistema és més ràpid. Ara la CPU ha d’esperar menys a que el Kernel escrigui a disc (hi ha menys iowait).
Dubto molt que amb un RAID hardware s’hagués pogut recuperar les dades. La llibertat d’un Linux Software RAID sobrepassa qualsevol consideració de rendiment.
Aspectes tècnics de PEPPOL
Nov 16
Aquí explicaré aspectes tècnics referents a enviar i rebre documents mitjançant PEPPOL, que son les inicials de “Pan-European Public Procurement OnLine”. Un projecte pilot que va sobre la contractació pública en línia a Europa que quan estigui en marxa servirà per intercanviar documents electrònics amb l’administració pública europea. Aquesta informació tècnica és pública, però està escampada en forums i documents de tot tipus.
Arquitectura
Els tres elements de l’arquitectura son els AP, els SMP i un únic SML.
- AP = Access Point. És el servei que permet rebre documents de Peppol. Per exemple ap.b2brouter.com
- SMP = Service Metadata Publisher. És el servei que permet publicar les dades del participants. Per exemple dir a quin AP s’ha d’enviar un cert tipus de documents. Un exemple de SMP seria smp.b2brouter.com
- SML = Service Metadata Locator. És un servidor DNS que donat un destinatari et dóna el SMP on hi ha publicades les seves dades. El domini de la zona DNS és peppolcentral.org.
Certificats
Els participants s’identifiquen i s’autoritzen mitjançant una PKI X.509. Al projecte pilot hi ha una root CA i tres CA intermèdies on la “PEPPOL Root Test CA” signa les tres CA intermèdies.
Es necessiten dos certificats, el de l’AP i el del SMP. Existeix un tercer certificat, que es diu STS, que no es fa servir. Per obtenir aquests certificats s’ha de demanar participar en el pilot PEPPOL.
- El certificat de l’AP està signat per la “PEPPOL Access Point Test CA”. Serveix per poder enviar a altres AP i rebre d’altres AP.
- El certificat del SMP està signat per la “PEPPOL Service Metadata Publisher Test CA”. Serveix per poder publicar entrades DNS al SML.
- El STS està signat per la “PEPPOL Security Token Service Test CA” i de moment no serveix per a res.
Enviar documents
És evident que per poder enviar s’ha de saber l’adreça del destinatari, i en el cas de Peppol l’adreça del destinatari és un Participant ID, un Process ID i un Document ID.
Per enviar un document el primer pas és esbrinar quin és l’AP del destinatari. Per fer això s’agafa l’adreça del destinatari (el participant, el procés i el document) i s’utilitza el SML i un SMP:
- El Participant ID es converteix a una zona DNS mitjançant un hash MD5, un prefixe “B-” i un sufixe. Per exemple el Participant ID “9912:esb63276174” es converteix en “B-ae2866398fd1d4c0d35343e8464a5258.iso6523-actorid-upis.sml.peppolcentral.org”
- La zona DNS es resol i s’obté una IP. Aquesta IP és la del SMP, que és el lloc on hi ha la informació referent al Participant ID que busquem. En l’exemple, la zona resol al CNAME smp.b2brouter.com i finalment a la IP del SMP.
- Finalment s’accedeix per HTTP a les dades del Participant ID que el SMP té publicades mitjançant la URL http://B-ae2866398fd1d4c0d35343e8464a5258.iso6523-actorid-upis.sml.peppolcentral.org/complete/iso6523-actorid-upis::9912:esb63276174
Un cop es coneix la URL del AP destí només cal enviar-li el document mitjançant el que anomenen “Secure Trusted Asynchronous Reliable Transport” o START per als amics, que defineix com els AP han d’utilitzar aquestes 5 tecnologies per comunicar-se:
- SOAP 1.1 – Simple Object Access Protocol.
- WS-Security 1.1 – a flexible and feature-rich extension to SOAP to apply security to web service.
- WS-Transfer – a specification defining the transfer of an XML-representation of an WS-addressable resource – as a standard approach to accessing the message channels.
- WS-ReliableMessaging 1.1 – a protocol that allows SOAP messages to be reliably delivered between distributed applications.
- SAML 2.0 – Security Assertion Markup Language – an XML-based open standard for exchanging authentication and authorization data between security domains.
Per sort la implementació de referència és en Java i Java ja té totes les llibreries ws-* necessàries.
Keystores Java
És molt important tenir clar quins certificats van a cada element de l’arquitectura:
- Tant el client com el servidor AP necessiten el certificat signat per la “PEPPOL Access Point Test CA” per poder enviar i rebre. Crearem una keystore i li direm ap.jks
- El SMP necessita el certificat signat per la “PEPPOL Service Metadata Publisher Test CA” per poder actualitzar les entrades DNS en el SML. Crearem una alta keystore i li direm smp.jks
- Necessitem també una keystore addicional per posar-hi els certificats en els que confiem. N’hi direm peppol-cacerts.jks
Per crear les keystores podem utilitzar el Portecle perquè el keytool és força críptic. Coses a tenir en compte:
- Posar l’alias “1” a la clau privada.
- Posar “peppol” de password, tant a la keystore com a la clau privada.
- Utilitzar l’opció “Import CA Reply” amb botó dret sobre la clau privada “1”, per afegir el nostre certificat signat per la CA.
- La keystore del servidor AP només pot tenir un certificat, perquè agafa el primer que troba i si en tingués més es podria confondre pobrissó.
Implementacions
Les implementacions que hem fet servir son Open Source:
- Servidor Access Point – Java web application, projecte Netbeans
- Client per enviar a un Access Point – Java application, projecte Netbeans
- Servidor Service Metadata Publisher – Java web application, projecte Maven
- Client per gestionar entrades al Service Metadata Publisher – Java application, projecte Maven
- Client per gestionar entrades al Service Metadata Locator – Java desktop application, projecte Maven
Evitar el backscatter de el Postfix davant d’un Exchange
Nov 14
Backscatter? Bé, sí, això passa quan tenim un filtre de correu que està davant d’un MTA on hi ha les bústies d’e-mail, però el filtre no sap quins destinataris existeixen al MTA i quins no.
Aquí expliquem com dir-li a un filtre Postfix quins son els destinataris d’un MTA Exchange i així evitar fer backscatter (en català seria algo així com “retrodispersió”).
Què és el Backscatting?
Al rebre un correu per una adreça que no existeix, el servidor hauria de rebutjar-lo durant la conversa SMTP, quan l’origen encara està connectat. Així l’origen pot informar del problema al remitent real del correu. En canvi, si el servidor accepta el correu, al no poder-lo lliurar ha de generar un bounce que anirà a parar al remitent que posi al correu. Els spammers manipulen els remitents dels missatges, i un servidor mal configurat acaba enviant spam en forma de bounces. A aquest tipus de spam se l’anomena Backscatter.
Postfix davant d’un Exchange
En el nostre escenari tenim un Postfix que es dedica a rebre correu, passar-lo per l’antispam, per l’antivirus i demés, per finalment lliurar-lo a un Microsoft Exchange. Com que aquest servidor no té les bústies, acceptàvem tot el correu que fos per als dominis propis i al cap d’un temps ja teníem la IP a una llista negra per enviar Backscatting.
Per solucionar-ho hem de saber quines bústies hi ha a l’Exchange. Només així podrem rebutjar correus dirigits a destinataris que no existeixen.
La part senzilla és configurar el Postfix, al main.cf afegim relay_recipient_maps, per a que comprovi les adreces a més dels dominis.
relay_recipient_maps = hash:/etc/postfix/relay_recipients
i creem /etc/postfix/relay_recipients amb la llista de bústies, té aquesta pinta:
bar@example.com OK
cal fer un postmap i un reload del postfix
/etc/init.d/postfix reload
Mantenir el llistat actualitzat
Ara ja no generem Backscatting, però cal mantenir actualitzat el llistat de bústies. Aquest llistat està a l’ActiveDirectory i per obtenir-lo hem agafat aquest script en VBS, i l’hem adaptat:
' file virtual.txt
'
' Ferdinand Hoffmann & Patrick Koetter
' 20021100901
' Shamelessly stolen from
' http://www.microsoft.com/windows2000/techinfo/ \
' planning/activedirectory/bulksteps.asp
'Global variables
Dim Container
Dim OutPutFile
Dim FileSystem
'Initialize global variables
Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")
Set OutPutFile = FileSystem.CreateTextFile("virtual.txt", True)
Set Container=GetObject("LDAP://DC=example,DC=com")
EnumerateUsers Container
'Clean up
OutPutFile.Close
Set FileSystem = Nothing
Set Container = Nothing
'Say Finished when your done
WScript.Echo "Finished"
WScript.Quit(0)
'List all Users
Sub EnumerateUsers(Cont)
Dim User
'Go through all Users and select them
For Each User In Cont
Select Case LCase(User.Class)
'If you find Users and Groups
'Added groups after Милен Панков mailed me about it :)
Case "user", "group"
'Select all proxyAddresses
Dim Alias
If IsEmpty(User.proxyAddresses) Then
' do nothing.
ElseIf (TypeName(User.proxyAddresses) = "String") Then
OutPutFile.WriteLine "alias: " & User.proxyAddresses
Else
For Each Alias in User.proxyAddresses
OutPutFile.WriteLine "alias: " & Alias
Next
End If
Case "organizationalunit", "container"
EnumerateUsers User
End Select
Next
End Sub
la sortida de l’script té aquesta pinta:
alias: smtp:bar@example.com
l’script el cridem diàriament amb una “tarea programada” i ens deixa el llistat a virtual.txt
Per accedir al llistat, hem optat per muntar el directori amb cifs+autofs. Instal·lem autofs i el configurem:
/auto /etc/auto.cifs
# /etc/auto.cifs
activedirectory -fstype=cifs,rw,username=Administrador,domain=EXAMPLE,password=secret ://192.168.1.17/spamassassin
així quan accedim a /auto/activedirectory es muntarà per samba //192.168.1.17/spamassassin que és on hem deixat l’script VBS i el llistat virtual.txt
per últim hem fet un script bash que actualitza el fitxer relay_recipients i si cal reinicia el postfix, i l’hem afegit al cron
USERSFILE=/auto/activedirectory/virtual.txt
TMPFILE=/root/exchangesync/users_exchange.txt
TMPFILE2=/root/exchangesync/users_exchange.parsed
echo "--- Inici: `date` ----------"
# Intentem accedir al fitxer 10 vegades perque l'autofs
# tingui temps de muntar el directori via smb
for i in `seq 1 10`;
do
if [ -f $USERSFILE ]; then
echo "found $USERSFILE"
break
else
if [ $i -eq 10 ]; then
echo "can't access $USERSFILE after 10 retries"
echo "------ Fi: `date` ----------"
exit 1
fi
echo "can't access $USERSFILE, retrying..."
sleep 2
fi
done
cat $USERSFILE > $TMPFILE
dos2unix $TMPFILE
awk -F: '/alias: (SMTP|smtp):/ {printf("%s\tOK\n",$3)}' $TMPFILE | sort > $TMPFILE2
oldmd5=`cat /etc/postfix/relay_recipients.md5`
newmd5=`md5sum $TMPFILE2 | cut -d" " -f1`
if [ "$oldmd5" != "$newmd5" ]; then
echo "md5 differ, reloading postfix"
diff -b /etc/postfix/relay_recipients $TMPFILE2
cp /etc/postfix/relay_recipients /etc/postfix/relay_recipients.old
cp $TMPFILE2 /etc/postfix/relay_recipients
echo -n $newmd5 > /etc/postfix/relay_recipients.md5
/usr/sbin/postmap /etc/postfix/relay_recipients && /etc/init.d/postfix reload
else
echo "md5 match, not reloading postfix"
fi
echo "------ Fi: `date` ----------"
echo
PHP4 i PHP5 a Debian Squeeze
Nov 7
Ens hem trobat amb la necessitat d’executar una aplicació web que necessita PHP4.
No volem substituir el PHP5 que porta Squeeze perquè no deixin de funcionar altres aplicacions, com l’Squirrelmail o el PhpMyAdmin, així que instal·larem PHP4 com a CGI.
PHP4 com a CGI
Per instal·lar el paquet php4-cgi, hem optat per afegir l’arxiu d’snapshots als sources.list, que permet accedir als paquets antics de Debian
(aquí expliquen altres mètodes)
# instalats de http://snapshot.debian.org/package/php4/
deb http://snapshot.debian.org/archive/debian/20070612T000000Z lenny main
instal·lem normalment
apt-get install php4-cgi php4-cli php4-common php4-curl php4-dev php4-domxml php4-gd php4-imap php4-mcal php4-mcrypt php4-mysql
per a que un VirtualHost d’Apache faci servir PHP4 cal afegir-li a la configuració:
(...)
# PHP4
<FilesMatch "\.ph(p3?|tml)$">
Options ExecCGI FollowSymLinks
SetHandler fcgid-script
FCGIWrapper /usr/bin/php-cgi .php
</FilesMatch>
</VirtualHost>
Optimitzar Munin amb tmpfs
Oct 24
Al servidor on allotgem les webs, l’Apache cada vegada anava més lent.
Un apachectl fullstatus
ens mostrava molts workers en estat L (“Logging”) esperant obtenir accés a disc.
Vam descobrir que el problema era el Munin, a mida que havíem anat afegint nodes i gràfiques, el rendiment havia anat baixant. Cada node té unes 80 bases de dades RRD, depenent del nombre de gràfiques; si monitoritzem uns 50 nodes, són uns 4000 fitxers RRD a actualitzar cada 5 minuts i l’accés a disc comença a ser un problema.
Per solucionar-ho vam moure les bases de dades a la memòria RAM
a la gràfica es veu clarament com va desaparèixer l’espera per accedir al disc (iowait)
Configurar munin + tmpfs
per reduir l’espai usat, no esta de més esborrar els RRD antics que ja no s’utilitzin
# du -sh /var/lib/munin
305M /var/lib/munin
fem una còpia de la carpeta
afegim a /etc/fstab una partició tmpfs prou gran per posar-hi /var/lib/munin i amb l’uid i gid de l’usuari munin
la muntem i hi copiem les dades
# mount /var/lib/munin
# cp -ra /var/lib/munin-cache/* /var/lib/munin/
ara tenim les bases de dades RRD a la RAM, l’accés a disc ja no hauria de ser un problema, però si s’apaga el servidor es perden les dades de la RAM, per tant cal programar un cron que vagi copiant les dades a disc
posem a /etc/cron.hourly/munin-cache
# hem posat /var/lib/munin a la RAM, cal copiar-ho a /var/lib/munin-cache
# per no perdre les dades en cas de reiniciar.
cp -ra /var/lib/munin/* /var/lib/munin-cache/
i ho fem executable
per que es restauri automàticament la còpia a l’engegar, afegim a /etc/rc.local