Información general
Aquest llibre conté el recull de pràctiques ha realitzar a l'assignatura d'Administració i Manteniment de Sistemes i Aplicacions (AMSA). Aquestes pràctiques estan enfocades a l'administració de sistemes GNU/Linux, en concret, amb la distribucions AlmaLinux i Debian.
-
AlmaLinux és una distribució de GNU/Linux basada en Red Hat Enterprise Linux (RHEL) i CentOS utilizarem la versió 9.4.
-
Debian és una distribució de GNU/Linux utilitzarem la versió 12.5.0.
Continguts
- Instal·lació i Configuració de Màquines Virtuals.
- Scripting.
- Arrancada del Sistema.
- Sistema de Fitxers.
- RAID.
- Servidors.
Utilització
Es tracten de laboratoris pràctics resolts que us permet experimentar amb els continguts teòrics presentats a les sessions de teoria. Moltes comandes i configuracions es troben amagades inicialment per tal que pugueu intentar resoldre els exercicis per vosaltres mateixos. Si us trobeu amb problemes o voleu comprovar la vostra solució, podeu consultar la solució clicant al botó en forma d'ull 👁️.
Adicionalment, es demanara l'entrega d'informes per a cada laboratori. Aquests informes han d'intentar donar resposta a les preguntes plantejades en el context de cada laboratori.
Instal·lació d'una màquina virtual
Per a realitzar tots els laboratoris d'aquest curs, necessitareu una màquina virtual amb un sistema operatiu basat en Linux. En aquest curs us proposo utilitzar, dos distribucions molt populars per a servidors en entorns de producció.
-
Debian 12: Debian és una distribució de Linux molt popular i estable. És una de les distribucions més antigues i utilitzades en servidors. Debian és conegut per la seva estabilitat, seguretat i facilitat d'ús. És una excel·lent opció per a servidors web, servidors de correu electrònic, servidors de bases de dades i altres aplicacions de servidor. Concretament, utilitzarem la versió 12.5.0.
-
AlmaLinux 9: AlmaLinux és una distribució de Linux basada en Red Hat Enterprise Linux (RHEL). És una distribució de Linux empresarial que ofereix suport a llarg termini i actualitzacions de seguretat. Es una de les alternativa open-source de RHEL. Concretament, utilitzarem la versió 9.4.
Software de virtualització
En aquest curs, us recomano utilitzar VMWare com a software de virtualització. VMWare és un dels software de virtualització més populars i utilitzats en entorns de producció. A més, VMWare ofereix una versió gratuïta per a ús personal i educatiu:
- Windows: VMWare Workstation Player
- Mac: VMWare Fusion
A més, VMWare funciona en les principals arquitectures de processador com x86 i ARM. Durant el curs, els exemple i el suport es basaran en l'ús de VMWare. Resta a la vostra elecció utilitzar un altre software de virtualització com VirtualBox, KVM, UTM o d'altres.
Tasques
- Instal·la un màquina virtual amb Debian 12.5.0 en mode text
- Informació bàsica sobre hostname i
hostnamectl
- Informació bàsica sobre resolució de noms
- Informació bàsica sobre com connectar-se a una màquina virtual amb SSH i transferència de fitxers
Activitats
- Documenta el procés d'instal·lació de la màquina virtual amb AlmaLinux 9.4 amb una interfície gràfica.
- Descriu les diferències entre el procés d'instal·lació de les dues distribucions.
- Investiga com es pot crear un clon d'una màquina virtual amb VMware i documenta el procés. Comenta els avantatges i inconvenients de clonar una màquina virtual.
Rúbriques d'avaluació
Realització de les tasques: 100%
Criteris d'avaluació | Excel·lent (5) | Notable(3-4) | Acceptable(1-2) | No Acceptable (0) |
---|---|---|---|---|
Contingut | El contingut és molt complet i detallat. S'han cobert tots els aspectes de la tasca. | El contingut és complet i detallat. S'han cobert la majoria dels aspectes de la tasca. | El contingut és incomplet o poc detallat. Falten alguns aspectes de la tasca. | El contingut és molt incomplet o inexistent. |
Estil | L'estil és molt adequat i professional. S'ha utilitzat un llenguatge tècnic precís. | L'estil és adequat i professional. S'ha utilitzat un llenguatge tècnic precís. | L'estil és poc adequat o professional. Hi ha errors en el llenguatge tècnic. | L'estil és molt poc adequat o professional. Hi ha molts errors en el llenguatge tècnic. |
Precisió i exactitud | La informació és precisa i exacta. No hi ha errors. | La informació és precisa i exacta. Hi ha pocs errors. | La informació és imprecisa o inexacta. Hi ha errors. | La informació és molt imprecisa o inexacta. Hi ha molts errors. |
Organització | La informació està ben organitzada i estructurada. És fàcil de seguir. | La informació està organitzada i estructurada. És fàcil de seguir. | La informació està poc organitzada o estructurada. És difícil de seguir. | La informació està molt poc organitzada o estructurada. És molt difícil de seguir. |
Justificació | S'han justificat les respostes amb arguments vàlids i exemples pràctics. | S'han justificat les respostes amb arguments vàlids. | S'han justificat les respostes amb arguments poc vàlids. | No s'han justificat les respostes. |
Expansió | S'han ampliat les respostes amb informació addicional rellevant. | S'han ampliat les respostes amb informació addicional. | S'han ampliat les respostes amb informació poc rellevant. | No s'han ampliat les respostes. |
Suport gràfic o audiovisual | S'han utilitzat recursos gràfics o audiovisuals per aclarir la informació. | S'han utilitzat recursos gràfics o audiovisuals. | S'han utilitzat pocs recursos gràfics o audiovisuals. | No s'han utilitzat recursos gràfics o audiovisuals. |
Instal·lació del sistema operatiu Debian 12
En aquest laboratori, instal·larem el sistema operatiu Debian 12 en una màquina virtual i descriurem els components principals del sistema operatiu. Aquesta instal·lació és la base per a tots els laboratoris que realitzarem en aquest curs. En alguns, us demanaré que modifiqueu alguns paràmetres de configuració per adaptar-los a les necessitats del laboratori.
Configuració de la màquina virtual amb VMWare
- Selecciona l’opció
Create a New Virtual Machine
a VMWare Workstation Player o VMWare Fusion. - Selecciona Install from disc or image.
- Selecciona la imatge ISO de Debian 12.
- Configura els recursos de la màquina virtual.
Instal·lació del sistema operatiu
-
Un cop iniciada la màquina virtual, podeu seleccionar la opció Install o bé Graphical install.
En aquest tutoriral, seleccionarem la opció Graphical install per a una instal·lació més amigable. La principal diferència entre les dues opcions és l'entorn gràfic.
-
Selecciona l'idioma d'instal·lació.
Podeu seleccionar l'idioma que vulgueu per a la instal·lació. En aquest cas, seleccionarem l'idioma Català.
-
Selecciona la ubicació geogràfica.
En aquest cas, seleccionarem la ubicació Espanya.
-
Selecciona la disposició del teclat.
En aquest cas, seleccionarem la disposició de teclat Català. Això ens asegurarà un mapeig correcte del teclat.
-
Espereu que el sistema carregui els components necessaris.
-
Configura la xarxa.
- El primer pas és configurar el nom d'amfitrió o hostname. Aquest nom permet identificar de forma única el vostre sistema. Podeu deixar el nom per defecte o canviar-lo al vostre gust.
En aquest cas, hem canviat el nom d'amfitrió a
lab00-debian
.🚀 Consell:
Els administradors de sistemes acostumen a administrar múltiples servidors i dispositius. Per tant, és important identificar cada dispositiu amb un nom únic per facilitar la gestió i la comunicació entre ells. Per tant, us recomano que utilitzeu un nom d'amfitrió significatiu per identificar-lo fàcilment.
Us recomano un cop instal·lat el sistema que doneu una ullada a l'apartat Hostname per obtenir més informació sobre com gestionar el nom d'amfitrió.
- El segon pas és configurar el domini de la xarxa. Aquest pas el podeu deixar en blanc si no teniu un domini específic. O bé, podem utilitzar
.local
com a domini local per identicar que el servidor pertany a la xarxa local.
💡 Nota:
En un domini empresarial, normalment s'utilitza el nom de domini de l'empresa. Imagina que aquesta màquina virtual és el servidor d'una base de dades mysql de l'empresa
acme.com
. En aquest cas, el domini seriaacme.com
. I el nom d'amfitrió podria sermysql01.acme.com
. -
Configura l'usuari administrador.
En aquest punt, heu de tenir en compte que si no poseu cap contrasenya, es crearà l'usuari normal amb permisos de
sudo
i això us permetra executar comandes amb privilegis d'administrador.Si poseu una contrasenya, aquesta serà la contrasenya de l'usuari
root
i no es crearà un usuari normal amb permisos desudo
. I tampoc s'instal·larà el paquetsudo
.⚠️ Compte
Com utilitzarem les màquines virtuals com a laboratoris de pràctiques, no cal que poseu una contrasenya molt segura. Podeu utilitzar una com a
1234
. Però, recordeu que en un entorn real, la seguretat és molt important i cal utilitzar contrasenyes segures. -
Configura un usuari normal.
- Nom complet: Podeu posar el vostre nom complet o el que vulgueu.
- Nom d'usuari: Podeu posar el vostre nom d'usuari o el que vulgueu.
- Contrasenya: El mateix que per l'usuari
root
.
-
Configura la zona horària.
En aquest cas, seleccionarem la zona horària de Madrid.
-
Configura el disc dur.
- Particionament: Durant el curs apendreu a realitzar particionament manual i, també discutirem sobre LV (Logical Volumes) i LVM (Logical Volume Manager). Però, per a una instal·lació senzilla, de moment, seleccionarem la primera opció (Guiat - utilitzar tot el disc).
- Selecciona el disc on instal·lar el sistema. En el meu cas, només tinc un disc virtual amb l'etiqueta
/dev/nvme0n1
. L'etiqueta indica el tipus de disc (NVMe) i el número de disc (1). Es possible tenir altres etiquetes com/dev/sda
per discos SATA o/dev/vda
per discos virtuals.
- Particions: Durant el curs apendreu les avantatges i com gestionar sistemes amb particions separades. Però, de moment, seleccionarem la primera opció (Totes les dades en una sola partició).
- Confirmeu els canvis. En aquest punt, el sistema crearà les particions necessàries:
- La primera partició serà la partició
/boot
on es guardaran els fitxers de boot. - La segona partició serà la partició
/
on es guardaran els fitxers del sistema. - La tercera partició serà la partició de swap on es guardaran les dades de la memòria virtual.
- La primera partició serà la partició
👁️ Observació:
En aquest punt es poden fer moltes personalitzacions com ara:
- Configurar un sistema RAID.
- Configurar un sistema LVM.
- Configurar un sistema de xifrat. Tots aquests temes els veurem més endavant en el curs.
- Escriu els canvis al disc.
-
Espera que s'instal·li el sistema.
-
Configura el gestor de paquets.
- Analitzar els discos de la instal·lació. Aquest pas permet seleccionar els discos on es troben els paquets d'instal·lació. Normalment, aquest pas no cal modificar-lo.
-
Configura el gestor de paquets. En aquest cas, seleccionarem el servidor de paquets més proper a la nostra ubicació.
-
Filtrar els servidors de paquets per ubicació.
-
Seleccionar el servidor de paquets.
👀 Nota:
A vegades, els servidors de paquets poden estar saturats o no funcionar correctament. En aquest cas, podeu seleccionar un servidor alternatiu o provar més tard.
-
-
Configura el proxy. Si esteu darrere d'un proxy, podeu configurar-lo en aquest pas.
ℹ️ Què és un proxy?
Un proxy és un servidor intermediari entre el vostre sistema i Internet. Aquest servidor pot ser utilitzat per controlar l'accés a Internet, per protegir la vostra privacitat o per accelerar la connexió a Internet. Les peticions de connexió a Internet es fan a través del servidor proxy, que actua com a intermediari i reenvia les peticions al servidor de destinació. Per exemple, en una empresa, el proxy pot ser utilitzat per controlar l'accés a Internet dels empleats i protegir la xarxa interna de possibles amenaces.
-
Espera que s'instal·lin els paquets.
-
Configura el paquet
popularity-contest
.- Aquest paquet permet enviar informació anònima sobre els paquets instal·lats al servidor de Debian per millorar la selecció de paquets i la qualitat dels paquets. Podeu seleccionar si voleu participar en aquest programa o no.
-
Selecció de programari. En aquest punt podeu seleccionar si voleu un servidor en mode text o amb interfície gràfica. També us permet seleccionar si voleu instal·lar els serveis web i ssh al servidor i finalment si voleu les utilitats estàndard del sistema. Aquestes opcions les anirem modifciant en funció dels laboratoris que realitzarem. Per defecte, seleccionarem el servidor en mode text, el servei SSH activat i les utilitats estàndard del sistema.
ℹ️ Què és un servidor en mode text?
Un servidor en mode text és un servidor que no té una interfície gràfica. Això significa que tota la interacció amb el servidor es fa a través de la línia de comandes. Aquest tipus de servidor és molt comú en entorns de producció, ja que consumeix menys recursos i és més segur que un servidor amb interfície gràfica.
ℹ️ Què és el servei SSH?
El servei SSH (Secure Shell) és un protocol de xifratament que permet connectar-se de forma segura a un servidor remot. Aquest servei és molt utilitzat per administrar servidors a distància, ja que permet accedir al servidor de forma segura i xifratada.
-
Espera que s'instal·li el programari.
-
Instal·lació acabada. Un cop finalitzada la instal·lació, el sistema es reiniciarà i podreu accedir al GRUB per seleccionar el sistema operatiu.
-
El GRUB us permet accedir al sistema operatiu. En aquest cas, seleccionarem Debian GNU/Linux. La resta d'opcions les veurem més endavant en el curs.
ℹ️ Què és el GRUB?
Com veurem al capítol de Booting, el GRUB és un gestor d'arrencada que permet seleccionar el sistema operatiu que volem iniciar. Aquest gestor és molt útil en sistemes amb múltiples sistemes operatius o múltiples versions del mateix sistema operatiu.
-
Inicieu sessió amb l'usuari i la contrasenya que heu configurat durant la instal·lació.
-
Tanqueu la sessió amb la comanda
exit
. -
Inicieu sessió amb l'usuari
root
i la contrasenya que heu configurat durant la instal·lació.
Hostname
Els administradors de sistemes acostumen a administrar múltiples servidors i dispositius. Per tant, és important identificar cada dispositiu amb un nom únic per facilitar la gestió i la comunicació entre ells. El nom d'un dispositiu s'anomena nom d'amfitrió o hostname. Per a gestionar el nom d'amfitrió d'un sistema Linux, utilitzarem la comanda hostnamectl
.
Comprovar el nom d'amfitrió actual
Per comprovar el nom d'amfitrió actual del vostre sistema, podeu utilitzar la comanda hostnamectl
:
hostnamectl
Aquesta comanda us mostrarà informació sobre el vostre sistema, incloent el nom d'amfitrió actual.
A part del nom d'amfitrió, també podeu veure informació com la versió del sistema operatiu, el kernel, la data i l'hora actuals, etc.
Modificar el nom d'amfitrió
Per canviar el nom d'amfitrió del vostre sistema, podeu utilitzar la comanda hostnamectl
amb l'opció set-hostname
. Per exemple, si voleu canviar el nom d'amfitrió a nou-nom
, executeu la següent comanda:
hostnamectl set-hostname nou-nom
Aquesta comanda canviarà el nom d'amfitrió del vostre sistema a nou-nom
. Si voleu comprovar que el canvi s'ha aplicat correctament, torneu a executar la comanda hostnamectl
. Per aplicar el canvi, sortiu de la sessió actual exit
i torneu a iniciar sessió.
🔗 Recordatori:
Cal tenir en compte que aquesta comanda requereix permisos d'administrador. Per tant, és possible que hàgiu de precedir la comanda amb
sudo
o executar-la com a usuariroot
.
Nom en xarxa
Hi ha dos maneres d'identificar un servidor o dispositiu connectat en una xarxa, o bé utilitzant la direcció IP del dispositiu o bé utilitzant el seu nom d'amfitrió. Per poder resoldre el nom d'amfitrió correctament, cal configurar-lo correctament en el sistema o disposar d'un servidor DNS que pugui resoldre el nom d'amfitrió en una adreça IP.
Network Address Translation (NAT)
Per defecte, VMWare utilitza una xarxa NAT per connectar les màquines virtuals. Per fer-ho, VMWare crea una xarxa privada a la qual es connecten les màquines virtuals i utilitza la xarxa de l'amfitrió per connectar-se a Internet. Això permet a les màquines virtuals connectar-se a Internet a través de l'amfitrió sense necessitat de configurar una xarxa addicional. Ara bé, això també significa que les màquines virtuals utilitzen una adreça IP privada que no és accessible des de l'exterior. Tot i això, aquesta configuració la podeu canviar si cal. Però, pels nostres laboratoris, aquesta configuració és suficient.
ℹ️ Què és NAT?
La xarxa NAT (Network Address Translation) és una tècnica que permet a diversos dispositius connectar-se a Internet utilitzant una única adreça IP pública. Aquesta tècnica és àmpliament utilitzada per a xarxes domèstiques i petites empreses per permetre a diversos dispositius connectar-se a Internet sense necessitat de disposar d'una adreça IP pública per a cada dispositiu.
Ús de la direcció IP
La direcció IP és una forma única d'identificar un dispositiu en una xarxa. Cada dispositiu connectat a una xarxa ha d'estar configurat amb una adreça IP única per poder comunicar-se amb altres dispositius. Les adreces IP poden ser dinàmiques (assignades per un servidor DHCP) o estàtiques (configurades manualment).
Quan es crea una màquina virtual utilitzant el programari VMWare per defecte, la màquina virtual obté una adreça IP a través del servidor DHCP de VMWare. Aquesta adreça IP es pot utilitzar per accedir a la màquina virtual des de l'amfitrió o altres dispositius de la xarxa.
Per obtenir aquesta informació podeu consultar la interficie gràfica de VMWare o bé utilitzar la comanda ip addr
en la terminal de la màquina virtual.
-
Interfície gràfica de VMWare:
-
Comanda
ip addr
:ip addr
Aquesta comanda us mostrarà la informació de la interfície de xarxa de la màquina virtual, incloent la seva adreça IP.
Podeu testar la connectivitat de la màquina virtual amb l'amfitrió o altres dispositius de la xarxa utilitzant la comanda ping
. Per exemple, per provar la connectivitat amb l'amfitrió, podeu utilitzar la següent comanda:
ping -c 4 <adreça IP de l'amfitrió>
Ús del nom d'amfitrió
El nom d'amfitrió és una forma més fàcil de recordar i identificar un dispositiu en una xarxa. En lloc d'utilitzar una adreça IP, podeu utilitzar un nom d'amfitrió per connectar-vos a un dispositiu. Per exemple, en lloc de connectar-vos a 172.16.10.199
, podeu connectar a lab0-amsa
.
Per fer-ho, cal modificar la configuració del vostre ordinador local perquè pugui resoldre el nom d'amfitrió correctament. Això es pot fer afegint una entrada al fitxer /etc/hosts
amb el nom d'amfitrió i la seva adreça IP. Per exemple afegint la següent línia al fitxer /etc/hosts
:
# /etc/hosts
172.16.10.199 lab0-amsa
- Windows:
C:\Windows\System32\drivers\etc\hosts
- Linux:
/etc/hosts
- macOS:
/etc/hosts
Un cop afegida aquesta entrada, podeu provar la connectivitat amb la màquina virtual utilitzant el nom d'amfitrió:
ping -c 4 lab0-amsa
Una forma alternativa de resoldre el nom d'amfitrió és utilitzar un servidor DNS. Un servidor DNS és un servidor que tradueix els noms d'amfitrió en adreces IP i viceversa. Aquest és el cas de la majoria de xarxes corporatives i d'Internet, on es fa servir un servidor DNS per resoldre els noms de domini.
Connexió SSH i SFTP
En els nostres laboratoris, utilitzarem màquines virtuals per simular els nostres servidors. Per tant, sempre tindreu accés físic a les màquines virtuals a través de la interfície gràfica de VMWare. No obstant això, en un entorn de producció, no sempre tindreu accés físic als servidors o no us resultarà pràctic anar físicament a cada servidor per gestionar-los. Per tant, és important tenir una forma de connectar-vos als servidors de forma remota per poder gestionar-los de manera eficient.
ℹ️ Què és SSH?
SSH (Secure Shell) és un protocol de xarxa que permet als usuaris connectar-se a un dispositiu remot de forma segura. SSH utilitza una connexió xifrada per autenticar els usuaris i protegir les dades que es transmeten entre els dispositius. Això fa que SSH sigui una eina molt útil per connectar-se a servidors remots de forma segura.
ℹ️ Què és SFTP?
SFTP (SSH File Transfer Protocol) és un protocol de transferència de fitxers que permet als usuaris transferir fitxers de forma segura entre dos dispositius. SFTP utilitza SSH per autenticar els usuaris i xifrar les dades que es transmeten entre els dispositius. Això fa que SFTP sigui una eina molt útil per transferir fitxers de forma segura entre servidors remots.
ℹ️ Què és secure copy (SCP)?
SCP (Secure Copy) és una eina que permet als usuaris copiar fitxers de forma segura entre dos dispositius utilitzant SSH. SCP utilitza SSH per autenticar els usuaris i xifrar les dades que es transmeten entre els dispositius.
Connexió SSH entre la vostra màquina i la màquina virtual
Per connectar-vos a una màquina virtual utilitzant SSH, necessitareu l'adreça IP de la màquina virtual o bé el hostname
de la màquina virtual. A més, necessitareu un client SSH instal·lat al vostre sistema local. A continuació, us mostrem com connectar-vos a una màquina virtual utilitzant SSH:
-
Mac/Linux:
ssh <usuari>@<adreça IP o hostname>
On: <usuari>
és el nom d'usuari amb el qual voleu connectar-vos a la màquina virtual i <adreça IP o hostname>
és l'adreça IP o el hostname
de la màquina virtual a la qual voleu connectar-vos.
Un cop connectats, podreu interactuar amb la màquina virtual com si estiguéssiu connectats físicament a la màquina. Per sortir de la sessió SSH, executeu la comanda exit
.
- Windows: Obrir una sessió de PowerShell i executar la comanda anterior. També podeu utilitzar un client SSH com PuTTY.
ℹ️ Què és el fingerprint que es mostra quan connecteu per primera vegada a un servidor SSH?
El fingerprint és una empremta digital única que identifica un servidor SSH. Quan connecteu per primera vegada a un servidor SSH, el vostre client SSH us mostrarà el fingerprint del servidor perquè pugueu verificar que esteu connectant-vos al servidor correcte. Això us protegeix contra atacs de suplantació de servidor.
😵💫 Troubleshooting:
Si una IP d'una màquina virtual a la qual havíeu accedit prèviament es reassigna a una altra màquina virtual i intenteu accedir a la màquina virtual original, el client SSH mostrarà un missatge d'advertència. Això succeeix perquè el fingerprint del servidor ha canviat. Quan connecteu per primera vegada a un servidor SSH, el vostre client SSH emmagatzema aquest fingerprint en el fitxer
~/.ssh/known_hosts
per a futures referències.Si el fingerprint del servidor canvia (per exemple, perquè l'adreça IP s'ha reassignat a una altra màquina virtual), el client SSH detectarà aquesta discrepància i mostrarà un missatge d'advertència per protegir-vos contra possibles atacs de suplantació de servidor. Aquest missatge us informa que el servidor al qual esteu intentant connectar-vos no coincideix amb el fingerprint emmagatzemat.
Per resoldre aquest problema i poder connectar-vos al servidor, podeu eliminar l'entrada del servidor del fitxer
~/.ssh/known_hosts
. Això permetrà al client SSH acceptar el nou fingerprint i establir la connexió sense mostrar l'advertència.Per resoldre aquest problema, simplement elimineu l'entrada del servidor del fitxer
~/.ssh/known_hosts
i torneu a intentar connectar-vos al servidor. En el sistema operatiu Windows, el fitxerknown_hosts
es troba a la carpetaC:\Users\<usuari>\.ssh\known_hosts
.
Transferència de fitxers amb SFTP
Per transferir fitxers entre la vostra màquina local i la màquina virtual utilitzant SFTP, necessitareu l'adreça IP de la màquina virtual o bé el hostname
de la màquina virtual. A més, necessitareu un client SFTP instal·lat al vostre sistema local. A continuació, us mostrem com transferir fitxers entre la vostra màquina local i la màquina virtual utilitzant SFTP:
-
Mac/Linux:
sftp <usuari>@<adreça IP o hostname>:<ruta>
On:
<ruta>
és la ruta al directori de la màquina virtual on voleu transferir els fitxers.- Els fitxers es transferiran al directori actual de la vostra màquina local.
Un cop connectats, podeu utilitzar les comandes
put
iget
per transferir fitxers entre la vostra màquina local i la màquina virtual. Si voleu transferir un directori sencer, podeu utilitzar la comandaput -r
oget -r
. Per acabar la sessió SFTP, executeu la comandaexit
. -
Windows: Obrir una sessió de PowerShell i executar la comanda anterior. També podeu utilitzar un client SFTP com WinSCP.
Si voleu fer servir SCP en lloc de SFTP, podeu utilitzar la comanda scp
en lloc de sftp
. La sintaxi de la comanda scp
és similar a la de la comanda cp
de Linux. Per exemple, per copiar un fitxer de la vostra màquina local a la màquina virtual, executeu la següent comanda:
scp <fitxer> <usuari>@<adreça IP o hostname>:<ruta>
on:
<fitxer>
és el fitxer que voleu copiar.<ruta>
és la ruta al directori de la màquina virtual on voleu copiar el fitxer.- El fitxer es copiarà al directori especificat de la màquina virtual.
- Si voleu copiar un directori sencer, podeu utilitzar l'opció
-r
.
Exemple pràctic de transferència de fitxers
-
Crear un fitxer
fitxer.txt
a la vostra màquina local.echo "Aquest és un fitxer de prova" > fitxer.txt
-
Copia el fitxer
fitxer.txt
a la màquina virtual a la ruta/home/usuari
.- Amb scp:
scp fitxer.txt jordi@172.16.10.199:/home/jordi
- Amb sftp:
sftp jordi@172.16.10.199:/home/jordi put fitxer.txt
-
Edita el fitxer
fitxer.txt
a la màquina virtual.echo "Aquest és un fitxer de prova editat" > fitxer.txt
-
Copia el fitxer
fitxer.txt
de la màquina virtual a la vostra màquina local.sftp jordi@172.16.10.199:/home/jordi get fitxer.txt
Scripting
En aquest laboratori es realitzaran tasques de scripting amb Bash i Awk. Aquests llenguatges són molt utilitzats en l'administració de sistemes GNU/Linux per automatitzar tasques repetitives.
Objectius
- Repassar els conceptes bàsics de Bash estudiats al curs de Sistemes Operatius.
- Aprendre a utilitzar Awk per processar fitxers de text.
- Conèixer les diferències entre Bash i Awk.
- Combina Bash i Awk per a realitzar tasques més complexes.
Continguts
Activitat
Heu d’incorporar al repositori cinc exemples diferents, ordenats de menor a major complexitat. Cada exemple ha de ser únic i ha d’incloure una explicació detallada del que fa el codi, així com versions tant en bash com en AWK. Si l’exemple que tenies pensat ja ha estat implementat per un company, hauràs de buscar-ne un de nou. Per tant, és recomanable que revisis els exemples que ja han publicat els teus companys abans de publicar els teus propis exemples.
Rúbriques d'avaluació
Presentació d'un Pull Request amb els scripts realitzats: 100%
- Format: Markdown
- Fitxer:
Scripts/awk-repo.md
En aquest laboratori s'avaluarà la capacitat de l'estudiant per a generar nous scripts en Bash i Awk. Aquest scripts hauran de ser funcionals i correctes, així com també hauran de ser ben documentats.
Criteris d'avaluació | Excel·lent (5) | Notable(3-4) | Acceptable(1-2) | No Acceptable (0) |
---|---|---|---|---|
Contingut | El contingut és molt complet i detallat. S'han cobert tots els aspectes de la tasca. | El contingut és complet i detallat. S'han cobert la majoria dels aspectes de la tasca. | El contingut és incomplet o poc detallat. Falten alguns aspectes de la tasca. | El contingut és molt incomplet o inexistent. |
Operacionals | Els scripts generats són funcionals i correctes. No hi ha errors. | Els scripts generats són funcionals i correctes. Hi ha pocs errors. | Els scripts generats són funcionals i correctes. Hi ha errors. | Els scripts generats no són funcionals o correctes. |
Creatius | Els scripts generats són originals i no s'han copiat de cap font. | Els scripts generats són originals i no s'han copiat de cap font. | Els scripts generats són originals i no s'han copiat de cap font. | Els scripts generats són còpia d'altres scripts. |
Documentació | Els scripts estan ben documentats i s'ha explicat el seu funcionament. | Els scripts estan ben documentats i s'ha explicat el seu funcionament. | Els scripts estan documentats. Falta explicar el seu funcionament. | Els scripts no estan documentats. |
Presentació | Els scripts s'han lliurat en un format adequat i s'han seguit les indicacions del professor. | Els scripts s'han lliurat en un format adequat i s'han seguit les indicacions del professor. | Els scripts s'han lliurat en un format adequat. Falten algunes indicacions del professor. | Els scripts no s'han lliurat en un format adequat. |
Didàctics | Els scripts són fàcils de seguir i entenent per a qualsevol persona. | Els scripts són fàcils de seguir i entenent per a qualsevol persona. | Els scripts són fàcils de seguir i entenent per a qualsevol persona. | Els scripts són difícils de seguir i entenent. |
Optimització | Els scripts són eficients i no es poden millorar. | Els scripts són eficients i no es poden millorar. | Els scripts són eficients i es poden millorar. | Els scripts no són eficients. |
Bash
En aquest laboratori repassarem els conceptes bàsics de Bash, el llenguatge de programació de scripts més utilitzat en sistemes GNU/Linux. Aquest laboratori està enfocat en repassar els conceptes bàsics que vau estudiar en l'assignatura de Sistemes Operatius.
Contextualització
En aquest laboratori crearem una aplicació per gestionar una llista de pokemons. Aquesta aplicació haurà de permetre afegir, llistar, eliminar i buscar pokemons. A més a més, haureu de fer servir un fitxer per emmagatzemar la informació dels pokemons.
Preparació
- Entorn de treball: Màquina virtual amb una distribució GNU/Linux instal·lada pot ser Debian o AlmaLinux.
Objectius
- Repassar els conceptes bàsics de Bash.
Tasques
-
Creeu un esquelet pel vostre script Bash.
#!/bin/bash # Constants # Functions # Main return 0
-
Implementeu una constant
POKEDEX_FILE
amb el nom del fitxer on emmagatzemareu la informació dels pokemons.POKEDEX_FILE="pokedex.txt"
-
Implementeu un menu amb la sintaxi
case
que permeti executar les següents comandes:help
,list
,search
,delete
inew
.case $1 in help) pokedex_help ;; list) pokedex_list ;; search) pokedex_search $2 ;; delete) pokedex_delete $2 ;; new) pokedex_new $2 $3 $4 $5 $6 $7 ;; *) echo "Comanda no trobada." pokedex_help ;; esac
-
Implementeu la funció
pokedex_help
que mostri per pantalla les instruccions d'ús del script.function pokedex_help() { echo "Ús: ./pokedex.sh <comanda> <arguments>" echo "Comandes:" echo " list: Llistar pokemons" echo " search <name>: Buscar pokemon" echo " delete <name>: Eliminar pokemon" echo " new <name> <type> <hp> <attack> <defense> <speed>: Afegir pokemon" }
-
Implementeu la funció
pokedex_list
que llegeixi el fitxerPOKEDEX_FILE
i mostri per pantalla la llista de pokemons.- Podeu fer servir la comanda
cat
per llegir el fitxerPOKEDEX_FILE
.
function pokedex_list() { cat $POKEDEX_FILE }
- Assegureu-vos que existeix el fitxer
POKEDEX_FILE
.
if [[ ! -f $POKEDEX_FILE ]]; then echo "El fitxer $POKEDEX_FILE no existeix." return 1 fi
- Podeu fer servir la comanda
-
Implementeu la funció
pokedex_search <name>
que llegeixi el fitxerPOKEDEX_FILE
i mostri per pantalla la informació del pokemon amb nom<name>
.- Podeu fer servir la comanda
grep
per buscar el pokemon amb nom<name>
.
function pokedex_search() { grep $1 $POKEDEX_FILE }
- Assegureu-vos que la funció
pokedex_search
rep un argument.
if [[ -z $1 ]]; then echo "Has d'indicar el nom del pokemon." echo "Ús: ./pokedex.sh search <name>" return 1 fi
- Podeu fer servir la comanda
-
Implementeu la funció
pokedex_delete <name>
que elimini el pokemon amb nom<name>
del fitxerPOKEDEX_FILE
.- Podeu fer servir la comanda
sed
per eliminar el pokemon amb nom<name>
.
function pokedex_delete() { sed -i "/$1/d" $POKEDEX_FILE }
- Assegureu-vos que la funció
pokedex_delete
rep un argument.
if [[ -z $1 ]]; then echo "Has d'indicar el nom del pokemon." echo "Ús: ./pokedex.sh delete <name>" return 1 fi
- Podeu fer servir la comanda
-
Implementeu la funció
pokedex_new <name> <type> <hp> <attack> <defense> <speed>
que permet afegir un nou pokemon a la pokedex.- Podeu fer servir la comanda
echo
per afegir el nou pokemon al fitxerPOKEDEX_FILE
.
function pokedex_new() { echo "$1 $2 $3 $4 $5 $6" >> $POKEDEX_FILE }
- Assegureu-vos que la funció
pokedex_new
rep tots els arguments necessaris.
if [[ -z $1 || -z $2 || -z $3 || -z $4 || -z $5 || -z $6 ]]; then echo "Has d'indicar el nom, tipus, hp, attack, defense i speed del pokemon." echo "Ús: ./pokedex.sh new <name> <type> <hp> <attack> <defense> <speed>" return 1 fi
- Podeu fer servir la comanda
Introducció al llenguatge AWK
Objectius
- Entendre la sintaxi bàsica d'AWK.
- Aprendre a utilitzar AWK per processar fitxers de text.
- Entendre les diferències entre AWK i BASH.
Prerequisits
- Una màquina virtual amb sistema operatiu Linux, preferiblement AlmaLinux 9.4. Es recomana accedir a la màquina virtual mitjançant SSH.
Què és AWK?
AWK és un llenguatge de programació potent i versàtil, dissenyat específicament per a l’anàlisi de patrons i el processament de text. La seva funció principal és processar fitxers de text de manera eficient, permetent la transformació de dades, la generació d’informes i la filtració de dades.
Pràcticament tots els sistemes Unix disposen d’una implementació d’AWK. Això inclou sistemes operatius com GNU/Linux, macOS, BSD, Solaris, AIX, HP-UX, entre d’altres. Per consultar el manual d’AWK, pots utilitzar la comanda man awk
. Per consultar la versió d’AWK instal·lada al teu sistema, pots utilitzar la comanda awk -W version
.
AWK es caracteritza per ser compacte, ràpid i senzill, amb un llenguatge d’entrada net i comprensible que recorda al llenguatge de programació C. Disposa de construccions de programació robustes que inclouen if/else, while, do/while
, entre d’altres. L’eina AWK processa una llista de fitxers com a arguments. En cas de no proporcionar fitxers, AWK llegeix de l’entrada estàndard, permetent així la seva combinació amb pipes per a operacions més complexes.
Utilització de l'eina AWK
Pots trobar tota la informació sobre el funcionament de l’eina AWK a la pàgina de manual. Per exemple, per obtenir informació sobre la comanda awk, pots utilitzar la comanda man awk
. Aquesta comanda et proporcionarà tota la informació necessària per utilitzar l’eina AWK.
-
Pots utilitzar l’eina amb el codi escrit directament acció-awk a la línia de comandes o combinada en un script:
awk [-F] '{acció-awk}' [ fitxer1 ... fitxerN ]
-
També pots utilitzar l’eina amb tota la sintaxi awk guardada en un fitxer script-awk des de la línia de comandes o combinada amb altres scripts:
awk [-F] -f script-awk [ fitxer1 ... fitxerN ]
En aquests exemples, [-F] és una opció que permet especificar el caràcter delimitador de camps, {acció-awk} és el codi AWK que vols executar, i [ fitxer1 ... fitxerN ] són els fitxers d’entrada que AWK processarà. Si no s’especifica cap fitxer, AWK llegirà de l’entrada estàndard.
Fitxer de Dades d'Exemple per utilitzar en aquest Laboratori
En aquest laboratori, farem servir un fitxer de dades específic com a conjunt de dades d’exemple. Aquest fitxer representa una pokedex i es pot obtenir amb la següent comanda:
curl -O https://gist.githubusercontent.com/armgilles/194bcff35001e7eb53a2a8b441e8b2c6/raw/92200bc0a673d5ce2110aaad4544ed6c4010f687/pokemon.csv
Aquest fitxer conté 801 línies (800 pokemons + 1 capçalera) i 13 columnes. Les columnes són les següents:
- #: Número de pokémon
- Name: Nom del pokémon
- Type 1: Tipus 1 del pokémon
- Type 2: Tipus 2 del pokémon
- Total: Total de punts de tots els atributs
- HP: Punts de vida
- Attack: Atac
- Defense: Defensa
- Sp. Atk: Atac especial
- Sp. Def: Defensa especial
- Speed: Velocitat
- Generation: Generació
- Legendary: Llegendari (0: No, 1: Sí)
Per comprovar aquestes dades, podem fer servir les següents comandes:
-
Utilitzeu la comanda
wc
per comptar el nombre de línies del fitxer:wc -l pokemon.csv
-
Utilitzeu la comanda
head
per mostrar les primeres 10 línies del fitxer:head pokemon.csv
-
Utilitzeu les comandes
wc
ihead
per comptar el nombre de columnes del fitxer. Recordeu que les columnes estan separades per comes:head -1 pokemon.csv | tr ',' '\n' | wc -l
Awk - Bàsic
Estrucutra Bàsica d'AWK
El llenguatge AWK s'organitza amb duples de la forma patró { acció }
. El patró pot ser una expressió regular o una condició lògica. L’acció és el que es vol realitzar amb les línies que compleixen el patró. Per tant, AWK processa els fitxers línia per línia. Per cada línia del fitxer, AWK avalua el patró. Si el patró és cert, executa l’acció. Si el patró és fals, passa a la següent línia.
Per exemple, si volem imprimir totes les línies d'un fitxer (acció) que contenten una expressió regular definida a regex (patró), podem fer servir la següent sintaxi:
awk '/regex/ { print }' fitxer
Observeu que utilitzem el caràcter /
per indicar que el patró és una expressió regular.
A més, AWK ens permet utilitzar una estructura de control BEGIN
i END
. La clàusula BEGIN
s'executa abans de processar qualsevol línia i la clàusula END
s'executa després de processar totes les línies. Aquestes clausules són opcionals i no són necessàries en tots els casos.
BEGIN { acció }
patró { acció }
END { acció }
Per exemple, si volem indicar que estem començant a processar un fitxer, podem fer servir la clàusula BEGIN
. I si volem indicar que hem acabat de processar el fitxer, podem fer servir la clàusula END
. A continuació, teniu un exemple de com utilitzar les clàusules BEGIN
i END
:
awk '
BEGIN { print "Començant a processar el fitxer..." }
/regex/ { print }
END { print "Finalitzant el processament del fitxer..." }
' fitxer
Aprenent a utilitzar AWK amb Exemples
Sintaxis Bàsica
En aquesta secció veurem com podem utiltizar AWK per substituir algunes comandes bàsiques de bash com cat, grep, cut
.
cat
La comanda cat
ens permet mostrar el contingut d'un fitxer. Per exemple, per mostrar el contingut del fitxer pokemon.csv:
cat pokemon.csv
Podem fer servir AWK per fer el mateix. Per exemple, per mostrar el contingut del fitxer pokemon.csv:
awk '{print}' pokemon.csv
on {print}
és l'acció que volem realitzar. En aquest cas, volem imprimir totes les línies del fitxer. Això és equivalent a la comanda cat
.
AWK també ens permet acompanyar l'acció amb variables. Per exemple, la variable $0 conté tota la línia. Per tant, podem utilitzar la variable $0 per imprimir totes les línies del fitxer:
awk '{print $0}' pokemon.csv
Nota: AWK processa els fitxers línia per línia. Per cada línia del fitxer, AWK avalua l'acció. Es a dir, amb la comanda awk '{print $0}' pokemon.csv
estem indicant que per cada línia del fitxer, imprimeixi la línia sencera. Per tant, aquesta comanda és equivalent a la comanda cat
.
Podeu comparar les sortides de les comandes cat
i awk
per assegurar-vos que són les mateixes utilitzant la comanda diff
:
diff <(cat pokemon.csv) <(awk '{print $0}' pokemon.csv)
grep
La comanda grep
ens permet cercar patrons en un fitxer. Per exemple, per mostrar totes les línies que contenen la paraula "Char" al fitxer pokemon.csv:
grep Char pokemon.csv
Podem fer servir AWK per fer el mateix. Per exemple, per mostrar totes les línies que contenen la paraula "Char" al fitxer pokemon.csv:
awk '/Char/ {print}' pokemon.csv
on /Char/
és el patró que volem cercar. Per tant, tenim un patró de cerca i una acció a realitzar. En aquest cas, estem cercant linia per linia la paraula "Char" i si la trobem, imprimim tota la línia. Això és equivalent a la comanda grep
.
Una confusió comuna es pensar que l'expressió /Char/
indica que la línia comença per "Char". Això no és cert. L'expressió /Char/
indica que la línia conté la paraula "Char". Per exemple, podem buscar totes les línies del fitxer pokemon.csv que contenen el patró "ois":
awk '/ois/ {print}' pokemon.csv
En la sortida, veureu que tant les paraules "poison" del tipus de pokémon com els diferents noms de pokémon que contenen la paraula "ois" són mostrats.
1,Bulbasaur,Grass,Poison,318,45,49,49,65,65,45,1,False
9,Blastoise,Water,-,530,79,83,100,85,105,78,1,False
...
71,Victreebel,Grass,Poison,490,80,105,65,100,70,70,1,False
...
691,Dragalge,Poison,Dragon,494,65,75,90,97,123,44,6,False
Conteu quantes línies compleixen aquest patró, combinant AWK amb la comanda wc
:
awk '/ois/ {print}' pokemon.csv | wc -l
En aquest cas, hi ha 64 entrades que satisfan aquest patró.
cut
La comanda cut
ens permet extreure columnes d'un fitxer. Per exemple, per mostrar només la primera columna del fitxer pokemon.csv:
cut -d, -f1 pokemon.csv
on -d,
indica que el separador de camps és la coma i -f1
indica que volem la primera columna. Podem fer servir AWK per fer el mateix. Per exemple, per mostrar només la primera columna del fitxer pokemon.csv:
awk -F, '{print $1}' pokemon.csv
on -F,
indica que el separador de camps és la coma i {print $1}
indica que volem la primera columna. Això és equivalent a la comanda cut
.
Cada item separat pel separador de camps es denomina camp. Per exemple, en el fitxer pokemon.csv, cada columna separada per una coma és un camp. Per defecte, el separador de camps és l'espai en blanc. Per tant, si no especifiquem el separador de camps, AWK utilitzarà l'espai en blanc com a separador de camps.
Si intentem imprimir la tercera columna sense especificar el separador de camps, la sortida no serà correcta:
awk '{print $3}' pokemon.csv
Això és degut a que el separador de camps per defecte és l'espai en blanc i no la coma. Ara bé, si modifiquem el separador de camps a l'espai en blanc, enlloc de la coma, podem obtenir la sortida correcta:
sed 's/,/ /g' pokemon.csv | awk '{print $3}'
En aquest cas, estem substituint totes les comes per espais en blanc i després utilitzant AWK per imprimir la tercera columna.
Verificacions lògiques
Es pot utilitzar com a patró una expressió composta amb operadors i retornar true o false.
Operador | Significat |
---|---|
< | Menor |
> | Major |
<= | Menor o igual |
>= | Major o igual |
== | Igualtat |
!= | Desigualtat |
~ | Correspondència amb expressió regular |
!~ | No correspondència amb expressió regular |
! | Negació |
&& | AND |
|| | OR |
() | Agrupació |
Per utilizar aquestes expressions, podem fer servir la següent sintaxi:
awk 'patró { acció }' fitxer
on el patró és una expressió composta amb operadors lògics i l'acció és el que es vol fer amb les línies que compleixen el patró. Per exemple:
-
Mostrar tots els pokemons que tenen més de 100 punts d'atac (valor de la columna 7):
awk -F, '$7 > 100 {print}' pokemon.csv
-
Mostrar tots els pokemons que tenen més de 100 punts d'atac (valor de la columna 7) i són de la primera generació (valor de la columna 12):
awk -F, '$7 > 100 && $12 == 1 {print}' pokemon.csv
-
Mostrar tots els pokemons que tenen més de 100 punts d'atac (valor de la columna 7) o són de la primera generació (valor de la columna 12):
awk -F, '$7 > 100 || $12 == 1 {print}' pokemon.csv
-
Mostrar tots els pokemons que són Mega pokemons (contenen la paraula "Mega" a la columna 2):
awk -F, '$2 ~ /Mega/ {print}' pokemon.csv
-
Mostra tots els pokemons que no són Mega pokemons (no contenen la paraula "Mega" a la columna 2):
awk -F, '$2 !~ /Mega/ {print}' pokemon.csv
Exercicis Bàsics
Aquests exercicis estan resolts en bash i en AWK. Podeu provar-los en el vostre sistema per entendre com funcionen. Intenta resoldre primer els exercicis en bash i després en AWK. Un cop pensada la solució, podeu comparar-la amb la solució proporcionada.
-
Implementeu una comanda que permeti filtrar tots els pokemon de tipus foc (Foc) i imprimir únicament per stdout el nom i els seus tipus (columnes 2, 3 i 4).
- En bash podem fer servir la comanda grep per filtrar les línies que contenen la paraula "Fire" i la comanda cut per extreure les columnes 2, 3 i 4:
grep Fire pokemon.csv | cut -d, -f2,3,4
- En AWK:
awk -F, '/Fire/ {print $2,$3,$4}' pokemon.csv
-
Implementeu una comanda que permeti imprimir totes les línies que continguin una 'b' o una 'B' seguida de "ut". Mostra només el nom del pokémon (columna 2).
- En AWk podem fer servir l'expressió regular [bB]ut:
awk -F, '/[bB]ut/ {print $2}' pokemon.csv
- En bash podem fer servir la comanda grep amb l'argument -i per ignorar la diferència entre majúscules i minúscules:
grep -i "but" pokemon.csv | cut -d, -f2
-
Implementeu una comanda que permeti imprimir totes les línies que comencin per un "K" majúscula. Mostra només el nom del pokémon (columna 2).
- En bash podem fer servir la comanda grep amb el meta caràcter ^ per indicar que la línia comença per "K" majúscula:
grep "^K" pokemon.csv | cut -d, -f2
- En AWK:
awk -F, '$2 ~ /^K/ {print $2}' pokemon.csv
!Compte: Per defecte, les expressions regulars actuen sobre tota la línia $0. Si voleu aplicar l'expressió regular a una columna determinada, necessiteu l'operador (~). Si intenteu aplicar:
awk -F,'/^K/ {print $2}' pokemon.csv
no funcionarà ja que l'inici ^ de $0 serà un enter. -
Imprimiu tots els pokemons que siguin del tipus foc o lluita. Imprimiu el nom, tipus 1 i tipus 2. Podeu fer servir l'operador | per crear l'expressió regular.
- En AWK podem fer servir l'operador | per combinar dos patrons:
awk -F, '/Fire|Fighting/ {print $2,$3,$4}' pokemon.csv
- En bash, podeu fer servir l'argument -E per utilitzar expressions regulars exteses amb la comanda grep:
grep -E "Fire|Fighting" pokemon.csv | cut -d, -f2,3,4
-
Imprimiu tots els pokemons que siguin del tipus foc i lluita. Imprimiu el nom, tipus 1 i tipus 2. Podeu fer servir l'operador && per crear l'expressió regular.
- En AWK podem fer servir l'operador && per combinar dos patrons:
awk -F, '/Fire/ && /Fighting/ {print $2,$3,$4}' pokemon.csv
- En bash, podeu fer servir l'argument -E per utilitzar expressions regulars exteses amb la comanda grep:
grep -E "Fire.*Fighting|Fighting.*Fire" pokemon.csv | cut -d, -f2,3,4
En aquest cas no podem fer servir l'operador && ja que grep no permet aquesta funcionalitat. Per tant, hem de fer servir l'operador | per combinar els dos patrons. A més, hem de fer servir l'expressió regular **Fire.Fighting|Fighting.Fire per indicar que volem les línies que contenen "Fire" seguit de "Fighting" o "Fighting" seguit de "Fire".
-
Imprimiu el nom de tots els pokemons de la primera generació que siguin llegendaris. Per fer-ho utilitzeu les columnes 12 i 13. La columna 12 indica la generació amb valors númerics (1,2,3,...) i la columna 13 indica si un pokémon és llegendari o no (0: No, 1: Sí).
- En AWK podem fer servir l'operador && per combinar dos patrons:
awk -F, '$12 == 1 && $13 == "True" {print $2}' pokemon.csv
- En bash, podem fer servir la comanda grep per filtrar les línies que contenen la primera generació i són llegendaris i la comanda cut per extreure la columna 2:
grep "1,True" pokemon.csv | cut -d, -f2
Aquesta solució no és la més òptima, ja que es podria donar el cas que altres columnes continguessin la paraula "1,True". Per solucionar-ho podem fer un script més complex que comprovi que la columna 12 conté el valor 1 i la columna 13 conté la paraula "True".
#!/bin/bash while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13; do if [[ "$col12" == "1" ]] && [[ "$col13" == "True" ]]; then echo "$col2" fi done < pokemon.csv
Awk - Intermedi
Variables en AWK
El llenguatge de programació AWK ens permet definir variables i utilitzar-les en les nostres accions. Les variables en AWK són dinàmiques i no necessiten ser declarades abans d'utilitzar-les. Això significa que podem utilitzar una variable sense haver-la declarat prèviament.
Per exemple, si volem comptar el nombre de línies que hi ha al fitxer pokemon.csv, podem fer servir una variable per a emmagatzemar el nombre de línies. A continuació, mostrem un exemple de com comptar el nombre de línies del fitxer pokemon.csv:
awk 'BEGIN { n=0 } { ++n } END{ print n }' pokemon.csv
On n és la variable que utilitzem per emmagatzemar el nombre de línies. Per començar, inicialitzem la variable n a 0 amb la clàusula {BEGIN}. Aquesta clausula és opcional, ja que les variables en AWK són dinàmiques i no necessiten ser declarades prèviament. Després, incrementem la variable n per a cada línia amb la clàusula {++n}. Finalment, utilitzem la clàusula {END} per imprimir el valor de la variable n després de processar totes les línies.
Operacions Aritmètiques
Operador | Aritat | Signigicat |
---|---|---|
+ | Binari | Suma |
- | Binari | Resta |
* | Binari | Multiplicació |
/ | Binari | Divisió |
% | Binari | Mòdul |
^ | Binari | Exponent |
++ | Unari | Increment 1 unitat |
-- | Unari | Decrement 1 unitat |
+= | Binari | x = x+y |
-= | Binari | x = x-y |
*= | Binari | x=x*y |
/= | Binari | x=x/y |
%= | Binari | x=x%y |
^= | Binari | x=x^y |
Implementeu un script que comprovi que el Total (columna 5) és la suma de tots els atributs (columnes 6,7,8,9,10 i 11). La sortida ha de ser semblant a:
Charmander->Total=309==309
Charmeleon->Total=405==405
Charizard->Total=534==534
-
En AWK:
awk -F, '{ print $2"->Total="$5"=="($6+$7+$8+$9+$10+$11)}' pokemon.csv
-
En bash:
#!/bin/bash while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13; do if [[ "$col5" == "$((col6+col7+col8+col9+col10+col11))" ]]; then echo "$col2->Total=$col5==$((col6+col7+col8+col9+col10+col11))" fi done < pokemon.csv
Variables Internes
AWK té variables internes que són molt útils per a la manipulació de dades. Aquestes variables són:
Variable | Contingut |
---|---|
$0 | Conté tot el registre actual |
NF | Conté el valor del camp (columna) actual. |
$1,$2..., | $1 conté el valor del primer camp i així fins l'últim camp. noteu que $NF serà substituït al final pel valor de l'últim camp. |
NR | Índex del registre actual. Per tant, quan es processa la primera línia aquesta variable té el valor 1 i quan acaba conté el nombre de línies processades. |
FNR | Índex del fitxer actual que estem processant. |
FILENAME | Nom del fitxer que estem processant. |
Per exemple:
-
Utilitzeu la variable NR per simplificar la comanda per comptar el nombre de línies del fitxer pokemon.csv:
awk 'END{ print NR }' pokemon.csv
-
Traduïu la capçalera del fitxer pokemon.csv al catala. La capçalera és la següent: # Name Type 1 Type 2 Total HP Attack Defense Sp. Atk Sp. Def Speed Generation Legendary. La traducció és la següent: # Nom Tipus 1 Tipus 2 Total HP Atac Defensa Atac Especial Defensa Especial Velocitat Generació Llegendari. I després imprimiu la resta de línies del fitxer.
awk 'NR==1 { $1="#"; $2="Nom"; $3="Tipus 1"; $4="Tipus 2"; $5="Total"; $6="HP"; $7="Atac"; $8="Defensa"; $9="Atac Especial"; $10="Defensa Especial"; $11="Velocitat"; $12="Generació"; $13="Llegendari"; print $0 } NR>1 {print}' pokemon.csv
-
Implementeu una comanda que permeti detectar entrades incorrectes a la pokedex. Un entrada incorrecta és aquella que no té 13 valors per línia. En cas de detectar una entrada incorrecta, la eliminarem de la sortida i comptarem el nombre de línies eliminades per mostrar-ho al final.
awk 'NF != 13 { n++ } NF == 13 { print } END{ print "There are ", n, "incorrect entries." }' pokemon.csv
Condicionals
Les sentències condicionals s'utilitzen en qualsevol llenguatge de programació per executar qualsevol sentència basada en una condició particular. Es basa en avaluar el valor true o false en les declaracions if-else i if-elseif
. AWK admet tot tipus de sentències condicionals com altres llenguatges de programació.
Implementeu una comanda que us indiqui quins pokemons de tipus foc són ordinaris o llegendaris. Busquem una sortida semblant a:
Charmander is a common pokemon.
Charizard is a legendary pokemon.
...
La condició per ser un pokémon llegendari és que la columna 13 sigui True.
awk -F, '/Fire/ { if ($13 == "True") { print $2, "is a legendary pokemon." } else { print $2, "is a common pokemon." } }' pokemon.csv
Es pot simplificar la comanda anterior amb l'ús de l'operador ternari ?::
awk -F, '/Fire/ { print $2, "is a", ($13 == "True" ? "legendary" : "common"), "pokemon." }' pokemon.csv
Formatant la sortida
AWK ens permet també utilitzar una funció semblant al printf de C. Permet imprimir la cadena
amb diferents formats: printf("cadena",expr1,,expr2,...)
%20s | Es mostraran 20 caràcters de la cadena alineats a la dreta per defecte. |
%-20s | Es mostraran 20 caràcters de la cadena alineats a l'esquerra per defecte. |
%3d | Es mostrarà un enter de 3 posicions alineat a la dreta |
%03d | Es mostrarà un enter de 3 posicions completat amb un 0 a l'esquerra i tot alineat a la dreta |
%-3d | Es mostrarà un enter de 3 posicions alineat a la esquerra. |
&+3d | Idem amb signe i alineat a la dreta |
%10.2f | Es mostrarà un nombre amb coma flotant amb 10 posicions, 2 de les quals seràn decimals. |
Per exemple:
awk -F, \
' BEGIN{
max=0
min=100
}
{
if ($3 =="Fire") {
n++
attack+=$7
if ($7 > max){
pmax=$2
max=$7
}
if ($7 < min){
pmin=$2
min=$7
}
}
}
END{ printf("Avg(Attack):%4.2f \nWeakest:%s \nStrongest:%s\n",attack/n,pmin,pmax)
}' pokemon.csv
Exercicis Intermedis
-
Implementeu un script que compti tots els pokemons que tenim a la pokedex i que tingui la sortida següent:
Counting pokemons... There are 800 pokemons.
Recordeu que la primera línia és la capçalera i no la volem comptar.
-
En bash:
!/bin/bash echo "Counting pokemons..." n=`wc -l pokemon.csv` n=`expr $n - 1` echo "There are $n pokemons."
-
En AWK:
awk 'BEGIN { print "Counting pokemons..." } { ++n } END{ print "There are ", n-1, "pokemons." }' pokemon.csv
-
-
Implementeu un comptador per saber tots els pokemons de tipus foc de la primera generació descartant els Mega pokemons i que tingui la sortida següent:
Counting pokemons... There are 12 fire type pokemons in the first generation without Mega evolutions.
-
Per fer-ho en bash, podeu combinar les comandes grep, cut, wc i expr. Nota, l'argyment -v de grep exclou les línies que contenen el patró i la generació s'indica a la columna 12 amb el valor 1:
!/bin/bash echo "Counting pokemons..." n=`grep Fire pokemon.csv | grep -v "Mega" | cut -d, -f12 | grep 1 | wc -l` n=`expr $n - 1` echo "There are $n pokemons in the first generation without Mega evolutions."
- Per fer-ho en AWK, teniu el negador ! per negar el patró:
awk -F, 'BEGIN { print "Counting pokemons..." } /Fire/ && !/Mega/ && $12 == 1 { ++n } END{ print "There are ", n, "fire type pokemons in the first generation without Mega evolutions." }' pokemon.csv
En aquest exemple, hem utilitzat l'operador lògic && per combinar dos patrons. Això significa que la línia ha de contenir el patró Fire i no ha de contenir el patró Mega. Això ens permet filtrar els Mega pokemons del nostre comptador. A més, hem utilitzat l'operador ! per negar el patró Mega. Això significa que la línia no ha de contenir el patró Mega. Finalment, hem utilitzat la clàusula {END} per imprimir el resultat final.
-
-
Indiqueu a quina línia es troba cada pokémon del tipus foc. Volem imprimir la línia i el nom del pokémon. La sortida ha de ser semblant a:
Line: 6 Charmander Line: 7 Charmeleon Line: 8 Charizard Line: 9 CharizardMega Charizard X Line: 10 CharizardMega Charizard Y ... Line: 737 Litleo Line: 738 Pyroar Line: 801 Volcanion
on el format de cada línia és Line: n\tNom del pokémon.
-
En AWK podem fer servir la variable NR per obtenir el número de línia actual. A més a més, podeu formatar la sortida amb
print cadena,variable,cadena,variable,...
:awk -F, '/Fire/ {print "Line: ", NR, "\t" $2}' pokemon.csv
-
En bash:
#!/bin/bash while IFS=, read -r col1 col2 col3 rest; do ((line_number++)) # Check if the line contains the word "Fire" if [[ "$col2" == *"Fire"* || "$col3" == *"Fire"* ]]; then echo "Line: $line_number $col2" fi done < pokemon.csv
-
-
Implementeu un script que permeti comptar el nombre de pokemons de tipus foc i drac. La sortida ha de ser semblant a:
Fire:64 Dragon:50 Others:689
-
En AWK:
awk -F, 'BEGIN{ fire=0; dragon=0; others=0 } /Fire/ { fire++ } /Dragon/ { dragon++ } !/Fire|Dragon/ { others++ } END{ print "Fire:" fire "\nDragon:" dragon "\nOthers:" others }' pokemon.csv
-
En bash:
#!/bin/bash fire=0 dragon=0 others=0 while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13; do if [[ "$col3" == *"Fire"* || "$col4" == *"Fire"* ]]; then ((fire++)) fi if [[ "$col3" == *"Dragon"* || "$col4" == *"Dragon"* ]]; then ((dragon++)) fi if [[ "$col3" != *"Fire"* && "$col4" != *"Fire"* && "$col3" != *"Dragon"* && "$col4" != *"Dragon"* ]]; then ((others++)) fi done < pokemon.csv echo "Fire:$fire" echo "Dragon:$dragon" echo "Others:$others"
-
-
Imprimiu la pokedex amb una nova columna que indiqui la mitjana aritmètica dels atributs de cada pokémon. La sortida ha de ser semblant a:
#,Name,Type 1,Type 2,Total,HP,Attack,Defense,Sp. Atk,Sp. Def,Speed,Generation,Legendary,Avg 1,Bulbasaur,Grass,Poison,318,45,49,49,65,65,45,1,False,53 2,Ivysaur,Grass,Poison,405,60,62,63,80,80,60,1,False,67.5 3,Venusaur,Grass,Poison,525,80,82,83,100,100,80,1,False,87.5
-
En AWK:
awk -F, '{ if (NR==1) print $0",Avg"; else print $0","($6+$7+$8+$9+$10+$11)/6 }' pokemon.csv
-
En bash:
#!/bin/bash while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13; do if [[ "$col1" == "#" ]]; then echo "$col1,$col2,$col3,$col4,$col5,$col6,$col7,$col8,$col9,$col10,$col11,$col12,$col13,Avg" else avg=$((($col6+$col7+$col8+$col9+$col10+$col11)/6)) echo "$col1,$col2,$col3,$col4,$col5,$col6,$col7,$col8,$col9,$col10,$col11,$col12,$col13,$avg" fi done < pokemon.csv
Nota: Bash de forma nativa no permet operacions aritmètiques amb nombres decimals. Per fer-ho, cal utilitzar una eina com
bc
. En aquest cas, podeu adaptar el codi per utilitzarbc
quan calculeu la mitjana i fer servirprintf
per formatar la sortida amb el nombre de decimals que vulgueu.
-
-
Cerca el pokémon més fort i més feble tenint en compte el valor de la columna 7 dels pokemons de tipus foc de la primera generació.
-
En AWK, assumiu que el valors de la columna 7 van de 0 a 100:
awk -F, 'BEGIN{ max=0; min=100 } /Fire/ && $12 == 1 { if ($7 > max) { max=$7; pmax=$2 } if ($7 < min) { min=$7; pmin=$2 } } END{ print "Weakest: "pmin "\nStrongest: "pmax }' pokemon.csv
-
En bash:
#!/bin/bash max=0 min=100 while IFS=, read -r col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13; do if [[ "$col3" == *"Fire"* ]] && [[ "$col12" == "1" ]]; then if [[ "$col7" -gt "$max" ]]; then max=$col7 pmax=$col2 fi if [[ "$col7" -lt "$min" ]]; then min=$col7 pmin=$col2 fi fi done < pokemon.csv echo "Weakest: $pmin" echo "Strongest: $pmax"
-
Awk - Avançat
Variables definides quan executem AWK
Variable | Valor per defecte | Significat |
---|---|---|
RS | /n (Salt de línia) | Valor que fem servir per separar els registres (entrada) |
FS | Espais o tabulacions | Valor que fem servir per separar els camps en l'entrada. |
OFS | espai | Valor que fem servir per separar el camps en la sortida. |
ORS | /n (Salt de línia) | Valor que fem servir per separar els registres (sortida). |
ARGV | - | Taula inicialitzada amb els arguments de la línia de comandes (opcions i nom del script awk s'exclouen). |
ARGC | - | Nombre d'arguments. |
ENVIRON | Variables entorn | Taula amb les variables entorn exportades per la shell. |
Per exemple:
-
Transformeu el fitxer pokemon.csv en un fitxer amb els camps separats per tabulacions:
awk -F, 'BEGIN{OFS="\t"} {print $0}' pokemon_tab.csv
-
Per fer servir el fitxer pokemon_tab.csv podem utilitzar els mateixos scripts que hem fet servir amb el fitxer pokemon.csv. Però indicant que el separador de camps és un tabulador. Per exemple, per comptar el nombre de pokemons lluitadors:
awk -F"\t" '/Fighting/ {print $2}' pokemon_tab.csv
-
Si volem fer servir una variable entorn per indicar el tipus de pokemons que volem comptar, podem fer-ho així:
awk -F"\t" -v type=$TYPE '{ if ($3 == type) { print $2 } }' pokemon_tab.csv
on $TYPE és una variable entorn que conté el tipus de pokemons que volem comptar.
Bucles
El llenguatge AWK també ens permet fer bucles accepta les següents estructures:
for (expr1;expr2;expr3) { acció }
: Aquest bucle executa la primera expressió, després avalua la segona expressió i si és certa executa l'acció. Després executa la tercera expressió i torna a avaluar la segona expressió. Això es repeteix fins que la segona expressió sigui falsa.
Per exemple, transformeu el fitxer pokemon.csv
en un fitxer amb els camps separats per ; utilitzant un bucle for:
awk -F, \
'BEGIN{OFS=";";}
{
for (i=1;i<=NF;i++)
printf("%s%s",$i,(i==NF)?"\n":OFS)
}' pokemon.csv
while (condició) { acció }
: Aquest bucle executa l'acció mentre la condició sigui certa.
Per exemple, substituïu els camps del tipus de pokemon per un camps tipus compost per els dos tipus de pokemon separats per un / dels primers 10 pokemons:
awk -F, \
'BEGIN{OFS=",";}
{
while (NR>1 && NR <= 11) {
print $1, $2, $3 "/" $4, $5, $6, $7, $8, $9, $10, $11, $12, $13
getline
}
}' pokemon.csv
La comanda getline
ens permet llegir la següent línia de l'entrada. Això ens permet llegir la següent línia dins del bucle while. Si no fem servir la comanda getline
, el bucle while es quedaria en un bucle infinit ja que la condició NR <= 11
sempre seria certa.
do { acció } while (condició)
: Aquest bucle executa l'acció una vegada i després avalua la condició. Si la condició és certa, torna a executar l'acció.
Per exemple, utilitzeu el bucle do per comptar el nombre de pokemons de tipus foc:
awk -F, \
'BEGIN{print "Counting pokemons..."; n=0}
{
do {
if ($3 == "Fire" || $4 == "Fire")
n++
} while (getline)
}
END{print "There are ", n, "fire type pokemons."}' pokemon.csv
Instruccions de control:
break
: Finalitza el bucle actual.continue
: Salta a la següent iteració del bucle.next
: Salta a la següent línia de l'entrada.
Per exemple:
-
Cerqueu la primera entrada que compleixi les següents condicions: el tipus de pokemon és "Fire" i la seva velocitat és més gran que 100:
awk -F, 'BEGIN {found = 0} { if (found == 0) { for (i=1; i<=NF; i++) { if ($i == "Fire" && $7 > 100) { print "El primer Pokémon de tipus Fire amb velocitat superior a 100 és: " $2; found = 1; break } } } }' pokemon.csv
Observació:
break
finalitza el bucle actual que recorre els camps de la línia. Per tant, ens permet deixar de buscar en una línia quan ja hem trobat el que volem. -
Cerqueu totes les entrades que compleixen les següents condicions: el tipus de pokemon és "Fire" i la seva velocitat és més gran que 100:
awk -F, '{ for (i=1; i<=NF; i++) { if ($i == "Fire" && $7 > 100) { print $2 } } }' pokemon.csv
o bé
awk -F, '{ for (i=1; i<=NF; i++) { if ($i == "Fire" && $7 > 100) { print $2; break } } }' pokemon.csv
Observació:
break
ens permet que quan trobem un pokemon que compleix les condicions, no cal seguir buscant en la mateixa línia i podem passar a la següent. En aquest cas,next
seria equivalent abreak
. -
Cerqueu tots els pokemons que són voladors i de foc assumint que les columnes poden estar en qualsevol ordre i que cada entrada pot estar ordenada de forma diferent:
awk -F, '{ for (i=1; i<=NF; i++) { if ($i == "Fire") { for (j=1; j<=NF; j++) { if ($j == "Flying") { print $2; next } } } } }' pokemon.csv
Observació:
next
ens permet que quan trobem un pokemon que compleix les condicions, no cal seguir buscant en la mateixa línia i podem passar a la següent.Observació:
break
ens donaria el mateix resultat en aquest cas. Perònext
és més eficient perquè no cal seguir recorrent els camps de la línia. La comandabreak
seguiria recorrent els camps al bucle de la variable i.
Arrays
AWK també ens permet fer servir arrays. Per exemple, podem fer servir un array per comptar el nombre de pokemons de cada tipus:
awk -F, '
{
if (NR > 1) {
type1 = $3
type2 = $4
types[type1]++
if (type2 != "") {
types[type2]++
}
}
}
END {
for (type in types) {
print type, types[type]
}
}' pokemon.csv
Els arrays en AWK són associatius, és a dir, no cal indicar la posició de l'element en l'array. Per exemple, si volem comptar el nombre de pokemons de cada tipus per generació:
gawk -F, '
{
if (NR > 1) {
type1 = $3
type2 = $4
gen = $12
types[type1][gen]++
if (type2 != "") {
types[type2][gen]++
}
}
}
END {
for (type in types) {
printf "%s\n", type
for (gen in types[type]) {
printf " Gen %d: %d\n", gen, types[type][gen]
}
}
}' pokemon.csv
Nota: En aquest exemple, hem fet servir un array bidimensional. El llenguatge
awk
no permet declarar arrays multidimensionals, per poder fer-lo servir necessitem la extensió gawk. Per instal·lar-la, podeu fer servir la comandaapt install gawk
odnf install gawk
.
Per fer-ho en AWK, podem utiltizar una clau combinada amb el tipus i la generació i la funció split per separar les dues claus:
awk -F, '
{
if (NR > 1) {
type1 = $3
type2 = $4
gen = $12
types[type1 " " gen]++
if (type2 != "") {
types[type2 " " gen]++
}
}
}
END {
for (typegen in types) {
split(typegen, temp, " ")
type = temp[1]
gen = temp[2]
printf "%s %d: %d\n", type, gen, types[typegen]
}
}' pokemon.csv | sort -k2 -n
Exercicis Avançats AWK
-
Implementeu un script que mostri la pokedex en ordre invers. Però mantenint la primera línia com a capçalera.
awk -F, ' { if (NR == 1) { print $0 } else { lines[NR] = $0 } } END { for (i = NR; i > 1; i--) { print lines[i] } }' pokemon.csv
-
Implementeu un script que simuli la comanda
sort -t, -k5 -n pokemon.csv
. Aquesta comanda ordena el fitxer pokemon.csv pel camp Total de forma numèrica. Podeu fer servir la funcióasort
per ordenar els pokemons. Aquesta funció ordena un array i retorna el nombre d'elements de l'array ordenat. Per exemple:asort(array, sorted, "@val_num_asc")
ordena l'array array de forma numèrica ascendent i guarda el resultat a l'array sorted.
A més, podeu fer servir la funció
split
que ens permet dividir una cadena de text en un array. Per exemple:split("a,b,c,d", array, ",")
divideix la cadena de text "a,b,c,d" en l'array array amb els valors "a", "b", "c" i "d".
awk -F, ' { if (NR == 1) { print $0 } else { lines[NR] = $0 totals[NR] = $5 " " NR } } END { n = asort(totals, sorted, "@val_num_asc") for (i = 1; i <= n; i++) { split(sorted[i], temp, " ") line = temp[2] print lines[line] } }' pokemon.csv
-
Implementeu un script que mostri una taula resum amb els pokemons de cada tipus a cada generació. Un exemple de la sortida esperada:
Tipus Gen 1 Gen 2 Gen 3 Gen 4 Gen 5 Gen 6 Normal 24 15 18 18 19 8 Dragon 4 2 15 8 12 9 Ground 14 11 16 12 12 2 Electric 9 9 5 12 12 3 Poison 36 4 5 8 7 2 Steel 2 6 12 12 12 5 Bug 14 12 14 11 18 3 Grass 15 10 18 17 20 15 Fire 14 11 9 6 16 8 Dark 1 8 13 7 16 6 Ice 5 5 7 8 9 4 Fighting 9 4 9 10 17 4 Water 35 18 31 15 18 9 Ghost 4 1 8 9 9 15 Flying 23 19 14 16 21 8 Rock 12 8 12 7 10 9 Fairy 5 8 8 2 3 14 Psychic 18 10 28 10 16 8 Notes:
- Els tipus de pokemons es troben a la columna 3 i 4 i la generació a la columna 12.
- Utilitzeu printf per formatar la sortida.
- En AWK:
awk -F, ' BEGIN { print "| Tipus | Gen 1 | Gen 2 | Gen 3 | Gen 4 | Gen 5 | Gen 6 |" print "|------------|-------|-------|-------|-------|-------|-------|" } { if (NR > 1) { type1 = $3 type2 = $4 gen = $12 types[type1][gen]++ if (type2 != "") { types[type2][gen]++ } } } END { for (type in types) { printf "| %-10s |", type for (gen = 1; gen <= 6; gen++) { printf " %-5s |", types[type][gen] ? types[type][gen] : 0 } print "" } }' pokemon.csv
-
Implementeu un parser que transformi el fitxer
pokemon.csv
en un fitxerpokemon.json
. Aquest fitxer ha de ser formatat de forma correcta. Podeu assumir que coneixeu els headers del fitxer i la tipologia de les seves dades. Per exemple, la primera línia del fitxer pokemon.csv ha de ser transformada en:{ "Name": "Bulbasaur", "Type 1": "Grass", "Type 2": "Poison", "Total": 318, "HP": 45, "Attack": 49, "Defense": 49, "Sp. Atk": 65, "Sp. Def": 65, "Speed": 45, "Generation": 1, "Legendary": false }
- Una solució simple en AWK:
awk -F, ' BEGIN { print "[" } { if (NR > 1) { printf " {\n" printf " \"Name\": \"%s\",\n", $2 printf " \"Type 1\": \"%s\",\n", $3 printf " \"Type 2\": \"%s\",\n", $4 printf " \"Total\": %d,\n", $5 printf " \"HP\": %d,\n", $6 printf " \"Attack\": %d,\n", $7 printf " \"Defense\": %d,\n", $8 printf " \"Sp. Atk\": %d,\n", $9 printf " \"Sp. Def\": %d,\n", $10 printf " \"Speed\": %d,\n", $11 printf " \"Generation\": %d,\n", $12 printf " \"Legendary\": %s\n", $13 printf " }%s\n", (NR == 800) ? "" : "," } } END { print "]" }' pokemon.csv > pokemon.json
- Una solució més complexa en AWK:
awk -F, ' BEGIN { print "[" } { if(NR == 1) { for (i = 2; i <= NF; i++) { headers[i] = $i } } else { if(NR != 2) { print " }," } printf " {\n" for (i = 2; i <= NF; i++) { if ($i ~ /^[0-9]+$/) { printf " \"%s\": %d,\n", headers[i], $i } else { printf " \"%s\": \"%s\",\n", headers[i], $i } } } } END { print " }\n]" }' pokemon.csv > pokemon.json
-
Implementeu un script que permeti simular un combat entre dos pokémons. Els pokémons es passen com a variables d'entorn i han d'utilitzar el nom del pokémon a la pokedex. La lògica del combat és comparar els valors de velocitat per saber qui ataca primer. El pokémon que ataca primer és el que té més velocitat. Si els dos pokémons tenen la mateixa velocitat, el primer pokémon que s'ha passat com a variable d'entorn ataca primer. El combat es fa de forma alternada fins que un dels dos pokémons es queda sense punts de vida. El dany es mesura com (Atac - Defensa) multiplicat per un valor aleatori entre 0 i 1. Aquest es resta a la vida del pokémon oponent. La sortida ha de ser semblant a:
Charizard attacks first! Charizard attacks Charmander with 50 damage! Charmander has 20 HP left. Charmander attacks Charizard with 30 damage! Charizard has 70 HP left. Charizard attacks Charmander with 40 damage! Charmander has -10 HP left. Charmander fainted!
- Una possible solució combinar AWK i bash:
#!/bin/bash # Get the pokemons from the command line arguments pokemon1=$1 pokemon2=$2 # Function to get stats of a pokemon get_stats() { awk -F, -v pokemon="$1" '$2 == pokemon { print $6, $7, $8, $9, $10, $11 }' pokemon.csv } # Get the stats of the pokemons stats1=$(get_stats $pokemon1) stats2=$(get_stats $pokemon2) # Extract the stats read hp1 attack1 defense1 spatk1 spdef1 speed1 <<< $stats1 read hp2 attack2 defense2 spatk2 spdef2 speed2 <<< $stats2 # Check who attacks first if [ $speed1 -gt $speed2 ]; then attacker=$pokemon1 hp=$hp2 defender=$pokemon2 attack=$attack1 defense=$defense2 else attacker=$pokemon2 defender=$pokemon1 hp=$hp1 attack=$attack2 defense=$defense1 fi echo "$attacker attacks first!" # Start the battle while true; do damage=$((($attack - $defense) * $RANDOM / 32767)) damage=${damage#-} hp=$(($hp - $damage)) echo "$attacker attacks $defender with $damage damage!" if [ $hp -le 0 ]; then echo "$defender has 0 HP left." echo "$defender fainted!" break else echo "$defender has $hp HP left." fi # Swap the attacker and defender tmp=$attacker attacker=$defender defender=$tmp tmp=$hp hp=$hp2 hp2=$tmp tmp=$attack attack=$attack2 attack2=$tmp tmp=$defense defense=$defense2 defense2=$tmp done
Repositori d'exercicis
Aquesta secció conté els exercicis realitzats pels estudiants de l'assignatura d'Administració i Manteniment de Sistemes i Aplicacions (AMSA).
Exercicis
Bàsics
Intermedis
Avançats
Arrancada del sistema
Quan arranquem un ordinador, tenen lloc una sèrie de processos que permeten que el sistema operatiu es carregui i es posi en marxa. Aquests processos són els que es coneixen com a arrancada del sistema. En un sistema linux, la seqüència d'arrancada es pot dividir en les següents fases:
-
Càrrega del BIOS o UEFI. Quan encenem l'ordinador, el primer programa que s'executa està emmagatzemat en una memòria no volàtil (NVRAM). Aquest programa pot ser el BIOS (Basic Input/Output System) en sistemes més antics o l'UEFI (Unified Extensible Firmware Interface) en sistemes més moderns. Aquest firmware és el responsable de gestionar les funcions bàsiques del sistema abans de carregar el sistema operatiu.
-
Test de l'ordinador. El BIOS o l'UEFI realitza un test de l'ordinador per assegurar-se que tots els components funcionen correctament. Aquest test s'anomena POST (Power-On Self Test). Si el test falla, l'ordinador emet una sèrie de senyals acústics o visuals per indicar quin component ha fallat.
-
Selecció del dispositiu d'arrancada. El BIOS o l'UEFI permet triar quin dispositiu volem utilitzar per a carregar el sistema operatiu. Aquest dispositiu pot ser el disc dur, un dispositiu USB, un CD-ROM, etc..
-
Identificació de la partició d'arrancada. El BIOS o UEFI localitza la partició d'arrencada del dispositiu seleccionat. En sistemes amb BIOS, es fa servir el Master Boot Record (MBR), mentre que en sistemes amb UEFI es fa servir la taula de particions GUID (GPT) per identificar la partició correcta (normalment, anomenada EFI). Aquesta partició conté el gestor d'arrencada i altres fitxers necessaris per continuar el procés d'arrencada.
-
Càrrega del gestor d'arrancada. El BIOS o UEFI carrega el gestor d'arrencada. El gestor d'arrancada és un petit programa que permet triar quin sistema operatiu volem carregar. Els gestors d'arrencada més comuns en sistemes Linux són GRUB (Grand Unified Bootloader) o LILO (Linux Loader). Aquests gestors d'arrancada mostren una llista amb els sistemes operatius disponibles i permeten triar-ne un.
-
Càrrega del kernel. En aquesta fase, el gestor d'arrancada descomprimeix el codi del nucli i el carrega a la memòria.
-
Càrrega del sistema de fitxers inicial. El nucli carrega un sistema de fitxers inicial (initramfs o initrd) que conté els mòduls i els programes necessaris per muntar el sistema de fitxers real del sistema operatiu.
-
Sistema d'inicialització. És el primer procés que s'executa en un sistema operatiu en l'espai usuari. En el cas de GNU/Linux, el sistema d'inicialització més comú és el systemd. Una altre gestor d'arrancada, més vell però molt utilitzat és el SysVInit (Init).
-
Execució dels targets o runlevels. El sistema d'inicialització carrega els diferents targets o runlevels, que defineixen l'estat del sistema en un moment determinat. Aquests runlevels poden ser diferents nivells d'arrencada, com arrencada en mode gràfic o mode de recuperació. Cada runlevel pot tenir diferents serveis i daemons activats o desactivats.
-
Execució dels scripts d'arrancada. El sistema d'inicialització executa els scripts d'arrancada definits per a cada runlevel. Aquests scripts són responsables de configurar els serveis i daemons del sistema, com ara la xarxa, els dispositius de maquinari, els sistemes de fitxers, entre altres.
-
Inici de la Sessió d'Usuari. Finalment, el sistema està preparat per a l'usuari. Si el sistema està configurat per a un entorn gràfic, es carrega el gestor de finestres o l'entorn d'escriptori. En sistemes sense entorn gràfic, es presenta una línia de comandes. En aquest punt, l'usuari pot iniciar sessió i començar a utilitzar el sistema.
-
Execució dels scripts d'inici de sessió. Un cop iniciada la sessió, s'executen els scripts d'inici de sessió de l'usuari. Aquests scripts poden configurar variables d'entorn, carregar programes o configurar preferències de l'usuari. Això permet personalitzar l'experiència de l'usuari i preparar l'entorn de treball.
En aquest laboratori veurem totes aquestes fases en una màquina virtual i modificarem els paràmetres per veure com afecten als sistemes.
Objectius
- Entendre com funciona el procés d'arrancada del sistema.
- Conèixer els diferents components implicats en l'arrancada del sistema.
- Apendre a gestionar i optimitzar el procés d'arrancada.
Continguts
Activitats
Realització de les tasques: 50%
S'ha de mostrar en un document amb format lliure les evidències de la realització de les tasques. Aquest document es pot incloure al informe tècnic o es pot lliurar com a document adjunt. En aquest document heu de mostrar les dificultats trobades i com les heu resolt. Us recomano que feu servir eines de captura de pantalla per a mostrar les evidències. Per exemple, podeu incloure una secció anomenada Troubleshooting on mostreu les dificultats trobades i com les heu resolt.
Informe tècnic: 50%
El informe tècnic ha de contenir respostes a les preguntes plantejades a continuació:
-
Investigació d'una unitat del sistema
- Elegeix una unitat del sistema, com ara
ssh.service
, i investiga la seva funció i configuració. - Utilitza les comandes
systemctl status
isystemctl cat
per obtenir més informació sobre la unitat. - Inclou a l'informe els resultats de la teva investigació:
- Descripció de la unitat.
- Documentació associada.
- Dependències i condicions.
- Tipus de servei i comandaments d'inici i parada.
- Temps d'execució i estat actual.
- Elegeix una unitat del sistema, com ara
-
Comparació entre arrencada amb i sense interfície gràfica
- Instal·la la interfície gràfica utilitzant la comanda
tasksel
i selecciona l'opcióDebian desktop environment
. - Compara el temps d'arrencada del sistema amb i sense interfície gràfica utilitzant la comanda
systemd-analyze
. - Inclou al informe de la diferència entre arrencar el sistema amb una interfície gràfica i sense interfície gràfica, incloent:
- Temps d'arrencada del kernel i l'espai d'usuari.
- Unitats crítiques i temps d'arrencada.
- Avantatges i desavantatges de cada configuració
- Instal·la la interfície gràfica utilitzant la comanda
-
Dissenyeu un escenari real on un script d'arrancada podria ser útil
- Pensa en un escenari real on un script d'arrancada podria ser útil per configurar l'entorn de l'usuari.
- Crea un script d'arrancada que realitzi una tasca específica en aquest escenari.
- Configura el script d'arrancada perquè s'executi automàticament quan un usuari inicia una sessió de terminal.
- Inclou a l'informe amb els detalls de l'escenari i el script d'arrancada, incloent:
- Descripció de l'escenari i la tasca a realitzar.
- Contingut del script d'arrancada.
- Configuració del script d'arrancada per a l'usuari.
Rúbriques d'avaluació
Criteris d'avaluació | Excel·lent (5) | Notable(3-4) | Acceptable(1-2) | No Acceptable (0) |
---|---|---|---|---|
Contingut | El contingut és molt complet i detallat. S'han cobert tots els aspectes de la tasca. | El contingut és complet i detallat. S'han cobert la majoria dels aspectes de la tasca. | El contingut és incomplet o poc detallat. Falten alguns aspectes de la tasca. | El contingut és molt incomplet o inexistent. |
Precisió i exactitud | La informació és precisa i exacta. No hi ha errors. | La informació és precisa i exacta. Hi ha pocs errors. | La informació és imprecisa o inexacta. Hi ha errors. | La informació és molt imprecisa o inexacta. Hi ha molts errors. |
Organització | La informació està ben organitzada i estructurada. És fàcil de seguir. | La informació està organitzada i estructurada. És fàcil de seguir. | La informació està poc organitzada o estructurada. És difícil de seguir. | La informació està molt poc organitzada o estructurada. És molt difícil de seguir. |
Diagrames i il·lustracions | S'han utilitzat diagrames i il·lustracions de collita pròpia per aclarir la informació. Són molt útils. | S'han utilitzat diagrames i il·lustracions de collita pròpia per aclarir la informació. Són útils. | S'han utilitzat pocs diagrames o il·lustracions de collita pròpia. Són poc útils. | No s'han utilitzat diagrames o il·lustracions de collita pròpia. |
Plagi | No hi ha evidències de plagi. Tota la informació és original. | Hi ha poques evidències de plagi. La majoria de la informació és original. | Hi ha evidències de plagi. Alguna informació no és original. | Hi ha moltes evidències de plagi. Poca informació és original. |
Bibliografia | S'ha inclòs una bibliografia completa i detallada. | S'ha inclòs una bibliografia completa. | S'ha inclòs una bibliografia incompleta. | No s'ha inclòs una bibliografia. |
Estil | L'estil és molt adequat i professional. S'ha utilitzat un llenguatge tècnic precís. | L'estil és adequat i professional. S'ha utilitzat un llenguatge tècnic precís. | L'estil és poc adequat o professional. Hi ha errors en el llenguatge tècnic. | L'estil és molt poc adequat o professional. Hi ha molts errors en el llenguatge tècnic. |
UEFI i dispositius d'arrancada
El Unified Extensible Firmware Interface (UEFI) és un estàndard de firmware dissenyat per reemplaçar els dissenys antics anomenats BIOS. Els principals problemes de les BIOS eren la falta d'estandardització.
ℹ️ UEFI o EFI?
La UEFI i la EFI són pràcticament el mateix. La EFI va ser el primer estàndard, però amb el temps va evolucionar cap a la UEFI actual.
En aquest laboratori, analitzarem el funcionament de la UEFI i com podem utilitzar-la.
Objectius
- Conèixer el funcionament de la UEFI.
- Impacte de la UEFI en l'arrancada del sistema.
- Apendre les funcions bàsiques de la consola UEFI.
- Configurar la UEFI per a diferents finalitats.
Preparació
-
Inicieu una màquina virtual amb el sistema operatiu AlmaLinux anomenada
VM1
. Podeu utilitzar la configuració per defecte. -
Inicieu una altra màquina virtual amb el sistema operatiu Debian anomenada
VM2
. Podeu utilitzar també la configuració per defecte. -
Afegiu a la màquina virtual
VM1
el disc virtual de la màquina virtualVM2
o viceversa. Per fer-ho amb VMWare:- Apagueu la màquina virtual.
- Aneu a la configuració de la màquina virtual.
- Aneu a Add.
- Selecciona Hard Disk.
- Selecciona Use an existing disk.
- Selecciona el disc virtual de la màquina virtual que vulgueu afegir.
- Inicieu la màquina virtual.
Un cop iniciada la màquina virtual, no hauríeu de detectar cap canvi. No obstant això, si inicieu sessió a la màquina virtual, podreu veure el disc afegit utilitzant la comanda
lsblk
.[root@localhost ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sr0 11:0 1 1.7G 0 rom nvme0n1 259:0 0 20G 0 disk ├─nvme0n1p1 259:1 0 600M 0 part /boot/efi ├─nvme0n1p2 259:2 0 1G 0 part /boot └─nvme0n1p3 259:3 0 18.4G 0 part ├─almalinux-root 253:0 0 16.4G 0 lvm / └─almalinux-swap 253:1 0 2G 0 lvm [SWAP] nvme0n2 259:4 0 20G 0 disk ├─nvme0n2p1 259:5 0 512M 0 part ├─nvme0n2p2 259:6 0 18.5G 0 part └─nvme0n2p3 259:7 0 976M 0 part
On
nvme0n2
és el disc afegit que conté la instal·lació de Debian invme0n1
és el disc original que conté la instal·lació d'AlmaLinux.
Tasques
- Inciant la consola UEFI
- Observant els Dispositius Disponibles
- Navegant per la Consola UEFI
- Arrancant des d'una Partició EFI
- Automatitzant l'Arrancada
- Creant una Entrada d’Arrancada Personalitzada
Inciant la consola UEFI
Per accedir a la consola UEFI, seguiu aquests passos:
-
Inicieu la màquina virtual
VM1
. -
Premeu la tecla ``ESC`durant l'arrencada de la màquina virtual per accedir a Boot Manager.
-
Seleccioneu EFI Internal Shell per accedir a la consola UEFI.
La consola UEFI és una interfície de text que permet interactuar amb el firmware de la màquina. El primer que necessiteu saber es com interactuar amb la consola. Per això, podeu utilitzar la comanda help
per obtenir una llista de comandes disponibles.
Observant els Dispositius Disponibles
Un dels usos més comuns de la consola UEFI és la selecció del dispositiu d'arrancada. Per veure quins dispositius estan disponibles, podeu utilitzar la comanda map
.
Shell> map
Aquesta comanda us mostrarà una llista de tots els dispositius disponibles i les seves adreces. Això us permetrà identificar quin dispositiu voleu utilitzar per a l’arrancada. En el nostre cas, us retornarà una llista similar a aquesta:
-
FS0
: Alias(s):CD0B0A0;;BLK1: PciRoot(OxO)/Pci(0x11,0x0)/Pci(0x3,0x0)/Sata(0x1,0x0,0x0)/CDROM(0x0) -
FS1
: Alias(s):HD1b;;BLK3: PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(1,GPT,61942D3C-DD95-47F4-8C57-C22009E9C7BA,0x800,0x12C000) -
FS2
: Alias(s):HD2b;;BLK7: PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x2,00-00-00-00-00-00-00-00)/HD(1,GPT,8DD9095B-5B0C-45A3-A026-33DE34ED23B5,0x800,0x10000) -
BLK0
: Alias(s): PciRoot(0x0)/Pci(0x11,0x0)/Pci(0x3,0x0)/Sata(0x1,0x0,0x0) -
BLK2
: Alias(s): PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00) -
BLK6
: Alias(s): PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x2,00-00-00-00-00-00-00-00) -
BLK4
: Alias(s): PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(2,GPT, 7D330E0D-0E09-440C-A79D-9239BD9F11C0,0x12C800,0x200000) -
BLK5
: Alias(s): PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(3,GPT, 94B55114-4795-4748-AD0E-BB068D437691,0x32C800,0x24D3000) -
BLK8
: Alias(s): PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x2,00-00-00-00-00-00-00-00)/HD(2,GPT, 760F1F2F-BA6F-479C-8D4D-8FA31D9226F6,0x100800,0x251700) -
BLK9
: Alias(s): PciRoot(0x0)/Pci(0x17,0x0)/Pci(0x0,0x0)/NVMe(0x2,00-00-00-00-00-00-00-00)/HD(3,GPT, CD375C90-A2BA-4507-9263-55BE97B26672,0x2617800,0x1E8000)
En aquest cas, tenim 3 sistemes de fitxers (FS0, FS1, FS2) i diversos dispositius de bloc (BLK0, BLK2, BLK6, BLK4, BLK5, BLK8, BLK9).
Els sistemes de fitxers representen dispositius que contenen un sistema de fitxers que la UEFI pot llegir. Això inclou dispositius com discos durs, SSDs, i CD-ROMs. Per exemple, FS0 representa un CD-ROM, mentre que FS1 i FS2 representen discos durs.
Els dispositius de bloc representen dispositius de baix nivell que no necessàriament tenen un sistema de fitxers que la UEFI pot llegir. Això inclou dispositius com discos durs, SSDs, i CD-ROMs, així com particions individuals dins d’aquests dispositius.
En els sistemes EFI, hi ha una partició especial anomenada Partició de Sistema EFI (ESP) que conté els fitxers d’arrancada del sistema operatiu. Aquesta partició es pot identificar pel seu tipus de sistema de fitxers EFI. Normalment utilitza un sistema de fitxers basat en FAT32. En aquest cas, els sistemes de fitxers FS1 i FS2 són les particions ESP dels discos durs NVMe1 i NVMe2 respectivament. A més, podem veure que els dos discos durs NVMe1 i NVMe2 tenen una taula de particions GPT i que la primera partició correspon a la partició ESP. Es pot veure el seu UUID, l’adreça d’inici i l’adreça final de la partició.
👁️ Observació
Les particions EFI sempre acostumen ser la primera partició de la taula de particions GPT. Això es deu a que UEFI sempre busca la partició EFI per carregar el gestor d’arrancada.
Els dispositius de bloc representen els discos durs i les seves particions. En aquest cas, tenim dos discos durs NVMe1 i NVMe2 amb les seves particions. Fixeu-vos que podem identificar el disc NVMe1 o NVMe2 amb BLK2 o BLK6 respectivament. A més, podem veure les particions del disc NVMe1 amb BLK4 i BLK5 i les particions del disc NVMe2 amb BLK8 i BLK9. En totes les entrades es pot veure el UUID de la taula de particions GPT, l’adreça d’inici i l’adreça final de la partició.
👁️ Observació
La etiqueta NVMe indica que el disc és un disc NVMe. Si el disc fos un disc SATA, la etiqueta seria SATA. En funció del hardware de la màquina virtual, els discos poden tenir diferents etiquetes.
Navegant per la Consola UEFI
Un cop identificats els dispositius disponibles, podeu utilitzar la consola UEFI per navegar per ells. Per exemple, per accedir a la partició ESP del disc NVMe1, podeu utilitzar la següent comanda:
Shell> fs1:
Això canviarà el directori de treball actual a la partició ESP del disc NVMe1. Si ara voleu accedir a fs2
, podeu utilitzar la comanda fs2:
.
Shell> fs2:
⚠️ Compte La consola UEFI acostuma a tenir un keymap diferent al vostre. Els caràcters poden no ser els mateixos que els que veieu a la pantalla. Per exemple, la tecla
:
pot serñ
o la tecla/
pot ser-
. Si teniu problemes amb les tecles podeu consultar el keymap de VMWare a la documentació oficial.
Un cop hàgiu accedit a una partició, podeu utilitzar la comanda ls
per veure el contingut de la partició.
FS1:\> ls
La comanda ls
us mostrarà una llista dels fitxers i directoris del directori actual. En aquest cas, veureu els fitxers i directoris del directori arrel de la partició ESP.
Finalment, podeu utilitzar la comanda cd
per canviar de directori.
FS1:\> cd EFI
FS1:\EFI> ls
FS1:\EFI> cd ..
Arrancant des d'una Partició EFI
Per arrancar la màquina virtual VM1
amb el disc NVMe2 seleccionat com a dispositiu d'arrancada (això carregarà el sistema operatiu Debian), seguiu aquests passos:
-
Navegueu a la partició ESP del disc NVMe2.
Shell> fs2:
-
Navegueu al directori
EFI
i seleccioneu el directori del sistema operatiu Debian.FS2:\> cd EFI FS2:\EFI> cd debian
-
Llisteu el contingut del directori per veure els fitxers d'arrancada.
En aquest directori, podeu observar diferents fitxers que acaben amb
.efi
. Aquests fitxers són els fitxers d'arrancada del sistema operatiu Debian. El nom ens indica el tipus de firmware que utilitzen. Per exemple,grubaa64.efi
és el fitxer d'arrancada del gestor d'arrancada GRUB per a sistemes de 64 bits.ℹ️ Quina és la diferència entre shimx64.efi, grubx64.efi, fbx64, mmx64?
Les principals diferències entre aquests fitxers són el tipus de firmware que utilitzen i la seva funció. El fitxer
shimx64.efi
és un fitxer d'arrancada segur que permet carregar altres fitxers d'arrancada segurs. El fitxergrubx64.efi
és el fitxer d'arrancada del gestor d'arrancada GRUB. Els fitxersfbx64.efi
immx64.efi
no són específics de cap sistema operatiu, sinó que són part del firmware UEFI i proporcionen funcionalitats addicionals. -
Seleccioneu el fitxer d'arrancada del grub per a arrancar el sistema operatiu Debian.
FS2:\EFI\debian> grubaa64.efi
Això carregarà el gestor d'arrancada GRUB i us permetrà seleccionar el sistema operatiu Debian per a l'arrancada.
Automatitzant l'Arrancada
👁️ Observació:
Aquest procediment és una mica tedios i ens pot resultar poc eficient si hem d'arrencar el sistema operatiu Debian sovint.
Per automatitzar l'arrancada del sistema operatiu Debian, podeu utilitzar la comanda boot
de la consola UEFI. Aquesta comanda us permetrà carregar un fitxer d'arrancada directament sense haver de navegar per la partició ESP.
boot fs2:\EFI\debian\grubaa64.efi
Tot i que aquesta comanda pot ser útil, encara requereix accedir manualment a la consola UEFI i introduir la comanda. Per tant, ara veurem com crear una entrada d'arrancada personalitzada a la taula d'arrancada de la UEFI semblant a la ja existent per a l'arrancada d'AlmaLinux anomenda AlmaLinux
.
Creant una Entrada d’Arrancada Personalitzada
La UEFI manté una taula d’arrancada que conté una llista d’entrades d’arrancada. Cada entrada correspon a un sistema operatiu o aplicació que pot ser arrancada per la UEFI. Per exemple, si tenim instal·lats els sistemes operatius AlmaLinux i Debian en la mateixa màquina, cada un tindrà la seva pròpia entrada d’arrancada a la taula d’arrancada de la UEFI.
Per crear una nova entrada d’arrancada per al sistema operatiu Debian, podem utilitzar la comanda bcfg
de la consola UEFI. Aquesta comanda proporciona una interfície per gestionar la taula d’arrancada de la UEFI.
-
Reinicieu la màquina virtual i accediu a la consola UEFI.
-
Utilitzeu la comanda bcfg boot add per crear una nova entrada d’arrancada. Per exemple, per afegir una nova entrada amb el nom Debian i el fitxer BOOTAA64.EFI de la partició FS2, utilitzeu la següent comanda:
bcfg boot add 6 fs2:\EFI\debian\grubaa64.efi Debian
En aquesta comanda, 6 és el número de la nova entrada a la UEFI. Aquest número ha de ser únic i no pot ser repetit. Si ja tenim una entrada amb el número 3, haurem de canviar el número per un altre número que no estigui en ús. Per saber quins números estan en ús, podem utilitzar la comanda
bcfg boot dump
. -
Un cop creada la nova entrada d’arrancada, podem voler canviar la seva posició a la llista d’arrancada. Per exemple, si volem que la nova entrada sigui la segona opció d’arrancada, podem utilitzar la comanda:
bcfg boot mv 6 1
En aquesta comanda, 6 és el número de l’entrada que volem moure, i 1 és la nova posició de l’entrada a la llista d’arrancada.
✏️ Nota:
Els items es numeren de 0 a n-1, on n és el nombre d'entrades.
-
Ara tenim la entrada AlmaLinux i Debian a la UEFI. Podem sortir de la consola UEFI i reiniciar la màquina virtual. Ara, quan accedim a la consola UEFI, veurem dues opcions: AlmaLinux i Debian.
Amb aquesta configuració, podem seleccionar quin sistema operatiu volem arrancar directament des del menú d’arrancada de la UEFI, sense haver d’accedir a la consola UEFI.
GRUB
El GRUB (Grand Unified Bootloader) és un gestor d'arrancada que s'utilitza en la majoria de les distribucions de GNU/Linux. El UEFI és l'encarregat de carregar el GRUB, En aquest laboratori veurem com funciona el GRUB i com podem configurar-lo per a arrancar amb diferents sistemes operatius.
👁️ Observació:
GRUB no és l'únic gestor d'arrancada que es pot utilitzar en un sistema GNU/Linux. Però és el més comú i el que s'utilitza per defecte en la majoria de les distribucions. Altres gestors d'arrancada com el LILO (Linux Loader) o rEFInd també són compatibles amb GNU/Linux.
Preparació
-
Entorn de treball: Màquina virtual amb una distribució GNU/Linux instal·lada pot ser Debian o AlmaLinux. La màquina virtual pot tenir una configuració per defecte. Característiques de la màquina virtual:
- Disc dur virtual de 20 GB.
- 1 CPU.
- 1 GB de memòria RAM.
A més, inicialitzeu com a mínim un usuari root amb contrasenya (pot ser 1234).
✏️ Nota:
En el meu cas he utilitzat una màquina virtual amb la imatge de Debian 12 proporcionada al inici de curs al campus virtual.
Tasques
- Modificació de les opcions del GRUB
- Accés no autoritzat a través del GRUB
- Dual Boot
- Anàlisi del procediment
- Actualitzant el GRUB
Modificació de les opcions del GRUB
Com heu pogut observar, la instal·lació del sistema operatiu Debian 12 ha configurat el GRUB de forma predeterminada.
En aquesta pantalla, podeu observar 3 entrades:
-
Debian GNU/Linux. Aquesta és l'entrada per defecte que carrega el sistema operatiu Debian 12.
-
Advanced options for Debian GNU/Linux. Aquesta entrada permet seleccionar una versió específica del kernel per a carregar.
En el nostre cas, podem seleccionar entre la versió 6.1.0-23 i la 6.1.0-18 ambdues amb les opcions
recovery mode
.ℹ️ Què és el mode de recuperació?
El mode de recuperació és un mode d'arrancada que carrega el sistema amb un conjunt de paràmetres mínims. Això permet accedir al sistema en un estat més bàsic i realitzar tasques de manteniment o recuperació del sistema.
-
UEFI Firmware Settings. Aquesta entrada permet accedir a la configuració de la UEFI.
Modificació de les opcions del GRUB (temporal)
Seleccioneu l'entrada Debian GNU/Linux
i premeu la tecla e
per a editar les opcions de l'arrencada de forma temporal, és a dir, aquestes opcions només es mantindran durant l'arrencada actual del sistema.
En aquesta pantalla, podeu observar les opcions de l'arrencada del sistema. Si analitzem la informació tenim:
-
Carreguem els mòduls del kernel:
ℹ️ Per què carreguem aquests mòduls?
Els mòduls del kernel són programes que s'executen en l'espai del nucli del sistema operatiu. Aquests mòduls permeten al sistema operatiu interactuar amb el maquinari de l'ordinador. En aquest cas, carreguem els mòduls necessaris per a interactuar amb el disc dur i el sistema de fitxers.
- load_video: Aquest mòdul s’encarrega de la inicialització del subsistema de vídeo. És necessari per a la correcta visualització de la interfície gràfica durant l’arrancada.
- insmod gzio: Aquest mòdul permet al kernel llegir fitxers comprimits en format gzip. És útil per a carregar imatges del kernel o del sistema d’inicialització que estiguin comprimits.
- insmod part_gpt: Aquest mòdul permet al kernel llegir particions de disc que utilitzen la taula de particions GUID (GPT). GPT és un estàndard modern per a la disposició de la taula de particions en un disc dur.
- insmod ext2: Aquest mòdul permet al kernel llegir i escriure en sistemes de fitxers ext2. Ext2 és un sistema de fitxers comú en Linux, encara que ara s’utilitza menys en favor de ext3 i ext4.
-
Indiquem el dispositiu on es troba el sistema operatiu:
- search --no-floppy --fs-uuid --set=root xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
on
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
és l'identificador únic del dispositiu on es troba el sistema operatiu. -
Carreguem el kernel del sistema operatiu;
- linux /boot/vmlinuz-6.1.0.23-arm64 root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ro quiet
on les opcions són:
ro
: indica que el sistema s'ha de muntar en mode de només lectura.quiet
: indica que el sistema s'ha de carregar sense mostrar missatges.
-
Finalment, carreguem el sistema d'inicialització:
- initrd /boot/initrd.img-6.1.0.23-arm64
ℹ️ Què és el sistema d'inicialització?
El sistema d'inicialització és el primer procés que s'executa en un sistema operatiu. En el cas de GNU/Linux, el sistema d'inicialització més comú és el systemd. Aquest sistema d'inicialització s'encarrega de carregar els serveis i els daemons del sistema operatiu.
Modifiquem les opcions de l'arrencada per mostrar els missatges del sistema durant l'arrencada. Per a fer-ho, eliminem l'opció quiet
de la línia linux
i premem la tecla ctrl+x
o F10
per a iniciar el sistema amb les opcions modificades.
Ara, el sistema mostrarà els missatges durant l'arrencada.
Modificació de les opcions del GRUB (permanent)
Aquestes opcions només es mantindran durant l'arrencada actual del sistema. Per a fer que aquestes opcions es mantinguin de forma permanent, haurem de modificar el fitxer de configuració del GRUB. Aquest fitxer normalment es troba a /etc/default/grub
.
-
Accedeix al sistema amb l'usuari root.
-
Fes una còpia de seguretat del fitxer de configuració del GRUB.
cp /etc/default/grub /etc/default/grub.bak
-
Edita el fitxer de configuració del GRUB amb un editor de text com
vi
.vi /etc/default/grub
Observareu un fitxer similar al:
-
Busca la línia que comença amb
GRUB_CMDLINE_LINUX_DEFAULT
i modifica-la per a afegir les opcions que vulguis. Per exemple, per a mostrar els missatges del sistema durant l'arrencada, elimina l'opcióquiet
.💡 Nota:
Les opcions del GRUB es separen per espais. Per a afegir una nova opció, simplement afegeix-la a la llista separada per un espai.
🔍 Pregunta: Quines altres opcions podries afegir al fitxer de configuració del GRUB?
Algunes opcions comunes que es poden afegir al fitxer de configuració del GRUB són:
GRUB_TIMEOUT
: temps d'espera per a seleccionar una entrada del GRUB.GRUB_DISABLE_OS_PROBER
: per defecte, en debian es troba activada. Per tant, no detectarà altres sistemes operatius instal·lat en el sistema.
-
Desa els canvis i surt de l'editor de text.
-
Un cop hagis modificat el fitxer de configuració del GRUB, hauràs de regenerar el fitxer de configuració del GRUB amb la comanda següent:
update-grub
Aquesta comanda regenerarà el fitxer de configuració del GRUB amb les opcions que has definit. Aquest fitxer es troba a
/boot/grub/grub.cfg
. Pots veure el contingut d'aquest fitxer amb la comanda següent:less /boot/grub/grub.cfg
⚠️ Compte:
No modifiquis manualment el fitxer
/boot/grub/grub.cfg
. Aquest fitxer es genera automàticament amb la comandaupdate-grub
i qualsevol modificació manual es sobreescriurà en la propera generació del fitxer. -
Reinicia el sistema per a aplicar els canvis.
reboot
Un cop reiniciat el sistema, el GRUB carregarà el sistema amb les opcions que has definit. Ara, el sistema mostrarà els missatges durant totes les arrencades.
Accés no autoritzat a través del GRUB
Assumeix que teniu un servidor instal·lat amb un carregar de sistema GRUB. Un atacant ha conseguit accés físic al vostre servidor i vol modificar la contrasenya de l'usuari root per a poder accedir al sistema amb privilegis d'administrador. Per a fer-ho, l'atacant ha reiniciat el sistema i ha accedit al carregador de sistema GRUB. A continuació assumirem el rol i veurem com podem accedir al sistema operatiu i modificar la contrasenya de l'usuari root a través del carregador de sistema GRUB.
-
Reinicia el sistema i accedeix al carregador de sistema GRUB.
-
Selecciona el sistema operatiu que vols arrancar i prem la tecla
e
per a editar les opcions de l'arrencada. -
Busca la línia que comença amb
linux
i acaba ambro
i afegeix-hi la següent opció:init=/bin/bash
.✏️ Nota:
La opció
ro
indica que el sistema s'ha de muntar en mode de només lectura. Això significa que no es poden modificar els fitxers del sistema. Afegint la opcióinit=/bin/bash
, indiquem al sistema que ha d'iniciar el procés d'inicialització amb/bin/bash
en lloc del sistema d'inicialització habitual. Això ens permetrà accedir al sistema amb un intèrpret de comandesbash
sense haver d'iniciar el sistema completament. -
Prem la tecla
Ctrl + X
per a iniciar el sistema amb les opcions modificades. -
Un cop iniciat el sistema, hauries d'accedir a una consola
bash
. -
Un cop aquí, montarem el sistema de fitxers en mode de lectura i escriptura amb la comanda següent:
mount -o remount,rw /
-
Ara que el sistema esta muntat, accedirem al sistema amb una chroot per a poder modificar la contrasenya de l'usuari root. Per a fer-ho, executa la comanda següent:
chroot /
ℹ️ Què és una chroot?
Una chroot és un entorn aïllat que permet executar programes en un directori arrel diferent del directori arrel del sistema. Això ens permet accedir al sistema com si estiguéssim dins del directori arrel del sistema, però sense haver d'iniciar el sistema completament. Això és útil per a realitzar tasques de manteniment o recuperació del sistema sense haver d'iniciar el sistema completament.
-
Un cop dins de la chroot, modifica la contrasenya de l'usuari root amb la comanda
passwd
:passwd
-
Introdueix la nova contrasenya de l'usuari root i confirma-la.
-
Un cop modificada la contrasenya, surt de la chroot amb la comanda
exit
:exit
-
Reinicia el sistema amb la comanda
reboot
:reboot
-
Un cop reiniciat el sistema, accedeix amb l'usuari root i la nova contrasenya que has definit.
🔍 Pregunta: Com podriam protegir els nostres servidors d'aquestes situacions?
- La principal manera de protegir els servidors d'aquest tipus d'atacs és assegurar-se que només les persones autoritzades poden accedir físicament al servidor.
- Configurar el GRUB perquè requereixi una contrasenya per a poder editar les opcions de l'arrencada és una bona pràctica. Això dificulta l'accés no autoritzat al sistema a través del GRUB.
👁️ Observació:
Malgrat l'ús d'una contrasenya per a protegir el GRUB, aquesta tècnica no és infal·lible. Un atacant amb accés físic pot montar un usb bootable i iniciar el sistema amb aquest dispositiu. Un cop iniciat el sistema, l'atacant podria montar el sistema de fitxers i modificar la contrasenya de l'usuari root. Ara bé, es podria configurar el BIOS o UEFI per a desactivar l'arrencada des de dispositius externs com els USBs. Això dificultaria l'accés no autoritzat al sistema a través d'aquesta tècnica.
🤔 Reflexió: En les dues situacions, si el disc dur està xifrat, l'atacant no podrà utilitzar aquestes tècniques per a accedir al sistema.
Dual Boot
En aquesta tasca, configurarem el GRUB per a poder arrancar amb dos sistemes operatius diferents. Per a fer-ho, utilitzarem la màquina virtual on ja tenim instal·lat un sistema operatiu GNU/Linux. A continuació, instal·larem un segon sistema operatiu i configurarem el GRUB per a poder arrancar amb els dos sistemes operatius.
-
Muntatge de la iso a la màquina virtual. A continuació es mostra el procediment per VMWare, adapatar-lo al vostre hypervisor.
- Accedeix a la màquina virtual on tens instal·lat un sistema operatiu GNU/Linux.
- Selecciona la màquina virtual i apaga-la.
- Prem el boto en forma d'eina 🔧 per a obrir la configuració de la màquina virtual.
- A la pestanya
CD/DVD (SATA)
, selecciona la opcióUse ISO image file
i selecciona la imatge ISO del sistema operatiu que vols instal·lar. - Prem la tecla
OK
per a tancar la finestra de configuració de la màquina virtual.
-
Arrancada de la màquina virtual amb la iso.
- Inicia la màquina virtual.
- Accedeix a la configuració UEFI.
- Selecciona el CD-ROM com a dispositiu d'arrancada.
- Accedeix al GRUB amb la imatge ISO del sistema operatiu que vols instal·lar. En aquest cas, Almalinux 9.4.
-
Instal·lació del sistema operatiu.
-
Segueix els passos d'instal·lació del sistema operatiu.
- Selecciona Destino de la instalación i prem Personalitzada.
- En aquest punt, el nostre disc virtual de 20 GB, té 4 particions ocupant tot l'espai.
- Per poder instal·lar el nou sistema operatiu haurem de reimensionar la partició (/) per alliberar espai per a la nova partició, en el nostre cas podem alliberar 10 GB. La partició (/) es redueix de 18,54 GB a 8,54 GB. Simplement heu de modificar el valor númeric com mostro a la imatge.
- Seleccioneu Partición estándar i premeu Pulse aqui para crearlas automáticamente.
-
Assigna una contrasenya a l'usuari root i finalitza la instal·lació.
-
-
Test de l'arrancada del sistema.
- Reinicia la màquina virtual.
- Accedeix al GRUB i comprova que pots seleccionar el sistema operatiu que vols arrancar.
- Selecciona el sistema operatiu que has instal·lat i comprova que pots iniciar-lo correctament.
Anàlisi del procediment
El GRUB és un gestor d’arrancada que es configura automàticament durant la instal·lació d’un sistema operatiu. Quan instal·les un nou sistema operatiu, l’instal·lador detecta altres sistemes operatius presents en el mateix disc dur i crea entrades per a cada sistema operatiu en el fitxer de configuració del GRUB. Aquestes entrades permeten seleccionar quin sistema operatiu volem carregar durant l’arrancada del sistema.
A més, durant la instal·lació d’un nou sistema operatiu, es crea una nova entrada a la UEFI per a poder iniciar aquest nou sistema operatiu. Aquesta entrada s’ha creat amb la informació del nou GRUB, de manera que aquest conté les entrades dels dos sistemes operatius.
Si accediu a l’entrada inicial de la UEFI (debian), veureu que el GRUB únicament conté el sistema operatiu que teníem instal·lat inicialment. En canvi, si accediu a l’entrada nova de la UEFI (almalinux), veureu que el GRUB conté els dos sistemes operatius.
👁️ Observació:
Quan instal·les un sistema operatiu Windows després d’un sistema operatiu GNU/Linux, el GRUB es sobreescriu pel carregador d’arrancada de Windows. Això significa que no podràs accedir al sistema operatiu GNU/Linux des del GRUB. Per poder accedir al sistema operatiu GNU/Linux, hauràs de restaurar el GRUB. Aquesta restauració es pot realitzar mitjançant una unitat d’arrancada en viu (live boot) i utilitzant eines com ara
boot-repair
.
Si compareu el grub de debian amb el d'almalinux, veure que estan organitzats de manera diferent. Això és degut a que cada distribució GNU/Linux té la seva pròpia configuració del GRUB. A més, cada distribució GNU/Linux pot utilitzar diferents versions del GRUB, amb diferents opcions i configuracions.
Actualitzant el GRUB
Actualitzant el GRUB de debian per a mostrar l'entrada d'almalinux
-
Accedeix a la màquina virtual on tens instal·lat el teu Debian.
-
Accedeix a la consola del sistema operatiu.
-
Edita el fitxer de configuració del GRUB de debian amb un editor de text com
vi
.vi /etc/default/grub
-
Descomenta la línia
GRUB_DISABLE_OS_PROBER
i assigna-li el valorfalse
.GRUB_DISABLE_OS_PROBER=false
-
Desa els canvis i tanca l’editor de text.
-
Actualitza el fitxer de configuració del GRUB amb la comanda següent:
update-grub
-
Reinicia el sistema amb la comanda següent:
reboot
-
Accedeix al GRUB de debian a través de la UEFI i comprova que ara pots seleccionar l’entrada d’almalinux.
🤔 Reflexió: Quin GRUB és millor?
Indiferent. Cada distribució GNU/Linux configura el GRUB de manera diferent per a adaptar-lo a les seves necessitats i requeriments. Això significa que cada distribució GNU/Linux pot tenir una configuració del GRUB diferent, amb diferents opcions i configuracions. La millor configuració del GRUB és aquella que millor s’adapta a les necessitats del teu sistema.
initramfs
La initramfs (intial RAM filesystem) és un sistema de fitxers temporal que es munta a la arrel del sistema de fitxers (rootfs) durant el procés d'arrencada del sistema. La initramfs s'utilitza per realitzar tasques d'inicialització del sistema abans que el sistema de fitxers arrel real estigui disponible. Per exemple, la initramfs pot ser utilitzada per carregar mòduls del nucli, muntar dispositius de bloc, o realitzar tasques de configuració de xarxa.
Quin és el funcionament de la initramfs?
La initramfs és un arxiu comprimit que conté un sistema de fitxers mínim necessari per inicialitzar el sistema. Aquest arxiu es descomprimeix a la memòria RAM durant l'arrencada i s'utilitza com el sistema de fitxers arrel temporal. La initramfs inclou scripts i binaris essencials que permeten al sistema realitzar tasques crítiques abans que el sistema de fitxers arrel real estigui disponible.
Hi ha diverses situacions en les quals un administrador de sistemes podria necessitar modificar la initramfs:
-
Inclusió de mòduls del nucli addicionals: Si el sistema requereix mòduls del nucli que no estan inclosos en la initramfs per defecte, com controladors de xarxa, controladors d'emmagatzematge, o sistemes de fitxers específics (per exemple, Btrfs o ZFS), serà necessari modificar la initramfs per incloure aquests mòduls.
-
Configuració de dispositius d'emmagatzematge complexos: Si el sistema utilitza configuracions d'emmagatzematge complexes, com RAID o LVM, pot ser necessari incloure scripts i binaris addicionals en la initramfs per assegurar que aquests dispositius siguin correctament inicialitzats i muntats.
-
Configuració de xarxa: En alguns casos, pot ser necessari incloure scripts de configuració de xarxa en la initramfs per assegurar que el sistema tingui accés a la xarxa durant el procés d'arrencada. Això pot ser útil en entorns on la xarxa és essencial per l'arrencada del sistema.
-
Solucionar problemes d'arrencada: Si el sistema experimenta problemes d'arrencada, modificar la initramfs pot ser una solució per incloure scripts de diagnòstic o correccions temporals que permetin al sistema arrencar correctament.
En aquest laboratori, explorarem com podem examinar i modificar la initramfs en un sistema Linux basat en Debian. Per a més informació sobre la initramfs, podeu consultar la documentació oficial de Debian a Debian Wiki - Initramfs.
Objectius
- Entendre què és la initramfs i com funciona.
- Aprendre a examinar el contingut de la initramfs.
- Aprendre a modificar la initramfs per incloure mòduls del nucli addicionals.
Preparació
-
Entorn de treball: Màquina virtual amb una distribució GNU/Linux instal·lada pot ser Debian o AlmaLinux. La màquina virtual pot tenir una configuració per defecte. Característiques de la màquina virtual:
- Disc dur virtual de 20 GB.
- 1 CPU.
- 1 GB de memòria RAM.
A més, inicialitzeu com a mínim un usuari root amb contrasenya (pot ser 1234).
En el meu cas he utilitzat una màquina virtual amb la imatge de Debian 12 proporcionada al inici de curs al campus virtual.
Tasques
- Examinar el contingut de la initramfs
- Carregar un mòdul del nucli addicional a la initramfs
- Personalitzar la initramfs
Examinant la initramfs
-
Inicia la màquina virtual: Inicia la màquina virtual i inicia sessió amb l'usuari root.
-
Examina el contingut de la initramfs: Utilitza la comanda
lsinitramfs
per examinar el contingut de la initramfs. Aquesta comanda mostrarà el contingut de la initramfs i els scripts i binaris que s'executen durant el procés d'arrencada.lsinitramfs /boot/initrd.img-$(uname -r)
En la figura anterior, he limitat la sortida amb la comanda
head
per mostrar només les 10 primeres línies de la sortida. La sortida completa mostrarà tot el contingut de la initramfs.Si analitzeu la sortida completa al vostre servidor, podreu veure que la initramfs conté diversos scripts i binaris que s'utilitzen durant el procés d'arrencada. Aquests scripts i binaris són responsables de realitzar tasques com muntar dispositius de bloc, carregar mòduls del nucli, i configurar la xarxa.
💡 Nota: La sortida de la comanda
lsinitramfs
pot ser molt extensa, ja que la initramfs conté molts scripts i binaris necessaris per l'arrencada del sistema. Si voleu veure la sortida completa, podeu redirigir-la a un fitxer o utilitzar la comandaless
per navegar-hi. -
Cerca si el modul
ext4
està present a la initramfs:lsinitramfs /boot/initrd.img-$(uname -r) | grep ext4
En aquest cas, hauria de veure que el mòdul
ext4
està present a la initramfs. Aquest mòdul és necessari per muntar sistemes de fitxers ext4 durant el procés d'arrencada.
Carregant un mòdul addicional
-
Carrega el mòdul del nucli: En aquest pas, carregarem un mòdul del nucli addicional a la initramfs actual. En aquest cas, carregarem el mòdul
nls_utf8
, que és un mòdul de suport per a la codificació de caràcters UTF-8. El primer pas és comprovar si el mòdul ja està carregat:lsmod | grep nls_utf8
Si la comanda no retorna cap sortida, significa que el mòdul
nls_utf8
no està carregat actualment al sistema. -
Comprovar si el modul esta carregat a la initramfs: Abans de carregar el mòdul a la initramfs, comprovem si ja està present:
lsinitramfs /boot/initrd.img-$(uname -r) | grep nls_utf8
Si la comanda no retorna cap sortida, significa que el mòdul
nls_utf8
no està present a la initramfs actual. -
Cerca la ubicació del mòdul del nucli: Utilitza la comanda
modinfo
per cercar la ubicació del mòdulnls_utf8
.modinfo nls_utf8
Aquesta comanda mostrarà informació detallada sobre el mòdul
nls_utf8
, incloent la ubicació del fitxer del mòdul. En aquest cas, el fitxer del mòdul es troba a/lib/modules/$(uname -r)/kernel/fs/nls/nls_utf8.ko
. -
Carrega el mòdul a la initramfs: Utilitza la comanda
echo
per afegir el mòdulnls_utf8
a la llista de mòduls que s'inclouran a la initramfs durant el procés de generació.echo nls_utf8 >> /etc/initramfs-tools/modules
-
Regenera la initramfs: Utilitza la comanda
update-initramfs
per regenerar la initramfs amb el mòdulnls_utf8
inclòs.update-initramfs -u
Aquesta comanda regenerarà la initramfs amb el mòdul
nls_utf8
inclòs. Si tot ha anat bé, no hauria de veure cap error durant el procés de generació. -
Reinicia el sistema: Reinicia el sistema per aplicar els canvis.
reboot
-
Comprova si el mòdul s'ha carregat: Després de reiniciar el sistema, comprova si el mòdul
nls_utf8
s'ha carregat correctament.lsmod | grep nls_utf8 lsinitramfs /boot/initrd.img-$(uname -r) | grep nls_utf8
Si la comanda
lsmod
retorna el mòdulnls_utf8
, significa que el mòdul s'ha carregat correctament al sistema. Si la comandalsinitramfs
retorna el mòdulnls_utf8
, significa que el mòdul s'ha inclòs correctament a la initramfs.
Personalitzar la initramfs
En aquesta secció, personalitzarem la initramfs afegint un missatge personalitzat que es mostrarà durant el procés d'inici. Això ens permetrà veure com podem modificar la initramfs per incloure scripts i binaris addicionals que es poden executar durant l'arrencada del sistema.
Nota:
Realitzeu les accions següents com a superusuari
su -
.
-
Crea un nou directori per construir la initramfs personalitzada:
mkdir /tmp/initramfs cd /tmp/initramfs
Això crea un espai de treball temporal on es construirà la nova imatge de la initramfs.
-
Extreu la imatge actual de la initramfs:
unmkinitramfs /boot/initrd.img-$(uname -r) .
ℹ️ Nota:
unmkinitramfs
és una eina que permet descomprimir la imatge de la initramfs a un directori de treball. Això permet modificar els fitxers continguts en la initramfs.
Compte!: Es possible que al descomprimir la imatge us generi dos carpetes
main
istable
. En aquest cas, heu de treballar amb la carpetamain
. Cerqueu dins demain
la carpetascripts
i dins d'aquesta la carpetainit-top
. Aquesta és la carpeta on s'executen els scripts durant l'arrencada de la initramfs. -
Crea un nou fitxer de script amb un missatge personalitzat:
echo 'echo "Hola, Initramfs!"' > scripts/init-top/custom_message.sh # Afegeix una pausa per veure el missatge echo '/usr/bin/sleep 10' >> scripts/init-top/custom_message.sh # Atorga permisos d'execució al script chmod +x scripts/init-top/custom_message.sh
-
Actualitza el manifest de la initramfs:
# Nota: order no existeix, és ORDER amb majúscules echo 'scripts/init-top/custom_message.sh' >> scripts/init-top/ORDER
Això afegeix el nou script al manifest de la initramfs, assegurant-se que s'executi durant el procés d'inici.
-
Crea una nova imatge de la initramfs amb el script personalitzat:
Realitzeu una de les següents opcions:
- Nova imatge de la initramfs (nom acaba en custom):
find . | cpio -o -H newc | gzip > /boot/initrd.img-$(uname -r)-custom
- Sobreescriure la imatge original:
find . | cpio -o -H newc | gzip > /boot/initrd.img-$(uname -r)
ℹ️ Nota:
Aquest pas utilitza
cpio
per empaquetar tots els fitxers del directori de treball en un sol arxiu, igzip
per comprimir-lo. La nova imatge es guarda a/boot
amb un nom personalitzat. Si voleu sobreescriure la imatge original, podeu utilitzar el nominitrd.img-$(uname -r)
. Si feu anar custom, al grub també cal indicar-ho. -
Actualitza la configuració de GRUB per utilitzar la nova imatge de la initramfs:
Com editarem la initramfs de forma temporal, no actualitzarem la configuració de GRUB de forma permanent. Per tant, no ens calen aquests passos.
update-initramfs -u -k $(uname -r) update-grub
ℹ️ Nota:
Per fer l'experiment no actualizarem el grub de forma permanent. Simplement, editarem la configuració de GRUB durant l'arrencada per utilitzar la nova imatge de la initramfs.
-
Reinicia el sistema: Reinicia el sistema per aplicar els canvis.
reboot
-
GRUB: A l'arrencada, accedeix a la configuració de GRUB i modifica la línia de comandament per utilitzar la nova imatge de la initramfs. Recorda prement la tecla
e
per editar la configuració de GRUB.# Elimina les opcions `quiet` i `splash` per veure el missatge personalitzat # Afegeix custom al final de la línia de comandament de la initramfs initrd /boot/initrd.img-$(uname -r)-custom
-
Comprova el missatge personalitzat durant l'arrencada: Després de reiniciar el sistema, observa el missatge personalitzat que s'ha afegit a la initramfs durant el procés d'inici.
Activitat opcional
- Quin seria el procediment si volem modificar de forma permanent la initramfs de la primera entrada de GRUB? Documenteu el procediment. Aquesta activitat comptarà únicament a la primera persona que faci un PR amb la resposta correcta. No compte a HandsOn, això es part de la millora dels continguts (un dels punts extres de la nota final).
Inici del sistema i Dimonis de gestió de serveis
Un cop el kernel ha estat carregat i ha completat el seu procés d’inicialització, crea un conjunt de processos espontanis en l’espai d’usuari. El primer d'aquests processos és el procés init, que és el pare de tots els altres processos en el sistema. El procés init és responsable de la inicialització del sistema i de la gestió de la resta de serveis. Tradicionalment, el procés init era conegut com a SysVinit, però amb el temps han sorgit alternatives com systemd.
🧐 El canvi de SysVinit a Systemd...
En moltes distribucions Linux es va fer per millorar l’eficiència i la gestió dels serveis del sistema. SysVinit utilitza scripts seqüencials per iniciar serveis, cosa que pot ser lenta i menys flexible. En canvi, Systemd permet una arrencada paral·lela, reduint significativament el temps d’inici del sistema. A més, Systemd ofereix una gestió més avançada dels processos amb funcionalitats com els cgroups, que permeten controlar els recursos utilitzats per cada servei. Ara bé, aquest canvi també ha generat controvèrsia, ja que molts usuaris prefereixen el sistema més senzill i transparent de SysVinit.
En aquest laboratori, explorarem el procés d'arrencada del sistema amb systemd i com crear i gestionar serveis amb aquesta eina. També veurem com utilitzar journalctl per analitzar els registres del sistema i com personalitzar el procés d'arrencada amb scripts i serveis personalitzats.
Objectius
- Comprendre el procés d'arrencada del sistema amb systemd.
- Crear i gestionar serveis amb systemd.
- Utilitzar journalctl per analitzar els registres del sistema.
- Personalitzar el procés d'arrencada amb scripts i serveis personalitzats.
Preparació de l'entorn
Per a aquest laboratori, necessitarem un sistema Linux amb systemd instal·lat. Aquest laboratori es pot realitzar en qualsevol distribució Linux moderna que utilitzi systemd com a gestor d'inicialització. En aquest laboratori, utilitzarem una màquina virtual amb Debian 12. A més, assegureu-vos de no instal·lar la interfície gràfica, i seleccionar el servidor SSH durant la instal·lació.
Tasques
- Analitzar el procés d'arrencada amb systemd
- Crear i gestionar serveis amb systemd
- Execució de serveis programats amb systemd
- Anàlisi de registres del sistema amb journalctl
- Afegir informació d'inici al sistema
Analitzant el procés d'arrancada
La comanda systemd
ens permet gestionar els serveis del sistema i controlar el procés d'arrencada. Podeu comprovar les seves possibilitats amb la comanda man systemd
. Una de les funcionalitats més útils de systemd
és la capacitat de generar informació detallada sobre el procés d'arrencada del sistema.
El primer pas per analitzar el procés d'arrencada amb systemd
és utilitzar la comanda systemd-analyze
per obtenir informació sobre el temps que ha trigat el sistema a arrencar. Aquesta comanda mostrarà informació sobre el temps que ha trigat el sistema a arrencar, incloent el temps que ha trigat el kernel i l'espai d'usuari.
Startup finished in 899ms (kernel) + 2.074s (userspace) = 2.973s
graphical.target reached after 2.068s in userspace.
Kernel | Espai d'usuari | Total |
---|---|---|
899ms | 2.074s | 2.973s |
En aquest cas, els primers 899ms s'utilitzen per carregar les funcions del kernel com ara els controladors de dispositius i el sistema de fitxers. Els següents 2.074s s'utilitzen per carregar l'espai d'usuari, com ara els serveis i els processos del sistema. En total, el sistema ha trigat 2.973s a arrencar.
Ara que tenim aquesta informació, podem utilitzar la comanda systemd-analyze blame
per obtenir informació detallada sobre el temps que ha trigat cada unitat a carregar durant el procés d'arrencada. Aquesta opció ens llistarà les unitats ordenades per temps d'arrencada, de major a menor.
Temps | Unitat |
---|---|
1.876s | systemd-random-seed.service |
784ms | dbus.service |
782ms | e2scrub_reap.service |
778ms | systemd-logind.service |
... | ... |
4ms | systemd-update-utmp-runlevel.service |
Amb aquesta informació, podem identificar les unitats que poden estar retardant el procés d'arrencada i optimitzar-les si cal. Per obtenir més informació sobre una unitat específica, podeu utilitzar la comanda systemctl status
seguida del nom de la unitat. Per exemple, si volem informació sobre la unitat systemd-random-seed.service
, podem executar:
systemctl status systemd-random-seed.service
Aquesta informació ens mostrarà:
- L'estat actual de la unitat (inactiu, actiu, desactivat, error o recarregant).
- La linia Loaded ens indica la ruta al fitxer on es desa la configuració de la unitat. En aquest cas,
/lib/systemd/system/systemd-random-seed.service
. A més ens indica static que vol dir que la unitat no es pot desactivar. Altres unitats ens poden indicar error, masked, not-found, enable o disabled - La entrada al manual de la unitat, si n'hi ha.
- Finalment, ens mostra informació sobre el procés: PID, estat del procés i temps que ha estat en execució (això en el exemple) també pot mostrar la memòria, el cgroup, o el nombre de tasques associades.
Si volem saber exactament què fa aquest servei, podem consultar el manual amb la comanda man systemd-random-seed.service
.
En el manual d'aquesta comanda us explicarà de forma detallada què aquest servei carrega una llavor aleatòria al espai del nucli quan arranca i la desa quan s'apaga. Aquesta llavor es guarda a /var/lib/systemd/random-seed
. Per defecte, no s’assigna entropia quan s’escriu la llavor al nucli, però això es pot canviar amb $SYSTEMD_RANDOM_SEED_CREDIT
. El servei s’executa després de muntar el sistema de fitxers /var/
, per la qual cosa és recomanable utilitzar un carregador d’arrencada que passi una llavor inicial al nucli, com systemd-boot
.
👁️ Observació:
Amb aquesta informació podem identificar quina és la funció de cada servei i decidir si pel nostre sistema és necessari o no. En aquest cas, el servei
systemd-random-seed.service
és necessari per a la generació de nombres aleatoris, per tant, no és recomanable desactivar-lo.
Si volem informació sobre la unitat systemd-random-seed.service
, podem utilitzar la comanda systemctl cat systemd-random-seed.service
per veure la configuració de la unitat.
# /lib/systemd/system/systemd-random-seed.service
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Load/Save Random Seed
Documentation=man:systemd-random-seed.service(8) man:random(4)
DefaultDependencies=no
RequiresMountsFor=/var/lib/systemd/random-seed
Conflicts=shutdown.target
After=systemd-remount-fs.service
Before=first-boot-complete.target shutdown.target
Wants=first-boot-complete.target
ConditionVirtualization=!container
ConditionPathExists=!/etc/initrd-release
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/lib/systemd/systemd-random-seed load
ExecStop=/lib/systemd/systemd-random-seed save
# This service waits until the kernel's entropy pool is initialized, and may be
# used as ordering barrier for service that require an initialized entropy
# pool. Since initialization can take a while on entropy-starved systems, let's
# increase the timeout substantially here.
TimeoutSec=10min
Aquesta informació ens mostra la configuració de la unitat, incloent la descripció, la documentació, les dependències, les condicions, el tipus de servei, els comandaments d'inici i parada, i altres opcions de configuració. El servei té una dependència de muntatge per a /var/lib/systemd/random-seed
, i s'executa després de systemd-remount-fs.service
i abans de first-boot-complete.target
i shutdown.target
. A més, ens indica que és un servei de tipus oneshot
, que s'executa una sola vegada i roman actiu després de la sortida. Els comandaments d'inici i parada són /lib/systemd/systemd-random-seed load
i /lib/systemd/systemd-random-seed save
, respectivament.
💡 Nota::
Si ovserveu el paramètre TimeoutSec=10min aquesta unitat pot trigar fins a 10 minuts a carregar. Si el sistema està en un entorn amb poca entropia, aquesta unitat pot trigar més temps a carregar.
Per exemple, editarem la unitat systemd-random-seed.service
per activar la entropia al sistema.Per editar la unitat podeu utilitzar qualsevol editor de text ( i.e vi
) o bé la comanda systemctl edit systemd-random-seed.service
que obrirà un editor de text per afegir la línia. Un cop obert l'editor heu d'afegir la lína a la secció [Service]
i desar el fitxer. Recordeu que per fer aquesta acció necessitareu permisos d'administrador. Per tant, su -
per canviar a l'usuari root i després fer la comanda.
Environment=SYSTEMD_RANDOM_SEED_CREDIT=4096
Compte! Si feu anar el
systemctl edit
aquest crearà un fitxer de configuració a/etc/systemd/system/systemd-random-seed.service.d/override.conf
que sobreescriurà la configuració de la unitat original. Per afegir la configuració còpieu la configuració original i afegiu la líniaEnvironment=SYSTEMD_RANDOM_SEED_CREDIT=4096
a la secció[Service]
.
Estem assignant un crèdit de 4096 a la llavor aleatòria. Això augmentarà la quantitat d'entropia que es passa al nucli quan s'escriu la llavor. Un crèdit més alt pot augmentar la seguretat del sistema, però també pot augmentar el temps d'arrencada en sistemes amb poca entropia.
Un cop hàgim fet els canvis, guardarem el fitxer i sortirem de l'editor. Després, podem fer un reboot
per aplicar els canvis. Quan el sistema s'hagi reiniciat, podem tornar a utilitzar la comanda systemd-analyze
per comprovar si els canvis han tingut algun impacte en el temps d'arrencada del sistema.
Inicial | Després de canviar la entropia | Diferència |
---|---|---|
2.973s | 3.008s | +0.035s |
En el meu cas, el temps d'arrencada ha augmentat lleugerament després de fer aquest canvi. Això és normal, ja que hem augmentat la quantitat d'entropia que es passa al nucli.
Una altra opció interesant que ens ofereix systemd
és la comanda systemd-analyze critical-chain
. Aquesta comanda ens permet veure la cadena crítica de les unitats de temps del sistema. Això ens mostra quines unitats són les més crítiques per al temps d'arrencada del sistema. Per analizar la sortida, heu de mirar el temps després del caràcter @
per veure quant temps ha trigat la unitat a activar-se o iniciar-se, i el temps després del caràcter +
per veure quant temps ha trigat la unitat a iniciar-se. A més, aquesta comanda només mostra el temps que les unitats han passat a l'estat activant-se, i no cobreix les unitats que mai han passat per l'estat activant-se (com les unitats de dispositius que passen directament de inactiu a actiu). Tot i això, és una eina útil per identificar les unitats que poden estar retardant el procés d'arrencada.
graphical.target @2.076s
└─multi-user.target @2.075s
└─ssh.service @1.497s +578ms
└─network.target @1.494s
└─networking.service @1.225s +268ms
└─apparmor.service @1.158s +63ms
└─local-fs.target @1.158s
└─run-credentials-systemd\x2dtmpfiles\x2dsetup.service.mount @1.171s
└─local-fs-pre.target @242ms
└─systemd-tmpfiles-setup-dev.service @224ms +17ms
└─systemd-sysusers.service @192ms +20ms
└─systemd-remount-fs.service @131ms +54ms
└─systemd-journald.socket @114ms
└─-.mount @86ms
└─-.slice @86ms
En aquest cas, podem veure que la unitat ssh.service
és la més crítica per al temps d'arrencada del sistema, ja que ha trigat 578ms a iniciar-se. A més, podem veure les dependències de totes les unitats que s'han carregat durant el procés d'arrencada. Començant pel graphical.target
i seguint per les unitats multi-user.target
, aquestes dos unitats ens asseguren que el sistema ha arrencat en mode gràfic i multiusuari. A partir d'aquest moment es carreguen la resta de serveis.
Un altra opció interessant és utilitzar la comanda systemd-analyze plot
per generar un gràfic del procés d'arrencada del sistema. Aquesta comanda generarà un fitxer SVG amb el gràfic del procés d'arrencada, que podeu visualitzar amb un navegador web o un visor d'imatges.
-
Si volem analitzar tots les unitats:
systemd-analyze plot > boot_system.svg
-
Si volem analitzar les unitats de la instancia de l'usuari:
systemd-analyze --user plot > boot_user.svg
-
Si volem les unitats de l'arrencada del sistema:
systemd-analyze --system plot > boot_system.svg
⚠️ Compte: Com puc visualtizar una imatge SVG en un debian sense interfície gràfica?
Per visualitzar una imatge SVG en un sistema sense interfície gràfica, podeu descarregar el fitxer SVG a la vostra màquina local i visualitzar-lo amb un visor d'imatges o un navegador web. Per exemple, podeu utilitzar la comanda
scp
per descarregar el fitxer SVG a la vostra màquina local:scp user@remote:/path/to/boot.svg /path/to/local/boot.svg
⚠️ Compte: Debian no permet conexions remotes com a root per defecte. Abans de fer-ho, com debian per defecte no permet l'execució de
scp
com a root, caldrà fer-ho com a usuari normal i després copiar el fitxer a la carpeta desitjada.mv boot.svg /tmp chown user:user /tmp/boot.svg
Per a més informació sobre les opcions de la comanda systemd-analyze
, podeu consultar el manual amb la comanda man systemd-analyze
.
Per acabar, podem comentar que així com systemctl status unitat
ens mostra la informació d'una unitat. També podem consultar la informació de totes les unitats amb:
systemctl status
: Mostra informació sobre l'estat actual del sistema o d'una unitat específica acompanyada de les dades més recents del registre del diari.
systemctl list-units
: Mostra una llista de totes les unitats carregades al sistema, incloent les unitats actives, inactives i fallades.
Totes aquestes comandes són molt complexes i tenen moltes opcions, per tant us recomano que consulteu el manual de cada comanda per obtenir més informació sobre com utilitzar-les i quines opcions podeu elegir.
Creant i Gestionant serveis
En aquesta secció, crearem un servei systemd per realitzar una còpia de seguretat del sistema a l'arrencada. Aquest servei s'executarà automàticament quan el sistema s'arrenqui i realitzarà una còpia de seguretat del sistema a una ubicació específica. Aquest servei pot ser interessant en situacions on l'ús pot comportar la pèrdua de dades o la corrupció del sistema.
-
Crea un script de còpia de seguretat: Crea un script de còpia de seguretat a
/usr/local/bin/backup
.sh amb el següent contingut:#!/bin/bash # Còpia de seguretat del sistema tar -czf /backup/system_backup_$(date +%Y%m%d).tar.gz /etc /var
Aquest script realitzarà una còpia de seguretat dels directoris
/etc
i/var
a la ubicació/backup
amb el nomsystem_backup_YYYYMMDD.tar.gz
, onYYYYMMDD
és la data actual. -
Crea un fitxer de servei systemd: Crea un fitxer de servei systemd a
/etc/systemd/system/backup.service
amb el següent contingut:[Unit] Description=System Backup Service After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh [Install] WantedBy=multi-user.target
Aquest fitxer de servei defineix un servei
backup
que s'executarà un cop s'hagi carregat el sistema de fitxers. El servei executarà l'script de còpia de seguretatbackup.sh
al directori/usr/local/bin
. El servei s'instal·larà a la unitatmulti-user.target
, de manera que s'executarà quan el sistema hagi carregat tots els serveis necessaris. -
Inicia el servei: Inicia el servei
backup
amb la comandasystemctl start backup
.systemctl start backup
-
Comprova l'estat del servei: Comprova l'estat del servei
backup
amb la comandasystemctl status backup
.systemctl status backup
-
Habilita el servei: Habilita el servei
backup
perquè s'executi a l'arrencada amb la comandasystemctl enable backup
.systemctl enable backup
-
Reinicia el sistema: Reinicia el sistema per aplicar els canvis.
reboot
-
Comprova si el servei s'ha executat: Després de reiniciar el sistema, comprova si el servei
backup
s'ha executat correctament.ls /backup
Ara el sistema arranca de forma més lenta ja que s'executa el servei de còpia de seguretat. Podeu utilitzat les comandes systemd-analyze
i systemd-analyze blame
per comparar els temps d'arrencada abans i després de la creació del servei.
En el meu cas, el temps d'arrencada ha augmentat lleugerament després de crear el servei de còpia de seguretat:
Inicial | Després de crear el servei | Diferència |
---|---|---|
2.973s | 10.380s | +7.407s |
👁️ Observació:
Noteu que l'augment es produeix en l'espai d'usuari, ja que el servei de còpia de seguretat s'executa després de carregar les funcions del kernel. Això és normal, ja que el servei de còpia de seguretat pot trigar una estona a completar-se, especialment si els directoris
/etc
i/var
són grans.
Serveis programats
Un altra funcionalitat interessant de systemd és la possibilitat de programar la execució de serveis amb systemd.timer
. Aquesta funcionalitat permet programar la execució de serveis en un moment concret o de forma periòdica. Això pot ser útil per realitzar tasques de manteniment automàticament, com ara còpies de seguretat, actualitzacions de sistema, etc.
Anem a veure com podem programar l'actualització del sistema amb un servei apt-update
i un temporitzador apt-update.timer
cada dia a les 00:00.
-
Crea un fitxer de servei
apt-update.service
: Crea un fitxer de serveiapt-update.service
a/etc/systemd/system/apt-update.service
amb el següent contingut:[Unit] Description=Update the package list [Service] Type=oneshot ExecStart=/usr/bin/apt update
Aquest fitxer de servei executa la comanda
apt update
per actualitzar la llista de paquets del sistema. -
Crea un fitxer de temporitzador
apt-update.timer
: Crea un fitxer de temporitzadorapt-update.timer
a/etc/systemd/system/apt-update.timer
amb el següent contingut:[Unit] Description=Run apt-update daily at 00:00 [Timer] OnCalendar=daily [Install] WantedBy=timers.target
Aquest fitxer de temporitzador programa l'execució del servei
apt-update.service
cada dia a les 00:00. -
Inicia el temporitzador: Inicia el temporitzador
apt-update.timer
amb la comandasystemctl start apt-update.timer
.systemctl start apt-update.timer
-
Habilita el temporitzador: Habilita el temporitzador
apt-update.timer
perquè s'executi a l'arrencada amb la comandasystemctl enable apt-update.timer
.systemctl enable apt-update.timer
💡 Nota:
Podeu utilitzar
systemctl enable --now unitat
per iniciar i habilitar una unitat al mateix temps. -
Comprova l'estat del temporitzador: Comprova l'estat del temporitzador
apt-update.timer
amb la comandasystemctl status apt-update.timer
.
Una vegada configurat el temporitzador, el sistema executarà el servei apt-update.service
cada dia a les 00:00 per actualitzar la llista de paquets del sistema.
Anàlisi de logs
Un altre eina útil que ens ofereix systemd és journalctl
, que ens permet analitzar els registres del sistema. Aquesta eina ens permet veure els registres del sistema en temps real, buscar registres específics, filtrar registres per unitat, i molt més.
Crearem un servei amb bash i awk que monitoritzi l'estat del sistema i registri la informació en un fitxer de registre. A continuació, utilitzarem journalctl
per analitzar els registres del sistema i buscar la informació del servei.
-
Crea un script de monitoratge:
#!/bin/bash # Monitor the system state echo "Date: $(date)" echo "Load: $(uptime | awk '{print $10}')" echo "Memory: $(free -m | awk 'NR==2{print $3}')" echo "Disk: $(df -h / | awk 'NR==2{print $5}')" echo "Processes: $(ps aux | wc -l)"
-
Crea un fitxer de servei
system-monitor.service
: En aquest cas, crearem un fitxer de serveisystem-monitor.service
a/etc/systemd/system/system-monitor.service
amb el següent contingut:[Unit] Description=System Monitor Service [Service] Type=simple ExecStart=/usr/local/bin/system-monitor.sh [Install] WantedBy=multi-user.target
-
Inicia el servei: Inicia el servei
system-monitor
amb la comandasystemctl start system-monitor
.systemctl start system-monitor
-
Comprova l'estat del servei: Comprova l'estat del servei
system-monitor
amb la comandasystemctl status system-monitor
.systemctl status system-monitor
Ups! Sembla que hi ha un error en el servei. Podem veure que el servei ha fallat a l'iniciar-se. La mateixa comanda ens indica la causa de l'error:
Permission denied
. Això significa que el script no té permisos d'execució. Per solucionar aquest problema, podem canviar els permisos del script perquè sigui executable amb la comandachmod +x /usr/local/bin/system-monitor.sh
.systemctl restart system-monitor
-
Un altra forma d'accedir a la informació del servei és utilitzar la comanda
journalctl
amb l'opció-u
seguida del nom de la unitat. Per exemple, per veure els registres del serveisystem-monitor
, podem utilitzar la comanda:journalctl -u system-monitor
Aquesta comanda ens mostrarà tots els registres associats amb el servei
system-monitor
, incloent els missatges de registre, les entrades de diari i altres informacions rellevants.👁️ Observació:
Tot i que
journalctl
sembla que ens mostra la mateixa informació quesystemctl status
,journalctl
ens permet accedir a tots els registres del sistema, no només als registres de les unitats. Això ens permet analitzar els registres del sistema de forma més detallada i buscar informació específica. A més, no sempre podem veure tota la informació d'una unitat ambsystemctl status
, ja que aquesta comanda només ens mostra les dades més recents del registre del diari.
💡 Nota:
journalctl
és una eina molt potent que ens permet analitzar els registres del sistema de forma detallada. Podeu utilitzar opcions com-f
per veure els registres en temps real,-n
per limitar el nombre de línies mostrades,-r
per mostrar els registres en ordre invers,-p
per filtrar els registres per prioritat, i moltes altres opcions. Podeu consultar el manual dejournalctl
amb la comandaman journalctl
per obtenir més informació sobre com utilitzar aquesta eina. Durant les vostres sessions administrant el sistema,journalctl
serà una eina molt útil per analitzar els registres del sistema i poder identificar problemes o errors.
Afegint informació d'inici
Els scripts d'arrancada en sistemes Unix i Linux són fitxers que s'executen automàticament quan un usuari inicia una sessió de terminal. Aquests scripts configuren l'entorn de l'usuari, definint variables d'entorn, carregant funcions i configuracions personalitzades, i executant comandes específiques.
Breument, tal com vam veure al curs de sistemes operatius, els scripts d'arrancada més comuns en sistemes Unix i Linux són:
/etc/profile
: Script d'arrancada global per a tots els usuaris del sistema./etc/profile.d/
: Directori que conté scripts d'arrancada addicionals.~/.bash_profile
: Script d'arrancada específic de l'usuari per a la shell bash.~/.bash_login
: Un altre script d'arrancada específic de l'usuari per a la shell bash.~/.profile
: Script d'arrancada específic de l'usuari per a la shell sh i altres shells compatibles.~/.bashrc
: Script d'arrancada específic de l'usuari per a la shell bash./root/.profile
: Script d'arrancada específic de l'usuari root per a la shell sh i altres shells compatibles.
Aquests scripts s'executen en un ordre específic quan un usuari inicia una sessió de terminal. A continuació, veurem una descripció de cada script d'arrancada i el seu ús, així com l'ordre d'execució dels scripts d'arrancada. Per veure l'ordre d'execució dels scripts d'arrancada, podeu consultar el manual de bash
amb la comanda man bash
i buscar la secció INVOCATION.
Anem a veure com podem mostrar informació sobre el servidor després de l'arrencada i el login de l'usuari. Aquesta informació pot ser útil per als administradors de sistemes per mostrar informació rellevant sobre el sistema, com ara la càrrega del sistema, l'ús de la CPU, la memòria disponible, la addresa IP i el nombre d'usuaris connectats.
-
Crea un script d'informació del sistema: Crea un script d'informació del sistema a
/usr/local/bin/system-info.sh
amb el següent contingut:#!/bin/bash # Informació del sistema echo "System Information" echo "------------------" echo "Hostname: $(hostname)" echo "IP Address: $(hostname -I | awk '{print $1}')" echo "Uptime: $(uptime | awk '{print $3 " " $4}')" echo "Load Average: $(uptime | awk '{print $10 " " $11 " " $12}')" echo "Memory Usage: $(free -h | grep Mem | awk '{print $3 "/" $2}')" echo "Disk Usage: $(df -h / | grep /dev | awk '{print $3 "/" $2}')" echo "Users: $(who | wc -l)"
Aquest script mostra informació rellevant sobre el sistema, com ara el nom de l'amfitrió, la addresa IP, el temps d'activitat, la càrrega del sistema, l'ús de la memòria, l'ús del disc i el nombre d'usuaris connectats.
-
Atorga permisos d'execució al script:
chmod +x /usr/local/bin/system-info.sh
-
Crea un script d'informació del sistema: Crea un script d'informació del sistema a
/etc/profile.d/system-info.sh
amb el següent contingut:# Informació del sistema /usr/local/bin/system-info.sh
Si posem l'script a
/etc/profile.d/
aquest s'executarà automàticament quan un usuari inicia una sessió de terminal. Això permet mostrar informació rellevant sobre el sistema després de l'arrencada i el login de l'usuari. -
Atorga permisos d'execució al script:
chmod +x /etc/profile.d/system-info.sh
-
Reinicia el sistema: Reinicia el sistema per aplicar els canvis.
reboot
Un cop el sistema s'hagi reiniciat, podeu iniciar una sessió de terminal i veure la informació del sistema després de l'arrencada i el login de l'usuari. Aquesta informació us pot ajudar a monitoritzar l'estat del sistema i identificar problemes o errors.
-
Inici de sessió amb un usuari normal:
-
Inici de sessió com a usuari root:
Si únicament voleu mostrar la informació del sistema quan s'inicia la sessió de l'usuari root, podeu afegir el script system-info.sh
al fitxer /root/.profile
en lloc de /etc/profile.d/system-info.sh
. Això farà que la informació del sistema es mostri només quan s'inicia la sessió de l'usuari root.
ℹ️ Diferencia entre .bashrc i .bash_profile?
El fitxer
.bashrc
s'executa cada vegada que s'inicia una sessió de terminal, mentre que el fitxer.bash_profile
s'executa només quan s'inicia una sessió de terminal interactiva. Això significa que el fitxer.bashrc
s'executarà cada vegada que s'obri una nova finestra de terminal, mentre que el fitxer.bash_profile
s'executarà només quan s'inicia una sessió de terminal interactiva. Per tant, si voleu mostrar la informació del sistema només quan s'inicia la sessió de l'usuari, podeu afegir el script al fitxer.bash_profile
en lloc de.bashrc
.
Sistema de Fitxers
En aquest laboratori apendrem a gestionar els sistemes de fitxers tradicionals en un servidor Linux; com ext4, i xfs. A més, aprendrem a realitzar tasques comunes com la creació de particions, el muntatge de sistemes de fitxers, la comprovació de la integritat dels fitxers, la realització de còpies de seguretat i la recuperació de dades en cas de corrupció. També analitzarem sistemes de fitxers temporals i un sistema de fitxers avançat com ZFS.
Objectius
Els objectius d'aquest laboratori són:
- Comprendre els conceptes bàsics dels sistemes de fitxers.
- Crear i gestionar particions en un servidor Linux.
- Muntar i desmuntar sistemes de fitxers.
- Comprovar la integritat dels fitxers en un sistema de fitxers.
Tasques
- Muntatge d'un disc extern per fer un backup
- Migració de dades a altres particions
- Simulació d'una corrupció a la partició
/home
i recuperació - Sistemes de fitxers temporals
- Explorant un sistema de fitxers avançat:
zfs
Muntatge d'un disc extern per fer un backup
En aquest laboratori simularem que volem muntar un disc dur extern en el nostre servidor per a realitzar còpies de seguretat de les nostres dades. Crearem una partició en el disc dur i la formatejarem amb el sistema de fitxers ext4
.
-
Connecta el disc dur extern a la màquina virtual.
-
Utilitza la comanda
lsblk
per a identificar el disc dur extern.👁️ Observació:
En aquest cas, el disc dur extern s'identifica com a
/dev/nvme0n2
. La etiquetanvme
indica que el disc dur és un disc dur SSD NVMe. Aquesta etiqueta pot variar en funció del tipus de disc dur que tingueu connectat com arasda
per a disc dur SATA ovda
per a disc dur virtual. -
Utilitza la comanda
fdisk
per a crear una nova partició en el disc dur extern.fdisk /dev/nvme0n2
La comanda ens mostrarà un missatge d'avís indicant que no hi ha cap taula de particions en el disc dur. Això és normal ja que el disc dur és nou i no té cap partició creada.
-
Crearem una nova taula de particions en el disc dur extern. Aquesta taula serà de tipus
msdos
.Command (m for help): o
💫 Recordatori:
Hi ha dos tipus de taula de particions:
msdos
igpt
. La taulamsdos
és més antiga i té limitacions en el nombre de particions que es poden crear. La taulagpt
és més nova i permet crear més particions. Per tant, és recomanable utilitzar la taulagpt
a no se que esteu treballant en un servidor antic.
👁️ Observació:
Com únicament volem fer una sola partició, la elecció de la taula de particions no afectarà en aquest cas.
-
Crearem una nova partició primària en el disc dur extern.
Command (m for help): n Select (default p): Partition number (1-4): 1 First sector (2048-20971519, default 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-20971519, default 20971519):
En aquest cas, crearem una partició primària que ocuparà tot el disc dur. Per tant, acceptarem els valors per defecte. Podeu veure el procés a la següent imatge.
Per a finalitzar la creació de la partició, premeu la tecla
w
per a guardar els canvis. -
Comprova que la partició s'ha creat correctament.
lsblk
Com podeu veure, la partició s'ha creat correctament i s'identifica com a
/dev/nvme0n2p1
. -
Formateja la partició amb el sistema de fitxers
ext4
.mkfs.ext4 /dev/nvme0n2p1
👁️ Observació:
La sortida de la comanda ens mostra el nombre d'inodes, blocs i tamany de blocs del sistema de fitxers creat i també l'identificador UUID del sistema de fitxers. Aquest identificador és únic per a cada sistema de fitxers i ens permet identificar-lo de forma unívoca.
Podeu utilitzar la comanda
blkid
per a veure l'identificador UUID del sistema de fitxers en qualsevol moment.blkid /dev/nvme0n2p1
També podeu utilitzar la comanda
tune2fs
per a canviar l'etiqueta del sistema de fitxers.tune2fs -L "Backup" /dev/nvme0n2p1
Per a comprovar que l'etiqueta s'ha canviat correctament, podeu utilitzar la comanda
lsblk
.lsblk -o LABEL,UUID,FSTYPE,SIZE,MOUNTPOINT
💡 Nota:
L'etiqueta del sistema de fitxers ens permet identificar-lo de forma més fàcil i intuïtiva. A més, ens permet identificar el contingut del sistema de fitxers sense haver de muntar-lo.
👁️ Observació:
La comanda
lsblk
té moltes opcions per a mostrar informació dels discs i les particions. Podeu consultar la documentació de la comanda per a veure totes les opcions disponibles (lsblk -h
). L'argument-o
ens permet seleccionar les columnes que volem mostrar. En aquest cas, hem seleccionat les columnesLABEL
,UUID
,FSTYPE
,SIZE
iMOUNTPOINT
. -
Monta la partició en un directori del sistema de fitxers.
mount /dev/nvme0n2p1 /mnt
-
Comprova que la partició s'ha muntat correctament o podeu fer amb
lsblk
odf
.df -h
En el meu cas, he utilitzat la comanda
df
per a comprovar que la partició s'ha muntat correctament. L'argument-h
ens permet mostrar les dades en un format llegible per a humans. -
Còpiem totes les dades del directori
/home
a la nova partició.cp -r /home/* /mnt
-
Comparem les dades del directori
/home
amb les dades de la partició.diff -r /home /mnt
👁️ Observació:
En aquest cas, la comanda
diff
ens mostrarà un missatge indicant que no hi ha cap diferència entre els dos directoris. Ara bé, en el meu cas es mostra el directori lost+found que únicament es troba al disc dur secundari (és a dir amnt
). Aquest directori és creat pel sistema de fitxersext4
i s'utilitza per a emmagatzemar els inodes dels fitxers que no estan associats a cap directori. Per tant, la seva presència és normal i com no hi ha cap altra diferència, podem assegurar que la còpia s'ha realitzat correctament. -
Desmunta la partició per a poder treure el disc dur extern.
umount /mnt
Migració de directoris a particions diferents
En aquest laboratori assumirem que volem reorganitzar els directoris del nostre sistema de fitxers per a millorar el rendiment i la seguretat del sistema. Crearem 3 noves particions en el disc dur i migrarem els directoris /var
, /tmp
i /opt
en aquestes noves particions.
-
Utilitzarem el mateix disc dur que en l'escenari anterior.
Com que ja tenim dades el que farem serà destruir totes les dades per a començar de nou. Per fer-ho, una forma senzilla és sobreescriure les dades amb zeros. Podem sobreescriure els 10GB del disc dur amb zeros amb la comanda
dd
.dd if=/dev/zero of=/dev/nvme0n2 bs=1M count=10000
💡 Nota:
La comanda
dd
ens permet copiar dades d'un lloc a un altre. En aquest cas, estem copiant zeros (/dev/zero
) al disc dur (/dev/nvme0n2
) amb un tamany de 1MB (bs=1M
) i tantes vegades com indiquem (count=10000
). Això sobreescriurà les dades del disc dur amb zeros i eliminarà totes les dades existents. -
Utilitzarem la comanda
fdisk
per a crear tres noves particions en el disc dur.- La primera partició serà per a
/var
amb el sistema de fitxersext4
, etiquetavar
mida 4GB. - La segona partició serà per a
/tmp
amb el sistema de fitxersxfs
, sense etiqueta i mida 2GB. - La tercera partició serà per a
/opt
amb el sistema de fitxersext4
, etiquetaopt
mida 3GB.
-
Crearem les noves particions en el disc dur. Podeu utilzar una pipeline per a automatitzar la creació de les particions.
echo -e "n\np\n\n\n+4G\nn\np\n\n\n+2G\nn\np\n\n\n+3G\nw" | fdisk /dev/nvme0n2
-
Formateja les particions amb els sistemes de fitxers corresponents i assigna les etiquetes.
mkfs.ext4 /dev/nvme0n2p1 tune2fs -L "var" /dev/nvme0n2p1 mkfs.xfs /dev/nvme0n2p2 mkfs.ext4 /dev/nvme0n2p3 tune2fs -L "opt" /dev/nvme0n2p3
💡 Nota:
El sistema de fitxers xfs no esta instal·lat per defecte a debian, per tant, haurem d'instal·lar-lo abans de poder utilitzar-lo (
apt install xfsprogs
).
- La primera partició serà per a
-
Monta les particions en directoris del sistema de fitxers. Montarem les particions a
/mnt
per a poder migrar els directoris.mkdir /mnt/var mount /dev/nvme0n2p1 /mnt/var mkdir /mnt/opt mount /dev/nvme0n2p3 /mnt/opt
💡 Nota: Com que la partició
/tmp
és temporal, no la muntarem ja que no necessitem migrar cap dada. -
Migrarem els directoris
/var
,/tmp
i/opt
a les noves particions. Per fer-ho podem utilitzar la comandacp
orsync
. En aquest cas utilitzarem rsync per a poder mostrar el progrés de la còpia. Normalment, la einarsync
no ve instal·lada per defecte en la majoria de distribucions, per tant, haurem d'instal·lar-la abans de poder utilitzar-la (apt install rsync
).rsync -av /var /mnt cp -ax /opt /mnt
🚀 Suggeriment:
Us recomano utilitzar la comanda
rsync
per a migrar els directoris ja que ens permet mostrar el progrés de la còpia i també ens permet reprendre la còpia en cas que es talli la connexió o hi hagi un error. A més, també ens permet excloure directoris o fitxers que no volem migrar i ens permet fer còpies incrementals. Podeu consultar la documentació de la comanda per a veure totes les opcions disponibles (man rsync
). -
Comprovem que les dades s'han migrat correctament.
diff -r /var /mnt/var diff -r /opt /mnt/opt
-
Montarem les particions en els directoris corresponents del sistema de fitxers.
umount /mnt/var mount /dev/nvme0n2p1 /var umount /mnt/opt mount /dev/nvme0n2p3 /opt mount /dev/nvme0n2p2 /tmp
Ara ja teniu els directoris
/var
,/tmp
i/opt
muntats en les noves particions. Podem fer servir la comandadf
per a comprovar que les particions s'han muntat correctament. -
Ara reinicieu el sistema:
reboot
💡 Nota:
Un cop reinicieu el sistema, els directoris
/var
,/tmp
i/opt
no estaran muntats en les noves particions. Podeu comprovar-ho amb la comandadf
. Això és normal ja que hem muntat les particions manualment i no hem el fitxer/etc/fstab
per a que es muntin automàticament en l'arrencada del sistema. -
Modifica el fitxer
/etc/fstab
per a que les particions es muntin automàticament en l'arrencada del sistema.echo "/dev/nvme0n2p1 /var ext4 defaults 0 0" >> /etc/fstab echo "/dev/nvme0n2p2 /tmp xfs defaults 0 0" >> /etc/fstab echo "/dev/nvme0n2p3 /opt ext4 defaults 0 0" >> /etc/fstab
💡 Nota:
El fitxer
/etc/fstab
conté la informació de les particions que es muntaran automàticament en l'arrencada del sistema. Cada línia del fitxer conté la informació d'una partició. Els camps de cada línia són: dispositiu, punt de muntatge, sistema de fitxers, opcions, freqüència de comprovació i ordre de comprovació. Podeu consultar la documentació del fitxer per a més informació (man fstab
). -
Comprova que les particions es muntin automàticament en l'arrencada del sistema.
reboot
Un cop reinicieu el sistema, les particions
/var
,/tmp
i/opt
s'hauran muntat automàticament en els directoris corresponents. Podeu comprovar-ho amb la comandadf
.
En aquest punt podriam optimitzar la configuració particions per a millorar el rendiment del sistema.
-
Utiltizarem els UUIDs en lloc dels dispositius per a muntar les particions. Això ens permetrà identificar les particions de forma unívoca i evitar problemes en cas que els dispositius canviïn d'identificador. Per fer-ho podem utilitzar la comanda
sed
per actualitzar el fitxer/etc/fstab
.sed -i "s|/dev/nvme0n2p1|UUID=$(blkid -s UUID -o value /dev/nvme0n2p1)|" /etc/fstab sed -i "s|/dev/nvme0n2p2|UUID=$(blkid -s UUID -o value /dev/nvme0n2p2)|" /etc/fstab sed -i "s|/dev/nvme0n2p3|UUID=$(blkid -s UUID -o value /dev/nvme0n2p3)|" /etc/fstab
🔍 Pregunta: En quins casos poden canviar els dispositius o tenir duplicats?
Els dispositius poden canviar d'identificador en cas que es connectin més dispositius al sistema o es canvii l'ordre de connexió dels dispositius. Això pot provocar que les particions es muntin en llocs diferents dels esperats. Per a evitar aquest problema, és recomanable utilitzar els UUIDs en lloc dels dispositius per a muntar les particions.
-
Utilitzarem opcions més específiques per protegir la partició
/tmp
per a evitar que s’executin programes des de la partició. Utilitzant les opcions nodev, nosuid, i noexec:-
Edita el fitxer
/etc/fstab
i afegeix les opcionsnodev
,nosuid
, inoexec
a la partició/tmp
.ℹ️ Què fan les opcions
nodev
,nosuid
, inoexec
?La opció nodev evita que es puguin executar dispositius en la partició. La opció nosuid evita que es puguin executar programes amb permisos de superusuari en la partició. La opció noexec evita que es puguin executar fitxers binaris des de la partició.
-
Comprova les opcions després d'editar el fitxer
/etc/fstab
.mount | grep /tmp
-
Per aplicar les opcions de muntatge a la partició
/tmp
, farem unreboot
del sistema. -
Testem les opcions de muntatge de la partició
/tmp
:-
Prova d'executar un programa des de la partició
/tmp
com a usuari no privilegiat.echo "echo 'Hello, World'" > /tmp/hello.sh chmod +x /tmp/hello.sh /tmp/hello.sh bash /tmp/hello.sh
-
Prova de fer el mateix com a usuari privilegiat.
su - /tmp/hello.sh bash /tmp/hello.sh
👁️ Observació:
Observeu que la opció
noexec
impedeix la execució dels binaris però no ens protegeix contra l'execució de scripts de bash. -
Prova d'accedir a un dispositiu creat a
/tmp
:-
Inicialitza un dispositiu a
/tmp
utilitzant la comandamknod
.mknod /tmp/dispositiu c 1 3
⚠️ Compte:
La comanda
mknod
única i exclusivament la poden fer els usuaris amb permisos de superusuari. Per tant, feu servir la comandasu
per a canviar a l'usuariroot
abans de fer servir la comandamknod
. -
Per accedir al dispositiu, utilitza la comanda
cat
.cat /tmp/dispositiu
👁️ Observació:
Fixeu-vos que quan intento accedir a un dispositiu al directori actual, no hi ha cap problema. Però quan intento accedir al dispositiu creat a
/tmp
, rebre un missatge d'error indicant que no es pot accedir al dispositiu. Això és degut a la opciónodev
que impedeix l'accés a dispositius en la partició. -
-
Per veure, les implicacions de la opció
nosuid
, podem realitzar el següent experiment:Per fer-ho, crearem un executable amb c que ens indicarà l'identificador de l'usuari real i l'identificador de l'usuari efectiu. On l'usuari real és l'usuari que ha iniciat la sessió i l'usuari efectiu és l'usuari que executa el programa. Si un programa té el bit
suid
activat, l'usuari efectiu serà l'usuari propietari del programa i no l'usuari que l'ha executat.#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { printf("Effective user ID: %d\n", geteuid()); printf("Real user ID: %d\n", getuid()); return 0; }
Compilem el programa amb la comanda
gcc
.gcc -o /tmp/suid /tmp/suid.c
💡 Nota:
El paquet
gcc
no ve instal·lat per defecte en una instal·lació mínima de Debian, per tant, haurem d'instal·lar-lo abans de poder utilitzar-lo (apt install build-essential
).-
Desactiva la opció
nosuid
i també la opciónoexec
per a la partició/tmp
. Per fer-ho, utilitza l'usuariroot
per a editar el fitxer/etc/fstab
. -
Remunta la partició
/tmp
. -
Prova d'executar el programa com a usuari no privilegiat.
/tmp/suid
-
Activa la opció
nosuid
i torna a provar d'executar el programa./tmp/suid
La següent imatge representa la seqüència de comandes per a provar la opció
nosuid
:👁️ Observació:
Fixeu-vos que quan la opció
nosuid
està activada, no es pot executar el programa amb permisos de superusuari. Això és important per a evitar que els usuaris no privilegiats puguin executar programes amb permisos de superusuari. Aquesta opció pot permetre escalar privilegis i comprometre la seguretat del sistema. -
-
-
🔍 Pregunta: Per què és important tenir els directoris
/var
,/tmp
i/opt
en particions diferents?La raó principal per a tenir els directoris
/var
,/tmp
i/opt
en particions diferents és per a millorar el rendiment i la seguretat del sistema. El directori/var
conté dades variables com ara logs, bases de dades, correu electrònic, etc. Si aquest directori es queda sense espai, el sistema podria fallar. El mateix raonament s'aplica al directori/tmp
i/opt
. Per això, és important tenir-los en particions separades per a evitar que el sistema falli. A més, tenir els directoris/var
,/tmp
i/opt
en particions separades també millora la seguretat del sistema ja que si una partició falla, les altres particions seguiran funcionant.
Anem a fer una simulació de com respon el sistema en cas de no tenir els directoris /var
, /tmp
i /opt
en particions separades. Per a això, simularem que el directori /opt
es va omplint fins a ocupar tot l'espai disponible en la partició principal del sistema.
-
Desmuntem la partició
/opt
per a poder continuar amb l'exercici.umount /opt
-
Creeu un fitxer de 20GB al directori
/opt
:dd if=/dev/urandom of=/opt/fitxer bs=1M count=20480
-
Comprova l'estat del sistema.
df -h
-
Intenta instal·lar un paquet amb
apt
i comprova que el sistema falla.apt install htop
Com podeu veure, el sistema fallarà ja que no té espai suficient per a instal·lar el paquet. Això és un problema greu ja que el sistema no podrà funcionar correctament fins que no alliberem espai en la partició principal.
-
Elimina el fitxer que has creat per a poder continuar amb la resta de l'exercici.
rm /opt/fitxer
-
Munteu la partició
/opt
i torneu a crear el fitxer per a omplir el directori.mount /dev/nvme0n2p3 /opt dd if=/dev/urandom of=/opt/fitxer bs=1M count=20480
-
Ara únicament teniu la partició
/opt
plena; però el sistema pot continuar fent tasques:apt install htop
Simulant una corrupció a /home
En aquest escenari simularem que hem patit una corrupció a la partició /home
i quines eines podem utiltzar per intentar recuperar les dades.
Preparació de l'escenari
El primer pas que farem serà migrar el directori /home
a una partició diferent per a poder simular la corrupció. A continuació, simularem la corrupció i finalment recuperarem les dades.
-
Crearem una nova partició en el disc dur extern. Recorda que ja tenim 3 particions creades en aquest disc dur, per tant, la nova partició serà la quarta. Aquesta partició la farem de 600M de mida i la formatejarem amb el sistema de fitxers
xfs
.echo -e "n\np\n4\n\n+600M\nw" | fdisk /dev/nvme0n2 mkfs.xfs /dev/nvme0n2p4
-
Crearem un directori on muntarem la nova partició.
mkdir /mnt/home
-
Muntarem la nova partició en el directori
/mnt/home
.mount /dev/nvme0n2p4 /mnt/home
-
Copiarem totes les dades del directori
/home
a la nova partició.rsync -a /home/ /mnt/
-
Desmontarem la partició.
umount /mnt/home
-
Modificarem el fitxer
/etc/fstab
per a que la partició es munti automàticament en l'arrencada del sistema.echo "/dev/nvme0n2p4 /home xfs defaults,nodev 0 0" >> /etc/fstab
-
Comprovarem que la partició es munta automàticament en l'arrencada del sistema.
reboot
Simulant la corrupció
Un cop hem migrat el directori /home
a una partició diferent, si tot ha anat bé, hauriau de tenir el següent resultat:
Ara podem crear fitxers i directoris al directori /home
del vostre usuari normal, en el meu cas jordi
.
mkdir codi
mkdir dades
touch dades/pokemon.csv
touch codi/main.c
touch codi/Makefile
touch codi/README.md
touch .vim
Per a simular una corrupció editarem alguns valors de la partició /home
amb un editor hexadecimal.
-
Desmuntem la partició
/home
.umount /home
Compte!: Si esteu connectats per SSH, no podreu desmuntar la partició
/home
ja que el vostre usuari està utilitzant aquesta partició. En la primera sessió. Per tant, haure de fer-ho a la consola de la màquina virtual. -
Obrirem la partició
/home
amb un editor hexadecimal. Podeu instal·lar l'editor hexadecimalhexedit
amb la comandaapt install hexedit
.hexedit /dev/nvme0n2p4
-
Modifiqueu bits a l'atzar i deseu els canvis. Per fer-ho escriviu damunt dels valors hexadecimals altres valors. Un cop fet guardeu amb Ctrl + X i Y.
Fixeu-vos en els primers valors resaltats en negreta són els que he modificat.
-
Ara intentarem muntar la partició
/home
per a comprovar que ha estat corrompuda.mount /home
Si la partició
/home
s'ha corromput, hauríeu de veure un missatge d'error com aquest: -
Els diferents sistemes de fitxers tenen eines per a comprovar la integritat dels fitxers. Per exemple, el sistema de fitxers
xfs
té l'einaxfs_ncheck
que permet comprovar la integritat dels fitxers.xfs_ncheck /dev/nvme0n2p4
-
Per a reparar la partició
/home
utilitzarem l'einaxfs_repair
.xfs_repair /dev/nvme0n2p4
-
Un cop reparada la partició
/home
, la muntarem de nou.mount /home
-
Comprovarem que la partició
/home
s'ha muntat correctament i conté els fitxers que havíem creat.ls /home
Sistemes de fitxers temporals
En aquest laboratori, compararem el rendiment dels sistemes de fitxers ext4, xfs i tmpfs en un entorn de còmput científic. Els sistemes de fitxers temporals, com tmpfs, poden millorar significativament el rendiment d’operacions d’entrada/sortida intensives.
Context
Assumeix l'administració d'un servidor de còmput científic que necessita realitzar moltes operacions d'entrada/sortida. En aquest escenari, el rendiment del sistema de fitxers pot ser crític per a l'eficiència del sistema. En aquest laboratori volem corrobarar la següent hipòtesi: els sistemes de fitxers temporals, com tmpfs, poden millorar significativament el rendiment d'operacions d'entrada/sortida intensives per aquest tipus de càrregues de treball.
Objectius
- Comprendre el rendiment dels sistemes de fitxers ext4, xfs i tmpfs.
- Comparar el rendiment dels sistemes de fitxers ext4, xfs i tmpfs en un entorn de còmput científic.
- Optimitzar el rendiment del sistema de fitxers utilitzant un sistema de fitxers temporal.
Preparació de l'entorn
- Creeu un nova màquina virtual amb Debian 12. Podeu utiltizar una configuració per defecte amb 2GB de RAM i 20GB d'espai en el disc principal. En cas, de tenir problemes de RAM durant l'execució de l'experiment, podeu augmentar la RAM a 4GB. Aquests problemes poden causar que el kernel mati el procés per falta de memòria (OOM Killer).
- Creeu un disc secundari de 20GB per crear els sistemes de fitxers ext4, xfs i tmpfs.
- Particioneu el disc secundari amb 3 particions: ext4, xfs i tmpfs cada una amb 5GB d'espai.
- Munteu les particions a les rutes
/mnt/ext4
,/mnt/xfs
i/mnt/tmpfs
respectivament.
Per crear el sistema de fitxers temporal tmpfs, podeu utilitzar la comanda següent:
mount -t tmpfs -o size=5G tmpfs /mnt/tmpfs
Per veure el sistema de fitxers muntat, podeu utilitzar la comanda següent:
df -h
Preparació de l'experiment
Per simular el nostre experiment, crearem un script de Python que generi un fitxer gran i realitzi moltes operacions d'escriptura aleatòria. Aquest script pot ser executat en un servidor de còmput per provar el rendiment del sistema de fitxers. Com a parametres d'entrada podem especificar la ruta del fitxer, la mida del fitxer, el nombre d'operacions d'escriptura aleatòria i la mida del bloc d'escriptura.
import os
import random
import time
import argparse
def create_large_file(file_path, size_in_mb):
with open(file_path, 'wb') as f:
f.write(os.urandom(size_in_mb * 1024 * 1024))
def random_write(file_path, num_operations, block_size):
with open(file_path, 'r+b') as f:
for _ in range(num_operations):
offset = random.randint(0, os.path.getsize(file_path) - block_size)
f.seek(offset)
f.write(os.urandom(block_size))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Simulació de càlcul intensiu d'entrada/sortida")
parser.add_argument('--file_path', type=str, default="/mnt/tmpfs/large_file.bin", help="Camí del fitxer a crear")
parser.add_argument('--log_file', type=str, default="/mnt/tmpfs/experiment_log.txt", help="Camí del fitxer de registre")
parser.add_argument('--size_in_mb', type=int, default=1024, help="Mida del fitxer en MB")
parser.add_argument('--num_operations', type=int, default=10000, help="Nombre d'operacions d'escriptura aleatòria")
parser.add_argument('--block_size', type=int, default=4096, help="Mida del bloc en bytes")
args = parser.parse_args()
start_time = time.time()
create_large_file(args.file_path, args.size_in_mb)
random_write(args.file_path, args.num_operations, args.block_size)
end_time = time.time()
total_time = end_time - start_time
log_message = f"Experiment completat en {total_time} segons"
print(log_message)
Execució de l'experiment
Un cop analitzat el codi, podem executar l'experiment per comparar el rendiment dels sistemes de fitxers ext4, xfs i tmpfs.
-
Executem l'experiment amb el sistema de fitxers ext4:
python3 simulate_io_intensive.py --file_path /mnt/ext4/large_file.bin --size_in_mb 1024 --num_operations 10000 --block_size 4096
-
Executem l'experiment amb el sistema de fitxers xfs:
python3 simulate_io_intensive.py --file_path /mnt/xfs/large_file.bin --size_in_mb 1024 --num_operations 10000 --block_size 4096
-
Executem l'experiment amb el sistema de fitxers tmpfs:
python3 simulate_io_intensive.py --file_path /mnt/tmpfs/large_file.bin --size_in_mb 1024 --num_operations 10000 --block_size 4096
Ara realitzarem l'experiment 10 vegades per obtenir una mitjana del temps d'execució per a cada sistema de fitxers.
- Sistema de fitxers: ext4
for i in {1..10}
do
python3 simulate_io_intensive.py --file_path /mnt/ext4/large_file.bin --size_in_mb 1024 --num_operations 10000 --block_size 4096
done
Temps d'execució (s) | Iteració |
---|---|
3.04 | 1 |
2.58 | 2 |
2.62 | 3 |
3.28 | 4 |
2.68 | 5 |
2.98 | 6 |
2.66 | 7 |
3.34 | 8 |
2.79 | 9 |
2.83 | 10 |
Mitjana | 2.88 |
- Sistema de fitxers: xfs
for i in {1..10}
do
python3 simulate_io_intensive.py --file_path /mnt/xfs/large_file.bin --size_in_mb 1024 --num_operations 10000 --block_size 4096
done
Temps d'execució (s) | Iteració |
---|---|
2.34 | 1 |
2.42 | 2 |
2.41 | 3 |
2.41 | 4 |
2.40 | 5 |
2.39 | 6 |
2.41 | 7 |
2.44 | 8 |
2.49 | 9 |
2.46 | 10 |
Mitjana | 2.42 |
- Sistema de fitxers: tmpfs
for i in {1..10}
do
python3 simulate_io_intensive.py --file_path /mnt/tmpfs/large_file.bin --size_in_mb 1024 --num_operations 10000 --block_size 4096
done
Temps d'execució (s) | Iteració |
---|---|
2.33 | 1 |
2.29 | 2 |
2.28 | 3 |
2.29 | 4 |
2.32 | 5 |
2.32 | 6 |
2.30 | 7 |
2.33 | 8 |
2.31 | 9 |
2.29 | 10 |
Mitjana | 2.31 |
Observeu com el sistema de fitxers tmpfs té un rendiment significativament millor que els sistemes de fitxers ext4 i xfs en aquest escenari. Això es deu al fet que tmpfs emmagatzema les dades a la memòria RAM en lloc de l'emmagatzematge en disc, el que permet un accés més ràpid a les dades. Ara bé, cal tenir en compte que les dades emmagatzemades a tmpfs es perden quan el sistema es reinicia.
Explorant d'un sistema de fitxers avançat: zfs
En aquesta secció, explorarem el sistema de fitxers ZFS (Zettabyte File System). ZFS és un sistema de fitxers avançat que ofereix moltes característiques interessants com ara la integritat de les dades, la compressió, la deduplicació, la replicació, la instantània, la clonació, etc. Per fer-ho utilitzarem la màquina virtual amb Almalinux 9.4.
-
Instal·la el repositori EPEL:
dnf install epel-release -y ```
-
Afegeix el repositori ZFS:
dnf install https://zfsonlinux.org/epel/zfs-release-2-3$(rpm --eval "%{dist}").noarch.rpm -y
-
Instal·lació dels paquets necessaris:
dnf install kernel-devel
-
Actualitzar el sistema:
dnf update -y
-
Segons la documentació, veure Getting Started: Per defecte, el paquet zfs-release està configurat per instal·lar paquets de tipus DKMS perquè funcionin amb una àmplia gamma de kernels. Per poder instal·lar els mòduls kABI-tracking, cal canviar el repositori predeterminat de zfs a zfs-kmod.
dnf config-manager --disable zfs dnf config-manager --enable zfs-kmod dnf install zfs
-
Reinicieu la màquina virtual:
reboot
-
Carregeu el modul zfs al kernel de linux:
modprobe zfs
Creació d'un pool ZFS
Una pool ZFS és un conjunt de dispositius de blocs que es poden utilitzar per emmagatzemar dades. Aquesta pool pot estar formada per un o més dispositius de blocs. Aquests dispositius poden ser discos durs, SSD, dispositius de xarxa, etc. Aquesta pool es pot utilitzar per crear conjunts de dades i sistemes de fitxers ZFS. Utiltizarem el disc /etc/vdb per crear la pool.
-
Creació de la pool:
zpool create -f zfspool /dev/vdb
-
Comprovació de la pool:
zpool status
pool: zfspool state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM zfspool ONLINE 0 0 0 vdb ONLINE 0 0 0 errors: No known data errors
-
Creació d'un sistema de fitxers que anomenarem (dades):
zfs create zfspool/dades
-
Comprovació del conjunt de dades:
zfs list
NAME USED AVAIL REFER MOUNTPOINT zfspool 135K 352M 25.5K /zfspool zfspool/dades 24K 352M 24K /zfspool/dades
NOTA: Ara mateix tenim muntats dos sistemes de fitxers: zfspool i zfspool/dades. Per defecte, els sistemes de fitxers ZFS es muntaran a /zfspool i /zfspool/dades. Però, podem canviar aquest comportament i muntar els sistemes de fitxers a un altre directori.
-
Anem a canviar el punt de muntatge de zfspool/dades a /mnt/dades:
mkdir /mnt/dades
zfs set mountpoint=/mnt/dades zfspool/dades
zfs list
NAME USED AVAIL REFER MOUNTPOINT zfspool 135K 352M 25.5K /zfspool zfspool/dades 24K 352M 24K /mnt/dades
-
Ara crearem uns quants fitxers i directoris a /mnt/data:
mkdir /mnt/dades/sergi mkdir /mnt/dades/adria touch /mnt/dades/sergi/a.txt touch /mnt/dades/sergi/a.c mkdir /mnt/dades/adria/config touch /mnt/dades/adria/config/.vim
-
ZFS ens permet crear snapshots (instantànies) dels nostres sistemes de fitxers. Aquestes instantànies són còpies de seguretat dels nostres sistemes de fitxers en un moment determinat. Aquestes instantànies es poden utilitzar per restaurar els nostres sistemes de fitxers en cas de fallada o error. Crearem una instantània del nostre sistema de fitxers zfspool/dades:
zfs snapshot zfspool/dades@snap1
-
Ara eliminarem el directori /mnt/dades/adria/config:
rm -rf /mnt/dades/adria/config
-
Podem utilitzar la comanda zfs rollback per restaurar el nostre sistema de fitxers a l'estat de l'instantània:
zfs rollback zfspool/dades@snap1
-
Comprovem que el directori /mnt/dades/adria/config ha estat restaurat:
ls -la /mnt/dades/adria/config
total 2 drwxr-xr-x. 2 root root 3 Oct 3 10:01 . drwxr-xr-x. 3 root root 3 Oct 3 10:01 .. -rw-r--r--. 1 root root 0 Oct 3 10:01 .vim
-
Podem utilitzar la comanda zfs clone per crear un clon del nostre sistema de fitxers zfspool/dades:
zfs clone zfspool/dades@snap1 zfspool/dades/clone1
OBSERVACIÓ 1: Els clons en ZFS permeten realitzar migracions de dades eficients i segures. Abans d'efectuar canvis en el sistema de producció o transferir dades a un nou sistema, es pot crear un clon de les dades existents per provar la migració sense afectar les dades originals
OBSERVACIÓ 2: Quan es requereix realitzar operacions de processament, anàlisi o transformació de dades, els clons permeten fer-ho sense modificar o posar en perill les dades originals.
zfs list
NAME USED AVAIL REFER MOUNTPOINT zfspool 217K 352M 24K /zfspool zfspool/dades 43K 352M 29K /mnt/dades zfspool/dades/clone1 0B 352M 29K /mnt/dades/clone1
-
Per eliminar un clon, utilitzarem la comanda zfs destroy:
zfs destroy zfspool/dades/clone1
-
Per eliminar una instantània, utilitzarem la comanda zfs destroy:
zfs destroy zfspool/dades@snap1
-
Per eliminar un sistema de fitxers, utilitzarem la comanda zfs destroy:
zfs destroy zfspool/dades
NOTA: Si enlloc d'eliminar volem únicament desmuntar, utilitzarem la comanda zfs umount. Per exemple:
zfs umount zfspool/dades
. -
Per eliminar una pool, utilitzarem la comanda zpool destroy:
zpool destroy zfspool
Raids
En aquest laboratori aprendrem a configurar i gestionar sistemes RAID en un servidor Linux. Aquesta tecnologia ens permetrà augmentar la disponibilitat i la tolerància a fallades dels nostres sistemes.
Objectius
- Comprendre els conceptes bàsics de RAID.
- Configurar diferents nivells de RAID.
- Comparar el rendiment de diferents nivells de RAID.
Comandes bàsiques
mdadm
: Utilitzada per gestionar dispositius RAID.lsblk
: Mostra informació sobre els dispositius de bloc.fio
: Eina de benchmarking per provar el rendiment dels dispositius de bloc.mount
: Utilitzada per muntar sistemes de fitxers.mkfs
: Utilitzada per crear sistemes de fitxers.
Continguts
Comparant el rendiment de diferents nivells de RAIDs
En aquest laboratori, compararem el rendiment de diferents nivells de RAID utilitzant l'eina de benchmark fio
. En concret, compararem el rendiment del RAID 0 i del RAID 1 en operacions d'escriptura i de lectura. Aquesta anàlisi ens permetrà comprendre les diferències de rendiment entre els dos tipus de RAID i determinar quin tipus de RAID és més adequat per a les nostres necessitats.
Configuració de l'entorn
En aquest laboratori utiltizarem una màquina virtual amb Debian 12 i 4 discos secundaris de 5GB cadascun. Aquests discos secundaris es configuraran en dos nivells de RAID diferents: RAID0 i RAID1.
📝 Nota
Si no voleu utilitzar 4 discs podeu utiltizar 2 disc amb diferents particions per a crear les RAID. El més important és que la RAID0 i la RAID1 tinguin el mateix nombre de discs, capacitat i tipus per poder fer una comparació justa.
Creació de les raids
-
Creació de raid0:
mdadm --create --verbose /dev/md0 --level=0 --raid-devices=2 /dev/nvme0n2 /dev/nvme0n3
-
Creació del sistema de fitxers:
mkfs.ext4 /dev/md0
-
Muntatge del sistema de fitxers:
mkdir /mnt/md0 mount /dev/md0 /mnt/md0
-
Creació de raid1:
mdadm --create --verbose /dev/md1 --level=1 --raid-devices=2 /dev/nvme0n4 /dev/nvme0n5
-
Creació del sistema de fitxers:
mkfs.ext4 /dev/md1
-
Muntatge del sistema de fitxers:
mkdir /mnt/md1 mount /dev/md1 /mnt/md1
Instal·lant l'eina de benchmark fio
La eina fio
ens permetrà realitzar diferents experriments per tal de comparar diferents operacions d'entrada/sortida amb diferents configuracions de blocs.
apt install fio -y
Proves de rendiment
-
Test de rendiment del RAID0 en oepracions d'escriptura:
fio --name=write-raid1 --ioengine=libaio --iodepth=32 --rw=write \ --bs=4k --size=500M --numjobs=4 --runtime=120 --time_based \ --ramp_time=15 --group_reporting --filename=/dev/raid1 \ --output-format=json --output=/tmp/write-raid1.json
-
Test de rendiment del RAID0 en operacions de lectura:
fio --name=read-raid0 --ioengine=libaio --iodepth=32 --rw=read \ --bs=4k --size=500M --numjobs=4 --runtime=120 --time_based \ --ramp_time=15 --group_reporting --filename=/dev/raid0 \ --output-format=json --output=/tmp/read-raid0.json
-
Test de rendiment del RAID1 en operacions d'escriptura:
fio --name=write-raid1 --ioengine=libaio --iodepth=32 --rw=write \ --bs=4k --size=500M --numjobs=4 --runtime=120 --time_based \ --ramp_time=15 --group_reporting --filename=/dev/raid1 \ --output-format=json --output=/tmp/write-raid1.json
-
Test de rendiment del RAID1 en operacions de lectura:
fio --name=read-raid1 --ioengine=libaio --iodepth=32 --rw=read \ --bs=4k --size=500M --numjobs=4 --runtime=120 --time_based \ --ramp_time=15 --group_reporting --filename=/dev/raid1 \ --output-format=json --output=/tmp/read-raid1.json
Anàlisi de resultats
Per analitzar els resultats obtinguts, ens centrarem en els següents paràmetres:
- Bandwidth: La velocitat de transferència de dades en bytes per segon.
- IOPS: El nombre d’operacions d’entrada/sortida per segon.
- Latència: El temps que triga el sistema a respondre a una petició d’entrada/sortida.
- Total IO: El nombre total d’operacions d’entrada/sortida.
Op. | RAID | Bandwidth (GB/s) | IOPS | Latència(µs) | Total IO (GB) |
---|---|---|---|---|---|
W | 0 | 10.58 | 2.65e+06 | 48.22 | 317.6 |
W | 1 | 7.93 | 1.98e+06 | 64.40 | 238.0 |
R | 0 | 18.76 | 4.69e+06 | 27.16 | 562.98 |
R | 1 | 18.82 | 4.71e+06 | 27.08 | 564.6 |
La taula mostra un resum dels resultats obtinguts de les proves de rendiment del RAID 0 i del RAID 1. Aquests resultats corroboren les diferències de rendiment entre els dos tipus de RAID. En primer lloc, si ens centrem en el Bandwidth, podem observar un rendiment similar en les operacions de lectura amb unes velocitats de 18.76GB/s i 18.82GB/s respectivament. En canvi, el RAID 0 té un rendiment superior en les operacions d'escriptura amb una velocitat de 10.59GB/s, mentre que el RAID 1 té una velocitat de 7.93GB/s. Això es deu al fet que en el RAID 0 les dades es distribueixen entre els dos discs, mentre que en el RAID 1 les dades s'han de copiar en tots dos discs. En segon lloc, si analitzem les variables de Latency i IOPS observem un rendiment similar en les operacions de lectura, amb una latència de 27.16µs i 27.08µs respectivament. En canvi, en les operacions d'escriptura, el RAID 0 té una latència de 48.22µs i 64.40µs en el RAID 1. Finalment, en termes de Total IO, el RAID 0 té un rendiment superior amb 317.69GB en les operacions d'escriptura, mentre que el RAID 1 té un rendiment de 238.01GB.
🚀 Conclusió:
Aquesta anàlisi demostra que el RAID 0 ofereix un rendiment superior en termes de velocitat d'escriptura, mentre que el RAID 1 proporciona una major seguretat de les dades a costa d'una velocitat d'escriptura més lenta. Per tant, la selecció del tipus de RAID depèn de les necessitats específiques de l'usuari, prioritzant la velocitat o la seguretat de les dades.
Tolerància a fallades
Preparació de l'entorn
En aquest laboratori podeu utilitzar la mateixa màquina virtual que en el laboratori anterior. Ens centrarem en la tolerància a fallades dels sistemes RAID0 i RAID1.
Simulant una fallada en un disc del RAID1
-
Crearem dades en el sistema de fitxers del RAID1.
fallocate -l 100M /mnt/md1/testfile
-
Simularem una fallada en un dels discos del RAID1. Utilitzant l'argument
--set-faulty
demdadm
podem simular una fallada en un dels discos.mdadm --manage /dev/md1 --set-faulty /dev/nvme0n4
-
Comproveu l'estat del RAID1 amb la comanda
mdadm --detail /dev/md1
.📝 Nota
Alternativament, podeu utilitzar la comanda
cat /proc/mdstat
per comprovar l'estat dels vostres dispositius RAID. -
Comproveu integritat de les dades:
ls -la /mnt/md1
Si tot ha anat bé, les dades haurien de ser accessibles.
Simulant una fallada en un disc del RAID0
-
Crearem dades en el sistema de fitxers del RAID0.
fallocate -l 100M /mnt/md0/testfile
-
Utilitzarem la comanda
hexdump
per escriure dades aleatòries al disc i corrompre'l.hexdump -C /dev/nvme0n2 | head -n 10
-
Desmuntarem el sistema de fitxers i el muntarem de nou.
umount /mnt/md0 mount /dev/md0 /mnt/md0
-
El sistema us hauria de mostrar un error semblant a aquest:
mount: /mnt/md0: can't read superblock on /dev/md0. dmesg(1) may have more information after failed mount system call.
En aquest cas, el sistema no pot muntar el sistema de fitxers ja que el disc ha estat corromput.
Migració d'un servidor tradicional a un servidor amb RAID
En aquest laboratori aprendrem a migrar un servidor tradicional a un servidor amb RAID.
Notes
📝 Nota 1
Es possible que observeu un missatge com el següent quan realitzeu el laboratori: mount: (hint) your fstab has been modified, but systemd still uses the old version; use 'systemctl daemon-reload' to reload. Podeu ignorar aquest missatge ja que no afecta el funcionament del laboratori. O si voleu podeu executar la comanda
systemctl daemon-reload
per assegurar-vos que el sistema ha recarregat la configuració.
Preparació de l'entorn
Assumirem una màquina virtual amb AlmaLinux on tenim un disc dur principal de 20GB particionat de la següent manera:
/boot
de 600MB amb el sistema de fitxersxfs
./boot/efi
de 1024MB amb el sistema de fitxersvfat
.swap
de 2GB./
de 16GB amb el sistema de fitxersxfs
.
Instal·leu els paquet següents que necessitarem per aquest laboratori:
-
mdadm
: Utilitzada per gestionar dispositius RAID.dnf install mdadm -y
-
rsync
: Utilitzada per copiar el contingut de les particions.dnf install rsync -y
Disseny de la nova arquitectura
Utiltizarem 2 discs secundaris de 20GB cadascun per crear la següent arquitectura:
- RAID 1 amb
/boot
i/boot/efi
. - RAID 1 amb
swap
. - RAID 1 amb
/
.
Preparació dels discs
-
Creació de la taula de particions i de les particions als discs secundaris.
-
/boot/efi
:echo -e "g\nn\np\n\n\n+600M\nt\n29\nw" | fdisk /dev/nvme0n2 echo -e "g\nn\np\n\n\n+600M\nt\n29\nw" | fdisk /dev/nvme0n3
-
boot
:echo -e "n\np\n\n\n+1024M\nt\n2\n29\nw" | fdisk /dev/nvme0n2 echo -e "n\np\n\n\n+1024M\nt\n2\n29\nw" | fdisk /dev/nvme0n3
-
swap
:echo -e "n\np\n\n\n+2G\nt\n3\n29\nw" | fdisk /dev/nvme0n2 echo -e "n\np\n\n\n+2G\nt\n3\n29\nw" | fdisk /dev/nvme0n3
-
/
:echo -e "n\np\n\n\n+16G\nt\n4\n29\nw" | fdisk /dev/nvme0n2 echo -e "n\np\n\n\n+16G\nt\n4\n29\nw" | fdisk /dev/nvme0n3
-
-
Comproveu que les particions s'han creat correctament amb
lsblk
.
RAID 1 amb /boot/efi
-
Creació del RAID 1 amb
/boot/efi
.mdadm --create --verbose /dev/md0 --level=1 --raid-devices=2 \ --metadata=1.0 /dev/nvme0n2p1 /dev/nvme0n3p1
-
Creació del sistema de fitxers
fat32
.mkfs.vfat /dev/md0
-
Crear un punt de muntatge temporal i muntar el sistema de fitxers.
mkdir /tmp/raid1 mount /dev/md0 /tmp/raid1
-
Copiar el contingut de
/boot/efi
al RAID 1.rsync -avx /boot/efi/ /tmp/raid1
-
Desmuntar la RAID:
umount /tmp/raid1
-
Seleccionar el UUID del RAID 1:
EFI_RAID_UUID=$(blkid -s UUID -o value /dev/md0)
-
Actualitzar
/etc/fstab
amb el nou UUID.CURRENT_BOOT_UUID=$(blkid -s UUID -o value /dev/nvme0n1p1) sed -i "s|UUID=$CURRENT_BOOT_UUID|UUID=$EFI_RAID_UUID |" /etc/fstab
RAID 1 amb boot
Repetiu els passos anteriors per crear el RAID 1 anomenta (/dev/md1) amb /boot
. Utiltizant les particions /dev/nvme0n2p2
i /dev/nvme0n3p2
.
-
Creació del RAID 1 amb
/boot
.mdadm --create --verbose /dev/md1 --level=1 --raid-devices=2 \ --metadata=1.0 /dev/nvme0n2p2 /dev/nvme0n3p2
-
Creació del sistema de fitxers
xfs
.mkfs.xfs /dev/md1
-
Crear un punt de muntatge temporal i muntar el sistema de fitxers.
mkdir /tmp/raid2 mount /dev/md1 /tmp/raid2
-
Copiar el contingut de
/boot
al RAID 1.rsync -avx /boot/ /tmp/raid2
-
Desmuntar la RAID:
umount /tmp/raid2
-
Seleccionar el UUID del RAID 1:
BOOT_RAID_UUID=$(blkid -s UUID -o value /dev/md1)
-
Actualitzar
/etc/fstab
amb el nou UUID.CURRENT_BOOT_UUID=$(blkid -s UUID -o value /dev/nvme0n1p2) sed -i "s|UUID=$CURRENT_BOOT_UUID|UUID=$BOOT_RAID_UUID |" /etc/fstab
RAID 1 amb swap
-
Creació del RAID 1 amb
swap
.mdadm --create --verbose /dev/md2 --level=1 --raid-devices=2 \ /dev/nvme0n2p3 /dev/nvme0n3p3
-
Creació del sistema de fitxers
swap
.mkswap /dev/md2
-
Activar el sistema de fitxers
swap
.swapon /dev/md2
-
Actualitzar
/etc/fstab
amb el nou UUID.CURRENT_SWAP_UUID=$(blkid -s UUID -o value /dev/nvme0n1p3) SWAP_RAID_UUID=$(blkid -s UUID -o value /dev/md2) sed -i "s|UUID=$CURRENT_SWAP_UUID|UUID=$SWAP_RAID_UUID |" /etc/fstab
-
Compproveu que la partició swap s'ha activat correctament.
swapon --show
RAID 1 amb /
-
Creació del RAID 1 amb
/
.mdadm --create --verbose /dev/md3 --level=1 --raid-devices=2 \ /dev/nvme0n2p4 /dev/nvme0n3p4
-
Creació del sistema de fitxers
xfs
.mkfs.xfs /dev/md3
-
Crear un punt de muntatge temporal i muntar el sistema de fitxers.
mkdir /tmp/raid3 mount /dev/md3 /tmp/raid3
-
Noms de dispositius RAID persistents.
mkdir -p /etc/mdadm mdadm --detail --scan > /etc/mdadm/mdadm.conf
-
Seleccionar el UUID del RAID 1:
ROOT_RAID_UUID=$(blkid -s UUID -o value /dev/md3)
-
Actualitzar
/etc/fstab
amb el nou UUID.CURRENT_ROOT_UUID=$(blkid -s UUID -o value /dev/nvme0n1p4) sed -i "s|UUID=$CURRENT_ROOT_UUID|UUID=$ROOT_RAID_UUID |" /etc/fstab
-
Copiar el contingut de
/
al RAID 1.cp -ax / /tmp/raid3
Configuració del GRUB
-
Actualitzar la configuració del GRUB.
vi /etc/default/grub
Teniu dos opcions per configurar el GRUB, com els noms dels dispositius no canviaran, ja que els hem fet persistent, podeu utilitzar el nom del dispositiu
/dev/mdX
o el UUID del RAID.GRUB_CMDLINE_LINUX="root=/dev/md3 rd.auto ..." GRUB_ENABLE_BLSCFG=false GRUB_CMDLINE_LINUX_DEFAULT=""
o bé utilitzant el UUID del RAID.
GRUB_CMDLINE_LINUX="root=UUID=<UUID> rd.auto ..." GRUB_ENABLE_BLSCFG=false GRUB_CMDLINE_LINUX_DEFAULT="" # on <UUID> és el UUID del RAID 1 amb /. # rd.auto: Per carregar automàticament els mòduls RAID. # GRUB_ENABLE_BLSCFG=false: Per desactivar el suport de BLS. # GRUB_CMDLINE_LINUX_DEFAULT="": Per desactivar les opcions per defecte.
-
Copiar el GRUB al nou disc.
cp /etc/default/grub /tmp/raid3/etc/default/grub
-
Instal·lar el GRUB a cada disc secundari.
efibootmgr --create --disk /dev/nvme0n2 --part 1 --label "almalinux-mirror-01" --loader "\EFI\almalinux\grubaa64.efi" efibootmgr --create --disk /dev/nvme0n3 --part 1 --label "almalinux-mirror-02" --loader "\EFI\almalinux\grubaa64.efi"
-
Actualitzar la configuració del GRUB.
grub2-mkconfig -o /boot/efi/EFI/almalinux/grub.cfg
-
Actualitzarem la
initramfs
per incloure els mòduls RAID.dracut -f
-
Reiniciar el sistema.
reboot
Nota: Aquesta configuració no és del tot correcta, i veureu que el raid de la partició del sistema
/
no es munta i es segueix utilitzant la partició original. Tot i això, si en el grub indiquemroot=/dev/md3
ird.auto
, el sistema arrenca correctament. Per tant, deures investigar com fer que el sistema munti el raid de la partició/
correctament.
Desplegant un servidor web: Wordpress
En aquest laboratori, desplegarem un servidor web senzill amb WordPress, una de les plataformes de gestió de continguts (CMS) més populars del món. WordPress permet crear i gestionar llocs web de manera intuïtiva i eficient, i és ideal per a projectes com blocs, botigues en línia, portals de notícies, i molt més.
Per a aquest desplegament, utilitzarem una arquitectura monolítica, una solució senzilla on tots els components del lloc web es troben en una sola màquina virtual. Aquesta configuració és adequada per a llocs web petits o amb poc trànsit, ja que ofereix una implementació ràpida i fàcil de gestionar. No obstant això, a mesura que el lloc web creixi o augmenti el trànsit, caldrà considerar opcions més complexes, com ara l'escalabilitat horitzontal o vertical.
Si consulteu la web oficial de Wordpress, veureu que la versió actual és la 6.6.2. I els seus requeriments per la instal·lació són els següents:
- PHP: Versió 7.4 o superior.
- MySQL o MariaDB: MySQL versió 5.7 o superior o MariaDB versió 10.3 o superior.
- Apache o Nginx: Versió 2.4 o superior per a Apache o versió 1.26 o superior per a Nginx.
- HTTPS: Recomanat per a la seguretat del lloc web.
Per tant, haurem de preparar un servidor que compleixi aquests requeriments abans de procedir a la instal·lació de Wordpress.
Requisits
- Màquina virtual amb sistema operatiu AlmaLinux.
Objectius
- Desplegar un servidor web senzill amb Wordpress.
- Configurar un servidor web amb Apache.
- Configurar una base de dades amb MariaDB.
- Configurar un servidor PHP amb PHP.
- Instal·lar i configurar Wordpress.
- Provar el lloc web de Wordpress.
Desplegant un servidor web: Wordpress
En aquest laboratori, desplegarem un servidor web senzill amb WordPress, una de les plataformes de gestió de continguts (CMS) més populars del món. WordPress permet crear i gestionar llocs web de manera intuïtiva i eficient, i és ideal per a projectes com blocs, botigues en línia, portals de notícies, i molt més.
Per a aquest desplegament, utilitzarem una arquitectura monolítica, una solució senzilla on tots els components del lloc web es troben en una sola màquina virtual. Aquesta configuració és adequada per a llocs web petits o amb poc trànsit, ja que ofereix una implementació ràpida i fàcil de gestionar. No obstant això, a mesura que el lloc web creixi o augmenti el trànsit, caldrà considerar opcions més complexes, com ara l'escalabilitat horitzontal o vertical.
Si consulteu la web oficial de Wordpress, veureu que la versió actual és la 6.6.2. I els seus requeriments per la instal·lació són els següents:
- PHP: Versió 7.4 o superior.
- MySQL o MariaDB: MySQL versió 5.7 o superior o MariaDB versió 10.3 o superior.
- Apache o Nginx: Versió 2.4 o superior per a Apache o versió 1.26 o superior per a Nginx.
- HTTPS: Recomanat per a la seguretat del lloc web.
Per tant, haurem de preparar un servidor que compleixi aquests requeriments abans de procedir a la instal·lació de Wordpress.
Requisits
- Màquina virtual amb sistema operatiu AlmaLinux.
Objectius
- Desplegar un servidor web senzill amb Wordpress.
- Configurar un servidor web amb Apache.
- Configurar una base de dades amb MariaDB.
- Configurar un servidor PHP amb PHP.
- Instal·lar i configurar Wordpress.
- Provar el lloc web de Wordpress.
Preparant el servidor
Un cop creada la màquina virtual, el primer pas és actualitzar el sistema operatiu amb la comanda següent per assegurar-nos que disposem de les últimes actualitzacions de seguretat.
💡 Nota
Mantenir el sistema operatiu actualitzat és una responsabilitat fonamental de qualsevol administrador de sistemes, ja que garanteix l'estabilitat i la seguretat del servidor. Per això, és recomanable començar qualsevol configuració executant una actualització completa del sistema.
dnf -y update
Aquesta comanda actualitza tots els paquets del sistema utilitzant el gestor de paquets DNF. L'opció -y
respon automàticament sí a totes les preguntes de confirmació, permetent que l'actualització es realitzi sense intervenció manual.
A més, si preferiu utilitzar un editor de text diferent de vi
, podeu instal·lar alternatives com vim
, emacs
o nano
amb les comandes següents:
dnf install vim -y
dnf install nano -y
dnf install emacs -y
Es recomanable tenir un script amb el resum de les comandes que s'han d'executar per preparar el servidor. Així, si cal crear un nou servidor o repetir la configuració en un altre moment, es pot utilitzar aquest script per automatitzar el procés.
#!/bin/bash
# Actualitzar el sistema
dnf -y update
# Instal·lar editors de text
dnf install vim -y
Instal·lant i configurant Apache
El primer pas per desplegar un servidor web amb WordPress és instal·lar i configurar un servidor web. Necessitem la versió 2.4 o superior d'Apache per a la nostra instal·lació.
-
Comprovem si el paquet httpd està disponible:
dnf search httpd
La sortida hauria de mostrar el paquet httpd i les seves dependències.
Last metadata expiration check: 0:00:00 ago on Tue 15 Feb 2022 09:00:00 PM UTC. ============== Name Exactly Matched: httpd ============== httpd.x86_64 : Apache HTTP Server
Si el paquet esta disponible, primer revisarem la informació del paquet amb la comanda
dnf info httpd
.Installed Packages Name : httpd Version : 2.4.57 Release : 11.el9_4.1 Architecture : aarch64 Size : 155 k Source : httpd-2.4.57-11.el9_4.1.src.rpm Repository : @System From repo : appstream Summary : Apache HTTP Server URL : https://httpd.apache.org/ License : ASL 2.0 Description : The Apache HTTP Server is a powerful, efficient, and extensible : web server.
Un cop ens assegurem que el paquet està disponible amb la versió correcta, procedirem a la instal·lació.
-
Instal·lem el dimoni httpd:
dnf install httpd -y
-
Comprovem l'estat del servei amb
systemctl
:systemctl status httpd
-
Visualitzem els fitxers de configuració del servei httpd:
less /usr/lib/systemd/system/httpd.service
[Unit] Description=The Apache HTTP Server Wants=httpd-init.service After=network.target remote-fs.target nss-lookup.target httpd-init.service Documentation=man:httpd.service(8) [Service] Type=notify Environment=LANG=C ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful # Send SIGWINCH for graceful stop KillSignal=SIGWINCH KillMode=mixed PrivateTmp=true OOMPolicy=continue [Install] WantedBy=multi-user.target
Aquest fitxer de configuració conté instruccions com:
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
: Defineix la comanda que s'utilitza per iniciar el servei. El mode foreground permet veure la sortida al terminal, útil per a la depuració.ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
: Permet recarregar la configuració del servidor sense interrompre les connexions actives, garantint que els canvis es puguin aplicar de manera controlada.KillSignal=SIGWINCH
: El senyal que s'envia per aturar el servei, assegurant una parada segura.PrivateTmp=true
: Millora la seguretat creant un sistema de fitxers temporal privat per al servei.OOMPolicy=continue
: Defineix el comportament del sistema en cas de manca de memòria, permetent que el servei continuï executant-se.
-
Habiliteu el servei per iniciar cada cop que el sistema arranqui:
systemctl enable httpd
-
Arranqueu i comproveu l'estat del servei:
systemctl start httpd systemctl status httpd
Un cop aixecat el servei, podem comprovar que el servei està en marxa i funcionant correctament. Intenteu accedir al servidor web amb la vostra IP a través d'un navegador web. En el meu cas, la IP del servidor és :127.16.10.206. Recordeu que per veure la IP del vostre servidor podeu utilitzar la comanda ip a
.
Observareu que no és possible accedir-hi i rebeu un missatge d'error ERR_CONNECTION_REFUSED. Això és normal, ja que AlmaLinux té un firewall activat per defecte que bloqueja el tràfic al port 80, que és el port per defecte del servidor web Apache.
systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2022-02-15 21:00:00 UTC; 1h 30min ago
Si desactiveu el servei de firewalld, podreu accedir al servidor web Apache. No obstant això, això no és una pràctica segura, ja que el firewall és una capa de seguretat important per protegir el vostre servidor.
systemctl stop firewalld
En aquest punt, podeu comprovar que el servidor web Apache està funcionant correctament.
Configuració del firewall
El firewall és un servei o programa que protegeix la xarxa del vostre servidor control·lant el tràfic de xarxa que entra i surt del servidor. Això és important per garantir que el vostre servidor sigui segur i protegit contra atacs maliciosos. Permetre només el tràfic necessari i bloquejar el tràfic no desitjat és una pràctica de seguretat recomanada per mantenir el vostre servidor segur. En aquest cas, necessitem permetre el tràfic HTTP (port 80) perquè el servidor web Apache sigui accessible des de l'exterior però bloquejar altres ports i serveis no necessaris.
En tots els sistmes linux el firewall es configura utilitzant les iptables
. En el nostre cas, podem veure les regles amb la comanda iptables -L
. Permetre el tràfic HTTP (port 80) amb les iptables
seria:
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state NEW -m udp -p udp --dport 80 -j ACCEPT
on:
-A INPUT
: Afegeix una regla a la cadena INPUT (paquets que entren al servidor).-m state --state NEW
: Només s'aplica a paquets nous.-m tcp -p tcp
: Només s'aplica a paquets TCP.-M udp -p udp
: Només s'aplica a paquets UDP.--dport 80
: Només s'aplica als paquets que arriben al port 80.-j ACCEPT
: Accepta els paquets que compleixen les condicions anteriors.
Però, tenim eines que ens faciliten la tasca com firewalld
o ufw
. En aquest cas, utilitzarem firewalld
. Firewalld és un firewall dinàmic per a sistemes Linux que proporciona una interfície de línia de comandes i una interfície gràfica per gestionar les regles del firewall. Firewalld té un programa de comandament anomenat firewall-cmd
que us permet gestionar les regles del firewall de manera senzilla i eficaç. Per permetre el tràfic HTTP (port 80) amb firewalld
, podeu utilitzar la comanda següent:
firewall-cmd --add-service=http --permanent
on:
--add-service=http
: Afegeix una regla per permetre el tràfic HTTP.--permanent
: Afegeix la regla de manera permanent, la qual cosa significa que es mantindrà després de reiniciar el sistema.
Per aplicar els canvis, cal recarregar el firewall amb la comanda següent:
firewall-cmd --reload
Amb aquesta configuració, el vostre firewall està configurat per permetre el tràfic HTTP (port 80) al vostre servidor. Per verificar que la configuració del firewall s'ha aplicat correctament i que el servei HTTP està habilitat, podeu utilitzar la següent comanda:
firewall-cmd --list-all
Aquesta comanda mostrarà la sortida amb informació detallada sobre la configuració actual del firewall. Per identificar si el servei HTTP està habilitat, busqueu la secció services i verifiqueu que aparegui el servei http com a un dels serveis habilitats.
La sortida hauria de semblar-se així:
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client http ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
En aquest exemple, podeu veure que el servei HTTP està habilitat, la qual cosa significa que el tràfic HTTP hauria de ser permès a través del firewall. A més a més, podeu veure altres serveis com el servei SSH, el servei DHCPv6-client i el servei Cockpit que també estan habilitats. Aquests serveis són necessaris per a la gestió del servidor i per a la connectivitat de xarxa.
Com deshabilitareu la regla per bloquejar el tràfic?
firewall-cmd --remove-service=http --permanent
firewall-cmd --reload
Instal·lant i configurant MariaDB
Per poder utilitzar el Wordpress necessitem d'una base de dades del tipus MariaDB o MySQL. El primer pas es revisar si el paquet mariadb està disponible amb la versió correcta.
dnf search mariadb
dnf info mariadb
Name : mariadb
Epoch : 3
Version : 10.5.22
Release : 1.el9_2.alma.1
Architecture : aarch64
Size : 18 M
Source : mariadb-10.5.22-1.el9_2.alma.1.src.rpm
Repository : @System
From repo : appstream
Summary : A very fast and robust SQL database server
URL : http://mariadb.org
License : GPLv2 and LGPLv2
Description : MariaDB is a community developed fork from MySQL - a multi-user, multi-threaded
: SQL database server. It is a client/server implementation consisting of
: a server daemon (mariadbd) and many different client programs and libraries.
: The base package contains the standard MariaDB/MySQL client programs and
: utilities.
-
Instal·lem el paquet mariadb:
dnf install mariadb-server mariadb -y
-
Iniciem el servei de MariaDB:
systemctl enable --now mariadb
-
Comprovem l'estat del servei:
systemctl status mariadb
-
Configurem MariaDB:
mysql_secure_installation 1. Enter current password for root (enter for none): 2. Switch to unix_socket authentication [Y/n] n 3. Set root password? Y 4. New password: xxxxxxx 5. Remove anonymous users? Y 6. Disallow root login remotely? Y 7. Remove test database and access to it? Y 8. Reload privilege tables now? Y
on:
- Enter current password for root (enter for none): En aquest punt, si és la primera vegada que configureu MariaDB, premeu simplement Enter, ja que encara no hi ha contrasenya establerta per a l'usuari root.
- Switch to unix_socket authentication [Y/n]: En aquest punt, respongueu n per desactivar l'autenticació de l'usuari root a través de unix_socket. Si respongueu Y, l'autenticació de l'usuari root es farà a través del sistema de fitxers, aquesta opció permet autenticacions avançades que veurem més endavant.
- Set root password? (Y/n): Respongueu Y per indicar que voleu establir una contrasenya per a l'usuari root de MariaDB. A continuació, introduïu la nova contrasenya quan se us demani. (per exemple: 1234).
- Remove anonymous users? (Y/n): Respongueu Y per eliminar els usuaris anònims. Això millora la seguretat del sistema, ja que no permet connexions no autenticades.
- Disallow root login remotely? (Y/n): Respongueu Y per desactivar l'inici de sessió remot per a l'usuari root. Això significa que l'usuari root només podrà iniciar sessió des de la màquina local.
- Remove test database and access to it? (Y/n): Respongueu Y per eliminar la base de dades de proves i l'accés a ella. Això elimina les bases de dades i els usuaris de prova, augmentant encara més la seguretat.
- Reload privilege tables now? (Y/n): Respongueu Y per recarregar les taules de privilegis de MariaDB. Això assegura que els canvis de configuració es facin efectius de seguida.
-
Inicieu sessió a MariaDB:
mysql -u root -p
-
Creeu una base de dades per a Wordpress:
CREATE DATABASE wordpress_db;
-
Creeu un usuari per a la base de dades:
CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'password';
- wordpress_user: Nom de l'usuari de la base de dades.
- password: Contrasenya de l'usuari de la base de dades.
- localhost: Nom de l'amfitrió on es connectarà l'usuari.
En aquest cas, heu de substituir wordpress_user i password pels valors que vulgueu utilitzar.
-
Atorgueu tots els permisos a l'usuari per a la base de dades:
GRANT ALL ON wordpress_db.* TO 'wordpress_user'@'localhost';
- wordpress_db: Nom de la base de dades.
- wordpress_user: Nom de l'usuari de la base de dades.
- localhost: Nom de l'amfitrió on es connectarà l'usuari.
Aquesta comanda atorga tots els permisos de la base de dades wordpress_db a l'usuari wordpress_user.
-
Actualitzeu els permisos:
FLUSH PRIVILEGES;
-
Sortiu de MariaDB:
EXIT;
Aquesta configuració de MariaDB és suficient per a la instal·lació de Wordpress. S'han adaptat els passos de la documentació oficial https://developer.wordpress.org/advanced-administration/before-install/creating-database/.
Instal·lant i configurant PHP
Actualment, la documentació oficial de WordPress recomana utilitzar PHP versió 7.4 o superior per a un funcionament òptim i segur del sistema.
-
Compovem si el paquet php està disponible:
dnf search php
-
Comprovem les versions disponibles de PHP:
dnf module list php
Aquesta comanda mostra una llista de les versions del mòdul PHP disponibles. Et permetrà veure quines versions de PHP pots instal·lar mitjançant mòduls.
-
Instal·lem la versió 8.1 de PHP:
dnf module install php:8.1 -y
L'ús de versions més recents de PHP ofereix molts avantatges, com ara un millor rendiment, més seguretat i noves característiques. Les versions antigues de PHP poden ser més vulnerables a problemes de seguretat i tenir limitacions de rendiment. Per tant, és important seguir les recomanacions de la documentació oficial de WordPress quant a la versió de PHP que has d'utilitzar per a la teva instal·lació.
Un cop instal·lada la versió de PHP, podem comprovar la versió actual amb la comanda
php -v
. I començar a instal·lar els paquets i complements necessaris:dnf install php-curl php-zip php-gd php-soap php-intl php-mysqlnd php-pdo -y
- php-curl: Proporciona suport per a cURL, que és una llibreria per a la transferència de dades amb sintaxi URL.
- php-zip: Proporciona suport per a la manipulació de fitxers ZIP.
- php-gd: Proporciona suport per a la generació i manipulació d'imatges gràfiques.
- php-soap: Proporciona suport per a la creació i consum de serveis web SOAP.
- php-intl: Proporciona suport per a la internacionalització i localització de l'aplicació.
- php-mysqlnd: És l'extensió MySQL nativa per a PHP, que permet la connexió i la comunicació amb bases de dades MySQL o MariaDB.
- php-pdo: Proporciona l'abstracció de dades d'Objectes PHP (PDO) per a la connexió amb bases de dades.
-
Per finalitzar, podem reiniciar el servei web (httpd).
systemctl restart httpd
Instal·lant i configurant Wordpress
Per instal·lar WordPress ens hem de baixar el paquet de la web oficial. Per fer-ho podem utilitzar la comanda wget
per descarregar el paquet de WordPress.
-
Instal·lem el paquet wget:
dnf install wget -y
-
Descarreguem el paquet de WordPress:
Es una bona pràctica utilitzar el directori temporal (/tmp) per descarregar el programari a instal·lar com el Wordpress. L'ús d'aquest directori ens proporciona:
-
Espai de disc temporal: Ubicació on es poden emmagatzemar fitxers sense preocupar-se pel seu ús posterior. És una ubicació amb prou espai de disc disponible, generalment, i sol estar netejada periòdicament pels sistemes operatius per evitar l'acumulació de fitxers temporals innecessaris.
-
Evitar problemes de permisos: El directori temporal (/tmp) sol tenir permisos que permeten a tots els usuaris crear fitxers temporals sense problemes de permisos. Això és important quan estàs treballant amb fitxers que poden ser manipulats per diversos usuaris o processos.
-
Seguretat: Com que el directori temporal és netejat periòdicament, hi ha menys risc de deixar fitxers temporals sensibles o innecessaris al sistema després d'una operació. Això ajuda a prevenir la acumulació de residus i a minimitzar els problemes de seguretat relacionats amb fitxers temporals.
-
Evitar col·lisions de noms de fitxers: Utilitzant el directori temporal, es redueixen les possibilitats de col·lisions de noms de fitxers. En altres paraules, si molts usuaris estan descarregant fitxers a la mateixa ubicació, utilitzar el directori temporal ajuda a garantir que els noms de fitxers siguin únics.
En resum, garanteix l'espai, la seguretat i la gestió adequats per a aquest tipus de fitxers, com és el cas de la descàrrega i descompressió de paquets com WordPress.
cd /tmp wget https://wordpress.org/latest.tar.gz -O wordpress.tar.gz
-
-
Després d'haver descarregat el paquet, el descomprimim amb la comanda
tar
:dnf install tar -y tar -xvf wordpress.tar.gz
-
Copiem els continguts a la carpeta del servidor Apache:
cp -R wordpress /var/www/html/
-
Assignem el ownership al usuari apache:
chown -R apache:apache /var/www/html/wordpress
El servei Apache s'executa amb l'usuari apache i el grup apache per defecte. Per tant, és important assegurar-se que els fitxers i directoris del lloc web tinguin el propietari i el grup correctes perquè el servidor web pugui accedir-hi i gestionar-los correctament. Aquesta informació la podeu trobar al fitxer de configuració del servidor web, normalment a /etc/httpd/conf/httpd.conf.
less /etc/httpd/conf/httpd.conf
-
Donem permisos (rwx) a l'usuari apache i el seu grup i permisos rw per qualsevol altre usuari:
chmod -R 775 /var/www/html/wordpress
Aquesta comanda estableix permisos de lectura, escriptura i execució per a l'usuari apache i el seu grup, i permisos de lectura i escriptura per a qualsevol altre usuari. Això permet que l'usuari apache pugui llegir, escriure i executar els fitxers i directoris del lloc web, mentre que altres usuaris poden llegir i escriure-hi. Aquesta configuració és adequada per a la majoria dels llocs web i proporciona un equilibri entre la seguretat i la facilitat d'ús. No obstant això, si teniu necessitats específiques de seguretat o de permisos, podeu ajustar aquests permisos segons les vostres necessitats. L'argument
-R
indica que els permisos s'aplicaran de manera recursiva a tots els fitxers i directoris dins de la carpeta especificada. -
Reiniciem el servei Apache:
systemctl restart httpd
Instal·lació del Wordpress
Un cop hàgiu completat aquests passos, ja podeu accedir a la instal·lació web de WordPress navegant a http://ip/wordpress/. On ip és la ip del vostre servidor. En el nostre cas, la ip del servidor és 172.16.10.206. Per tant: http://172.16.10.206/wordpress/. O bé podeu utilitzar el nom de domini si teniu un configurat.
El primer pas serà completar un formulari amb la informació de la base de dades que hem creat anteriorment. Aquesta informació és necessària per connectar WordPress a la base de dades i emmagatzemar-hi la informació del lloc web.
- Nom de la base de dades:
wordpress-db
- Nom d'usuari de la base de dades:
wordpress-user
- Contrasenya de la base de dades:
password
- Servidor de la base de dades:
localhost
- Prefix de la taula:
wp_
Un cop hàgiu introduït aquesta informació, podeu continuar amb el procés d'instal·lació de WordPress.
En aquest punt, observareu el missatge d'error Unable to write to wp-config.php file és típic d'un problema de permisos en el sistema de fitxers quan s'intenta escriure un fitxer com el wp-config.php durant la instal·lació de WordPress.
Ara bé, ja hem donat permisos a l'usuari apache perquè pugui escriure a la carpeta de WordPress. El problema resideix en els permisos de SELinux.
SELinux és un sistema de seguretat que proporciona controls addicionals de seguretat basats en polítiques. Impedeix que els processos realitzin certes accions que no estan permeses per la política de seguretat. Ho podem comprovar amb la comanda:
getenforce
Aquesta comanda et mostrarà l'estat actual de SELinux, que pot ser Enforcing, Permissive o Disabled.
Una solució ràpida seria desactivar SELinux amb la comanda:
setenforce 0
No obstant això, és millor entendre com funciona i com gestionar-lo adequadament. Aquesta és la manera més segura de resoldre problemes relacionats amb permisos sense comprometre la seguretat del sistema. Quan es configuren les etiquetes SELinux correctes i es gestionen els permisos de fitxers de manera adequada, SELinux pot oferir una protecció addicional per al vostre sistema.
Mes endavant al curs veurem com configurar SELinux de manera adequada. De moment us deixo la resolució del problema amb SELinux.
-
Instal·lem les eines de SELinux en cas de no tenir-les:
dnf install policycoreutils-python-utils -y
-
Configurem les etiquetes SELinux per a la carpeta de WordPress:
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/wordpress(/.*)?'
on:
-a
: Afegeix una nova regla.-t httpd_sys_rw_content_t
: Estableix l'etiqueta SELinux per als fitxers i directoris de la carpeta de WordPress.'/var/www/html/wordpress(/.*)?'
: Ruta de la carpeta de WordPress.
-
Aplicar les etiquetes SELinux configurades:
restorecon -Rv /var/www/html/wordpress
on:
-R
: Aplica els canvis de manera recursiva a tots els fitxers i directoris dins de la carpeta especificada.-v
: Mostra la sortida detallada de les accions realitzades./var/www/html/wordpress
: Ruta de la carpeta de WordPress.
Amb aquestes accions hem creat una política que permet als processos del servei httpd llegir i escriure a la carpeta de WordPress.
-
Inici de la configuració:
-
Introdueix les dades de la base de dades:
-
Realitza la instal·lació:
-
Configuració del lloc web:
on:
- Site Title: Títol del lloc.
- Username: Nom d'usuari per accedir al panell d'administració.
- Password: Contrasenya per accedir al panell d'administració.
- Your Email: Correu electrònic per a la recuperació de la contrasenya.
Un cop hàgiu introduït aquesta informació, podeu continuar amb el procés d'instal·lació de WordPress. Després d'instal·lar amb èxit WordPress, podreu iniciar la sessió al panell d'administració amb el nom d'usuari i la contrasenya que heu triat i començar a personalitzar i gestionar el vostre lloc web.
-
Inicia sessió amb les credencials creades:
-
Panell d'administració:
-
Visualització del lloc web:
En aquest punt tenim 2 accessos al nostre servidor web. Un és el panell d'administració de WordPress i l'altre és el lloc web en si mateix:
- Panell d'administració: http://ip/wordpress/wp-admin/
- Lloc web: http://ip/wordpress/
On ip és la ip del vostre servidor o el vostre nom de domini si teniu un configurat.
Desplegament al núvol (AWS)
En aquest laboratori desplegarem un servidor web amb Wordpress a Amazon Web Services (AWS). Utilitzarem una instància EC2 amb Amazon Linux 2023 i una base de dades RDS amb MySQL.
Podeu revisar també la guía oficial de Wordpress a AWS.
Configuració de la clau SSH
La clau SSH és un mecanisme de seguretat que permet l'autenticació segura entre dos sistemes. Per a la connexió amb el servidor d'Amazon EC2, utilitzarem una clau SSH per autenticar-nos. Aquesta clau SSH es pot crear amb la utilitat ssh-keygen
que ve amb la majoria de sistemes Linux o podeu fer servir una power shell de Windows.
En aquest mecanisme, el servidor d'Amazon EC2 té la clau pública i el client té la clau privada. Quan el client es connecta al servidor, el servidor comprova si la clau pública del client coincideix amb la clau privada del servidor. Si les claus coincideixen, el client es connecta al servidor. Per tant, la clau privada no s'ha de compartir amb ningú. Mentre que la clau pública es pot compartir amb qualsevol i la podeu fer servir en múltiples servidors. A dia d'avui, no hi ha cap mecanisme per obtenir la claue privada a partir de la clau pública.
Creació de la clau SSH
La comanda ssh-keygen
permet crear una clau SSH. Aquesta comanda té diversos paràmetres que permeten personalitzar la clau SSH. Els paràmetres més comuns són:
-t
: Especifica el tipus de xifratge de la clau. Els tipus més comuns són rsa, dsa, ecdsa i ed25519.-f
: Especifica el nom del fitxer on es guardarà la clau.-b
: Especifica la longitud de la clau en bits.
En el nostre cas crearem una clau SSH amb el tipus de xifratge ed25519
i la guardarem al fitxer ~/.ssh/aws-key
.
ssh-keygen -t ed25519 -f ~/.ssh/aws-key
Enter passphrase (empty for no passphrase):
Ener same passphrase again:
Nota:
Si no voleu posar una contrasenya a la clau, simplement premeu la tecla
Enter
quan us demani la contrasenya.
Aquesta comanda generarà dues claus, una clau privada ~/.ssh/aws-key
i una clau pública ~/.ssh/aws-key.pub
.
Configuració de la clau SSH a Amazon EC2
-
Inicieu sessió al vostre compte d'Amazon Educate, aneu a moduls del Learner Lab. AWS. Fent clic a Start lab i quan el laboratori estigui en marxa, feu clic a la icona verda per obrir la consola d'Amazon AWS.
-
A la consola d'Amazon AWS, cerqueu KEY PAIRS a la barra de recerca i feu clic a Key Pairs relacionades amb el servei EC2.
-
Feu clic a Actions i seleccioneu Import Key Pair.
-
Copieu el contingut de la clau pública
~/.ssh/aws-key.pub
i enganxeu-lo al camp Public key contents. -
Doneu un nom a la clau i feu clic a Import key pair.
-
La clau s'importarà amb èxit i la podreu veure a la llista de claus.
Creació d'una instància EC2
-
Anem a la consola d'Amazon AWS i cerquem EC2 a la barra de recerca.
-
A la consola d'Amazon EC2, fem clic a Launch Instance.
-
Omplim el formulari amb els paràmetres següents:
- Name:
WP-01
- OS:
Amazon Linux 2023 AMI
- Instance Type:
t2.micro
- Key Pair:
AMSA
- Network: Per defecte
- Activeu Allow SSH traffic from anywhere.
- Name:
-
Cliqueu a Launch.
-
Espereu uns minuts fins que la instància estigui en marxa.
-
Un cop en marxa, feu clic al identificador de la instància per veure els detalls.
-
Feu clic a Connect per veure les instruccions per connectar-vos a la instància.
-
Obriu una terminal i connecteu-vos a la instància amb la comanda
ssh -i ~/.ssh/aws-key ec2-user@IP
. -
Si tot ha anat bé, ja esteu connectats a la instància EC2.
-
Un cop connectats, ja podem repetir els passos per instal·lar Apache com vam fer a la màquina local.
sudo dnf install httpd -y sudo systemctl start httpd sudo systemctl enable httpd
-
Obriu un navegador i poseu la IP de la instància EC2. En aquest punt, veureu que no podeu accedir a la pàgina web.
- Si reviseu la màquina virtual, observareu que el firewall està desactivat i per tant, no és el culpable.
- El núvol d'Amazon té un firewall per defecte que bloqueja el tràfic a les instàncies. Aquest firewall es diu Security Group i s'ha de configurar per permetre el tràfic HTTP.
-
Anem a la consola d'Amazon EC2 i als detalls de la instància, fem clic a Security i Security Groups.
-
Feu clic a Edit inbound rules i afegiu una regla nova per permetre el tràfic HTTP.
- Type:
HTTP
- Source:
Anywhere
- Description:
Allow HTTP traffic
- Cliqueu a Save rules.
- Type:
-
Torneu a la pàgina web i refresqueu-la. Ara ja veureu la pàgina web d'Apache.
Nota:
Si feu clic als enllaços igual el navegador cerca https i no http. De moment no tenim configurat el certificat SSL i per tant, no funcionarà. Assegureu-vos de posar http a la barra d'adreces i si teniu https, eliminar la s manualment i refrescar la pàgina.
-
Ara ja podem instal·lar PHP igual que vam fer a la màquina local.
sudo dnf install php8.1 -y sudo dnf install php-curl php-zip php-gd php-soap php-intl php-mysqlnd php-pdo -y sudo systemctl restart httpd
Bases de dades RDS
El servei de bases de dades relacional d'Amazon Web Services (RDS) és una opció molt interessant per a desplegar bases de dades MySQL, MariaDB, PostgreSQL, Oracle, SQL Server i Aurora. Aquest servei ofereix una gestió fàcil i eficient de les bases de dades, així com la possibilitat de fer còpies de seguretat, escalabilitat i alta disponibilitat.
Per utiltizar RDS amb WordPress, seguirem els següents passos:
-
Anem a la consola de Amazon RDS.
-
A la consola de Amazon RDS, fem clic a Create database.
- Seleccionem el mode Standard Create.
- Seleccionem el motor de base de dades MySQL.
- Seleccionem la versió de la base de dades MySQL 8.0.25.
- Seleccionem la plantilla Free tier.
- Nom de la base de dades wordpress.
- Master username admin.
- Seleccioneu auto-generate a password.
La resta de paràmetres els deixarem per defecte.
Recordatori:
Fer clic a Connection details per veure la password generada. Si no ho feu, haureu d'anar a modificar, regenerar la password i aplicar els canvis.
-
Espereu uns minuts fins que la base de dades estigui en marxa.
-
Ara ja podem connectar-nos a la base de dades amb un client MySQL com MySQL Workbench o phpMyAdmin.
- Hostname:
database-1.cik8jidkherq.us-east-1.rds.amazonaws.com
- Port:
3306
- Username:
admin
- Password:
XXXXXXXXXXXXXXX
Nota:
Per simplicitat, instal·larem el client MySQL a la mateixa instància EC2 on tenim instal·lat Apache i PHP.
sudo dnf install mariadb105 -y
- Hostname:
-
Un cop connectats, ja podem crear la base de dades wordpress i l'usuari wordpress amb tots els permisos.
mysql -h database-1.cik8jidkherq.us-east-1.rds.amazonaws.com -u admin -p
Ups! No ens podem connectar a la base de dades. Això és degut a que la base de dades està protegida per un Security Group que no permet connexions des de l'exterior. Per solucionar-ho, hem d'afegir una regla al Security Group de la base de dades per permetre connexions des de la instància EC2.
CREATE DATABASE wordpress; CREATE USER 'wordpress'@'%' IDENTIFIED BY 'wordpress'; GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'%'; FLUSH PRIVILEGES;
AWS S3
Amazon Simple Storage Service (S3) és un servei de magatzematge d'objectes que ofereix escalabilitat, disponibilitat i durabilitat. Aquest servei permet emmagatzemar i recuperar dades a través d'una interfície web.
Per a més informació, consulta la documentació oficial d'Amazon S3.
La capa gratuita d'AWS inclou 5 GB de magatzematge d'objectes, 20.000 sol·licituds GET i 2.000 sol·licituds PUT al mes. Superades aquestes limitacions, es facturaran segons el consum.
Configuració d'una instància EC2 per accedir a S3
Per accedir a S3 des d'una instància EC2, primer cal configurar les credencials d'accés a S3 a la instància. Aquests són els passos a seguir:
-
Executa el següent comandament per configurar les credencials AWS a la instància:
aws configure
Completa els camps amb les teves credencials:
AWS Access Key ID [None]: <ACCESS_KEY> AWS Secret Access Key [None]: <SECRET_KEY> Default region name [None]: us-east-1 Default output format [None]: None
-
Alternativament, pots configurar directament la teva
Access Token
:aws configure set aws_session_token <ACCESS_TOKEN>
Un cop configurades les credencials, la instància EC2 estarà preparada per accedir a S3.
Nota: Per obtenir les credencials d'accés a AWS, heu de visitar AWS Details.
Operacions bàsiques amb S3
-
Copiar un document d'EC2 a S3:
echo "Hello World" > file.txt aws s3 cp file.txt s3://<bucket-name>/file.txt
-
Copiar un document de S3 a EC2:
# Assumeix que `a.txt` ja existeix a S3. dir=/home/ec2-user aws s3 cp s3://<bucket-name>/a.txt $dir/a.txt
-
Crear una carpeta a S3:
aws s3 mb s3://<bucket-name>/folder
-
Eliminar un document de S3:
aws s3 rm s3://<bucket-name>/file.txt
-
Eliminar documents de S3 de manera recursiva:
aws s3 rm s3://<bucket-name>/ --recursive
-
Llistar els documents d'un bucket de S3:
aws s3 ls s3://<bucket-name>
-
Llistar els documents d'un bucket de S3 de forma recursiva:
aws s3 ls s3://<bucket-name> --recursive
-
Sincronitzar un directori local amb un bucket de S3:
aws s3 sync /home/ec2-user s3://<bucket-name>
-
Sincronitzar un bucket de S3 amb un directori local:
aws s3 sync s3://<bucket-name> /home/ec2-user
Per exemple, podem descarregar un notebook de Jupyter a la instància EC2 i pujar-lo a S3 sincronitzant la carpeta local (notebooks) amb el bucket de S3 (jordi-amsa/notebooks):
aws s3 mb s3://jordi-amsa/notebooks
mkdir notebooks
cd notebooks
wget https://github.com/JordiMateoUdL/Model-reusability-on-the-edge/blob/master/notebooks/Generating%20synthethic%20data.ipynb
mv 'Generating synthethic data.ipynb' notebook1.ipynb
aws s3 sync notebooks s3://jordi-amsa/notebooks
Xarxa a AWS
Virtual Private Cloud (VPC)
Una VPC és una xarxa virtual que es pot configurar a AWS. Per defecte, AWS crea una VPC per a cada compte, però també es poden crear noves VPCs. Una VPC es pot configurar amb subxarxes, taules de rutes, grups de seguretat, etc.
En la imatge es mostren 4 VPCs diferents. Cada VPC està aïllada de les altres. Una VPC es crea dins d'una regió específica i pot abastar múltiples zones de disponibilitat dins d'aquesta regió.
A més, en l'arquitectura de la imatge, el tràfic es comparteix entre dues VPCs a la mateixa regió però en diferents zones de disponibilitat. No obstant això, les VPCs de les regions 1 i 2 no poden connectar-se entre elles.
Per crear una VPC, es pot utilitzar la consola de AWS, la interfície de línia de comandes o l'API de AWS.
-
Consola de AWS:
- Anar a la consola de AWS.
- Anar a la secció de VPC.
- Seleccionar "Your VPCs".
- Clicar a "Create VPC".
- Omplir els camps necessaris.
- Clicar a "Create VPC".
-
Interfície de línia de comandes:
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --region us-east-1 --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=amsa-vpc}]"
En aquest exemple, s’utilitza una màscara de xarxa /16, que permet disposar de fins a 65,536 adreces IP. No obstant això, algunes d’aquestes IP seran reservades per AWS per a serveis interns, de manera que el nombre efectiu d’adreces disponibles serà lleugerament inferior.
Per defecte, les VPC no tenen connexió a Internet. Per proporcionar accés, es poden configurar una Internet Gateway (IGW) per connectar la VPC a Internet o una Virtual Private Gateway (VGW) per connectar-la a una xarxa privada, com una VPN. Aquestes passarel·les permeten establir la connectivitat necessària segons les necessitats de l'entorn de xarxa.
Subxarxes
Les subxarxes són una part d'una VPC. Una VPC pot tenir múltiples subxarxes. Cada subxarxa es pot configurar amb una zona de disponibilitat específica. Això permet distribuir les càrregues de treball en diferents zones de disponibilitat. Un exemple útil de subxarxes és la creació de subxarxes públiques i privades en funció de les necessitats de seguretat i operacionals.
En la imatge es mostra una VPC amb un bloc CIDR de 10.0.0.0/24 que suporta 256 adreces IP. Aquest bloc CIDR es pot dividir en dues subxarxes, cadascuna amb 128 adreces IP. Una subxarxa utilitza el bloc CIDR 10.0.0.0/25 (per a les adreces 10.0.0.0 - 10.0.0.127) i l'altra utilitza el bloc CIDR 10.0.0.128/25 (per a les adreces 10.0.0.128 - 10.0.0.255).
Per crear una subxarxa, es pot utilitzar la consola de AWS, la interfície de línia de comandes o l'API de AWS.
-
Consola de AWS:
- Anar a la consola de AWS.
- Anar a la secció de VPC.
- Seleccionar "Subnets".
- Clicar a "Create subnet".
- Omplir els camps necessaris.
- Clicar a "Create subnet".
-
Interfície de línia de comandes:
aws ec2 create-subnet --vpc-id <vpc-id> --cidr-block 10.0.1.0/24 --availability-zone us-east-1a # Per exemple: # aws ec2 create-subnet --vpc-id vpc-013ece49204bdf533 --cidr-block 10.0.1.0/24 --availability-zone us-east-1a
Desplegant una EC2 a una VPC
En aquesta activitat, es desplegarà una VPC amb dues subxarxes, una pública i una privada. A més, es configurarà una Internet Gateway per connectar la VPC a Internet.
En aquesta figura, es mostra una VPC amb dues subxarxes, una pública i una privada. La subxarxa pública té una connexió a Internet a través d'una Internet Gateway. La subxarxa privada no té connexió a Internet. Per defecte, les VPC no tenen connexió a Internet. Per proporcionar accés, es poden configurar una Internet Gateway (IGW) i una taula de rutes per connectar la VPC a Internet.
Per desplegar aquesta arquitectura, es pot utilitzar CloudFormation. A continuació, es mostra un exemple de plantilla de CloudFormation per desplegar aquesta arquitectura.
-
Creació del Internet Gateway (IGW):
- Anar a VPC > Internet Gateways.
- Clicar a "Create internet gateway".
- Omplir els camps necessaris (AMSA-IGW).
- Attach el AMSA-IGW a AMSA-VPC.
-
Crear l'enrutador de la taula de rutes:
- Anar a VPC > Route Tables.
- Clicar a "Create route table".
- Nom: AMSA-PublicNet-RT-TO-Internet.
- VPC: AMSA-VPC.
- Clicar a "Edit routes".
- Afegir una nova ruta:
- Destination: 0.0.0.0/0.
- Target: AMSA-IGW.
Cadascuna de les subxarxes de la VPC es pot associar a una taula de rutes. Una subxarxa es pot associar explícitament a una taula de rutes personalitzada o implícitament a la taula de rutes principal.
-
Una associació explícita implica que una subxarxa està associada a una taula de rutes personalitzada. En l'exemple, la subxarxa pública està associada a la taula de rutes personalitzada AMSA-PublicNet-RT-TO-Internet, que redirigeix tot el tràfic a l'Internet Gateway. Aquesta associació explícita fa que la subxarxa sigui una subxarxa pública.
-
Una associació implícita implica que la subxarxa està associada a la taula de rutes principal. En l'exemple, la subxarxa privada està associada a la taula de rutes principal, que redirigeix tot el tràfic al Virtual Private Gateway. No obstant això, no té una ruta a l'Internet Gateway, fent que la subxarxa sigui una subxarxa només per a VPN.
La diferència clau entre les associacions explícites i implícites rau en la taula de rutes implicada. La taula de rutes principal està associada implícitament a totes les subxarxes de la VPC, mentre que les taules de rutes personalitzades estan associades explícitament a subxarxes específiques.
La imatge mostra una arquitectura de xarxa dins d’una VPC, amb una configuració que inclou subxarxes, taules de rutes, gateways per connectar un entorn privat a Internet i a un centre de dades mitjançant una VPN.
-
Subxarxa pública: En aquesta subxarxa és on es troben les instàncies EC2 accessibles des d’Internet. Té una associació explícita amb una taula de rutes (Route Table A) que inclou una ruta cap a l'Internet Gateway, permetent a les instàncies connectar-se a Internet. Està associada amb el Security Group A, que defineix les polítiques de seguretat per a les instàncies en aquesta subxarxa.
-
Subxarxa privada: En aquesta subxarxa és per a recursos que necessiten seguretat addicional i que no haurien de ser accessibles directament des d'Internet. Té una associació implícita amb una taula de rutes (Route Table B), que no inclou una ruta cap a l'Internet Gateway, de manera que les instàncies no poden accedir a Internet directament. Està associada amb el Security Group B, que gestiona les regles de seguretat d'aquest entorn privat.
Per tant, la taula de rutes A permet a les instàncies de la subxarxa pública accedir a Internet a través de l'Internet Gateway, mentre que la taula de rutes B permet a les instàncies de la subxarxa privada comunicar-se amb el centre de dades corporatiu a través de la VPN Gateway.
Nota: La VPN Connection és el túnel que connecta la VPN Gateway de la VPC amb el Customer Gateway situat al centre de dades corporatiu. El Customer Gateway és un dispositiu de xarxa (pot ser un router o un firewall) situat a les instal·lacions del client, que gestiona el trànsit cap a la VPC. Aquesta configuració permet als recursos de la subxarxa privada accedir al centre de dades corporatiu i viceversa, de manera segura, sense exposar aquests recursos a Internet.
Desplegant Wordpress a una VPC Privada
-
Creació de la VPC i les Subxarxes
- Crea una VPC amb un rang d'adreces IP, per exemple, 10.0.0.0/16.
- Configura dues subxarxes públiques per a les instàncies de l'aplicació a diferents zones de disponibilitat (AZ).
- Subxarxa 1 (pública) en AZ 1 amb rang d'IP 10.0.1.0/24 (us-east-1a).
- Subxarxa 2 (pública) en AZ 2 amb rang d'IP 10.0.2.0/24 (us-east-1b).
- Configura una subxarxa privada per a la base de dades en una zona de disponibilitat específica. (us-east-1c).
-
Configuració de la Taula de Rutes
- Crea una Internet Gateway i associa-la amb la VPC.
- Configura una taula de rutes per a les subxarxes públiques (HDCB-APPS-R1 i HDCB-APPS-R2).
- Configura una taula de rutes separada per la subxarxa privada (HDCB-DATA-R). Aquesta taula no tindrà rutes a Internet. Només tindrà rutes per accedir internament als recursos de la VPC.
-
Configuració del Balancer de Càrrega (Load Balancer)
- Crea un Application Load Balancer (ALB) i selecciona les dues subxarxes públiques.
- Configura el balançador perquè escolti al port 80 per HTTP.
- Crea un grup objectiu (Target Group) per a les instàncies de l'aplicació.
- Defineix L'objectiu com a Instances i el protocol com a HTTP al port 80.
- Assigna les instàncies que crearem a continuació al grup objectiu perquè el balançador distribueixi el tràfic entre elles.
-
Crea Instàncies EC2 per a Wordpress una a cada instància.