2. Inicio y Apagado del Sistema
En la arquitectura x86, la BIOS contiene todo el código requerido para obtener acceso inicial al teclado, pantalla, unidades de disco, de comunicaciones en serie y un número de funciones variadas. Una vez que el sistema completo está en marcha, la mayoría de estos dispositivos habrán mejorado sus capacidades cuando los controladores de dispositivos especializados y completos se cargan y asumen el control.
La BIOS se coloca típicamente en un chip ROM que viene con el equipo (el que a menudo se llama BIOS ROM). Esto asegura que la BIOS estará siempre disponible y no será dañada por fallas en el disco. Esto también hace que sea posible que un equipo arranque.
Durante el proceso de arranque, la BIOS carga el gestor de arranque desde el MBR.
Existen diferentes gestores de arranque utilizados en Linux, incluyendo:
- GRUB
- LILO
- efilinux
- Das U-Boot.
Prácticamente todas las distribuciones modernas de Linux (no-embebidas) usan GRUB (GRand Unified Boot Loader). Las características de GRUB incluyen la capacidad de arrancar varios sistemas operativos, tanto en una interfaz gráfica y en otra basada en texto que permite ser usado a través de un cable serial, una potente interfaz de línea de comandos para la configuración interactiva, iniciando desde la red sin disco de arranque y otras características avanzadas.
El cargador de Linux (LILO) es viejo y obsoleto.
efilinux es un gestor de arranque alternativo diseñado específicamente para el mecanismo de UEFI.
Das U-Boot es el cargador más popular para sistemas Linux embebidos; hay algunos otros, entre ellos bareboot. Sin embargo, en realidad no estamos considerando el espacio embebido en este curso.
Más adelante vamos a discutir acerca de donde las distribuciones de Linux cooperan para colocar ciertos tipos de archivos en lugares estándar en el sistema. En particular, los archivos de configuración de todo el sistema se colocan generalmente en /etc y sus subdirectorios, mientras que los específicos del usuario se colocan a menudo en sus directorios personales.
Las distribuciones desarrollaron sus propias reglas sobre exactamente dónde colocar información en /etc. Por ejemplo, todos los sistemas derivados de Red Hat hacen uso extensivo de /etc/sysconfig, mientras que los sistemas basados en Debian han utilizado /etc/default. Curiosamente, RHEL 7 y SUSE usan ambos.
En un sistema RHEL 6:
$ ls -F /etc/sysconfig
atd grub modules samba
auditd htcacheclean netconsole sandbox
authconfig httpd network saslauthd
autofs i18n networking selinux
cbq init network-scripts sendmail
cgconfig ip6tables-config nfs smartmontools
cgred.conf ip6tables-config.rpmnew ntpd snmpd
clock iptables-config ntpdate snmptrapd
collectl iptables-config.rpmnew pluto sshd
console irqbalance prelink sysstat
cpuspeed kdump quota_nld sysstat.ioconf
crond kernel radvd system-config-firewall
dhcpd keyboard raid-check system-config-users
dhcpd6 ksm readahead udev
dhcrelay libvirtd readonly-root vncservers
dhcrelay6 libvirt-guests rhn wpa_supplicant
ebtables-config lm_sensors rngd xinetd
firstboot mcelogd rsyslog
Para ver el contenido de un archivo:
$ cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=quad64
GATEWAY=192.168.1.1
lo cual configura algunas variables ambientales usadas por varios scripts de inicio.
Los archivos en este directorio son usados a menudo por el script que controla el servicio asociado en /etc/init.d; por ejemplo, el script /etc/init.d/network incluye la línea con el siguiente archivo:
. /etc/sysconfig/network
el que define estas variables cuando la red se inicia.
En un sistema Ubuntu 14.04:
$ ls -F /etc/default
acpid console-setup grub.ucf-dist locale rsyslog
acpi-support crda halt nfs-common saned
alsa cron im-config nss speech-dispatcher
anacron cups irqbalance ntfs-3g sysstat
apport dbus kdump-tools ntpdate ufw
avahi-daemon devpts kerneloops pulseaudio useradd
bridge-utils grub kexec qemu-kvm whoopsie
brltty grub~ keyboard rcS
bsdmainutils grub.d/ libvirt-bin rsync
El uso de este directorio es similar al /etc/sysconfig de Red Hat:
- Los archivos son utilizados para proveer opciones adicionales al iniciar un servicio.
- Normalmente contienen código para configurar variables de entorno.
Por ejemplo, el archivo /etc/default/useradd establece los valores predeterminados que se utilizan cuando se crean nuevas cuentas de usuario.
shutdown se utiliza para apagar el sistema de forma segura, notificando a todos los usuarios que el sistema va a apagarse y luego lo detiene de manera elegante y no destructiva. Después de que está apagado, el sistema es detenido o reiniciado.
Sin opciones (por ejemplo, shutdown now) el comportamiento por defecto es apagar por completo el sistema. Algunas distribuciones, como Ubuntu, violan esto y van a modo monosuario en vez de apagarse.
Un error común es no especificar un argumento de tiempo (tal como now o algún tiempo real). Esto es requerido.
También existen los comandos heredados reboot, halt y poweroff, los que muchos usuarios veteranos utilizan con frecuencia.
$ sudo shutdown -h +1 "Power Failure imminent"
$ sudo shutdown -h now
$ sudo shutdown -r now
$ sudo shutdown now
Las opciones pueden ser listadas fácilmente por el mensaje de ayuda:
$ shutdown --help
shutdown [OPTIONS...] [TIME] [WALL...]
Shut down the system.
--help Show this help
-H --halt Halt the machine
-P --poweroff Power-off the machine
-r --reboot Reboot the machine
-h Equivalent to --poweroff, overridden by --halt
-k Don't halt/power-off/reboot, just send warnings
--no-wall Don't send wall message before halt/power-off/reboot
-c Cancel a pending shutdown
Organice los pasos básicos de la secuencia de inicio en el orden correcto.
El cargador de arranque es ejecutado.
El kernel Linux y la imagen initrd o initramfs son cargadas en memoria y el núcleo se ejecuta.
El proceso init se inicia.
Módulos adicionales del kernel (incluyendo controladores de dispositivo) se cargan y se inician los servicios del sistema.
Usted debería ser capaz de:
- Explicar el proceso de arranque.
- Identificar varios tipos de cargadores de arranque.
- Describir qué hace la BIOS.
- Identificar los archivos de configuración correspondientes.
- Describir cómo el sistema se apaga y reinicia.
3. GRUB
Un sistema que no puede iniciar es bastante inútil. Los sistemas Linux tienen mucha flexibilidad en la forma de arrancar. Es posible elegir versiones diferentes del kernel u opciones, o incluso diferentes sistemas operativos en escenarios de inicio múltiple. La mayoría de los sistemas no embebidos utiliza el Grand Unified Boot Loader para realizar los primeros pasos de una inicialización exitosa del sistema. GRUB también tiene capacidades interactivas, así como una utilidad de contraseñas seguras.
Al final de este capítulo usted debería ser capaz de:
- Explicar cuál es el rol de GRUB.
- Comprender las diferencias entre las versiones GRUB 1 y GRUB 2.
- Estar familiarizado con las selecciones interactivas que se pueden realizar en el arranque.
- Saber cómo instalar GRUB.
- Explicar cómo se usan y modifican los archivos de configuración que GRUB necesita.
Para cualquier versión, el archivo de configuración principal contiene algunos parámetros globales y luego una sección para cada sistema operativo o núcleo configurado.
Prácticamente todos sistemas basados en x86 de Linux (dejando de lado la esfera de los sistemas embebidos) usan GRUB actualmente (GRand Unified Bootloader) para manejar las primeras fases de arranque del sistema. Otras plataformas pueden tener otros equivalentes, como ELILO, utilizado en sistemas EFI como IA64 (Itanium) y Das U-BOOT utilizado en muchas configuraciones de sistemas embebidos.
Algunas características importantes de GRUB son:
- Sistemas operativos alternativos pueden ser elegidos en el momento del arranque.
- Los kernels alternativos o ramdisk inicial pueden ser elegidos durante el arranque para un determinado sistema operativo.
- Los parámetros de arranque pueden cambiarse fácilmente al arrancar sin tener que editar archivos de configuración, etc. de antemano.
Las distribuciones de Linux más antiguas (por ejemplo, RHEL 6) usan versiones antiguas de GRUB, 1.0 o menor, mientras que las más recientes se basan en GRUB 2. Mientras que los detalles son diferentes entre las versiones, la filosofía básica es la misma.
El archivo de configuración básico de arranque se llama:
/boot/grub/grub.cfg o /boot/grub2/grub.cfg
Este archivo es autogenerado por update-grub (o grub2-mkconfig en RHEL 7), basado en los archivos de configuración en el directorio /etc/grub.d y en /etc/default/grub, y nunca deberían ser editados a mano. Normalmente esas herramientas son ejecutadas desde otros scripts provistos por cada distribución, usados para actualizar o compilar kernels Linux.
El archivo de configuración básico de arranque se llama:
/boot/grub/grub.conf o /boot/grub/menu.lst.
Nuevamente, recomendamos no editar a mano el archivo de configuración. Por ejemplo, en RHEL 5-7 se modifica desde la herramienta grubby. Sin embargo, si usted realiza cambios, serán mantenidos, mientras que para GRUB 2 cualquier cambio directo en grub.cfg se pierde tan pronto como el archivo se genera nuevamente.
Al arranque del sistema, después de las etapas iniciales del POST y BIOS, GRUB se ejecutará y mostrará un menú.
Este puede o no tener gráficos en él (al menos para el fondo de pantalla de splash). El menú contiene una lista de imágenes de arranque de uno o más sistemas operativos o distribuciones de Linux. En GRUB 2 (o, si usas 'chainloading' para conectar múltiples instalaciones de GRUB en el mismo disco, un tema complicado que no trataremos aquí) también pueden haber submenús con aún más opciones.
Usando las flechas arriba y abajo y la tecla Enter, usted puede seleccionar la opción de arranque correcta, o puede esperar durante un periodo de tiempo configurable antes de entrar en la opción predeterminada.
Sin embargo, es posible hacer mucho más. Después de seleccionar una entrada, puede escribir e para editar y luego entrar en una shell interactiva. En esta shell, puede modificar la sección en el archivo de configuración que describe esa opción de arranque particular. Por lo general, esto se hace para modificar la línea de comandos del kernel; por ejemplo, agregando la palabra single al final de la línea de comando hará que el sistema arranque en el modo monousuario con el fin de tomar acciones correctivas. Una vez que el cambio deseado se ha realizado, usted puede presionar la tecla adecuada para iniciar el sistema.
En la parte inferior de la pantalla verá que aparece información sobre las combinaciones de teclas exactas, así que no es necesario memorizarlas.
Tenga en cuenta que cualquier cambio que realice en la configuración no es persistente y se perderá en el próximo inicio. Para realizar cambios permanentes, es necesario modificar los archivos en el sistema, usando las utilidades adecuadas.
También es posible introducir una shell pura, en lugar de editar una sección en particular. Puede ejecutar una serie de comandos diferentes e incluso tratar de reinstalar o reparar GRUB. Si hay problemas serios, como no encontrar un archivo de configuración, GRUB vuelve al modo de línea de comandos y usted podría rescatar el sistema sin tener que recurrir a los medios físicos (DVDs).
La palabra instalación puede tener significados diversos en relación a GRUB:
- Instalar el programa grub y sus herramientas asociadas en sus lugares respectivos. En GRUB 1 hay un solo programa llamado grub, pero en GRUB 2 hay un montón de utilidades con nombres como grub2-* o grub-*; el cómo están empaquetados depende bastante de la distribución.
- Instalar los archivos que GRUB necesita para operar en el momento de arranque, ya sea en /boot/grub o /boot/grub2. Esto es independiente de los archivos que el kernel Linux necesita (vmlinuz-*, initramfs_*), los cuales deberán estar en el directorio /boot también.
- Instalar GRUB como el gestor de arranque en el sistema; generalmente esto se hace en el comienzo de todo el disco duro, pero también puede ser realizado en una partición y acceder a él través de 'chainloading', es decir de un GRUB a otro.
Si no instala GRUB durante la instalación o si necesita volver a instalarlo en algún momento más adelante, el procedimiento exacto para hacerlo depende de la versión de GRUB.
Para la Versión 2, el procedimiento de instalación es tan simple como:
$ sudo grub2-install /dev/sda
Por favor lea la página del manual con cuidado antes de ejecutar un comando como ese; hay muchas opciones y hacer algo mal en GRUB puede hacer que el sistema no arranque. En particular tendrá que indicarle al sistema donde encontrar el directorio /boot y en qué partición reside.
En la versión 1 la herramienta pertinente es grub-install. También es posible ejecutar grub en la línea de comandos, para luego entrar a un programa interactivo. Por ejemplo:
$ sudo grub
> root (hd0,0)
> setup (hd0)
> exit
lo cual debería instalar grub en el primer disco y los archivos de arranque en la primera partición.
En ambas versiones de GRUB, el primer y segundo disco duro es denominado como hd0, el segundo como hd1, etc. Sin embargo, en la versión 1 las particiones comienzan contando desde 0 y en la versión 2 desde 1:
- sda1 es (hd0,1) en GRUB 2, pero (hd0,0) en GRUB 1.
- sdc4 es (hd2,4) en GRUB 2, pero (hd2,3) en GRUB 1.
No hay necesidad de enfatizar que confundirse acerca de esto puede ser muy destructivo. Ambas versiones de GRUB a veces usan la notación de sda# y a veces usan (hd0,#), así que puede ser aún más confuso.
Dentro del archivo de configuración, cada sección tiene que especificar cuál es la partición raíz; esto no es lo mismo que lo que queremos decir cuando hablamos del directorio raíz del sistema. En este contexto significa la partición que contiene el kernel (en el directorio /boot). Por ejemplo, es muy común tener /boot en su partición propia, digamos /dev/sda1. Luego, en GRUB 1 podrá encontrar una sección simple como la siguiente:
title 3.17.3
root (hd0,0)
kernel vmlinuz-3.17.3 ro root=/dev/sda2 quiet
initrd initramfs-3.17.3.img
Sin embargo, si /boot no tiene su propia partición, se vería como lo siguiente:
title 3.17.3
root (hd0,0)
kernel /boot/vmlinuz-3.17.3 ro root=/dev/sda1 quiet
initrd /boot/initramfs-3.17.3.img
También es posible especificar kernel (hd0,0)/vmlinuz .... , y dejar de lado la línea root.
En GRUB 2 la sintaxis es diferente pero obvia; una mirada rápida a /boot/grub2/grub.cfg lo dejará claro.
Nos vamos a concentrar en GRUB 2 porque las versiones anteriores se están volviendo obsoletas rápidamente. Además es esencialmente el mismo en las diversas distribuciones de Linux.
Recuerde que no debería editar grub.cfg directamente. Hay dos lugares en el directorio /etc que deberían requerir atención y se utilizan para reconstruir grub.cfg cuando el sistema se ve alterado con la instalación de kernel nuevos, o cuando se ejecuta de forma manual un programa de actualización (como update-grub).
El primero es /etc/default/grub. En un sistema RHEL 7 luce de la siguiente forma:
$ cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16 rhgb quiet" GRUB_DISABLE_RECOVERY="true"
Red Hat ha abreviado bastante este archivo en comparación con otras distribuciones. Por ejemplo, en un sistema Ubuntu 14.4 se ve de la siguiente forma:
$ cat /etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
#GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR='lsb_release -i -s 2> /dev/null || echo Debian'
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US"
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command 'vbeinfo'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
El otro directorio que importa es /etc/grub.d:
$ ls -l /etc/grub.d
total 76
-rwxr-xr-x 1 root root 9424 Sep 8 17:35 00_header
-rwxr-xr-x 1 root root 6058 Sep 8 17:35 05_debian_theme
-rwxr-xr-x 1 root root 11608 Sep 8 17:35 10_linux
-rwxr-xr-x 1 root root 10412 Sep 8 17:35 20_linux_xen
-rwxr-xr-x 1 root root 1992 Sep 8 17:35 20_linux_xen
-rwxr-xr-x 1 root root 11692 Sep 8 17:35 30_os-prober
-rwxr-xr-x 1 root root 1416 Sep 8 17:35 30_uefi-firmware
-rwxr-xr-x 1 root root 214 Sep 8 17:35 40_custom
-rwxr-xr-x 1 root root 216 Sep 8 17:35 41_custom
-rw-r--r-- 1 root root 483 Sep 8 17:35 README
donde una vez más estamos mostrando Ubuntu 14.04. Cada uno de estos archivos se ejecutan en orden ascendente cuando se actualiza el archivo de configuración. No los discutiremos aquí debido a que están bien autodocumentados y recomendamos que les eche un vistazo.
Para GRUB 1 cada distribución puede tener algunas peculiaridades, pero básicamente se edita grub.conf directamente o a través de un script como grubby.
¿Cuáles de las siguientes afirmaciones son ciertas?
- Un cargador de arranque como GRUB es necesario para Linux solamente. Otros sistemas operativos, particularmente los propietarios, no necesitan un cargador de arranque para iniciarse.
- GRUB es capaz de iniciar múltiples sistemas operativos como Linux, FreeBSD y Microsoft Windows.
- No es posible utilizar GRUB en modo interactivo cuando el sistema inicia.
- Según cómo está configurado el gestor de arranque puede tener un impacto importante en la seguridad del sistema.
- GRUB puede soportar solamente una configuración para cada sistema operativo. Por lo tanto, no es posible utilizarlo para seleccionar entre los diferentes kernels, opciones del kernel o sistemas de archivos raíz para una sola instalación de Linux.
- El archivo de configuración principal de GRUB 2, grub.cfg, debe ser editado directamente.
Usted debería ser capaz de:
- Explicar cuál es el rol de GRUB.
- Comprender las diferencias entre GRUB 1 y GRUB 2.
- Estar familiarizado con las selecciones interactivas que puede hacer en el arranque.
- Saber cómo instalar GRUB.
- Explicar cómo se usan y modifican los archivos de configuración que GRUB necesita.
4. init: SystemV, Upstart, Systemd
Cuando un sistema Linux se inicia, muchas tareas deben llevarse a cabo de manera cooperativa. Los dispositivos tienen que ser reconocidos e inicializados, los servicios del sistema tienen que ser lanzados, los sistemas de archivos tienen que estar disponibles, procesos de gestión importantes tienen que iniciarse y el sistema debe estar disponible a los usuarios para iniciar sesión. Todo esto debe hacerse en la secuencia correcta y lo más rápidamente posible.
Al final de este capítulo usted debería estar capacitado para:
- Entender la importancia del proceso init.
- Explicar cómo funciona el método tradicional de SysVinit, cómo incorpora los niveles de ejecución y qué sucede en cada uno.
- Saber usar chkconfig y service (y utilidades alternativas) para iniciar y detener servicios o hacerlos persistentes luego del reinicio del sistema.
- Entender por qué surgieron los métodos alternativos Upstart y systemd y cómo funcionan.
- Usar systemctl para configurar y controlar systemd.
/sbin/init (normalmente llamado init) es el primer proceso (o tarea) a nivel de usuario que se ejecuta en el sistema y continúa funcionando hasta que el sistema se apaga. Tradicionalmente ha sido considerado el padre de todos los procesos del usuario, aunque técnicamente eso no es cierto ya que algunos procesos son iniciados directamente por el kernel.
init coordina las etapas posteriores del proceso de arranque, configura todos los aspectos del ambiente e inicia los procesos necesarios para entrar/autenticarse en el sistema. init también trabaja estrechamente con el kernel para limpiar lo necesario a medida en que los procesos terminan.
Tradicionalmente casi todas las distribuciones basan el proceso init en el venerable SysVinit de UNIX. Sin embargo, este esquema fue desarrollado décadas atrás en circunstancias muy diferentes:
- El objetivo eran sistemas multiusuario de tipo mainframe (y no ordenadores personales, portátiles y otros dispositivos).
- El objetivo era un sistema de procesador único.
- El tiempo de inicio (y apagado) no era un asunto importante; era mucho más importante hacer que las cosas funcionaran bien.
El inicio fue visto como un proceso serial, dividido en una serie de etapas secuenciales. Cada etapa requería ser finalizada antes de que la próxima pudiera iniciar. Por lo tanto, el arranque no aprovechó el procesamiento en paralelo que podría hacerse en múltiples procesadores.
En segundo lugar, el apagado/reinicio fue visto como un acontecimiento relativamente raro y exactamente cuánto demoraban no era considerado importante.
Para lidiar con estas limitaciones intrínsecas en SysVinit, se han desarrollado nuevos métodos para controlar el arranque del sistema. Si bien es cierto que existen otros, dos esquemas principales fueron adoptados por distribuidores Empresariales:
- Upstart fue desarrollado por Ubuntu y fue incluido por primera vez en el lanzamiento de la versión 6.10 en el 2006 y pasó a ser utilizado por defecto en el lanzamiento de la versión 9.10, el 2009. También fue adoptado en Fedora 9 (en el 2008) y en RHEL 6 y sus clones, tales como CentOS, Scientific Linux y Oracle Linux. En openSUSE fue ofrecido como una opción desde la versión 11.3. También se ha utilizado en varios dispositivos embebidos y móviles.
- systemd es más reciente y Fedora fue la primera distribución de las principales en adoptarlo en el 2011.
RHEL 7 se basa en systemd y cada distribución principal de Linux lo ha adoptado y usado por defecto, o ha anunciado planes para hacerlo. Los desarrolladores principales de systemd están estrechamente vinculados a la comunidad del kernel de Linux. Incluso Ubuntu ha programado el retiro de Upstart en su favor.
La migración a los nuevos esquemas puede ser complicada debido a que los errores de software y funciones faltantes pueden ser muy incapacitantes, de hecho han habido capas que requieren compatibilidad esencial. Por lo tanto, los métodos y utilidades SysVinit persistirán por mucho tiempo aunque bajo el capó, las cosas son muy diferentes.
La historia de las controversias y todo eso es muy complicado, y personalidades interesantes han asegurado no que toda la discusión es de carácter técnico. En nuestro contexto no veremos a través de esta lente.
En adelante vamos a concentrarnos en SysVinit y systemd con una breve sección sobre Upstart (aunque RHEL 6 y algunas otras distribuciones han estado usando Upstart, éste ha sido completamente oculto detrás de una capa de compatibilidad usando las utilidades SysVinit normales).
Un sistema SysVinit inicia a través de una secuencia de 'runlevels' (niveles de ejecución) que definen diferentes estados del sistema; están numerados del 0 al 6.
El runlevel 0 está reservado para el apagado del sistema, runlevel 1 para el modo monousuario y runlevel 6 para reiniciar el sistema. Los otros runlevels se usan para definir qué servicios están ejecutándose en un sistema normal; según el caso, las distribuciones definen algo de forma diferente. Por ejemplo, en sistemas basados en Red Hat, runlevel 2 se define como un sistema en funcionamiento sin red o X, runlevel 3 incluye soporte de red, y runlevel 5 incluye red y X.
Runlevel | Significado |
---|---|
S,s | Lo mismo que 1 |
0 | Apagado del sistema |
1 | Modo monousuario |
2 | Modo multiusuario, sin NFS, login de texto solamente |
3 | Modo multiusuario, con NFS y red, login de texto solamente |
4 | No usado |
5 | Modo multiusuario, con NFS y red, login gráfico con X |
6 | Reinicio |
El runlevel actual pueden ser desplegado simplemente con el comando runlevel, como se muestra aquí:
$ runlevel
N 5
donde el primer caracter es el nivel previo; N significa desconocido.
telinit puede ser usado para cambiar el nivel de ejecución del sistema. Por ejemplo, para ir desde runlevel 3 a runlevel 5, ejecute lo siguiente:
$ sudo /sbin/telinit 5
Cuando el proceso init es iniciado, lo primero que hace es leer /etc/inittab. Históricamente, este archivo ha instruido a init acerca de los scripts que debe ejecutar para llevar al sistema a cada runlevel. Y se ha hecho con una serie de líneas, una para cada runlevel:
id:runlevel(s):action:process
donde:
- id: un identificador único de 1 a 4 caracteres para la entrada.
- runlevel(s): cero o más caracteres individuales o identificadores de dígitos, el que indica en qué nivel de ejecución se realizará la acción.
- action: describe la acción a ser realizada.
- process: especifica el proceso a ser ejecutado.
Sin embargo, en sistemas más recientes como RHEL 6 que enmascaran upstart detrás de una capa de compatibilidad, la única línea descomentada y lo único que se encuentra en este archivo es el runlevel predeterminado con la línea:
id:5:initdefault
Este es el runlevel al cual llegará el sistema una vez que haya terminado de iniciar. Sin embargo, si se especifica otro valor en la línea de comandos del núcleo, init ignora el valor por defecto (esto se hace añadiendo el dígito entero a la línea de comandos del núcleo). El runlevel por defecto es generalmente 5 para un sistema completo, lo cual considera soporte multiusuario, sistema gráfico en red o 3 para un servidor sin una interfaz gráfica.
El método tradicional es que primero se ejecute el script rc.sysinit, el cual realiza numerosas funciones, como iniciar LVM, montar sistemas de archivos, etc. Este script reside en el directorio /etc, pero probablemente lo encontrará en /etc/rc.d con un enlace simbólico a /etc.
A continuación, se ejecuta el script rc (en el mismo directorio) con el runlevel deseado como argumento. Esto hace que el sistema vaya al directorio rc.d/rc[0-6].d y ejecute todos los scripts que están ahí:
$ ls -lF /etc/rc.d/rc5.d
total 0
lrwxrwxrwx. 1 root root 14 Sep 3 10:05 K05pmcd -> ../init.d/pmcd*
lrwxrwxrwx. 1 root root 14 Sep 3 10:05 K05pmie -> ../init.d/pmie*
lrwxrwxrwx. 1 root root 18 Sep 3 10:05 K05pmlogger -> ../init.d/pmlogger*
lrwxrwxrwx. 1 root root 15 Sep 3 10:05 K05pmmgr -> ../init.d/pmmgr*
lrwxrwxrwx. 1 root root 17 Sep 3 10:05 K05pmproxy -> ../init.d/pmproxy*
lrwxrwxrwx. 1 root root 16 Sep 3 10:05 K05pmwebd -> ../init.d/pmwebd*
lrwxrwxrwx 1 root root 37 Sep 6 08:50 K08vmware-USBArbitrator -> /etc/rc.d/init.d/vmware-USBArbitrator*
lrwxrwxrwx. 1 root root 20 Sep 3 03:57 K50netconsole -> ../init.d/netconsole*
lrwxrwxrwx. 1 root root 17 Sep 3 09:39 S10network -> ../init.d/network*
lrwxrwxrwx 1 root root 16 Sep 6 08:50 S19vmware -> ../init.d/vmware*
lrwxrwxrwx. 1 root root 17 Sep 3 04:04 S20iprinit -> ../init.d/iprinit*
lrwxrwxrwx. 1 root root 19 Sep 3 04:04 S20iprupdate -> ../init.d/iprupdate*
lrwxrwxrwx. 1 root root 17 Sep 3 10:05 S21iprdump -> ../init.d/iprdump*
lrwxrwxrwx 1 root root 17 Sep 6 08:51 S25vmamqpd -> ../init.d/vmamqpd*
lrwxrwxrwx 1 root root 37 Sep 6 08:50 S50vmware-USBArbitrator -> /etc/rc.d/init.d/vmware-USBArbitrator*
lrwxrwxrwx. 1 root root 15 Sep 3 03:59 S97rhnsd -> ../init.d/rhnsd*
El script rc.local puede ser usado para iniciar aplicaciones específicas del sistema.
Note lo siguiente:
- Todos los scripts reales están en /etc/init.d: cada directorio de nivel de ejecución solo enlaza a ellos.
- Los nombres de los scripts de inicio comienzan con s.
- Los nombres de los scripts de detención comienzan con k.
La existencia (o falta) de un vínculo simbólico de un script en un directorio de runlevel determina si el script se ejecuta en ese runlevel o no.
El número que le sigue a la K o S en cada nombre de script determina el orden en el cual los scripts son invocados. El nombre del script corresponde también al nombre del servicio.
Controlar qué scripts de inicialización se ejecutan al entrar a cada runlevel consiste en gestionar los enlaces simbólicos. Mientras que es posible administrar estos vínculos de forma manualmente, hay utilidades como chkconfig que están diseñadas para hacer esto de manera consiste y simple.
chkconfig se utiliza para consultar y configurar en qué runlevels van a correr los diferentes servicios del sistema.
No es difícil añadir sus propios servicios y escribir scripts de inicio. Solamente hay que poner el script en /etc/init.d, el cual debe tener ciertas características (¡sólo algunas líneas en el comienzo del archivo!) y luego usar chkconfig --add para habilitarlo o chkconfig --del para desactivar el uso de las instrucciones on y off.
Verifica un servicio en particular para comprobar si está configurado para correr en el runlevel actual:
$ chkconfig some_service
Esto devolverá "verdadero" si el servicio está configurado para ejecutarse, y por el contrario, "falso". Note que aún si el servicio está configurado para correr, podría estar detenido actualmente.
- Ver qué servicios están configurados para correr en cada uno de los runlevels:
$ chkconfig --list [service names] - Configurar un servicio para que se ejecute en el próximo reinicio:
$ sudo chkconfig some_service on - Configurar un servicio para que no se ejecute en el próximo reinicio:
$ chkconfig some_service off - Tenga en cuenta que las operaciones on y off no inciden en el estado actual del servicio para iniciarlo o detenerlo. Esto se realiza de la siguiente forma:
$ sudo service some_service [ stop | start ]
¿Cómo lo hace chkconfig para determinar qué número debería aparecer luego de la S o K en un enlace simbólico? ¿Cómo sabe qué runlevels configurar en on u off y qué estado configurar en los enlaces simbólicos? La información está en los propios scripts, los cuales contienen una línea en la parte de arriba, como la siguiente:
# chkconfig: 2345 10 90
El primer argumento luego de chkconfig: aquí se definen los runlevels en los cuales el servicio va a ejecutarse por defecto. En el ejemplo de arriba con los runlevels 2, 3, 4 y 5.
El segundo y tercer número son los prefijos numéricos en los scripts de inicio y detención; en el caso de arriba inician con S10 y finalizan con K90.
Cada sistema operativo tiene servicios que generalmente arrancan en la inicialización del sistema y a menudo permanecen funcionando hasta el apagado. Tales servicios pueden ser iniciados, detenidos o reiniciados en cualquier momento, lo que generalmente requiere privilegios de root. En un sistema Linux usando o emulando SysVinit, los servicios están en el directorio /etc/init.d.
En sistemas basados en Red Hat es posible ver el estado de un servicio en particular de la siguiente forma:
$ sudo service network status
Configured devices:
lo eth0 eth1 eth2 wlan0
Currently active devices:
lo eth0
$ sudo service vsftpd status
vsftpd (pid 5284) is running...
service tiene diversas opciones, las que varían según el servicio en particular; por ejemplo:
$ sudo service network
Usage: /etc/init.d/network {start|stop|restart|reload|status}
$ sudo service iptables
Usage: /etc/init.d/iptables {start|stop|restart|condrestart|status|panic|save}
Todo servicio se dirige al directorio /etc/init.d y ejecuta el script apropiado en ese directorio con las opciones suministradas.
Es posible ver el estado de todos los servicios en el sistema con:
$ sudo service --status-all
acpid (pid 4170) is running...
anacron (pid 4540) is running...
atd (pid 4553) is running...
....
smartd (pid 4614) is running...
smbd is stopped
......
El iniciar y detener servicios con service es efectivo sólo durante la operación actual del sistema; todos los cambios se pierden al reiniciar. Para configurar que un servicio en particular se active o no durante la inicialización del sistema - en sistemas basados en Red Hat - se utiliza chkconfig como se describió anteriormente.
En sistemas basados en Debian, incluyendo Ubuntu, las utilidades anteriores funcionarán solamente si se han instalado los paquetes sysvinit-utils y chkconfig, como se muestra aquí:
$ sudo apt-get install sysvinit-utils chkconfig
Sin embargo, las versiones recientes de Ubuntu ya no tienen el paquete chkconfig; tendrá que utilizar la utilidad update-rc.d que se describe más abajo.
Como alternativa, puede utilizar los comandos nativos en estos sistemas. Por ejemplo, el equivalente de la utilidad service es:
$ sudo invoke-rc.d cups [ status | start | stop ]
$ sudo status cups
para visualizar o cambiar el estado de cups. El comando status es más reciente y es preferido sobre invoke-rc.d.
Del mismo modo el equivalente de chkconfig sería:
$ sudo update-rc.d cups [ defaults | purge ]
$ sudo sysv-rc-conf cups [ on | off ]
Usted deberá consultar las páginas man para acceder a la documentación completa.
Upstart es manejado por eventos, en lugar de ser un conjunto de procedimientos en forma serial. Las notificaciones de eventos son enviadas al proceso init para ejecutar ciertos comandos en el momento justo después de que han cumplido los requisitos previos. Debido a que Upstart está siendo reemplazado por systemd, no invertiremos mucho tiempo en él ni hacemos ejercicios al respecto.
Los archivos de configuración de upstart son:
/etc/init/rcS.conf
/etc/rc-sysinit.conf
/etc/inittab
/etc/init/rc.conf
/etc/rc[0-6].d
Cuando el kernel inicia el proceso init, éste ejecuta el script rcS.conf. Esto a su vez, hace que rc-sysinit.conf se ejecute.
rc-sysinit.conf realizará una serie de tareas, incluyendo iniciar LVM, montar sistemas de archivos y luego ejecuta todos los scripts para el runlevel por defecto especificado en /etc/inittab.
Esto se logra mediante la ejecución de rc.conf y pasando al runlevel. Los scripts del runlevel levantan los servicios en el sistema.
Finalmente, scripts adicionales como prefdm.conf son ejecutados (para el runlevel 5 solamente).
Como se mencionó anteriormente, /etc/inittab está obsoleto y ahora sólo se utiliza para configurar el runlevel predeterminado mediante la línea initdefault. Otra configuración se realiza mediante Upstart en el directorio /etc/init. En general, Upstart se encontrará en el directorio /etc/event.d.
Por ejemplo, el número de consolas tty activas ahora se establece mediante la variable ACTIVE_CONSOLES en /etc/sysconfig/init, la que es leída por /etc/init/start-ttys.conf. El valor predeterminado es ACTIVE_CONSOLES=/dev/tty [1-6], el cual inicia un proceso getty desde tty1 hasta tty6.
Usando initctl usted puede ver, iniciar y detener procesos casi del mismo modo que lo hace service. La sintaxis es como sigue:
$ initctl options command
donde options puede tener los siguientes valores:
- start: Inicia un proceso
- stop: Detiene un proceso
- restart Reinicia un proceso
- reload Envía la señal HUP a un proceso
- status Consulta el estado de un proceso
- list: Lista los procesos conocidos
- emit Emite un evento.
Es posible encontrar un buen resumen de cómo utilizar initctl y muchas otras características de upstart en http://upstart.ubuntu.com/cookbook.
El sistema de administración central systemd y manejador de sesión para Linux está tomando lugar rápidamente en todas las distribuciones importantes.
systemd es compatible con SysVinit y el concepto de runlevels está soportado a través de 'targets' de nivel de ejecución. El programa telinit es emulado para trabajar con runlevels.
Las características de systemd y del gestor de sesión incluyen lo siguiente:
- Es compatible con los scripts de SysVinit.
- Inicia más rápido que los sistemas anteriores.
- Provee altas capacidades de paralelización.
- Usa socket y activación D-Bus para iniciar servicios.
- Reemplaza scripts de shell scripts con programas.
- Ofrece inicio de demonios sobre demanda.
- Realiza seguimiento de los procesos usando cgroups.
- Soporta la creación de snapshots y restauración del estado del sistema.
- Mantiene puntos de montaje y automontaje.
- Implementa una elaborada lógica de control de servicio basada en dependencia transaccional.
- Puede trabajar como un reemplazo de SysVinit.
En vez de utilizar scripts bash, systemd usa archivos .service. Adicionalmente, systemd clasifica todos los demonios en su propio cgroups del núcleo Linux (grupos de control).
Aunque systemd prefiere utilizar un conjunto de archivos de configuración correspondientes a un estándar nuevo, también puede utilizar archivos de configuración heredados dependiente de cada distribución.
Un ejemplo de un archivo de configuración nuevo sería /etc/hostname, el cual reemplazaría a /etc/sysconfig/network en Red Hat, /etc/HOSTNAME en SUSE y a /etc/hostname (adoptado como estándar) en Debian.
Otros archivos pueden incluir:
- /etc/vconsole.conf: mapa de teclado por defecto y fuente de consola.
- /etc/sysctl.d/*.conf: directorio para los parámetros sysctl del kernel.
- /etc/os-release: archivo de ID de la distribución.
systemctl es la utilidad principal para manejar servicios. La sintaxis básica es la siguiente:
$ systemctl [options] command [name]
Para ver un excelente resumen de cómo pasar desde SysVinit a systemd, consulte la documentación SysVinit to Systemd Cheatsheet en https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet.
A continuación puede ver algunos ejemplos de cómo usar systemctl:
- Para ver el estado de todo lo que controla systemd:
$ systemctl - Para ver todos los servicios disponibles:
$ systemctl list-units -t service --all - Para mostrar los servicios activos solamente:
$ systemctl list-units -t service - Para iniciar (activar) una o más unidades:
$ sudo systemctl start foo
$ sudo systemctl start foo.service
$ sudo systemctl start /path/to/foo.service
en donde una unidad puede ser un servicio o un socket. - Para detener (desactivar):
$ sudo systemctl stop foo.service - Para habilitar/deshabilitar un servicio:
$ sudo systemctl enable sshd.service
$ sudo systemctl disable sshd.service
Esto es el equivalente de chkconfig --add/--del y no inicia el servicio.
Nota: algunos comandos systemctl de los mostrados arriba pueden ser ejecutados como usuario normal, sin embargo otros tienen que ser ejecutados como root o con sudo.
SysVinit Command | Systemd Command | Notas |
---|---|---|
service foo start | systemctl start foo.service | Inicia un servicio; no hay efecto luego del reinicio. |
service foo stop | systemctl stop foo.service | Detiene un servicio; no hay efecto luego del reinicio. |
service foo restart | systemctl restart foo.service | Detiene el servicio y luego loreinicia. |
service foo reload | systemctl reload foo.service | Cuando está soportado, recarga los archivos de configuración sin interrumpir las operaciones pendientes. |
service foo condrestart | systemctl condrestart foo.service | Reinicia si el servicio ya está en ejecución. |
service foo status | systemctl status foo.service | Indica si un servicio está en ejecución actualmente. |
ls /etc/rc.d/init.d/ | systemctl list-unit-files --type=service | Lista los servicios que pueden ser iniciados o detenidos. |
ls /etc/rc.d/init.d/ | ls /lib/systemd/system/*.service | Lista todos los servicios y otras unidades (preferido). |
chkconfig foo on | systemctl enable foo.service | Habilita en el próximo reinicio u otro evento. |
chkconfig foo off | systemctl disable foo.service | Deshabilita en el próximo reinicio u otro evento. |
chkconfig foo | systemctl is-enabled foo.service | Comprueba si un servicio está configurado o no para iniciarse. |
chkconfig --list | systemctl list-unit-files --type=service | Imprime una tabla listando cada servicio y qué configuración tiene para cada runlevel, ya sea on u off. |
chkconfig --list | ls /etc/systemd/system/*.wants/ | Comando preferido para la misma operación. |
chkconfig foo --list | ls /etc/systemd/system/*.wants/foo.service | Lista en qué runlevels este servicio está configurado para estar on u off. |
chkconfig foo --add | systemctl daemon-reload | Recarga cuando un servicio nuevo se crea o cualquier configuración se modifica. |
Hasta hace poco tiempo atrás, casi todas las distribuciones estaban basadas en SysVinit. Sin embargo hubo problemas que motivaron el desarrollo de systemd. ¿Cuál de las siguientes afirmaciones es correcta?
SysVinit fue diseñado para mainframes, los que tienen requerimientos diferentes a computadores de escritorio, sistemas embebidos y plataformas para dispositivos móviles.
SysVinit fue diseñado para sistemas de núcleos múltiples.
Los tiempos de inicio y apagado no son importantes actualmente.
SysVinit no es confiable.
systemd se orienta a tener un diseño modular y a tener compatibilidad con el SO, objetivos que no se alcanzan con SysVinit.
¿Qué runlevel corresponde a cada ítem de los que se enumeran a continuación?
- Apagado del sistema
- Reinicio
- Modo monousuario
- Modo normal de sólo texto
- Modo normal gráfico
- Laboratorio 4.1 (código fuente: fake_service)
- Laboratorio 4.2
Usted debería ser capaz de:
- Comprender la importancia del proceso init.
- Explicar cómo funciona el método tradicional de SysVinit, cómo incorpora los runlevels y lo que sucede en cada uno de ellos.
- Saber cómo usar chkconfig y service (y utilidades alternativas) para iniciar y detener servicios, o hacerlos persistentes entre reinicios del sistema.
- Entender por qué surgieron los métodos alternativos Upstart y systemd y cómo funcionan.
- Usar systemctl para configurar y controlar systemd.
5. Diseño del Árbol del Sistema de Archivos de Linux
Hay muchos tipos de archivos presentes en un sistema Linux. Se diferencian por su propósito, tamaño, dueño, permisos para ser compartidos. Así mismo, por su permanencia temporal o definitiva en el sistema. Debido a lo anterior, la organización coherente de todo el árbol del sistema de archivos es muy importante, como también su estandarización entre las distribuciones de Linux (en tanto sea posible).
Al final de este capítulo usted debería estar capacitado para:
- Explicar por qué Linux requiere la organización de un gran árbol de sistemas de archivos, y cuáles son las principales consideraciones de cómo hacerlo.
- Conocer el rol desempeñado por el Estándar de Jerarquía del Sistema de Archivos (Filesystem Hierarchy Standard o FHS).
- Describir qué debe estar disponible en el arranque en el directorio raíz (/), y lo que debe estar disponible una vez que el sistema ha iniciado.
- Explicar cada uno de los subdirectorios principales del árbol en términos de propósito y contenido.
Linux, como todos los sistemas operativos basados en UNIX, consiste en un árbol grande de sistemas de archivos. Generalmente es diagramado como un árbol invertido con el directorio raíz / en la parte superior del árbol.
Dentro de este tremendo sistema de archivos lógico pueden haber varios, incluso muchos sistemas de archivos distintos, montados en puntos que corresponden a los subdirectorios. Estos distintos sistemas de archivos suelen estar en particiones diferentes, en diversas cantidades y tipos de dispositivos, incluyendo aquellos que se encuentran en red.
De forma independiente de cómo exactamente las cosas están unidas entre sí, todo se ve como un gran sistema de archivos; las aplicaciones no se preocupan en absoluto de los dispositivos físicos en los cuales residen los archivos.
En el pasado los diferentes sistemas operativos tipo UNIX organizaron este gran árbol de diversas maneras; incluso entre las distribuciones de Linux había muchas diferencias. Esto hizo que tanto el desarrollo de aplicaciones como llevar a cabo tareas de administración en más de un tipo de sistema fuera difícil y a menudo frustrante.
Como consecuencia de lo anterior, el ecosistema Linux ha trabajado arduamente para establecer procedimientos estandarizados para minimizar esos inconvenientes.
Cuando se habla de cómo se organizan los archivos y datos en el gran árbol de directorios, es importante conocer la taxonomía en cuánto a qué tipo de información tiene que ser leída y cuál escrita. En particular, hay dos tipos de diferencias:
- Compartidos vs no-compartidos
Los datos compartibles corresponden a los que se pueden compartir entre diferentes máquinas. Los datos no compartibles son aquellos que son específicos para un determinado host. Por ejemplo, los directorios personales de los usuarios pueden ser compartibles, mientras que los archivos de bloqueo de dispositivos no lo son. - Variable vs. estático
Los archivos estáticos incluyen binarios, bibliotecas, documentación y todo lo que no cambia sin ayuda del administrador de sistemas. Los archivos variables son cualquier cosa que puede cambiar, incluso sin ayuda del administrador de sistemas.
A menudo estas distinciones lógicas están incorporadas como distintos tipos de información que residen en varios directorios, o incluso en particiones y sistemas de archivos.
El Estándar de Jerarquía del Sistema de Archivos (FHS, de Filesystem Hierarchy Standard), administrado inicialmente por el Free Standards Group y ahora por la Linux Foundation, especifica los directorios principales que deben estar presentes y describe sus propósitos. Se puede descargar desde http://www.pathname.com/fhs/.
Al especificar un diseño estándar, el FHS simplifica el tema de la localización de los archivos. Aunque la mayoría de las distribuciones de Linux respetan el FHS, probablemente ninguno de ellos lo sigue exactamente. Por otro lado, la última versión oficial no tiene en cuenta algunos desarrollos nuevos.
A las distribuciones les gusta probar diferentes cosas y eventualmente algunos de los experimentos terminan siendo ampliamente aceptados.
Los distribuidores de Linux pasan mucho tiempo asegurándose de que el diseño de su sistema de archivos es coherente y que evoluciona correctamente en el tiempo.
A continuación se muestra una lista de los directorios principales bajo /:
Directorio | ¿En FHS? | Propósito |
---|---|---|
/ | Sí | Directorio principal de la jerarquía completa del sistema de archivos. |
/bin | Sí | Programas ejecutables esenciales que deben estar disponibles en modo monousuario. |
/boot | Sí | Archivos necesarios para arrancar el sistema, como el kernel, imagen initrd o initramfs, además de archivos de configuración y programas del gestor de arranque. |
/dev | Sí | Nodos de dispositivo, usados para interactuar con dispositivos de hardware y software. |
/etc | Sí | Archivos de configuración del sistema. |
/home | Sí | Directorios de usuario, incluyendo la configuración personal, archivos, etc. |
/lib | Sí | Bibliotecas requeridas por binarios ejecutables en /bin y /sbin. |
/lib64 | No | Bibliotecas de 64-bit requeridas por binarios ejecutables en /bin y /sbin, en sistemas que pueden correr aplicaciones tanto de 32-bit como 64-bit. |
/media | Sí | Puntos de montaje para dispositivos removibles como CDs, DVDs, pendrives, etc. |
/mnt | Sí | Sistemas de archivos montados temporalmente. |
/opt | Sí | Paquetes opcionales de software. |
/proc | Sí | Sistema de archivos virtual que provee información acerca del sistema y los procesos corriendo en él. Puede ser usado para modificar parámetros del sistema. |
/sys | No | Sistema de archivos virtual que provee información acerca del sistema y los procesos corriendo en él. Puede ser usado para modificar parámetros del sistema. Es similar a un árbol de dispositivos y es parte del Unified Device Model. |
/root | Sí | Directorio personal del usuario root. |
/sbin | Sí | Binarios esenciales del sistema. |
/srv | Sí | Datos específicos del sitio utilizados por el sistema. Rara vez se utiliza. |
/tmp | Sí | Archivos temporales; en muchas distribuciones los datos se pierden entre reinicios. Puede ser un ramdisk en memoria. |
/usr | Sí | Aplicaciones, herramientas y datos multiusuario; en teoría es sólo-lectura. |
/var | Sí | Datos variables que puedan cambiar durante la operación del sistema. |
Es posible que haya directorios adicionales en el directorio raíz, específicos a cada distribución. Estos podrían incluir /misc, que se puede utilizar para información de diverso tipo y /tftpboot, que se utiliza para el inicio a través de tftp. En caso de haber archivos en ese directorio, están relacionados con el inicio del sistema sin utilizar un disco duro. Note que no viola la FHS el tener otros directorios; sin embargo, la norma es violada cuando se tienen componentes en directorios distintos a los dictados por el estándar.
Mientras que todo el sistema de archivos puede ser visto como un gran árbol, como hemos señalado, pueden haber varias particiones y sistemas de archivos trabajando de forma unida.
La partición y sistema de archivos en el cual el directorio raíz está contenido es bastante especial y a menudo está en una partición dedicada, con otros componentes con directorios como /home, /var, /opt , etc, los cuales son montados posteriormente.
La partición raíz debe contener todos los archivos esenciales necesarios para iniciar el sistema y luego montar el resto de los sistemas de archivos. Por lo tanto necesita utilidades, archivos de configuración, información del cargador de arranque y otros datos esenciales del inicio. Debe estar habilitado para:
- Iniciar el sistema.
- Restaurar el sistema desde copias de seguridad de medios externos, tales como cintas y otros medios extraíbles, o NAS, etc.
- Recuperar y/o reparar el sistema; un administrador experimentado debe tener las herramientas para diagnosticar y reconstruir un sistema dañado.
De acuerdo con el FHS, ninguna aplicación o paquete debería crear nuevos subdirectorios en el directorio raíz.
El directorio /bin es muy importante y éste:
- Contiene programas y scripts ejecutables necesitados tanto por administradores de sistemas y usuarios sin privilegios, que son necesarios cuando todavía no se ha montado ningún otro sistema de archivos, por ejemplo, al iniciar en modo monousuario o en modo de recuperación.
- También puede contener ejecutables que son utilizados indirectamente por scripts.
- No debe contener ningún subdirectorio.
Los programas que deben existir en /bin incluyen:
cat, chgrp, chmod, chown, cp, date, dd, df, dmesg, echo, false, hostname, kill, ln, login, ls, mkdir, mknod, more, mount, mv, ps, pwd, rm, rmdir, sed, sh, stty, su, sync, true, umount, y uname.
También test puede estar ahí. De forma adicional puede incluirse:
csh, ed, tar, cpio, gunzip, zcat, netstat, y ping.
Los comandos binarios que no son considerados esenciales lo suficiente para ir en /bin van en /usr/bin. Solamente los programas requeridos por los usuarios que no son root se colocan en esta categoría.
Nota: Algunas distribuciones muy recientes están abandonando la estrategia de la separación /bin y /usr/bin (como también /sbin y /usr/sbin) y solo tienen un directorio con enlaces simbólicos, preservando así una visión de dos directorios. Consideran como obsoleto el concepto tradicional de permitir la posibilidad de colocar /usr en una partición separada para ser montada después del inicio.
Los archivos esenciales para iniciar el sistema deben estar en el directorio /boot y sus subdirectorios. Los dos archivos absolutamente esenciales son:
- vmlinuz: El kernel Linux comprimido.
- initramfs: El sistema de archivos de RAM inicial, el cual se monta antes de que el sistema real de archivos raíz esté disponible.
Estos archivos tienen nombres largos que dependen de la versión del núcleo, en donde el nombre exacto está en función de la distribución de Linux. Además, en lugar de initramfs, el archivo puede ser llamado initrd, siglas de disco RAM inicial, el cual si bien es cierto corresponde al método antiguo, el nombre se usa en algunas distribuciones todavía.
El contenido exacto de /boot variará según la distribución y el tiempo; en un sistema RHEL 7 tenemos:
$ ls -lF /boot
total 135336
-rw-r--r-- 1 root root 122094 Nov 4 09:20 config-3.10.0-123.13.1.el7.x86_64
-rw-r--r-- 1 root root 81386 Dec 7 12:03 config-3.17.5
-rw-r--r-- 1 root root 81896 Dec 15 07:28 config-3.18.0
-rw-r--r-- 1 root root 81896 Dec 16 15:56 config-3.18.1
drwxr-xr-x. 6 root root 4096 Dec 16 15:57 grub2
-rw-r--r--. 1 root root 40732911 Sep 3 04:07 initramfs-0-rescue-3a0cc7a6d7bb4525815f4d2b4298e611.img
-rw-r--r-- 1 root root 16406996 Dec 10 07:25 initramfs-3.10.0-123.13.1.el7.x86_64.img
-rw-r--r-- 1 root root 13967066 Dec 7 12:03 initramfs-3.17.5.img
-rw-r--r-- 1 root root 13914297 Dec 15 07:28 initramfs-3.18.0.img
-rw-r--r-- 1 root root 13915331 Dec 16 15:56 initramfs-3.18.1.img
-rw-r--r--. 1 root root 865512 Sep 3 04:06 initrd-plymouth.img
-rw-r--r-- 1 root root 228603 Nov 4 09:23 symvers-3.10.0-123.13.1.el7.x86_64.gz
lrwxrwxrwx 1 root root 24 Sep 28 10:18 System.map -> /boot/System.map-3.15.0+
-rw------- 1 root root 2841409 Nov 4 09:20 System.map-3.10.0-123.13.1.el7.x86_64
-rw-r--r-- 1 root root 2875608 Dec 7 12:03 System.map-3.17.5
-rw-r--r-- 1 root root 2891484 Dec 15 07:28 System.map-3.18.0
-rw-r--r-- 1 root root 2891509 Dec 16 15:56 System.map-3.18.1
lrwxrwxrwx 1 root root 21 Sep 28 10:18 vmlinuz -> /boot/vmlinuz-3.15.0+
-rwxr-xr-x. 1 root root 4902000 Sep 3 04:07 vmlinuz-0-rescue-3a0cc7a6d7bb4525815f4d2b4298e611
-rwxr-xr-x 1 root root 4904592 Nov 4 09:20 vmlinuz-3.10.0-123.13.1.el7.x86_64
-rw-r--r-- 1 root root 5363200 Dec 7 12:03 vmlinuz-3.17.5
-rw-r--r-- 1 root root 5404992 Dec 15 07:28 vmlinuz-3.18.0
-rw-r--r-- 1 root root 5405440 Dec 16 15:56 vmlinuz-3.18.1
Hace mucho tiempo estos archivos esenciales se solían poner directamente en /, en vez de usar un directorio /boot por separado, siguiendo las prácticas tradicionales de UNIX. Hoy en día esto se considera obsoleto.
Usted puede haber notado que existen varias versiones del núcleo en /boot, y para cada uno hay cuatro archivos disponibles (la posibilidad de elegir entre los núcleos se hace mediante GRUB en el inicio).
Los otros dos archivos además de vmlinuz y initramfs son:
- config: Es el archivo de configuración utilizado al compilar el kernel. Está presente sólo para referencia y porque puede ser de utilidad al depurar programas.
- System.map: La tabla de símbolos del kernel, la cual es muy útil en la depuración de programas. Entrega las direcciones hexadecimales de todos los símbolos del kernel.
Ninguno de estos archivos es requerido para iniciar o ejecutar el sistema.
Las distribuciones pueden poner otros archivos y directorios en /boot, tales como los sectores de arranque maestros guardados y otros datos no editados a mano.
Este directorio contiene archivos de dispositivos especiales (también conocidos como nodos de dispositivo) los cuales representan los dispositivos incorporados o conectados al sistema. Estos archivos especiales son esenciales para que el sistema funcione correctamente.
Dichos archivos de dispositivo representan caracteres (una trama de bytes) y dispositivos de bloque E/S. Los dispositivos de red no tienen nodos de dispositivo en Linux y en cambio son referenciados por su nombre, como eth1 o wlan0.
Listado de /dev
$ cd /dev ; ls -lF
lrwxrwxrwx 1 root root 3 Aug 28 10:12 cdrom1 -> sr0
....
lrwxrwxrwx 1 root root 15 Aug 28 10:12 fitbit -> bus/usb/003/002
....
crw-rw---- 1 root lp 6, 0 Aug 28 10:12 lp0
crw-rw---- 1 root lp 6, 1 Aug 28 10:12 lp1
....
brw-rw---- 1 root disk 8, 4 Aug 28 10:12 sda4
brw-rw---- 1 root disk 8, 5 Aug 28 10:12 sda5
brw-rw---- 1 root disk 8, 6 Aug 28 10:12 sda6
....
brw-rw----+ 1 root cdrom 11, 0 Aug 28 10:12 sr0
Note que los dispositivos de caracter comienzan con una c, los bloques con una b y los enlaces simbólicos con una l (L minúscula).
Todas las distribuciones modernas de Linux (no embebidas) utilizan el sistema udev, el cual crea nodos en /dev sólo a medida en que se necesita, lo que sucede cuando se encuentran dispositivos, ya sea al inicio o al conectarlos al sistema (discutiremos udev en una sección posterior).
Si usted fuera a echar un vistazo en el directorio /dev en un sistema de archivos sin montar, lo encontraría vacío; en el inicio se crea y monta un sistema de archivos virtual en /dev, el que luego es populado con nodos de dispositivos, como lo requiere udev. Los sistemas Linux embebidos pueden fijar los nodos de dispositivos y no utilizar udev o alguna alternativa como mdev.
Este directorio contiene los archivos de configuración de la máquina local y algunos scripts de inicio; aquí no debería haber ningún programa ejecutable binario.
Las distribuciones a menudo agregan archivos de configuración y directorios a /etc. Por ejemplo, Red Hat añade un número de directorios adicionales incluyendo /etc/sysconfig, donde se alojan archivos y directorios de configuración del sistema.
Otros subdirectorios importantes incluyen /etc/skel, que contiene archivos de plantilla usados para popular directorios de usuario recién creados. También /etc/init.d, que contiene scripts de inicio y detención cuando se utiliza la inicialización de System V.
Los archivos y directorios que pueden encontrarse aquí incluyen:
csh.login, exports, fstab, ftpusers, gateways, gettydefs, group, host.conf, hosts.allow, hosts.deny, hosts,equiv, hosts.lpd, inetd.conf, inittab, issue, ld.so.conf, motd, mtab, mtools.conf, networks, passwd, printcap, profile, protocols, resolv.conf, rpc, securetty, services, shells, syslog.conf.
En los sistemas Linux los directorios de usuarios están en /home, como /home/coop, /home/alumno, etc. Toda la configuración personal, datos y programas ejecutables se ponen en esta jerarquía de directorios. /home también puede contener subdirectorios para varios grupos o asociaciones de usuarios, como /home/estudiantes, /home/staff, /home/aliens, etc.
En otros sistemas operativos tipo UNIX, existe el concepto del árbol de directorios /home, pero puede ser sutilmente diferente. Por ejemplo, en Solaris los directorios de usuarios se crean en /export/home y luego la utilidad automount los montará en /home. Esto se debe a la situación habitual en que el directorio de los usuarios puede estar en cualquier lugar en una red corporativa, probablemente en un servidor NFS, en donde el directorio de cada usuario se montará automáticamente cuando esté en uso.
Linux también tiene la utilidad automount, pero muchos usuarios no están conscientes de ellos, y en sistemas personales probablemente el concepto de puntos de montaje NFS no aplicará.
Un usuario siempre puede sustituir la variable de ambiente $HOME para su directorio raíz, o la abreviación ~; es decir, los siguientes usos son equivalentes:
$ ls -l $HOME/public_html
$ ls -l ~/public_html
Hay una excepción: el directorio home del usuario root en los sistemas Linux siempre se encuentra en /root. Algunos sistemas UNIX antiguos pueden usar / en cambio, lo que puede causar algún desorden.
Este directorio debe contener sólo las bibliotecas necesarias para ejecutar los binarios en /bin y /sbin. Estas bibliotecas son particularmente importantes para iniciar el sistema y ejecutar comandos en el sistema de archivos raíz.
Los módulos del kernel (a menudo controladores de dispositivo o sistemas de archivos) se encuentran bajo /lib/modules/<kernel-versión-número>.
Los archivos de PAM (Pluggable Authentication Modules) se almacenan en el directorio /lib/security.
Los sistemas que soportan tanto binarios de 32 bits y 64 bits deben mantener ambos tipos de bibliotecas en el sistema. En los sistemas basados en Red Hat hay directorios separados para las bibliotecas de 32 bits (/lib) y 64 bits (/lib64).
Este directorio se usa normalmente para montar sistemas de archivos en medios extraíbles. Estos incluyen CDs, DVDs, unidades USB y disquetes del paleolítico.
Los sistemas Linux modernos montan estos medios de forma dinámica durante la inserción, momento en el cual udev crea directorios bajo /media y luego monta los sistemas de archivos extraíbles allí, con los nombres que se establecen a través de las reglas de udev especificadas en los archivos de configuración. Al desmontar y extraer los medios, los directorios que fueron usados como puntos de montaje en /media desaparecerán.
Si el medio extraíble tiene más de una partición y sistema de archivos, aparecerá más de una entrada en /media. En muchas distribuciones de Linux el administrador de archivos (como Nautilus) se abrirá cuando el medio es montado.
Nota: En algunas distribuciones más recientes (incluyendo SUSE y RHEL 7) los medios extraíbles se montarán en /run/media/[nombre de usuario]/... Vamos a tratar /run al final de este capítulo.
Se dispone de este directorio para que el administrador del sistema pueda montar temporalmente un sistema de archivos en caso de necesitarlo. Se usa comúnmente para sistemas de archivos en red, incluyendo:
- NFS
- Samba
- CIFS
- AFS
Históricamente, /mnt también fue usado para los tipos de archivos que se montan actualmente en /media (o /run/media) en los sistemas modernos.
En términos generales, este directorio no debe ser utilizado por programas de instalación. Una mejor alternativa es otro directorio temporal que no esté siendo usado.
Este directorio está diseñado para paquetes de software que desean mantener la totalidad o gran parte de sus archivos en un lugar aislado en vez de dispersarse por todo el sistema en los directorios compartidos con otros programas.
Por ejemplo, si dolphy_app fuera el nombre de un paquete en /opt, todos sus archivos deben residir en directorios bajo /opt/dolphy_app, incluyendo /opt/dolphy_app/bin para binarios y /opt/dolphy_app/man para las páginas man.
Esto puede hacer que tanto la instalación y desinstalación de software sean relativamente fácil, ya que todo está aislado de forma conveniente en una ubicación predecible y estructurada. También hace que sea más fácil para los administradores de sistemas el determinar la naturaleza de cada archivo asociado a un paquete.
Note, sin embargo, que si uno utiliza sistemas de empaquetamiento como RPM y APT, como veremos más adelante, también es fácil de instalar y desinstalar conservando un claro sentido de las ubicaciones de archivos, sin exhibir tal conducta antisocial con la distribución.
En Linux, el directorio /opt es utilizado a menudo por proveedores de aplicaciones, ya sea con software propietario o aquellos que desean evitar las complicaciones asociadas a los cambios entre distribuciones. Por ejemplo, en RHEL 7 los únicos paquetes se encuentran en esta categoría están en /opt/skype y /opt/google, en donde este último tiene subdirectorios para chrome, earth y talkplugin.
Los directorios /opt/bin, /opt/doc, /opt/include, /opt/info, /opt/lib y /opt/man están reservados para uso del administrador del sistema local. Los paquetes pueden proporcionar archivos que estén vinculados o copiados en estos directorios reservados, pero también deben ser capaces de funcionar sin los programas que están en estos directorios especiales.
Este directorio es el punto de montaje para un seudosistema de archivos, donde toda la información reside sólo en memoria, no en disco. Tal como /dev, el directorio /proc está vacío en un sistema que no está corriendo.
El kernel muestra algunas estructuras de datos importantes a través de las entradas disponibles en /proc. Además, cada proceso activo en el sistema tiene su propio subdirectorio, el que ofrece información detallada sobre el estado del proceso, los recursos que está utilizando y su historia.
Las entradas en /proc a menudo se denominan archivos virtuales y tienen cualidades interesantes. Mientras que la mayoría tienen cero bytes de tamaño, cuando se visualiza su contenido es posible comprobar que pueden tener una gran cantidad de información.
Adicionalmente, la mayoría de los ajustes de hora y fecha en los archivos reflejan la hora y fecha actuales, indicativo del hecho de que están en constante cambio. De hecho, la información de estos archivos se obtiene sólo cuando son visualuzados, no se están actualizando constantemente o periódicamente.
Importantes pseudoarchivos, incluyendo /proc/interrupts, /proc/meminfo, /proc/mounts y /proc/partitions, proporcionan un vistazo del estado actual del hardware del sistema.
Otros archivos como /proc/filesystems y el directorio /proc/sys/, proveen información de configuración del sistema y de las interfaces.
Para propósitos de organización, los archivos que contienen información sobre un tema similar se agrupan en directorios virtuales y subdirectorios. Por ejemplo, /proc/scsi/ contiene información de todos los dispositivos SCSI físicos. De la misma forma, los directorios de procesos contienen información acerca de cada proceso corriendo en el sistema.
A lo largo de este curso examinaremos ampliamente las entradas en /proc, y echaremos un vistazo más detallado en los capítulos siguientes acerca de la configuración del kernel y monitoreo del sistema.
Este directorio es el punto de montaje para el seudosistema de archivos sysfs, donde toda la información reside sólo en memoria, no en disco. Al igual que /dev y /proc, el directorio /sys está vacío en un sistema detenido.
sysfs se utiliza tanto para recopilar información sobre el sistema, como también modificar su comportamiento mientras se ejecuta. En ese sentido se parece a /proc, pero es más nuevo y se ha adherido a normas estrictas acerca de qué tipo de entradas que puede contener. Por ejemplo, casi todos los seudoarchivos en /sys contienen sólo una línea o valor; no existe ninguna de las entradas largas que se pueden encontrar en /proc.
Al igual que con /proc, examinaremos entradas en /sys a lo largo de este curso, lo que será relevante en los próximos capítulos acerca de la configuración del kernel y monitoreo del sistema.
Este directorio (pronunciado "slash-root") es el directorio de inicio para el usuario root.
La cuenta de root que es dueña de este directorio se debe utilizar solamente para las acciones que requieren privilegios de superusuario. Para aquellas acciones que pueden realizarse como un usuario sin privilegios, utilice otra cuenta.
Este directorio contiene los archivos binarios esenciales para arrancar, restaurar, recuperar y/o reparar los binarios en el directorio /bin. También debe tener lo necesario para montar otros sistemas de archivos en /usr, /home y otros lugares de ser necesario, una vez que el sistema de archivos raíz esté en buenas condiciones en el arranque.
Los siguientes programas deberían estar incluidos en este directorio (siempre y cuando sus subsistemas estén instalados):
fdisk, fsck, getty, halt, ifconfig, init, mkfs, mkswap, reboot, route, swapon, swapoff, update.
Nota: como se mencionó anteriormente, algunas distribuciones nuevas están abandonando la estrategia de separar /sbin y /usr/sbin (como también /bin y /usr/bin), y sólo tienen un directorio con enlaces simbólicos, preservando una vista de dos directorios.
Este directorio se utiliza para almacenar archivos temporales, y puede ser accedido por cualquier usuario o aplicación. Sin embargo, no se puede esperar que los archivos en /tmp estén ahí por largo tiempo:
- Algunas distribuciones corren trabajos de cron automatizados, los que generalmente eliminan los archivos de más 10 días, a menos que los scripts de purga hayan sido modificado para excluirlos. Esta es la política de RHEL 6.
- Algunas distribuciones eliminan el contenido de /tmp con cada reinicio del sistema. Esta ha sido la política de Ubuntu.
- Algunas distribuciones modernas utilizan un sistema de archivos virtual, usando el directorio /tmp sólo como un punto de montaje para un disco ram utilizando el sistema de archivos tmpfs. Esta es la política por defecto de los sistemas Fedora recientes. Cuando el sistema se reinicia, toda la información se pierde; ¡/tmp es de hecho temporal!
En este último caso, hay que evitar la creación de archivos de gran tamaño en /tmp, debido a que en realidad va a ocupar espacio en memoria en vez de disco, y es fácil dañar o bloquear el sistema a través del agotamiento de la memoria. Si bien es cierto que la guía para las aplicaciones es evitar poner archivos de gran tamaño en /tmp, hay un gran número de aplicaciones que violan esta política. Incluso si fuera posible ponerlos en otro lugar (tal vez mediante la especificación de una variable de entorno), muchos usuarios no saben cómo configurarlo, y por otro lado, todos los usuarios tienen acceso a /tmp.
Esta política puede ser cancelada en los sistemas utilizando systemd, como en Fedora, a través del siguiente comando:
$ systemctl mask tmp.mount
Luego de lo cual es necesario reiniciar el sistema.
El directorio /usr puede ser visto como una jerarquía secundaria. Se utiliza para los archivos que no son necesarios para el inicio del sistema. De hecho, /usr no necesita estar localizado en la misma partición que el directorio raíz y se puede compartir entre los hosts que utilizan la misma arquitectura de sistema a través de la red.
Los paquetes de software no deberían crear subdirectorios directamente bajo /usr. Podrían existir algunos enlaces simbólicos a otros lugares por razones de compatibilidad.
Este directorio tiene usualmente datos de sólo lectura. Contiene binarios que no son necesarios en modo monousuario. Contiene el directorio /usr/local, donde es posible almacenar binarios locales. Las páginas man se encuentran en /usr/share/man.
Directorio | Propósito |
---|---|
/usr/bin | Binarios y scripts no esenciales, que no se necesitan en modo monousuario. En general corresponden a aplicaciones de usuario, las cuales no son necesarias para iniciar el sistema. |
/usr/include | Archivos header, usados para compilar aplicaciones. |
/usr/lib | Bibliotecas para programas en /usr/bin y /usr/sbin. |
/usr/lib64 | Bibliotecas de 64-bit para programas de 64-bit en /usr/bin y /usr/sbin. |
/usr/sbin | Binarios no esenciales del sistema, tales como demonios. |
/usr/share | Datos compartidos, usados por aplicaciones. Generalmente son independientes de la arquitectura. |
/usr/src | Código fuente, usualmente para el kernel Linux. |
/usr/X11R6 | Archivos de X Window; generalmente obsoleto. No está presente en la mayoría de las distribuciones modernas de Linux. |
/usr/local | Datos y programas locales específicos al sistema local. Los subdirectorios incluyen bin, sbin, lib, share, include, etc. |
Directorio | Propósito |
---|---|
/var/ftp | Se usa para la base del servidor ftp. |
/var/lib | Datos persistentes que son modificados por programas a medida en que son ejecutados. |
/var/lock | Archivos de bloqueo que se usan para controlar el acceso simultáneo a los recursos. |
/var/log | Archivos de registro. |
/var/mail | Buzones de correo de los usuarios. |
/var/run | Información acerca del sistema en funcionamiento desde el último arranque. |
/var/spool | Tareas en la cola o esperando a ser procesadas, tales como la cola de impresión. |
/var/tmp | Archivos temporales para ser preservados luego del reinicio del sistema. A veces se enlaza a /tmp. |
/var/www | Raíz para la jerarquía de los sitios web. |
Este directorio contiene archivos de datos variables (o volátiles) que cambian frecuentemente durante el funcionamiento del sistema. Estos incluyen:
- Archivos de registro.
- Directorios y archivos de spool para imprimir, colas de correo, etc.
- Archivos de datos administrativos.
- Archivos transitorios y temporales, como contenido del caché.
Obviamente, /var no puede ser montado como un sistema de archivos de sólo lectura.
Por razones de seguridad, a menudo se considera una buena idea montar /var como un sistema de archivos por separado. Además, si el directorio se llena, no debería producir un bloqueo del sistema.
/var/log es donde se encuentran la mayoría de los archivos del registro del sistema. El directorio /var/spool es donde se almacenan los archivos locales para procesos como correo, impresión y trabajos de cron a la espera de ser liberados de la cola.
Un nuevo árbol de directorio montado en /run ha estado en uso desde hace varios años por las principales distribuciones de Linux, y pese a que ha sido propuesto para el FHS, no ha sido aceptado formalmente. Sin embargo es bueno saber acerca de su existencia, ya que muy probablemente se encontrará con él.
El propósito de /run es almacenar archivos transitorios: aquellos que contienen información del tiempo de ejecución (runtime), los cuales probablemente sean escritos tempranamente en el inicio del sistema, y que no requieren ser preservados al reiniciar.
Generalmente /run se implementa como un punto de montaje vacío, con un disco ram tmpfs (tal como /dev/shm) montado en tiempo de ejecución. Por lo tanto, este es un seudosistema de archivos existente sólo en memoria.
Algunos directorios existentes, tal como /var/run y /var/lock, serán enlaces simbólicos a los directorios bajo /run. Otros, dependiendo de cada distribución, pueden apuntar a directorios bajo /run.
Según el Filesystem Hierarchy Standard (FHS), qué directorio de alto nivel (bajo /, como /tmp y no como /tmp/otros) son los más apropiados para:
- archivos de configuración.
- archivos personales.
- archivos del registro del sistemas, como los registro del servidor.
- archivos que son utilizados sólo en el inicio, tales como el kernel e initrd.
- módulos del kernel Linux, los que son extensiones cargables del kernel.
Hay algunos directorios que contienen entradas especiales, las cuales resumen las propiedades del sistema, en vez de mostrar otro tipo de datos almacenados en el disco. Esos pseudo-sistemas de archivos son muy importantes para que el sistema funcione adecuadamente. ¿Cuáles de los siguientes directorios contienen este tipo de datos? Seleccione todos los que apliquen:
/boot
/dev
/etc
/lib
/mnt
/opt
/proc
/sys
/srv
Usted debería ser capaz de:
- Explicar porqué Linux requiere que su árbol de sistemas de archivos esté organizado, y cuáles son las consideraciones más importantes en relación a cómo hacerlo.
- Saber cuál es el rol que juega el Estándar de jerarquía del sistema de archivos (FHS).
- Describir qué debe estar disponible durante el inicio en el directorio raíz (/) , y qué debe estar disponible una vez que el sistema ya se haya iniciado.
- Explicar cada uno de los principales subdirectorios del árbol en términos de propósito y contenido.
6. Servicios del Kernel y Configuración
El kernel del sistema operativo se encuentra en el corazón de todos los sistemas Linux, desde el dispositivo embebido o móvil más pequeño, a la supercomputadora más poderosa. Cabe destacar que el kernel tiene las mismas tareas esenciales en este amplio espectro. Controla el acceso al hardware, la competencia por los recursos entre diferentes aplicaciones y otras tareas, maneja la actividad de E/S, los archivos y almacenamiento de datos, seguridad, redes, etc. Al seleccionar los parámetros de línea de comandos del kernel en el inicio, el sistema puede comportarse de diferentes formas.
Al final de este capítulo usted debería ser capaz de:
- Conocer las principales responsabilidades que el kernel debe cumplir y saber cómo lo hace.
- Explicar qué parámetros pueden ser configurados en la línea de comandos del kernel y cómo hacerlos efectivos, ya sea para un sólo inicio del sistema o de forma persistente.
- Saber en donde encontrar documentación detallada acerca de estos parámetros.
- Saber cómo usar sysctl para configurar parámetros del kernel ya sea una vez que el sistema ha iniciado, o de forma persistente luego del reinicio del sistema.
En rigor, Linux es sólo el kernel del sistema operativo. Este último incluye muchos otros componentes, como bibliotecas y aplicaciones que interactúan con el kernel.
El kernel es el componente central esencial que conecta el hardware al software y maneja recursos del sistema, como memoria y asignación de tiempo de CPU a las aplicaciones y servicios que compiten por ellos. Se ocupa de todos los dispositivos conectados utilizando los controladores de dispositivos, y hace que estén disponibles para el uso del sistema operativo.
Un sistema que ejecuta solamente el kernel tiene una funcionalidad bastante limitada. Esto se encuentra sólo en dispositivos dedicados y enfocados a los sistemas embebidos.
Las principales responsabilidades del kernel incluyen:
- Inicialización del Sistema y booteo.
- Planificación de procesos.
- Gestión de Memoria.
- Controlar acceso al hardware.
- E/S (Entrada/Salida) entre aplicaciones y dispositivos de almacenamiento.
- Implementación de sistemas de archivos locales y de red.
- Control de seguridad, tanto a nivel local (como los permisos del sistema de archivos) y en red.
- Control de la red.
Para la versión GRUB 1 (la antigua), una línea de comandos del kernel podría verse así:
kernel /boot/vmlinuz-3.19.1 ro root=LABEL=RHEL6-64 quiet crashkernel=auto SYSFONT=latarcyrheb-sun16 LANG=en_US.UTF-8 KEYTABLE=us
o
kernel /vmlinuz-2.6.32-279.14.1.el6.x86_64 ro
root=UUID=178d0092-4154-4688-af24-cda272265e08
rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD
SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
y se encontraría en /boot/grub/grub.conf. Todo lo que viene después del archivo que se especifica en vmlinuz es una opción. Cualquier opción que no es comprendida por el kernel se pasará a init (pid = 1), el primer proceso de usuario que se ejecuta en el sistema.
Para la versión GRUB 2 (la nueva), una línea de comandos del kernel podría verse así:
linux16 /boot/vmlinuz-3.16.0 root=UUID=178d0092-4154-4688-af24-cda272265e08 ro vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16 rhgb quiet LANG=en_US.UTF-8
y se encontraría en /boot/grub2/grub.cfg.
En la versión 2 no se debe editar este archivo directamente, sino que modificar los archivos relevantes bajo /etc.
Varios parámetros son pasados al sistema durante el inicio a través de la línea de comandos del kernel. Normalmente están en la línea del kernel (o linux16) en el archivo de configuración de GRUB, pero pueden ser modificados en el inicio.
En los ejemplos anteriores las filas largas fueron divididas para su visualización, pero cada una de ellas corresponden a una línea larga. Recuerde que discutimos cómo configurar las dos versiones de GRUB, y que la versión 2 no debe editarse directamente, sino modificar los archivos correspondientes en /etc.
Basta hacer lo siguiente para ver con qué línea de comandos inició un sistema:
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-3.18.1 root=UUID=9d6b5801-9c7e-4c17-9068-49923952338e ro rhgb quiet loop.max_loop=256 LANG=en_US.UTF-8
Aquí puede ver el significado de alguno de los parámetros de arranque mencionados:
- ro: monta el directorio raíz en modo sólo-lectura en el inicio.
- root: sistema de archivos raíz.
- rd_LVM_LV: activa el sistema de archivos root en el volumen lógico especificado.
- rd_NO_LUKS: deshabilita la detección de cifrado LUKS.
- rd_NO_DM: deshabilita la detección de DM RAID.
- LANG: es el lenguaje del sistema.
- SYSFONT: es la fuente de consola.
- KEYTABLE: es el nombre del archivo de configuración del teclado.
- rhgb: para soporte de booteo gráfico en sistemas Red Hat.
- quiet: deshabilita la mayoría de los mensajes del registro.
Tenga en cuenta que los parámetros que comienzan con rd se usan solamente en los sistemas basados en Red Hat. Alguna documentación al respecto puede encontrarse en https://fedoraproject.org/wiki/Dracut/Options.
Hay una lista sorprendentemente larga de los parámetros disponibles del kernel. Documentación detallada al respecto se puede encontrar aquí:
- En las fuentes del kernel, en el archivo Documentation/kernel-parameters.txt.
- En línea, en http://kernel.org/doc/Documentation/kernel-parameters.txt.
- En el paquete de documentación del kernel proveído por la mayoría de las distribuciones, con un nombre similar a kernel-doc o linux-doc.
- Ejecutando el comando man bootparam.
Los parámetros pueden ser especificados simplemente como un valor dado como argumento, o de la forma param=valor, donde el valor dado puede ser un string, entero, arreglo de enteros, etc, tal como se explica en el archivo de documentación.
Por convención, no debería haber parámetros intencionalmente escondidos o secretos, todos ellos deberían estar explicados en la documentación. Los parches a las fuentes del kernel con parámetros nuevos deben incluir modificaciones en el archivo de documentación.
La interfaz sysctl puede ser utilizada para leer y ajustar los parámetros del kernel en tiempo de ejecución. Los valores actuales se pueden visualizar con el siguiente comando:
$ sysctl -a
....
kernel.pid_max = 32768
...
kernel.threads-max = 63707
....
net.ipv4.ip_default_ttl = 64
....
net.ipv4.ip_forward = 0
....
vm.nr_hugepages = 16
vm.swappiness = 10
....
Cada valor corresponde a un seudoarchivo en particular bajo /proc/sys, en donde las diagonales son reemplazadas por puntos. Por ejemplo, las dos siguientes sentencias son equivalentes:
$ sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
$ sudo sysctl net.ipv4.ip_forward=1
donde la segunda forma se usa para establecer un valor con la interfaz de línea de comando sysctl. No se puede dejar espacios alrededor del signo = en este comando. Note que en la primera forma, no es posible utilizar sudo con echo; el comando debe hacerse en la forma en que se muestra, o ejecutándolo como root.
Si va a través de los seudoarchivos en /proc/sys va a obtener la misma información que provee sysctl -a. Puede obtener todos los detalles sobre cómo utilizar sysctl con man 8 sysctl. Para obtener información acerca de cómo se usa la función sysctl() desde un programa para realizar las mismas operaciones, ejecute man 2 sysctl.
Si la configuración está en /etc/sysctl.conf (ver man sysctl.conf para más detalles), es posible realizar ajustes en el inicio del sistema.
Note que el comando:
$ sudo sysctl -p
lleva a cabo de forma inmediata lo que se encuentra en el archivo de configuración, ajustando todos los parámetros según se haya especificado; esto también es parte del proceso de inicio.
En algunas distribuciones recientes basadas en systemd (como en RHEL 7), el archivo de configuración es ahora /usr/lib/sysctl.d/00-system, pero el archivo original está soportado todavía, ya que está autodocumentado en ese archivo.
En este capítulo se describen dos formas de realizar ajustes al kernel. La línea de comandos del kernel permite especificar opciones al inicio, mientras que el uso de sysctl permite la especificación de opciones de tiempo de ejecución. Seleccione cuál de las siguientes opciones corresponden a ajustes en tiempo de ejecución:
Habilitar IP forwarding
Montar el sistema de archivos raíz en modo sólo lectura
Activar el sistema de archivos raíz en el volumen lógico especificado
Número máximo PID
Deshabilitar la detección de DM RAID
Seleccionar el lenguaje del sistema
Ingresar en modo monousuario
Usted debería ser capaz de:
- Conocer las principales responsabilidades que el kernel debe cumplir y saber cómo lo hace.
- Explicar qué parámetros pueden ser configurados en la línea de comandos del kernel y cómo hacerlos efectivos, ya sea para un sólo inicio del sistema o de forma persistente.
- Saber en donde encontrar documentación detallada acerca de estos parámetros.
- Saber cómo usar sysctl para configurar parámetros del kernel ya sea una vez que el sistema ha iniciado, o de forma persistente luego del reinicio del sistema.
7. Módulos del Kernel
El kernel Linux hace un uso extensivo de módulos, los cuales contienen software importante que puede ser cargado y descargado según se necesite después que el sistema ha iniciado. Muchos módulos incorporan controladores de dispositivos para el control de hardware, ya sea como parte del sistema o periféricos. Otros módulos pueden controlar protocolos de red, proveer soporte a diferentes tipos de sistemas de archivos y muchos otros propósitos. Los parámetros pueden ser especificados al cargar los módulos con el fin de controlar su comportamiento. El resultado final es una gran flexibilidad y agilidad en la respuesta a las condiciones y necesidades cambiantes.
Al final de este capítulo usted debería ser capaz de:
- Enumerar las ventajas en la utilización de módulos del kernel.
- Utilizar insmod, rmmod y modprobe para cargar y descargar módulos del kernel.
- Saber cómo usar modinfo para encontrar información acerca de los módulos del kernel.
Muchas piezas de soporte en el kernel Linux están diseñadas como parte integral del kernel cuando éste se carga inicialmente, o para ser agregadas (o removidas) más tarde en forma de módulos según sea necesario. De hecho, la mayoría de los componentes del kernel se integran como módulos, con excepción de los elementos centrales.
Tales módulos pueden o no ser controladores de dispositivos. Por ejemplo, pueden implementar un cierto protocolo de red o sistema de archivos que maneja un dispositivo de hardware o software. Incluso en los casos en que prácticamente siempre se necesitará la funcionalidad, la incorporación de la capacidad de carga y descarga como módulo facilita el desarrollo de software, ya que no hacen falta reinicios del kernel para probar los cambios realizados.
Incluso con el uso generalizado de los módulos del kernel, Linux conserva una arquitectura de kernel monolítico en vez de un microkernel. Esto es porque cuando se carga un módulo se convierte en una parte completamente funcional del kernel, con pocas restricciones. Estos se comunican con todos los subsistemas del kernel principalmente a través de recursos compartidos, como memoria y archivos de bloqueo, más que a través de pasar mensajes como puede ocurrir en un microkernel.
Linux no es el único sistema operativo que utiliza módulos; Solaris lo hace y también AIX, quienes las llaman extensiones del kernel. Sin embargo, Linux las utiliza de manera particularmente robusta.
Hay una serie de herramientas que se utilizan con los módulos del kernel:
- lsmod: Lista los módulos cargados.
- insmod: Carga módulos directamente.
- rmmod: Remueve módulos directamente.
- modprobe: Carga o descarga módulos, utilizando una base de datos preconstruida de los módulos con información de sus dependencias.
- depmod: Reconstruye la base de datos de dependencia de módulos; es requerida por modprobe y modinfo.
- modinfo: Proporciona información acerca de un módulo.
La carga y descarga del módulo se debe realizar como usuario root. Si se conoce la ruta completa, el módulo se puede cargar directamente de la siguiente forma:
$ sudo /sbin/insmod <pathto>/module_name.ko
La ubicación normal de los módulos del kernel está bajo el árbol de directorios /lib/modules/<kernel-version>. Un módulo del kernel siempre tiene una extensión .ko, como e1000e.ko, ext4.ko, o usbserial.ko.
Los módulos del kernel están asociados a la versión específica del kernel y deben coincidir con el kernel en ejecución o no pueden ser cargados. Deben ser compilados ya sea cuando el propio kernel es compilado, o posteriormente en un sistema que contiene las fuentes del kernel y la configuración de compilación para realizarlo de forma apropiada.
Mientras el módulo es cargado es posible ver su estado con lsmod:
$ lsmod
Module Size Used by
...
usb_storage 50309 0
vmnet 38408 13
fuse 74097 5
....
snd_hda_codec_analog 9813 1
snd_hda_codec_generic 47551 1 snd_hda_codec_analog
snd_hda_intel 19279 4
snd_usb_audio 140055 3
....
soundcore 5891 2 snd,snd_hda_codec
nouveau 911957 4
ahci 23547 8
libahci 21534 1 ahci
skge 29924 0
.....
El módulo se puede remover directamente como sigue:
$ sudo /sbin/rmmod module_name
Note que al remover un módulo no es necesario proveer ya sea la ruta completa del archivo o la extensión .ko.
En la mayoría de los casos los módulos no son cargados ni descargados con insmod y rmmod. En vez de eso, se usa modprobe, de la forma que se muestra en continuación:
$ sudo /sbin/modprobe module_name
$ sudo /sbin/modprobe -r module_name
en donde la segunda forma es usada para remover el módulo. Para que modprobe funcione, los módulos tienen que estar instalados en el lugar correcto, generalmente bajo /lib/modules/$(uname -r), donde $(uname -r) entrega la versión actual del kernel, por ejemplo 3.18.3.
Hay algunas cosas importantes para mantener en mente al cargar y descargar módulos:
- No es posible descargar un módulo que está siendo usado por uno u otros módulos, lo cual se puede determinar a partir de la lista que provee lsmod.
- No es posible descargar un módulo que está siendo usado por uno o más procesos, lo cual también puede ser visto en la salida de lsmod. Sin embargo, hay módulos que no llevan un registro de este tipo de referencias, como los módulos de los controladores de dispositivos de red, ya que sería muy difícil reemplazar temporalmente un módulo sin apagar y reiniciar gran parte de la pila de red.
- Cuando un módulo es cargado con modprobe, el sistema automáticamente carga todos los módulos de los cuales depende, los cuales necesitan ser cargados primero.
- Cuando un módulo es descargado con modprobe -r, el sistema descargará automáticamente cualquier otro módulo que esté siendo utilizado por éste, siempre y cuando no estén siendo usados de forma simultánea por otros módulos cargados.
modinfo puede ser usado para encontrar información acerca de los módulos del kernel (tanto si están actualmente cargados o no), como se muestra a continuación:
$ /sbin/modinfo my_module
$ /sbin/modinfo <pathto>/my_module.ko
Por ejemplo:
$ modinfo e1000
filename: /lib/modules/3.1.0/kernel/drivers/net/e1000/e1000.ko
version: 7.3.21-k8-NAPI
license: GPL
description: Intel(R) PRO/1000 Network Driver
author: Intel Corporation, <linux.nics@intel.com>
srcversion: E005D763BC7910379BDD09A
alias: pci:v00008086d00002E6Esv*sd*bc*sc*i*
alias: pci:v00008086d000010B5sv*sd*bc*sc*i*
alias: pci:v00008086d00001099sv*sd*bc*sc*i*
....
alias: pci:v00008086d00001000sv*sd*bc*sc*i*
depends: vermagic: 3.1.0 SMP preempt mod_unload
parm: TxDescriptors:Number of transmit descriptors (array of int)
parm: RxDescriptors:Number of receive descriptors (array of int)
parm: Speed:Speed setting (array of int)
parm: Duplex:Duplex setting (array of int)
parm: AutoNeg:Advertised auto-negotiation setting (array of int)
parm: FlowControl:Flow Control setting (array of int)
parm: XsumRX:Disable or enable Receive Checksum offload (array of int)
parm: TxIntDelay:Transmit Interrupt Delay (array of int)
parm: TxAbsIntDelay:Transmit Absolute Interrupt Delay (array of int)
parm: RxIntDelay:Receive Interrupt Delay (array of int)
parm: RxAbsIntDelay:Receive Absolute Interrupt Delay (array of int)
parm: InterruptThrottleRate:Interrupt Throttling Rate (array of int)
parm: SmartPowerDownEnable:Enable PHY smart power down (array of int)
parm: copybreak:Maximum size of packet that is copied to a new buffer on receive (uint)
parm: debug:Debug level (0=none,...,16=all) (int)
lo cual despliega información acerca de la versión, nombre de archivo, qué dispositivos de hardware puede manejar el controlador y qué parámetros pueden ser suministrados durante la carga.
Mucha de la información acerca de los módulos puede ser visualizada también en el árbol de directorios del seudosistema de archivos /sys; en el ejemplo anterior se podría mirar bajo /sys/module/e1000, y algunos - si es que no todos los parámetros - se pueden leer y/o escribir bajo /sys/module/e1000/parameters. Le mostraremos cómo configurarlos en el ítem siguiente.
En muchos casos es posible especificar valores de los parámetros al cargar el módulo, como se muestra aquí:
$ sudo /sbin/insmod <pathto>/e1000e.ko debug=2 copybreak=256
o de forma más fácil para un módulo que está presente en la ubicación adecuada del sistema:
$ sudo /sbin/modprobe e1000e debug=2 copybreak=256
Los archivos en el directorio /etc/modprobe.d controlan algunos parámetros que entran en juego cuando la carga se realiza con modprobe. Estos parámetros incluyen alias de nombre de módulo y opciones proveídas automáticamente. También es posible poner módulos específicos en una lista negra para evitar que sean cargados.
Los ajustes se aplican tanto a módulos que están cargados y descargados, y la configuración puede ser modificada a medida en que las necesidades cambian.
El formato de los archivos en /etc/modprobe.d es simple: un comando por línea, con líneas en blanco y otras con #, en las cuales se ignora el contenido (lo cual es útil para agregar comentarios). Una diagonal inversa al final de una línea causa que ésta continúe en la siguiente, lo cual le brinda un mayor orden al archivo.
¿Qué utilidad coincide con la descripción?
- Lista los módulos cargados.
- Carga o descarga módulos usando una base de datos de módulos preconstruídos.
- Descarga un módulo directamente.
- Reconstruye la base de datos de dependencia de módulos.
- Provee información acerca de un módulo.
Usted debería ser capaz de:
- Enumerar las ventajas de utilizar módulos del kernel.
- Usar insmod, rmmod y modprobe para cargar y descargar módulos del kernel.
- Saber cómo usar modinfo para encontrar encontrar información acerca de módulos del kernel.
8. Dispositivos y UDEV
Linux usa udev, una pieza de software inteligente para descubrir hardware y dispositivos periféricos tanto durante el inicio como después, una vez que son conectados al sistema. Los nodos de dispositivo son creados automáticamente, para luego utilizados por las aplicaciones y subsistemas del sistema operativo para comunicarse y transferir datos desde y hacia los dispositivos. Los administradores del sistema pueden controlar cómo opera udev a través de la creación de reglas especiales para asegurar que los resultados corresponden al comportamiento deseado.
Al final de este capítulo usted debería ser capaz de:
- Explicar el rol de los nodos de dispositivo y cómo se usan los números mayor y menor.
- Comprender la necesidad de usar udev y enumerar sus componentes principales.
- Describir cómo funciona el administrador de dispositivos udev.
- Identificar archivos de reglas de udev y aprender a crear reglas personalizadas.
Los dispositivos orientados a caracteres y bloques tienen entradas de sistemas de archivos asociados a ellos; por otro lado, los dispositivos de red en Linux no los poseen. Estos nodos de dispositivo pueden ser usados por programas para comunicarse con los dispositivos, usando llamadas al sistema E/S normal como open(), close(), read() y write(). Por otra parte, los dispositivos de red funcionan a través de la transmisión y recepción de paquetes, los cuales deben construirse a partir de la decodificación de flujos de datos, o ser reensamblados cuando son recibidos.
Un controlador de dispositivo puede administrar múltiples nodos de dispositivo, los cuales están localizados normalmente en el directorio /dev:
$ ls -l /dev
total 0
crw------- 1 coop audio 14, 4 Jul 9 01:54 audio
crw------- 1 root root 10, 62 Jul 9 01:54 autofs
lrwxrwxrwx 1 root root 4 Jul 9 01:54 cdrom -> scd0
lrwxrwxrwx 1 root root 4 Jul 9 01:54 cdrw -> scd0
crw------- 1 coop root 5, 1 Jul 9 06:54 console
....
lrwxrwxrwx 1 root root 4 Jul 9 01:54 dvd -> scd0
lrwxrwxrwx 1 root root 4 Jul 9 01:54 dvdwriter -> scd0
crw------- 1 root root 10, 228 Jul 9 01:54 hpet
crw-r----- 1 root kmem 1, 2 Jul 9 01:54 kmem
crw------- 1 root root 1, 11 Jul 9 01:54 kmsg
crw-r----- 1 root kmem 1, 1 Jul 9 01:54 mem
crwxrwxrwx 1 root root 1, 3 Jul 9 01:54 null
crw-rw---- 1 root root 10, 144 Jul 9 01:54 nvram
brw------- 1 coop disk 11, 0 Jul 9 01:54 scd0
....
brw-r----- 1 root disk 8, 0 Jul 9 01:53 sda
brw-r----- 1 root disk 8, 1 Jul 9 01:53 sda1
brw-r----- 1 root disk 8, 2 Jul 9 06:54 sda2
....
brw-r----- 1 root disk 8, 16 Jul 9 01:53 sdb
brw-r----- 1 root disk 8, 17 Jul 9 01:53 sdb1
brw-r----- 1 root disk 8, 18 Jul 9 01:53 sdb2
....
crw------- 1 coop audio 14, 1 Jul 9 01:54 sequencer
crw------- 1 coop audio 14, 8 Jul 9 01:54 sequencer2
crw-rw-rw- 1 root tty 5, 0 Jul 9 01:54 tty
crw-rw---- 1 root root 4, 0 Jul 9 14:54 tty0
crw------- 1 root root 4, 1 Jul 9 06:54 tty1
cr--r--r-- 1 root root 1, 9 Jul 9 01:53 urandom
....
crw-rw-rw- 1 root root 1, 5 Jul 9 01:54 zero
Los nodos de dispositivo pueden ser creados de la siguiente forma:
$ sudo mknod [-m mode] /dev/name <type> <major> <minor>
e.g., mknod -m 666 /dev/mycdrv c 254 1
Los números mayor y menor identifican el controlador asociado al dispositivo. En este esquema el controlador reserva de forma única un grupo de números. En la mayoría de los casos (con excepciones) los nodos de dispositivo del mismo tipo (de bloque o caracter) que tienen el mismo número mayor, usan el mismo controlador.
Al listar algunos nodos de dispositivo de la forma en que se muestra, se obtiene lo siguiente:
$ ls -l /dev/sda*
brw-rw---- 1 root disk 8, 0 Dec 29 06:40 /dev/sda
brw-rw---- 1 root disk 8, 1 Dec 29 06:40 /dev/sda1
brw-rw---- 1 root disk 8, 2 Dec 29 06:40 /dev/sda2
.......
Los números mayor y menor se muestran en el mismo lugar que el tamaño de archivo al visualizar archivos normales; en el ejemplo de arriba sería 8, 0, etc. Mientras que los usuarios finales probablemente no necesitarán referirse explícitamente a los números mayor y menor (ya que lo harán por nombre), los administradores de sistema podrían requerir hacerlo de vez e cuando, en caso que el sistema se confunda acerca de los dispositivos, o si se ha agregado hardware en tiempo de ejecución.
El número menor es usado sólo por el controlador de dispositivo para diferenciar entre los diferentes dispositivos que este puede controlar, o cómo son usados. Estos pueden corresponder a instancias diferentes de un mismo tipo de dispositivo (como la primera y segunda tarjeta de sonido o partición de disco duro), o diferentes modos de operación de un determinado dispositivo (como diferentes densidades en una unidad de disquete).
Los números de dispositivo tienen sentido en el espacio de usuario también. Las llamadas al sistema mknod() y stat() entregan información acerca de los números mayor y menor.
Los métodos de gestión de nodos de dispositivo se tornaron torpes y difíciles a medida en que Linux evolucionó. El número de nodos de dispositivo en /dev y sus subdirectorios alcanzó una cantidad entre 15.000 a 20.000 en la mayoría de las instalaciones durante la serie del kernel 2.4. Nodos para todo tipo de dispositivos - los que nunca van a ser utilizados en la mayoría de las instalaciones - todavía son creados de forma predeterminada, ya que los distribuidores no tienen la certeza de qué hardware estará presente en un sistema.
Por supuesto, muchos desarrolladores y administradores de sistema recortaron la lista a lo que realmente se necesita, lo cual es especialmente útil en sistemas embebidos, pero esto correspondió a una tarea esencialmente manual y propensa a generar errores.
Note que mientras los nodos de dispositivo no son archivos normales y no ocupan mucho espacio en el sistema de archivos, el tener directorios muy grandes disminuye la velocidad de acceso a los nodos de dispositivo, especialmente en el primer uso. Por otro lado, el agotamiento de los números mayor y menor disponibles requiere un enfoque más moderno y dinámico en cuanto a la creación y el mantenimiento de los nodos de dispositivo.
Lo ideal sería registrar dispositivos por nombre. Sin embargo, no es posible librarse de los números mayor y menor del todo, debido a que el estándar POSIX los exige (POSIX es un acrónimo de Interfaz de sistema operativo portable, una familia de estándares diseñados para asegurar la compatibilidad entre diferentes sistemas operativos).
El método udev crea nodos de dispositivo al vuelo, a medida en que son requeridos. No hay necesidad de mantener un gran cantidad de nodos de dispositivo que no van a ser usados nunca. La u en udev viene de usuario e indica que la mayoría del trabajo de creación, eliminación y modificación de nodos de dispositivo se realiza en el espacio de usuario.
udev maneja la generación dinámica de nodos de dispositivo y evolucionó de tal forma que reemplazó mecanismos como devfs y hotplug. Una característica interesante es el soporte de nombres persistentes para los dispositivos; los nombres no necesitan depender del orden en el cual los dispositivos son conectados. Tal comportamiento es controlado en las especificaciones de las reglas de udev.
udev se ejecuta como demonio (ya sea udevd o systemd-udevd) y monitorea un netlink socket. Cuando dispositivos nuevos son inicializados o removidos, el utilitario uevent del kernel envía un mensage a través del socket, el que es recibido por udev, el cual realiza la acción apropiada para crear o remover entradas de los nodos de dispositivo de acuerdo a las reglas.
Los tres componentes de udev son:
- La biblioteca libudev, la cual permite el acceso a la información de los dispositivos.
- El demonio udevd, el cual gestiona el directorio /dev .
- La utilidad udevadm para el control y diagnóstico.
La manera más apropiada de utilizar udev es tener un sistema original; el directorio /dev está vacío en el arranque del kernel y luego se puebla con nodos de dispositivo a medida en que se necesitan. Cuando se usa de esta forma, es necesario iniciar usando una imagen initramfs, la cual puede contener un conjunto de nodos de dispositivos preliminares, como también la infraestructura de udev.
A medida en que se agregan o remueven dispositivos desde el sistema - en este caso al trabajar con el subsistema hotplug - udev actúa ante la notificación de eventos para crear y remover nodos de dispositivo. La información necesaria para crearlos con los nombres adecuados, números mayor y menor, permisos, etc., es obtenida a través del registro existente en el seudosistema de archivos sysfs (montado en /sys) y un conjunto de archivos de configuración.
El archivo principal de configuración es /etc/udev/udev.conf. Este contiene información de dónde poner los nodos de dispositivo, permisos por defecto, dueños, etc. Por defecto, las reglas para los nombres de los dispositivos están ubicadas en el directorio /etc/udev/rules.d. A través de la lectura de la página man de udev es posible obtener una gran cantidad de información específica acerca de cómo configurar reglas para situaciones comunes.
Cuando udev recibe un mensaje desde el kernel acerca de dispositivos que están siendo añadidos o removidos, analiza los archivos de configuración en /etc/udev/rules.d/*.rules para determinar si hay reglas que apliquen al dispositivo en cuestión.
Entonces udev toma las acciones apropiadas, incluyendo:
- Asignación de nombre a los nodos de dispositivo.
- Creación de nodos de dispositivo y links simbólicos.
- Ajuste de permisos de archivo y dueño para los nodos de dispositivo.
- Realizar otras acciones para inicializar el dispositivo y ponerlo disponible.
Estas reglas son completamente personalizables.
Los archivos de las reglas de udev están localizados bajo /etc/udev/rules.d/<rulename>.rules , con nombres como los siguientes:
- 30-usb.rules
- 90-mycustom.rules
Por defecto, cuando udev lee los archivos de reglas busca archivos con el sufijo .rules. Si encuentra más de un archivo, los lee uno por uno, de manera lexicográfica, es decir, en orden alfabético ascendente. El nombre estándar de un archivo de reglas corresponde generalmente a un número de dos dígitos seguido por un nombre descriptivo de la regla en cuestión, para finalizar con el sufijo .rules.
El formato para una regla udev es simple:
<match><op>value [, ...] <assignment><op>value [, ... ]
Hay dos partes separadas que están definidas en una misma línea:
- La primera parte consiste en uno o más pares indicados por == . Estos tratan de coincidir con los atributos y/o características de un dispositivo a algún valor.
- La segunda parte consiste en una o más asignaciones clave-valor, las que asignan un valor a un nombre, tal como un nombre de archivo, pertenencia a un grupo, incluso permisos de archivo, etc.
Si no se encuentra una regla que coincida, se usa el nombre de nodo de dispositivo y otros atributos por defecto.
Aquí hay un ejemplo de un archivo de reglas para un dispositivo Fitbit:
$ cat /etc/udev/conf.d/rules.d/99-fitbit.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="2687", ATTR{idProduct}=="fb01", SYMLINK+="fitbit", MODE="0666"
$ cat /etc/udev/conf.d/rules.d/98-kexec.rules
SUBSYSTEM=="cpu", ACTION=="online", PROGRAM="/bin/systemctl try-restart kdump.service" SUBSYSTEM=="cpu", ACTION=="offline", PROGRAM="/bin/systemctl try-restart kdump.service" SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/systemctl try-restart kdump.service" SUBSYSTEM=="memory", ACTION=="remove", PROGRAM="/bin/systemctl try-restart kdump.service"
$ cat 80-kvm.rules
KERNEL=="kvm", GROUP="kvm", MODE="0666"
$ cat 99-fuse.rules
KERNEL=="fuse", MODE="0666",OWNER="root",GROUP="root"
¿Qué dispositivos de hardware se listan bajo /dev como archivos especiales? Seleccione todos los que apliquen:
Mouse
Adaptador de vídeo
Adaptador de red
Cámara web
Disco duro
Dispositivo USB
Usted debería ser capaz de:
- Explicar el rol de los nodos de dispositivo y cómo se usan los números mayor y menor.
- Comprender la necesidad del método udev y enumerar sus componentes principales.
- Describir cómo funciona el administrador de dispositivos udev.
- Identificar archivos de reglas de udev y saber crear archivos de reglas personalizadas.
9. Particionamiento y Formateo de Discos
El particionado y formateo de los discos duros disponibles es una parte crítica en la instalación del sistema. Es posible escoger diferentes esquemas en función del tamaño del sistema, el número de usuarios y sus necesidades. Otros ítems a tomar en cuenta es el tipo de hardware del que se dispone, particularmente el tipo de bus de datos al cual el sistema de almacenamiento está conectado.
Se debe tener mucho cuidado al configurar o modificar las tablas de particiones, ya que los errores de este tipo pueden ser muy destructivos.
Al final del capítulo usted debería ser capaz de:
- Describir y contrastar los tipos de discos duros y buses de datos más comunes.
- Explicar cómo es la geometría de un disco y otros conceptos de particionamiento.
- Comprender cómo los dispositivos de disco son nombrados y cómo identificar sus nodos de dispositivo asociados.
- Distinguir las distintas estrategias de particionamiento y saber seleccionarlas correctamente.
- Usar las utilidades blkid y fdisk.
- Respaldar y restaurar tablas de partición.
Existe una gran variedad de tipos de discos duros; cada uno está caracterizado por el tipo de bus de datos a través del cual se conecta, como también otros factores como velocidad, capacidad y cuán bien operan múltiples unidades de forma simultánea.
- IDE y EIDE (Entorno de desarrollo integrado e IDE mejorado)
Estos fueron el estándar en notebooks y PCs de escritorio por años. Sin embargo, son pequeños y lentos en comparación a hardware más moderno, por lo cual actualmente están obsoletos; de hecho, los controladores no están disponibles en máquinas actualizadas. - SATA (Serial ATA)
Este tipo fue diseñado para reemplazar a Parallel ATA (PATA) (el cual fue conocido originalmente como IDE). Tenían una mayor transferencia de datos, cables más pequeños y eran detectados como dispositivos SCSI por el sistema operativo, lo cual simplificó el tema de escribir controladores de software (entre otras cosas), aún siendo que el hardware no es realmente SCSI.
En comparación a PATA, SATA ofrece un cable de tamaño menor (7 pines), sustitución en caliente (hot swapping) y una transferencia de datos más rápida y eficiente. Los controladores más nuevos pueden manejar 16 GB/s, pero 3 GB/s y 6 GB/s son los valores más comunes en dispositivos del segmento usuario normal. - SCSI (Interfaz de Sistema para Pequeñas Computadoras)
Estos han sido el pilar de los servidores empresariales por décadas. Mientras que pueden tener una capacidad menor que los discos SATA, tienen a ser mucho más rápidos y a trabajar en paralelo mucho mejor, de la forma en la que se requiere para algunas configuraciones en RAID.
Hay varias versiones de SCSI: Fast, Wide, Ultra y UltraWide, lo cual torna un poco confusas las cosas. Además, hay muchos controladores de dispositivo diferentes, dependiendo del hardware específico. Eso no sucede en SATA, ya que en ese caso existen controladores estandarizados que pueden adaptarse a una gran variedad de hardware.
Los discos SCSI van desde un rango pequeño (bus de 8 bits) a uno amplio (bus de 16 bits), con una tasa de transferencia desde 5MB por segundo (un valor bajo, correspondiente a dispositivos SCSI estándar) a cerca de 160MB por segundos (Ultra-Wide SCSI-3).
La mayoría de los PCs usan unidades SCSI de un solo extremo o diferenciales. Desafortunadamente, los dos tipos no son compatibles entre sí. De todas formas, ambos tipos pueden coexistir en el mismo controlador.
Los controladores de una sola terminación soportan hasta 7 dispositivos, con una longitud de cable de cerca de 6 metros. Los controladores diferenciales soportan hasta 15 dispositivos, con una longitud máxima del cable de unos 12 metros. - SAS
El Serial Attached SCSI es un protocolo serial punto a punto nuevo, que viene a reemplazar a la interfaz SCSI. Las tasas de transferencia son similar a SATA, pero el rendimiento general es mejor. - USB
Los dispositivos de Bus Universal en Serie incluyen memorias y discos duros externos USB. El sistema operativo los ve como dispositivos SCSI.
En la misma categoría están las unidades SSD modernas (dispositivos de estado sólido), las cuales han bajado de precio, no tienen partes movibles, usan menos energía que las unidades de disco giratorio y tienen velocidades de transferencia más rápidas. Los SSD internos son instalados de forma similar y en los mismos encapsulados que los discos convencionales.
Los SSD todavía cuestan un poco más pero el precio está bajando. Es algo común tener discos SSD y convencionales en una misma máquina, en donde las operaciones de rendimiento crítico y de alto tráfico de datos son llevadas a cabo en las unidades SSD.
La geometría del disco es un concepto con una historia larga para dispositivos giratorios; se habla de cabezales, cilindros, pistas y sectores.
Para examinar la geometría del disco con fdisk:
$ sudo fdisk -l /dev/sda
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000001
Device Boot Start End Blocks Id System
/dev/sda1 * 1 3800 30522368 83 Linux
/dev/sda2 3800 3851 409518 83 Linux
.....
Tenga en cuenta que el uso de la opción -l sólo lista la tabla de particiones sin entrar en modo interactivo.
Los discos giratorios se componen de uno o más platos, cada uno de los cuales es leído por uno o más cabezales. Los cabezales leen una pista del plato a medida en que el disco gira.
Estas pistas circulares están divididas en bloques de datos llamados sectores, generalmente de 512 bytes de tamaño. Un cilindro es un grupo que está formado por una misma pista en todos los platos.
A medida en que el tiempo pasa la figura de la estructura física ha sido cada vez menos relevante, debido a que se conoce poco de la electrónica interna de la unidad. Además, los SSD no tienen partes móviles ni ninguna de las partes descritas anteriormente.
Actualmente los discos están siendo fabricados con sectores más grandes que 512 bytes; están disponibles en 4 KB. Mientras que sectores de tamaño más grandes pueden conducir a velocidades de transferencia mayores, el soporte del sistema operativo no está listo todavía para lidiar con tamaños grandes.
Los discos se dividen en particiones. En términos geométricos, estos consisten en grupos físicamente contiguos de sectores o cilindros.
Una de las particiones primarias puede ser designada como una partición extendida, la cual puede ser subdividida en particiones lógicas.
SCSI y estándares relacionados como SATA, suportan hasta 15 particiones en el disco. Las particiones 1-4 son primarias o extendidas; las particiones 5-15 son lógicas. Sólo puede haber una partición extendida, pero esta puede ser dividida en cuántas particiones lógicas se necesiten, hasta que se alcance el número máximo de particiones permitidas.
Por ejemplo, la primera unidad SCSI o SATA se denomina sda, la segunda sdb y así sucesivamente. En la primera unidad, /dev/sda1 es la primera partición primaria, /dev/sda2 es la segunda, etc.
Si creamos una partición extendida como /dev/sda3, esta podría ser dividida en particiones lógicas, con designaciones numéricas como /dev/sda5, /dev/sda6, etc.
Nota: Linux no requiere que las particiones comiencen o terminen en los límites de los cilindros, pero otros sistemas operativos podrían presentar problemas ante la misma situación. Por esta razón, las herramientas de particionamiento de Linux tratan de terminar en los límites, con el fin de integrarse bien con otros sistemas. Obviamente, las particiones tampoco deberían traslaparse.
Hay diversas razones que justifican didivir los datos del sistema en múltiples particiones, incluyendo:
- Separación
Es deseable aislar los datos de usuario y aplicaciones de los archivos del sistema operativo, la mayoría de los cuales son de lectura solamente, excepto durante la instalación y actualizaciones del sistema. Por ejemplo, /home, que contiene archivos específicos de los usuarios se suele poner en una partición por separado. - Datos compartidos
Múltiples sistemas operativos o máquinas pueden usar los mismos sistemas de archivos. Por ejemplo, /home podría estar montado como un directorio compartido en una red, a través de NFS. O alguien podría tener un sistema de inicio múltiple, incluso varias versiones de Linux, entre las cuales usted podría desear compartir /usr/local o /home, por dar un par de ejemplos. - Seguridad
Puede ser deseable imponer diferentes cuotas (espacio en disco), permisos y ajustes para diferentes partes del sistema. - Tamaño
Algunos datos son más bien constantes y otros variables o volátiles, y a menudo pueden incrementar su tamaño un poco. Por ejemplo, tales datos variables son almacenados generalmente en una partición montada en /var. Si la partición se queda sin espacio disponible, en el caso de estar en una partición por separado de /, será menos probable que el sistema se bloquee. - Rendimiento
Los datos que tienen que ser leídos con mayor frecuencia, en grandes trozos de información, serán accedidos más rápidamente si están en un disco rápido (como los SSD), o en términos anticuados, cercanos al centro del disco, en donde los tiempos de búsqueda son más cortos. - Intercambio (swap)
En los sistemas Linux es preferible tener un espacio de intercambio (conocido como swap) en una partición por separado, en lugar de un archivo en alguna partición que esté siendo utilizada con otro propósito. Esto tiene una ventaja secundaria, ya que los esquemas de hibernación utilizan el espacio en la partición de intercambio.
Un esquema común de particionamiento contiene una partición /boot, una para el sistema raíz /, una partición de intercambio y otra para el directorio /home.
Tenga en cuenta que es más difícil redimensionar una partición después de su creación e instalación del sistema. Recomendamos que haga un plan inteligente al respecto.
Discutiremos acerca de diseños de sistemas de archivos y el impacto de las particiones en ellos más adelante.
La tabla de partición del disco está contenida en el Registro de arranque principal (MBR), la cual es de 512 bytes de longitud y cuya estructura está definida por una convención que es independiente del sistema operativo.
La tabla de partición tiene 64 bytes de largo y está ubicada después del byte 446 del registro de arranque. Nota para los curiosos: hay 2 bytes más al final del MBR, lo cual se conoce como el número mágico, firma del MBR, o marca de final de sector, que tiene siempre el valor 0x55AA.
Los primeros 446 bytes están reservados para código máquina. Por lo general, forman parte de un programa de cargador de arranque como GRUB.
Sólo una partición en un disco específico puede ser marcada como activa. Cuando el sistema inicia, el cargador de booteo maestro busca ítems para cargar en esa partición.
Cada entrada en la tabla de partición tiene 16 bytes de largo y describe una de las cuatro posibles particiones primarias. La información que tiene cada una es la siguiente:
- Bit activo
- Dirección de inicio en formato cilindro/cabezal/sectores (CHS), lo cual es ignorado por Linux de todas formas
- Código del tipo de partición, indicando: xfs, LVM, ntfs, ext4, swap, etc
- Dirección final en CHS (también ignorado por Linux)
- Sector the inicio, contando linealmente desde 0
- Número de sectores en la partición.
Linux usa sólo los últimos dos campos para direccionamiento, utilizando el método de direccionamiento de bloque lógico (LBA).
El kernel Linux interactúa a bajo nivel con los discos a través de nodos de dispositivos que normalmente se encuentran en el directorio /dev. Generalmente los nodos de dispositivos son accedidos sólo a través de la infraestructura del sistema de archivos virtual del kernel; si se accede de cualquier otra forma a los nodos de dispositivo, es posible destruir un sistema de archivos completo. Eso es justamente lo que se hace al formatear una partición, como en el siguiente comando:
$ sudo mkfs.ext4 /dev/sda9
Los nodos de dispositivo para discos SCSI y SATA siguien una convención de nombres simple:
- El primer disco duro es /dev/sda.
- El segundo disco duro es /dev/sdb.
- etc.
Las particiones son enumeradas como sigue:
- /dev/sdb1 es la primera partición del segundo disco.
- /dev/sdc4 es la cuarta partición del tercer disco.
En las sentencias de arriba, sd puede ser un disco SCSI o SATA. Cuando aún se encontraban discos IDE, eran llamados /dev/hda3, /dev/hdb , etc.
El comando ls -l /dev mostrará los nodos de dispositivo disponibles.
Para dispositivos SCSI necesitamos elaborar un poco más en lo que se entiende por primer disco duro, segundo, etc. Estos están determinados por la combinación del número ID/número del controlador.
La designación de la unidad (a, b, c, etc.) está basada principalmente en el número de ID del dispositivo SCSI en vez de su posición en el bus mismo.
Por ejemplo, si tuviéramos dos controladoras SCSI, uno con ID 1 y otro con ID 3 en la controladora 0; uno con ID 2 y otro con ID 5 en la controladora 1 (note que el ID 2 está en la última unidad):
- ID 1 sería /dev/sda
- ID 3 sería /dev/sdb
- ID 2 (en la controladora 1) sería /dev/sdc
- ID 5 sería /dev/sdd
blkid es una utilidad para localizar dispositivos de bloque y entregar información acerca de sus atributos. Funciona con la biblioteca libblkid. Puede tomar como argumento un dispositivo en particular o una lista.
$ sudo blkid /dev/sda*
dev/sda: PTTYPE="dos"
/dev/sda1: LABEL="boot" UUID="b0fa22fc-8882-4f1c-bc16-6cf7fc4e9454" TYPE="ext4" PTTYPE="dos"
/dev/sda10: UUID="JQshRp-Jxa5-0oiC-X1Oe-si8d-lRQD-48aYNt" TYPE="LVM2_member"
/dev/sda11: LABEL="RHEL7" UUID="b8beaf53-af11-4b14-9e7d-b17069f336ae" TYPE="ext4" PTTYPE="dos"
/dev/sda12: LABEL="SWAP" UUID="2b2603f9-a701-4f91-b284-426769f50e51" TYPE="swap"
/dev/sda3: PTTYPE="dos"
/dev/sda5: LABEL="RHEL6-64" UUID="89a3c451-847f-40a1-97af-64a56fe27474" TYPE="ext4" PTTYPE="dos"
/dev/sda6: UUID="YJ2PA3-GSsm-m9rH-XNUM-Ca2X-fkju-OYtiO8" TYPE="LVM2_member"
/dev/sda7: LABEL="RHEL7XFS" UUID="178d0092-4154-4688-af24-cda272265e08" TYPE="xfs"
/dev/sda8: UUID="NdnbYk-ACCB-9UTX-i3kc-rK0m-Fbht-KjJZwP" TYPE="LVM2_member"
/dev/sda9: UUID="CMc2EP-ijCM-jA8V-ZH5M-B6AA-z0TD-ILMFFE" TYPE="LVM2_member"
blkid funcionará solamente en dispositivos que contienen datos, es decir, una partición vacía no generará un identificador de bloque UUID.
blkid tiene dos formas principales de operación: ya sea buscando un dispositivo con un par específico NOMBRE=valor, o desplegando pares de NOMBRE=valor para uno o más dispositivos.
Si no se especifican argumentos, se listarán todos los dispositivos. Existe un buen número de opciones que indican cómo especificar qué atributos se desean listar.
Una herramienta relacionada es lsblk, la cual presenta los resultados en un formato de árbol, como se muestra abajo.
$ lsblk -i
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
|-sda1 8:1 0 100M 0 part /boot_master
|-sda3 8:3 0 1K 0 part
|-sda5 8:5 0 11.7G 0 part /RHEL6-64
|-sda6 8:6 0 36.2G 0 part
| `-VG-dead 254:5 0 60G 0 lvm /DEAD
|-sda7 8:7 0 12G 0 part
|-sda8 8:8 0 353.2G 0 part
| |-VG-tmp 254:0 0 2G 0 lvm
| |-VG-local 254:1 0 24G 0 lvm /usr/local
| |-VG-src 254:2 0 16G 0 lvm /usr/src
| |-VG-virtual 254:3 0 225G 0 lvm /VIRTUAL
| |-VG-iso_images 254:4 0 60G 0 lvm /ISO_IMAGES
| |-VG-dead 254:5 0 60G 0 lvm /DEAD
| |-VG-audio 254:6 0 12G 0 lvm
| `-VG-pictures 254:7 0 12G 0 lvm /PICTURES
|-sda9 8:9 0 23.2G 0 part
| |-VG-virtual 254:3 0 225G 0 lvm /VIRTUAL
| `-VG-dead 254:5 0 60G 0 lvm /DEAD
|-sda10 8:10 0 11.7G 0 part
| |-VG-virtual 254:3 0 225G 0 lvm /VIRTUAL
| |-VG-dead 254:5 0 60G 0 lvm /DEAD
| `-VG-pictures 254:7 0 12G 0 lvm /PICTURES
|-sda11 8:11 0 15.7G 0 part /
`-sda12 8:12 0 2G 0 part [SWAP]
sr0 11:0 1 1024M 0 rom
Los sistemas Linux deberían tener un mínimo de dos particiones:
- /(root): utilizado para todo el sistema de archivos lógico
- En la práctica la mayoría de las instalaciones tendrán más de un sistema de archivos y más de una partición, las cuales trabajan unidas a través de los puntos de montaje.
- Con la mayoría de los tipos de sistemas de archivos es difícil redimensionar la partición raíz; usando LVM, lo cual discutiremos más adelante, podemos facilitar esta tarea.
Aunque si bien es cierto es posible correr Linux con sólo la partición raíz, la mayoría de los sistemas usan más particiones para realizar respaldos de forma más fácil, usar de forma más eficiente las unidades de disco e implementar una mejor seguridad.
- Intercambio: se usa como una extensión de la memoria física; páginas de memoria que no tienen un respaldo en archivo físico, pueden ser movidas al disco hasta que se necesiten nuevamente.
- La recomendación usual es que el tamaño del área de intercambio debería ser igual al de la memoria física, aunque a veces se recomienda usar el doble. Sin embargo, la opción adecuada depende de los escenarios de usos del sistema, como también de las capacidades de hardware. Ejemplos de este tema pueden ser encontrados en https://help.ubuntu.com/community/SwapFaq y en http://www.novell.com/support/kb/doc.php?id=7010157.
- El sistema puede tener múltiples particiones o archivos de intercambio.
- En un sistema de un sólo disco, trate de ubicar la partición de intercambio al centro del mismo; en sistemas de discos múltiples, trate de repartir áreas de intercambio en los discos.
- Agregar más y más áreas de intercambio no ayudará necesariamente, ya que a partir de cierto punto se vuelve inútil. En los casos en que aparentemente falte memoria, es necesario agregar más memoria física o reevaluar la configuración del sistema.
El área de intercambio es usado como memoria virtual; cuando las páginas de procesos son movidas fuera de la memoria física, generalmente son almacenadas en el área de intercambio.
Particionar y reparticionar discos son operaciones peligrosas. Para tener la posibilidad de volver a la situación original si algo sale mal, es necesario saber cómo realizar respaldos y restaurar tablas de particiones.
Es bastante simple realizar una copia de seguridad con dd, como sigue:
$ sudo dd if=/dev/sda of=mbrbackup bs=512 count=1
lo cual respaldará el MBR en el primer disco, incluyendo la tabla de particiones de 64 bits, la cual es parte de ella.
El MBR puede ser restaurado de ser necesario, de la siguiente forma:
$ sudo dd if=mbrbackup of=/dev/sda bs=512 count=1
Note que los comandos mencionados copiarán solamente la tabla de partición primaria; no se harán cargo de cualquier tabla de partición que esté almacenada en otras partitiones (como particiones extendidas, por ejemplo).
Nota: usted debería asumir que modificar la tabla de partición del disco podría eliminar toda la información de todos los sistemas de archivos en el disco (no debería, pero es mejor ser precavido). Por lo tanto, siempre es prudente realizar una copia de seguridad de toda la información antes de realizar cualquier trabajo de este tipo.
En particular, es necesario ser cuidadoso al usar dd: un error simple de tipeo o una opción usada erróneamente podría destruir la información completa del disco, ¡en cualquier caso lo mejor es hacer respaldos!
Hay una serie de utilidades que pueden ser usadas para modificar las tablas de partición:
- fdisk Es un editor de tabla de particiones que tiene un menú. Es el más estándar y uno de los editores más flexibles. Esta es la única herramienta de este tipo que discutiremos.
- sfdisk es un programa de edición de particiones no interactivo, el cual es útil para hacer scripts. ¡Use esta herramienta con mucho cuidado!
- parted es el programa de manipulación de particiones del proyecto GNU. Puede crear, eliminar, redimensionar y mover particiones (incluyendo ciertos sistemas de archivos).
- gparted es una interfaz gráfica de parted, la cual es utilizada ampliamente.
Muchas distribuciones Linux tienen una versión Live CD que se puede ejecutar ya sea desde un CDROM o un dispositivo USB. Esos medios suelen incluir una copia de gparted, por lo cual puede ser usado fácilmente como una herramienta gráfica de particionamiento en discos que no están siendo utilizados.
Note que gparted puede realizar muchas operaciones más que sólo agregar y eliminar particiones (y las demás operaciones que realiza fdisk), como asignar el tipo de partición. Es posible mover, redimensionar y formatear particiones, lo cual implica entender los detalles de diversos tipos de sistemas de archivos. Lo anterior va mucho más lejos de las funciones esenciales de un editor de particiones.
Si bien es cierto que esto es muy útil, es difícil hacerlo bien y los errores pueden tener consecuencias serias. Por lo anterior, se recomienda ir a la línea de comandos y realizar cada una de estas operaciones por separado, con herramientas de bajo nivel (como fdisk). De hecho Red Hat Enterprise Linux ya no soporta gparted.
fdisk estará incluido siempre en toda instalación de Linux, por lo cual es buena idea aprender a usarlo. Usted debe ser root para ejecutar fdisk. Puede ser algo complejo de usar y se recomienda hacerlo con precaución.
La interfaz de fdisk es simple y posee un menú de texto. Se inicia en un disco en particular de la siguiente forma:
$ sudo fdisk /dev/sdb
los principales comandos (de una letra) son:
- m: Despliega el menú.
- p: Lista la tabla de particiones.
- n: Crea una partición nueva.
- d: Elimina una partición.
- t: Cambia el tipo de partición.
- w: Escribe la información nueva de la tabla de particiones y sale.
- q: Sale sin realizar cambios.
Afortunadamente no se realizan cambios hasta que la tabla de particiones es escrita en el disco, presionando w. Por lo tanto, es importante revisar que la tabla de partitiones es correcta (con la tecla p), antes de escribir a disco con w. Si algo está mal, usted puede salir de forma segura con la tecla q (a menos que ya haya guardado los cambios).
El sistema no utilizará la nueva tabla de partición hasta el próximo reinicio. Sin embargo, es posible usar el siguiente comando:
$ sudo partprobe -s
para tratar de leer la tabla de partición modificada. Sin embargo, esto no siempre funciona de manera confiable y lo mejor es reiniciar antes de formatear particiones nuevas y realizar otras operaciones, ya que mezclar particiones o sobreponer una en otra puede ser catastrófico.
En cualquier momento es posible ejecutar el siguiente comando:
$ cat /proc/partitions
con el fin de visualizar qué particiones reconoce el sistema operativo.
Al agregar un disco interno nuevo a un servidor existente, ¿cuál sería el mejor orden lógico para ejecutar los siguientes pasos con el fin de montar el disco de forma persistente (luego de reiniciar el sistema)?
Crear una partición nueva.
Formatearla con un sistema de archivos.
Editar /etc/fstab.
Reiniciar el sistema.
Los nombres tradicionales para dispositivos de almacenamiento tales como /dev/sda no son confiables para la identificación de un disco, ya que al cambiar el puerto en el cual está conectado el disco, o al conectar el disco a otro servidor puede resultar en un nombre diferente.
Linux permite el uso de etiquetas y UUIDs para asignar nombres a los dispositivos de almacenamiento. ¿Cómo se llama la herramienta que despliega los UUIDs de los dispositivos de bloque que están conectados actualmente al sistema?
Usted debería ser capaz de:
- Describir y contrastar los tipos más comunes de discos duros y buses de datos.
- Explicar cómo es la geometría de un disco y otros conceptos de particionamiento.
- Comprender cómo se les asigna el nombre a los dispositivos de disco y cómo identificar los nodos de dispositivo asociados.
- Distinguir y seleccionar entre diferentes estrategias de particionamiento.
- Use utilities such as blkid and fdisk.
- Respaldar y restaurar tablas de partición.
10. Cifrado de Discos
Los sistemas de archivos pueden ser cifrados para proteger la información de accesos no autorizados y de intentos de corromper los datos que contienen. El cifrado puede ser elegida en la instalación o ser incorporada más tarde. Las distribuciones de Linux usan a menudo el método LUKS y llevan a cabo tareas de cifrado usando la herramienta cryptsetup.
Al final del capítulo usted debería ser capaz de:
- Proveer buenas razones para el uso de cifrado y saber cuándo se requiere.
- Ententer cómo opera LUKS a través del uso de cryptsetup.
- Ser capaz de configurar y usar particiones y sistemas de archivos cifrados.
- Saber cómo configurar el sistema para montar particiones cifradas en el arranque.
El cifrado de datos debería ser usado en cualquier lugar en donde hay información sensible que está siendo almacenada y transmitida. La configuración y el uso de cifrado a nivel de dispositivo de bloque es una de las protecciones más robustas contra los daños producidos por pérdida o compromiso de información contenida en discos duros y otros medios.
Las distribuciones de Linux modernas ofrecen la alternativa de cifrar todas o algunas de las particiones durante la instalación. También es fácil crear y formatear particiones cifradas posteriormente, pero no es posible cifrar una partición existente sin tener que copiar los datos a ella.
Las distributiones de Linux modernas proveen un cifrado a nivel de dispositivo de bloque principalmente a través de LUKS (Linux Unified Key Setup). Usar este tipo de cifrado es altamente recomendable para sistemas portátiles como laptops, tabletas y teléfonos inteligentes.
LUKS está basado en cryptsetup, una herramienta potente que también puede usar otros métodos como volúmenes dm-crypt (planos), loop-AES y formato compatible con TrueCrypt. No vamos a discutir esas alternativas, ya que LUKS es el método estándar y usado más a menudo en Linux (fue diseñado originalmente para Linux, pero también ha sido exportado a otros sistemas operativos).
El módulo del kernel dm-crypt usa la infraestructura de device mapper del kernel, la cual es usada también de forma importante en LVM, lo cual veremos más adelante.
Debido a que LUKS almacena toda la información necesaria en la cabecera de la partición, es simple migrar particiones a otros discos o sistemas.
LUKS también puede ser usado para cifrar particiones de intercambio de forma transparente.
Básicamente, todo se realiza con el programa cryptsetup. Una vez que los volúmenes han sido cifrados, pueden ser montados y desmontados con las utilidades normales.
La sintaxis común de un comando es la siguiente:
cryptsetup [OPTION...] <action> <action-specific>
y una lista con todas las opciones puede ser generada con:
$ cryptsetup --help
Asumiendo que la partición LVM /dev/VG/MYSECRET ya existe, los siguientes comandos configurarán el cifrado, la pondrán a disposición de LUKS, le darán formato, la usarán y desmontarán.
Lo primero que se debe realizar es darle formato LUKS a la partición:
$ sudo cryptsetup luksFormat /dev/VG/MYSECRET
Se le pedirá ingresar una contraseña, la cual tendrá que usar para abrir el volumen cifrado más tarde. Note que tendrá que hacer esto una vez solamente, durante la configuración del cifrado.
Usted podría enfrentar ciertas dificultades si el kernel del sistema no soporta el método de cifrado que usa cryptsetup por defecto. En ese caso usted puede examinar /proc/crypto para ver los métodos que soporta el sistema, y luego especificar uno, como se muestra a continuación:
$ sudo cryptsetup luksFormat --cipher aes /dev/VG/MYSECRET
Usted puede abrir el volumen en cualquier momento, con el siguiente comando:
$ sudo cryptsetup --verbose luksOpen /dev/VG/MYSECRET SECRET
tras lo cual se le pedirá ingresar la contraseña. Luego de eso es posible formatear el sistema de archivos:
$ sudo mkfs.ext4 /dev/mapper/SECRET
Y montarlo:
$ sudo mount /dev/mapper/SECRET /mnt
A partir de este momento usted dispone de una partición sin cifrar montada en /mnt, con la cual puede trabajar a su gusto. Cuando haya terminado de realizar las tareas en cuestión, la puede desmontar de la siguiente forma:
$ sudo umount /mnt
luego remueva la asociación mapper por el momento (siempre podrá usar la partición nuevamente):
$ sudo cryptsetup --verbose luksClose SECRET
Para montar una partición cifrada en el arranque hay que satisfacer dos condiciones:
- Agregar una línea apropiada en /etc/fstab. No hay nada de especial en esta línea y no se refiere al cifrado en ningún sentido.
- Agregar una entrada a /etc/crypttab. Puede ser tan simple como esto:
SECRET /dev/mapper/MYSECRET
Usted puede hacer otras cosas en este archivo, como especificar la contraseña si no desea ingresarla en el arranque (lo cual sería contraproducente para la seguridad del sistema). Haga man crypttab para ver todo lo que puede hacer con este archivo.
Gracias a LUKS, crear particiones cifradas en distribuciones Linux modernas es muy fácil. Organice los siguientes pasos para preparar y montar una partición cifrada en el mejor orden lógico:
Crear una partición para el dispositivo de bloque cifrado.
Darle formato con cryptsetup.
Crear la contraseña para descifrar el dispositivo.
Darle formato con un sistema de archivos estándar, como ext4.
Montar el sistema de archivos en el dispositivo de bloque.
Usted debería ser capaz de:
- Proveer buenas razones para el uso de cifrado y saber cuándo se requiere.
- Ententer cómo opera LUKS a través del uso de cryptsetup.
- Ser capaz de configurar y usar particiones y sistemas de archivos cifrados.
- Saber cómo configurar el sistema para montar particiones cifradas en el arranque.
11. Sistemas de archivos Linux y el VFS
Los sistemas Linux son capaces de usar una amplia variedad de sistemas de archivos. Esta versatilidad se consigue a través de la capa de abstracción del Sistema de Archivos Virtual (VFS), la cual se sitúa entre el software y el sistema de archivos en el disco. Los sistemas de archivos transaccionales avanzados se han convertido en el estándar en las distribuciones empresariales.
Al final del capítulo usted debería ser capaz de:
- Explicar la organización básica de un sistema de archivos.
- Comprender el rol del VFS.
- Conocer qué sistemas de archivos están disponibles en Linux y cuáles son los que pueden ser usados en su sistema actual.
- Comprender porqué los sistemas de archivos con journaling representan avances importantes.
- Discutir el uso de sistemas de archivos especiales en Linux.
Los programas necesitan leer y escribir archivos, en vez de tener que lidiar con los lugares físicos en el hardware en el cual los archivos están almacenados.
Los archivos y sus nombres son una abstracción de la capa física de E/S. Escribir en el disco de forma directa (ignorando la capa del sistema de archivos) es muy peligroso y se realiza sólo por programas de bajo nivel del sistema operativo, nunca por una aplicación de usuario.
Los sistemas de archivos locales generalmente residen en una partición de disco, la cual puede ser una partición física en un disco o una partición lógica controlada por un Logical Volume Manager (LVM). Los sistemas de archivos también pueden estar en la red, de tal forma que el encapsulado físico queda totalmente oculto al sistema local.
Todos los sistemas Linux usan una jerarquía de árbol invertido del directorio raíz (/). Mientras que todo el árbol puede estar contenido en un sistema de archivos local en una partición, usualmente hay varias particiones (o sistemas de archivos de red) trabajando de forma unida en los puntos de montaje. Estos también pueden incluir medios extraíbles como dispositivos USB, discos ópticos, etc.
Adicionalmente, algunos sistemas de archivos seudovirtuales (abstracciones útiles que existen en memoria solamente) serán montadas en el árbol; estos incluyen /proc, /sys, /dev y tal vez /tmp, como también /run.
Cada uno de los elementos montados en el árbol puede tener su propio tipo de sistema de archivos. Pero ante las aplicaciones y el sistema operativo se muestra como una una sola estructura de árbol unificado.
Linux implementa un Virtual File Sistem (VFS), sistema de archivos virtual, como lo hacen todos los sistemas operativos modernos. Cuando una aplicación necesita acceder a un archivo, ésta interactúa con la capa de abstracción del VFS, el cual traduce todas las llamadas E/S (operaciones de lectura/escritura, etc) en código específico relacionado con el sistema de archivos real en particular.
De esta forma, tanto el sistema de archivos real como el medio físico y hardware sobre el cual reside, no necesitan ser considerados por las aplicaciones. Por otro lado, los sistemas de archivos de red (como NFS) pueden ser manejados de forma transparente.
Esto permite a Linux trabajar con una variedad de sistemas de archivos mayor que cualquier otro sistema operativo. Este atributo ha sido un factor importante en su éxito.
La mayoría de los sistemas de archivos tienen acceso de lectura y escritura completo, mientras que otros sólo tienen acceso a lectura y tal vez de escritura de tipo experimental. Algunos tipos de sistemas de archivos - especialmente aquellos que no están basados en UNIX - pueden requerir mayor manipulación para ser representados en el VFS.
Variantes como vfat no diferencias permisos de lectura/escritura/ejecución para los campos dueño/grupo/todos; el VFS tiene que suponer cómo especificar diferentes permisos para los tres tipos de usuarios, y tal asunto puede tener influencia en las operaciones de montaje. Existen implementaciones que no basan su soporte en el sistema de archivos del kernel, como el de lectura/escritura ntfs-3g (http://www.tuxera.com/community/ntfs-3g-download), el cual si bien es cierto es confiable, tiene un rendimiento menor que aquellos sistemas de archivos con soporte en el kernel.
Nombre | Descripción |
---|---|
ext2 | Sistema de archivos nativo de Linux |
minix | Antecesor de ext2 |
proc | Usado para /proc/ |
msdos | MSDOS |
umsdos | Extensiones a MSDOS |
vfat | Windows VFAT (incluye FAT32, FAT, etc.) |
ntfs | Windows NT NTFS (sólo lectura) |
sysv | SystemV/Xenit/Coherent FS |
hpfs | OS/2 HPFS |
ufs | Sun |
udf | CD R/W, DVD |
hfs | Apple MacIntosh Filesystem (HFS) |
hfs+ | Apple MacIntosh Extended HFS |
befs | BeOS filesystem |
jffs, jffs2 | Journalling Flash Filesystem |
iso9660 | cdrom etc., incluyendo extensiones Joliet |
cramfs | Compressed read-only filesystem (sistema de archivos comprimido de sólo lectura) |
romfs | Small read-only filesystem (sistema de archivos pequeño de sólo lectura) |
tmpfs | Ram disk de intercambio |
ramfs | Ram disk, de un sistema de archivos, por ejemplo |
gfs2 | Sistema de archivos de clúster de Red Hat |
nfs | Network Filesystem (hasta la versión 4) |
smb | Samba networking |
ncp | Novell Netware FS que usa Protocolo NCP |
coda | Sistema de archivos distribuido experimental |
afs | Sistema de archivos distribuido Andrew, de Carnegie Mellon |
ocfs2 | Sistema de archivos de clúster de Oracle |
Una serie de nuevos sistemas de archivos de alto rendimiento incluyen la capacidad de journaling completo.
Los sistemas de archivos con journaling se recuperan muy rápidamente de crashes/congeladas o caídas con poco o nada de corrupción. Si bien esto tiene el costo de tener que realizar más operaciones, las mejoras adicionales pueden compensar el costo con creces.
En un sistema de archivos con journaling las operaciones se agrupan en transacciones. Una transacción debe ser llevada a cabo sin errores, de forma completa, ya que de otra manera el sistema de archivos no es modificado. Se mantiene un archivo de registro para las transacciones. Cuando ocurre un error, por lo general sólo la última transacción necesita ser examinada.
Los siguientes sistemas de archivos con journaling están disponibles de forma libre en Linux:
- ext3 fue una extensión del sistema de archivos anterior ext2, el cual no tenía journaling.
- ext4 es un avance significativo derivado de ext3. Las características incluyen extents, bloques de 48 bits y de hasta 16 TB de tamaño. La mayoría de las distribuciones de Linux han usado ext4 como el sistema de archivos por defecto por varios años a la fecha.
- reiserfs fue la primera implementación de journaling usada en Linux, pero perdió su liderazgo y su desarrollo fue abandonado.
- JFS fue originalmente un producto de IBM y fue portado desde el sistema operativo AIX.
- XFS originalmente fue un producto de SGI y se portó desde el sistema operativo IRIX. RHEL 7 adoptó a XFS como su sistema de archivos por defecto.
- btrfs es el sistema de archivos con journaling más nuevo y todavía está bajo un desarrollo fuerte y rápido.
Usted puede ver una lista de los tipos de sistemas de archivos soportados por el kernel Linux en ejecución con el siguiente comando:
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev ramfs
nodev bdev
nodev proc
nodev cgroup
nodev cpuset
nodev tmpfs
nodev devtmpfs
nodev binfmt_misc
nodev debugfs
nodev sockfs
nodev pipefs
nodev devpts
squashfs
nodev hugetlbfs
iso9660
nodev mqueue
ext3
ext2
ext4
fuseblk
nodev fuse
nodev fusectl
nodev autofs
nodev rpc_pipefs
nodev nfsd
Note que para algunos tipos de sistemas de archivos adicionales, el código de soporte puede ser cargado sólo cuando el sistema trata de acceder a la partición que los contiene.
Linux hace un uso amplio de sistemas de archivos especiales para ciertas tareas. Estos son particularmente útiles para acceder varias estructuras de datos y ajustes de rendimiento del kernel, o para implementar funciones específicas.
Sistema de archivos | Punto de montaje | Propósito |
---|---|---|
rootfs | Ninguno | Provee un directorio raíz vacío durante la carga del kernel. |
hugetlbfs | Cualquiera | Provee acceso a páginas extendidas (2 o 4 MB en X86). |
bdev | Ninguno | Usado para dispositivos de bloque. |
proc | /proc | Seudosistema de archivos a través del cual se accede a muchas estructuras y subsistemas. |
sockfs | Ninguno | Usado por sockets BSD. |
tmpfs | Cualquiera | Disco RAM para intercambio, con redimensionamiento. |
shm | Ninguno | Usado por memoria compartida de System V IPC. |
pipefs | Ninguno | Usado para pipes (tuberías). |
binfmt_misc | Cualquiera | Usado por varios formatos ejecutables. |
devpts | /dev/pts | Usado por seudoterminales Unix98. |
usbfs | /proc/bus/usb | Usado por el subsistema USB para dispositivos dinámicos. |
sysfs | /sys (o en otra parte) | Usado como árbol de dispositivo. |
debugfs | /sys/kernel/debug (o en otra parte) | Usado para depuración de acceso a archivos. |
Note que algunos de esos sistemas de archivos especiales no tienen punto de montaje; esto significa que las aplicaciones de usuario no interactúan con ellos, pero el kernel lo hace, tomando ventaja de las capas y el código del VFS.
El archivo especial _______________________ contiene una lista de todos los sistemas de archivos soportados por el sistema operativo.
¿Cuáles son las ventajas de tmpfs sobre un disco RAM? Seleccione todas las respuestas que apliquen:
No es necesario formatearlas antes de usar.
Utiliza la memoria de una forma eficiente.
El tamaño máximo del sistema de archivos es 4GB.
Puede usar tanto RAM como área de intercambio.
Actualmente usted debería ser capaz de:
- Explicar la organización básica de un sistema de archivos.
- Comprender el rol del VFS.
- Conocer qué sistemas de archivos están disponibles en Linux y cuáles son los que pueden ser usados en su sistema actual.
- Comprender porqué los sistemas de archivos con journaling representan avances importantes.
- Discutir el uso de sistemas de archivos especiales en Linux.
12. Características de los sistemas de archivos: atributos, creación, verificación, montado
Las características importantes de los sistemas de archivos incluyen inodos, archivos de directorio y tanto enlaces simbólicos (soft) como duros (hard). Los atributos extendidos amplían los permisos de archivos tradicionales de UNIX. Existen utilidades específicas asociadas a los sistems de archivos que realizan tareas como crearlos y darles formato, comprobar si hay errores y repararlos. También montar y desmontar los sistemas de archivos durante el arranque o en un momento posterior.
Al final del capítulo usted debería ser capaz de:
- Estar familiarizado con conceptos tales como inodos, archivos de directorios y atributos extendidos.
- Crear y formatear sistemas de archivos.
- Verificar y reparar errores en sistemas de archivos.
- Montar y desmontar sistemas de archivos.
Un inodo es una estructura de datos en el disco que describe y almacena los atributos del archivo, incluyendo su localización. Cada archivo está asociado con su propio inodo. La información almacenada en el inodo incluye lo siguiente:
- Permisos
- Usuario y grupo propietario
- Tamaño
- Registros de tiempo (al nanosegundo)
- Momento en el cual se realizó el último acceso
- Momento en el cual se realizó la última modificación del contenido
- Momento en el cual se realizó la última modificación del inodo.
Nota: los nombres de los archivos no se almacenan en el inodo asociado al archivo, sino que lo hacen en el archivo de directorio.
Toda la actividad E/S concerniente a un archivo usualmente involucra el inodo del archivo como información que debe ser actualizada.
Un archivo de directorio es un tipo de archivo en particular, el cual es usado para asociar nombres de archivo a inodos. Hay dos formar de asociar (o enlazar) un nombre de archivo con un inodo:
- Con enlaces duros, que apuntan a un inodo.
- Con enlaces simbólicos, los cuales apuntan a un nombre de archivo el cual tiene un inodo asociado.
Cada asociación de un contenido de los archivos de directorio y un inodo es conocido como un enlace. Enlaces adicionales pueden ser creados usando el comando ln.
Debido a que es posible (y muy común) que dos o más entradas de directorio apunten al mismo inodo (enlaces duros), un archivo puede ser conocido por múltiples nombres, en los que cada uno de ellos tiene su propio lugar en la estructura de directorios. Sin embargo, puede tener un inodo solamente, sin importar qué nombre está siendo usado.
Cuando un proceso se refiere a un nombre de ruta, el kernel busca directorios para encontrar el número de inodo correspondiente. Luego de que el nombre ha sido convertido a un número de inodo, el inodo se carga en memoria y es usado en solicitudes posteriores.
Los atributos extendidos asociados a los metadatos no son interpretados directamente por el sistema de archivos. Existen cuatro espacios de nombres (namespaces): usuario, de confianza, seguridad y sistema. Más adelante veremos que el espacio de nombres sistema es usado por las listas de control de acceso (ACLs) y el espacio de nombres seguridad es usado por SELinux.
Los valores de los atributos son almacenados en el inodo de archivo y pueden ser modificados y configurados sólo por el usuario root. Se visualizan con lsattr y configuran con chattr.
En el espacio de nombres de usuario, las siguientes banderas pueden ser configuradas en los archivos:
- i: inmutable
Un archivo con el atributo de inmutabilidad (i) no puede ser modificado (ni siquiera por root). No puede ser borrado o renombrado. No se puede crear un link duro a él y no es posible escribir datos al archivo. Sólo el superusuario puede configurar o eliminar este atributo. - a: agregar solamente
Un archivo con el atributo de agregar solamente (a) puede ser abierto en modo agregar para escritura solamente. Sólo el superusuario puede configurar o eliminar este atributo. - d: no respaldar
Un archivo con el atributo no respaldar (d) es ignorado cuando el programa dump se ejecuta. Esto es útil para el área de intercambio y archivos de caché que no se desean respaldar. - A: No actualizar atime
Un archivo con el atributo no-atime-update (A) no modificará su registro atime (tiempo de acceso) cuando el archivo es accesado pero no modificado. Esto puede incrementar el rendimiento en algunos sistemas debido a que reduce la cantidad de actividad de E/S del disco.
Note que hay otros atributos que se pueden configurar: al ejecutar man chattr se mostrará la lista completa. El formato para chattr es el siguiente:
$ chattr [+|-|=mode] filename
lsattr se usa para desplegar los atributos de un archivo:
$ lsattr filename
Cada tipo de sistema de archivos tiene una herramienta para formatear un sistema de archivos en una partición. El nombre genérico para esas utilidades es mkfs. Sin embargo es sólo una interfaz para los programas del sistema de archivos específico:
$ ls -lh /sbin/mkfs*
-rwxr-xr-x 1 root root 11K Apr 10 03:50 /sbin/mkfs
-rwxr-xr-x 1 root root 181K Oct 15 2012 /sbin/mkfs.btrfs
-rwxr-xr-x 1 root root 26K Apr 10 03:50 /sbin/mkfs.cramfs
-rwxr-xr-x 5 root root 68K Jul 16 15:31 /sbin/mkfs.ext2
-rwxr-xr-x 5 root root 68K Jul 16 15:31 /sbin/mkfs.ext3
-rwxr-xr-x 5 root root 68K Jul 16 15:31 /sbin/mkfs.ext4
-rwxr-xr-x 5 root root 68K Jul 16 15:31 /sbin/mkfs.ext4dev
lrwxrwxrwx 1 root root 7 Dec 6 2011 /sbin/mkfs.msdos -> mkdosfs
lrwxrwxrwx 1 root root 12 Sep 28 2011 /sbin/mkfs.ntfs -> /sbin/mkntfs
lrwxrwxrwx 1 root root 7 Dec 6 2011 /sbin/mkfs.vfat -> mkdosfs
Por tanto, los dos comandos de a continuación son completamente equivalentes:
$ sudo mkfs -t ext4 /dev/sda10
$ sudo mkfs.ext4 /dev/sda10
El formato general para mkfs es el siguiente:
mkfs [-t fstype] [options] [device-file]
donde [device-file] es generalmente un nombre de dispositivo como /dev/sda3 o /dev/vg/lvm1.
Cada tipo de sistema de archivos tiene sus propias opciones que pueden ser configuradas en el proceso de formateo. Por ejemplo, cuando se crea un sistema de archivos ext4, un asunto para considerar es la configuración del journaling. Estos incluyen el tamaño de archivo del journal y si se utilizará o no un archivo de journal externo.
Es necesario revisar la página man de cada uno de los programas mkfs.* para ver los detalles.
Cada tipo de sistema de archivos tiene una utilidad diseñada para verificar errores (y en lo posible repararlos, en caso que se encuentren). El nombre genérico para esas herramientas es fsck. Sin embargo esto es sólo una interfaz para los programas específicos de cada sistema de archivos:
$ ls -l /sbin/fsck*
-rwxr-xr-x 1 root root 34680 Apr 10 03:50 /sbin/fsck
-rwxr-xr-x 1 root root 15976 Apr 10 03:50 /sbin/fsck.cramfs
-rwxr-xr-x 5 root root 197352 Jul 16 15:31 /sbin/fsck.ext2
-rwxr-xr-x 5 root root 197352 Jul 16 15:31 /sbin/fsck.ext3
-rwxr-xr-x 5 root root 197352 Jul 16 15:31 /sbin/fsck.ext4
-rwxr-xr-x 5 root root 197352 Jul 16 15:31 /sbin/fsck.ext4dev
lrwxrwxrwx 1 root root 7 Dec 6 2011 /sbin/fsck.msdos -> dosfsck
lrwxrwxrwx 1 root root 13 Sep 28 2011 /sbin/fsck.ntfs -> ../bin/ntfsck
lrwxrwxrwx 1 root root 7 Dec 6 2011 /sbin/fsck.vfat -> dosfsck
Por tanto, los dos comandos de a continuación son completamente equivalentes:
$ sudo fsck -t ext4 /dev/sda10
$ sudo fsck.ext4 /dev/sda10
fsck se ejecuta automáticamente luego de un número de montajes o un intervalo desde la última vez que fue ejecutado, o luego de un apagado anormal. Debería ser ejecutado en sistemas de archivos sin montar.
Usted puede forzar una verificación de todos los sistemas montados en el próximo arranque con los siguientes comandos:
$ sudo touch /forcefsck
$ sudo reboot
El archivo /forcefsck desaparecerá luego de que la verificación sea exitosa. Esta forma de verificación es muy útil, ya que permite ejecutar fsck en el sistema de archivos root, lo cual es muy difícil de realizar en un sistema que está corriendo.
El formato general de fsck es el siguiente:
fsck [-t fstype] [options] [device-file]
donde [device-file] es generalmente un nombre de dispositivo como /dev/sda3 o /dev/vg/lvm1. Usualmente no es necesario especificar el tipo de sistema de archivo, ya que fsck puede detectarlo a través de examinar los superbloques al comienzo de la partición.
Es posible controlar si los errores encontrados deben repararse uno a uno manualmente con la opción -r, o automáticamente de la mejor forma posible usando la opción -a. Adicionalmente, cada tipo de sistema de archivo puede tener sus propias opciones particulares que pueden ser configuradas al momento de la verificación.
Note que los sistemas de archivos con journaling son mucho más rápidos para verificar que los sistemas de archivos de generaciones anteriores por dos razones:
- Raramente es necesario escanear la partición completa para buscar errores, ya que todo - con excepción de la última transacción - ha sido registrado y confirmado, por lo cual se requiere muy poco tiempo para verificar.
- Incluso si uno verifica el estado del sistema de archivos completo, los sistemas de archivos nuevos han sido diseñados con fsck rápido; de hecho los sistemas de archivos antiguos no consideraron este tema cuando fueron diseñados, debido a que los tamaños eran mucho más pequeños.
Para ver los detalles de los programas fsck.* vea la página man de cada uno.
Todos los archivos accesibles en Linux están organizados en una gran estructura de árbol jerárquica con la parte superior del mismo en el directorio root ( / ). Sin embargo, es común tener más de una partición (cada una de las cuales puede tener su propio tipo de sistema de archivos), las que trabajan juntas en el mismo árbol de sistema de archivos. Estas particiones pueden estar en diferentes dispositivos físicos, o incluso localizadas en una red.
El programa mount permite montar un sistema de archivos en cualquier punto de la estructura de árbol; por el contrario, umount permite desmontarlo.
El punto de montaje corresponde al directorio donde el sistema de archivos está montado. Este debe existir con anterioridad a que mount pueda usarlo; el comando mkdir puede ser usado para crear un directorio vacío. Si un directorio preexistente es usado para tal efecto y contiene archivos previamente al ser usado como punto de montaje, los archivos se ocultarán al momento del montaje. Estos archivos no son borrados y estarán visibles nuevamente cuando el sistema de archivos es desmontado.
Sólo el superusuario puede montar y desmontar sistemas de archivos.
Cada sistema de archivos es montado bajo un directorio específico, como en el caso que se muestra a continuación:
$ sudo mount -t ext4 /dev/sdb4 /home
- Monta un sistema de archivos ext4.
- El sistema de archivos está localizado en una partición específica del disco duro (/dev/sdb4).
- El sistema de archivos está montado en la posición /home en el árbol de directorios actual.
- Cualquier archivo que esté en el directorio original /home estará oculto hasta que la partición se desmonte.
Note que en este ejemplo el sistema de archivos es montado utilizando el nodo de dispositivo sobre el que reside. Sin embargo, también es posible montarlo usando una etiqueta o un UUID. Por lo tanto, los siguientes comandos son todos equivalentes:
$ sudo mount /dev/sda2 /home
$ sudo mount LABEL=home /home
$ sudo mount -L home /home
$ sudo mount UUID=26d58ee2-9d20-4dc7-b6ab-aa87c3cfb69a /home
$ sudo mount -U 26d58ee2-9d20-4dc7-b6ab-aa87c3cfb69a /home
Las etiquetas son asignadas por utilidades específicas de cada tipo de sistema de archivos, tal como e2label. Los UUIDs se asignan cuando las particiones son creadas como contenedores para el sistema de archivos.
Mientras cualquiera de estos tres métodos para especificar el dispositivo puede ser usado, los sistemas modernos desestiman el uso del nodo de dispositivo debido a que los nombres pueden cambiar de acuerdo a cómo el sistema arranca, qué discos duros son encontrados primero, etc. Las etiquetas son una mejora, pero en raras ocasiones se podría tener dos particiones que se muestran con la misma etiqueta. Los UUIDs, sin embargo, siempre deberían ser únicos y son creados cuando las particiones se crean.
mount tiene muchas opciones, algunas genéricas como -a (lo cual monta todos los sistemas de archivos mencionados en /etc/fstab) y muchas que son específicas al sistema de archivos; de hecho, mount tiene una página man muy larga. Un ejemplo común sería el siguiente:
$ sudo mount -o remount,ro /myfs
lo cual montaría nuevamente un sistema de archivos con un atributo de sólo lectura.
A continuación se muestra cómo obtener un resumen rápido de las opciones de mount:
$ mount --help
Usage:
mount [-lhV]
mount -a [options]
mount [options] [--source] <source> | [--target] <directory>
mount [options] <source> <directory>
mount <operation> <mountpoint> [<target>]
Options:
-a, --all mount all filesystems mentioned in fstab
-c, --no-canonicalize don't canonicalize paths
-f, --fake dry run; skip the mount(2) syscall
-F, --fork fork off for each device (use with -a)
-T, --fstab <path> alternative file to /etc/fstab
-h, --help display this help text and exit
-i, --internal-only don't call the mount.<type> helpers
-l, --show-labels lists all mounts with LABELs
-n, --no-mtab don't write to /etc/mtab
-o, --options <list> comma-separated list of mount options
-O, --test-opts <list> limit the set of filesystems (use with -a)
-r, --read-only mount the filesystem read-only (same as -o ro)
-t, --types <list> limit the set of filesystem types
--source <src> explicitly specifies source (path, label, uuid)
--target <target> explicitly specifies mountpoint
-v, --verbose say what is being done
-V, --version display version information and exit
-w, --rw, --read-write mount the filesystem read-write (default)
-h, --help display this help and exit
-V, --version output version information and exit
.....
Los sistemas de archivos pueden ser desmontados de la siguiente forma:
$ umount [device-file | mount-point]
A continuación hay un par de ejemplos de cómo desmontar un sistema de archivos:
- Desmontar el sistema de archivos /home :
$ sudo umount /home - Desmontar el dispositivo /dev/sda3 :
$ sudo umount /dev/sda3
Tenga en cuenta que el comando para desmontar un sistema de archivos es umount (¡no unmount!).
Tal como mount, umount tiene muchas opciones, muchas de las cuales son específicas al tipo de sistema de archivos. Nuevamente, las páginas man son la mejor fuente para obtener las opciones específicas.
El error más común que se encuentra al desmontar un sistema de archivos es tratar de hacerlo en un sistema de archivos que está en uso actualmente; es decir, hay aplicaciones usando archivos u otras entradas en el sistema de archivos.
Esto puede ser tan simple como tener una terminal abierta en un directorio en el sistema de archivos montado. Tan solo haciendo cd en esa ventana o cerrándola, solucionará el error del dispositivo que está en uso y se permitirá desmontardo.
Sin embargo, si hay otros procesos induciendo ese error, deberá cerrarlos antes de poder desmontar el sistema de archivos. Usted puede usar fuser para encontrar qué usuarios están usando el sistema de archivos y detener sus procesos (sea cuidadoso con esto, tal vez sea buena idea informar a los usuarios antes de hacerlo). También se puede usar lsof ("lista de archivos abiertos") para ver qué archivos están siendo utilizados y que están bloqueando el desmontado.
Durante el arranque del sistema se ejecuta el comando mount -a. Esto monta todos los sistemas de archivos listados en el archivo de configuración /etc/fstab. Las entradas pueden referirse a sistemas de archivos locales o remotos, montados a través de la red.
A continuación hay un ejemplo mostrando cómo montar todos los sistemas de archivos listados en el archivo de configuración /etc/fstab durante el arranque del sistema:
$ cat /etc/fstab
LABEL=RHEL6-64 / ext4 defaults 1 1
LABEL=RHEL6-32 /RHEL6-32 ext4 defaults 1 2
LABEL=boot /boot ext3 defaults 1 2
....
LABEL=local /usr/local ext4 defaults 1 2
LABEL=tmp /tmp ext4 defaults 1 2
LABEL=src /usr/src ext4 defaults 1 2
LABEL=VIRTUAL /VIRTUAL ext4 defaults 1 2
LABEL=BEAGLE /BEAGLE ext4 defaults 1 2
/dev/sda1 /c ntfs-3g uid=500,gid=500 0 0
/teaching/FTP/LFT /var/ftp/pub2 none bind 0 0
laptop:/share /share nfs defaults 0 0
LABEL=SWAP swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
Este archivo muestra qué sistemas de archivos serán montados en el arranque y dónde pueden encontrarse en el sistema local o en la red. Puede especificar quién podría montarlos y con qué permisos, y otras opciones relevantes. Algunas de esas líneas se refieren a seudosistemas de archivos especiales como proc, sys y devpts.
Cada registro en el archivo contiene campos separados por espacios en blanco, listando lo siguiente:
- Dispositivo de nodo, etiqueta o UUID. Para sistemas de archivos que no tienen un nodo de dispositivo, como tmpfs, proc y sysfs, este campo es un marcador de posición solamente; a veces verá la palabra none en la columna.
- Punto de montaje. Esto también puede ser un marcador de posición solamente, como en el caso de swap, el cual no está montado en ninguna parte.
- Tipo de sistema de archivos.
- Una lista de opciones separadas por coma.
- Frecuencia de dump (o un cero), usado por el comando dump -w.
- fsck pass, número de verificación (o 0, lo cual significa que no se comprueba el estado en el arranque).
Las herramientas mount y umount pueden usar la información que se encuentra en /etc/fstab; en este caso podríamos hacer lo siguiente (usando la información del ejemplo anterior)
$ sudo mount /usr/src
en vez de
$ sudo mount LABEL=src /usr/src
La lista de sistemas de archivos montados actualmente puede ser vista ejecutando el siguiente comando:
$ mount
/dev/sda5 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda6 on /RHEL6-32 type ext4 (rw)
/dev/sda2 on /boot_master type ext4 (rw)
/dev/mapper/VG-tmp on /tmp type ext4 (rw)
/dev/mapper/VG-local on /usr/local type ext4 (rw)
/dev/mapper/VG-src on /usr/src type ext4 (rw)
/dev/mapper/VG-audio on /AUDIO type ext4 (rw)
/dev/mapper/VG-pictures on /PICTURES type ext4 (rw)
/dev/mapper/VG-dead on /DEAD type ext4 (rw)
/dev/mapper/VG-virtual on /VIRTUAL type ext4 (rw)
/dev/mapper/VG-virtual2 on /VIRTUAL2 type ext4 (rw)
/dev/mapper/VG-virtual3 on /VIRTUAL3 type ext4 (rw)
/dev/mapper/VG-iso_images on /ISO_IMAGES type ext4 (rw)
/usr/local/FTP on /var/ftp/pub type none (rw,bind)
/usr/src/KERNELS.sqfs on /usr/src/KERNELS type squashfs (rw,loop=/dev/loop0)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
vmware-vmblock on /var/run/vmblock-fuse type fuse.vmware-vmblock (rw, nosuid, nodev, default_permissions, allow_other)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
¿Qué información no se almacena en el inodo?
Permisos
Usuario y grupo propietario
Nombre de archivo
Marcas de tiempo
Tamaño
Identifique las herramientas que se describen a continuación:
- es la herramienta general para formatear sistemas de archivos.
- es la herramienta general para verificar y reparar sistemas de archivos.
- es una herramienta para listar los atributos extendidos de un archivo.
- es una herramienta para cambiar los atributos extendidos de un archivo.
- es una herramienta para listar los archivos en uso.
Actualmente usted debería ser capaz de:
- Estar familiarizado con conceptos tales como inodos, archivos de directorios y atributos extendidos.
- Crear y formatear sistemas de archivos.
- Verificar y reparar errores en sistemas de archivos.
- Montar y desmontar sistemas de archivos.
13. Características del sistema de archivos: intercambio, cuotas, uso
Linux usa una implementación de espacio de intercambio robusto, a través de la cual el sistema de memoria virtual permite el uso aparente de más memoria que la disponible en forma física. Las cuotas del sistema de archivos pueden ser usadas para administrar el uso del espacio en disco de las cuentas de usuario. Las herramientas df y du son útiles para monitorear de forma simple el uso y capacidad del sistema de archivos.
Al final de este capítulo usted debería ser capaz de:
- Explicar los conceptos de área de intercambio y cuotas.
- Usar las herramientas que ayudan a administrar las cuotas: quotacheck, quotaon, quotaoff, edquota y quota.
- Usar las herramientas df y du.
Linux emplea un sistema de memoria virtual en el cual el sistema operativo funciona como si tuviera más memoria de la que realmente tiene. Este tipo de memoria funciona de dos maneras:
- Muchos programas no usan toda la memoria que tienen permitido usar. A veces esto se debe a que los procesos hijos heredan una copia de las regiones de memoria de los padres, que utilizan la técnica COW (Copy On Write), en la cual el hijo obtiene solamente una copia única (de a una página) cuando hay un cambio.
- Cuando la presión de memoria se vuelve importante, regiones de memoria menos activa pueden ser escritas al área de intercambio, para ser llamadas sólo cuando se requieren nuevamente.
Tal movimiento en el área de intercambio sea realiza usualmente a una o más particiones o archivos; Linux permite múltiples áreas de intercambio, por lo cual las necesidades pueden ser ajustadas dinámicamente. Cada área tiene una prioridad asociada; las de prioridad baja no son utilizadas hasta que otras de prioridad mayor están llenas.
En la mayoría de los casos el tamaño recomendado de intercambio es el total de RAM en el sistema. Es posible ver lo que el sistema está usando actualmente en las áreas de intercambio de la siguiente forma:
$ cat /proc/swaps
Filename Type Size Used Priority
/dev/sda9 partition 4193776 0 -1
/dev/sdb6 partition 4642052 0 -2
y el uso actual de memoria con:
$ free -o
total used free shared buffers cached
Mem: 4047236 3195080 852156 0 818480 1430940
Swap: 8835828 0 8835828
Los únicos comandos que implican el área de intercambio son los siguientes:
- mkswap: formatea una partición o archivo de intercambio
- swapon: activa una partición o archivo de intercambio
- swapoff: desactiva una partición o archivo de intercambio
En algún momento la mayoría de la memoria está en uso para almacenar en caché contenidos de archivo para prevenir ir a leer al disco más de lo necesario, o en un orden o tiempo que podría estar debajo de lo óptimo. Este tipo de página en memoria no se escribe en el área de intercambio, ya que están respaldadas en los archivos en sí, por lo cual hacerlo no tendría sentido; en cambio, las páginas que han sido modificadas y que no tienen respaldo físico - conocidas como dirty pages en inglés - son movidas al disco.
Vale la pena señalar que en Linux la memoria que usa el kernel, de forma opuesta a la memoria de aplicaciones y a diferencias de otros sistemas operativos, nunca se traslada al área de intercambio.
Linux puede usar y aplicar cuotas en sistemas de archivos. Las cuotas de disco les permite a los administradores controlar el espacio máximo que usuarios o grupos en particular tienen habilitados para su uso. Se permite una flexibilidad considerable y las cuotas pueden ser asignadas en base a cada sistema de archivos. Se provee de protección para que los usuarios no agoten los recursos colectivos.
Las siguientes herramientas permiten controlar las cuotas:
- quotacheck: genera y actualiza los archivos que llevan la cuenta de las cuotas
- quotaon: habilita el sistema de cuotas
- quotaoff: deshabilita el sistema de cuotas
- edquota: se usa para editar cuotas de usuarios o grupos
- quota: informa acerca del uso y límites de las cuotas.
Las operaciones de cuota requieren la existencia de los archivos aquota.user y aquota.group en el directorio raíz del sistema de archivos que está usando cuotas.
Las cuotas pueden estar habilitadas o deshabilitadas en función de cada sistema de archivos. Adicionalmente, Linux soporta el uso de cuotas basadas en el id de usuario y grupo.
Los diferentes sistemas de archivos pueden tener utilidades adicionales relacionadas a las cuotas, tales como xfs_quota.
Para crear una cuota de sistema de archivos hay que asegurarse de haber montado el sistema de archivos con las opciones de cuotas de usuario y/o grupo. Sin eso nada funcionará. Los pasos básicos son los siguientes:
- Montar el sistema de archivos con las opciones de cuota de usuario y/o grupo:
- Agregar las opciones usrquota y/o grpquota a la entrada del sistema de archivos en /etc/fstab
- Remontar el sistema de archivos (o montarlo si es nuevo). - Ejecutar quotacheck en el sistema de archivos para configurar las cuotas.
- Habilitar las cuotas en el sistema de archivos.
- Configurar las cuotas con el programa edquota.
Por lo tanto, para crear una cuota de sistema de archivos primero hay que asegurarse de haber montado el sistema de archivos con las opciones de cuota para usuarios y/o grupos. Recuerde que sin ellos no va a funcionar.
Primero es necesario agregar las opciones correctas en el archivo /etc/fstab, como se muestra a continuación:
/dev/sda5 /home ext4 defaults,usrquota 1 1
donde hemos asumido que /home está en una partición dedicada.
Luego realice un test con los siguientes comandos:
$ sudo mount -o remount /home
$ sudo quotacheck -vu /home
$ sudo quotaon -vu /home
$ sudo edquota someusername
Usted también podría querer configurar períodos de gracia con edquota. Las opciones de montaje que deberían ser usadas en el archivo /etc/fstab son usrquota para cuotas de usuario y grpquota para cuotas de grupo.
La herramienta quotacheck crea y actualiza los archivos que llevan la cuenta de las cuotas (aquota.user y aquota.group) en el sistema de archivos.
Para actualizar los archivos de usuarios para todos los sistemas de archivos en /etc/fstab con opciones de cuota de usuario, haga lo siguiente:
$ sudo quotacheck -ua
Para actualizar los archivos de grupo para todos los sistemas de archivos en /etc/fstab con opciones de cuota de grupo, haga lo siguiente:
$ sudo quotacheck -ga
Para actualizar el archivo de usuario de un sistema de archivos en particular, haga lo siguiente:
$ sudo quotacheck -u [somefilesystem]
Para actualizar el archivo de grupo de un sistema de archivos en particular, haga lo siguiente:
$ sudo quotacheck -g [somefilesystem]
Use la opción -v para obtener una salida más detallada.
quotacheck es ejecutado generalmente sólo cuando las cuotas son habilitadas inicialmente (o cuando necesitan ser actualizadas). El programa también podría ser ejecutado cuando fsck reporta errores en el sistema de archivos durante el arranque del sistema.
quotaon se usa para habilitar las cuotas en el sistema de archivos; quotaoff se usa para deshabilitarlas. Los comandos anteriores se usan de la siguiente forma:
$ sudo quotaon [flags] [filesystem]
$ sudo quotaoff [flags] [filesystem]
en donde los parámetros (flags) pueden ser:
-a, --all turn quotas off for all filesystems
-f, --off turn quotas off
-u, --user operate on user quotas
-g, --group operate on group quotas
-p, --print-state print whether quotas are on or off
-x, --xfs-command=cmd perform XFS quota command
-F, --format=formatname operate on specific quota format
-v, --verbose print more messages
-h, --help display this help text and exit
-V, --version display version information and exit
Note que estos dos programas son realmente uno y funcionan de acuerdo al nombre con el cual son invocados.
Por ejemplo:
$ sudo quotaon -av
/dev/sda6 [/]: group quotas turned on
/dev/sda5 [/home]: user quotas turned on
$ sudo quotaoff -av
/dev/sda6 [/]: group quotas turned off
/dev/sda5 [/home]: user quotas turned off
$ sudo quotaon -avu
/dev/sda5 [/home]: user quotas turned on
$ sudo quotaoff -avu
/dev/sda5 [/home]: user quotas turned off
$ sudo quotaon -avg
/dev/sda6 [/]: group quotas turned on
$ sudo quotaoff -avg
/dev/sda6 [/]: group quotas turned off
Tenga en cuenta que las operaciones de cuota fallarán si los archivos aquota.user o aquota.group no existen.
La herramienta quota se usa para generar reportes de cuotas:
- quota (o quota -u) informa su cuota actual de usuario.
- quota -g informa su cuota actual de grupo.
- El superusuario puede ver las cuotas de cualquier usuario u grupo al especificar un nombre de usuario o grupo.
Por ejemplo:
$ sudo quota george
Disk quotas for user george (uid 1000):
Filesystem blocks quota limit grace files quota limit grace
/dev/sda5 837572 500 1000 5804 0 0
$ sudo quota gracie
Disk quotas for user gracie (uid 1001):
Filesystem blocks quota limit grace files quota limit grace
/dev/sda5 83757 5000 10000 5804 0 0
El comando edquota ejecuta el editor de cuotas. Para el usuario o grupo especificado se crea un archivo temporal con una representación de texto de las cuotas de disco actuales para ese usuario o grupo.
Entonces un editor es invocado con el fin de modificar las cuotas en el archivo mencionado. Una vez que el editor se cierra, el archivo temporal se lee y los archivos binarios de cuota llevan a cabo los cambios.
Los únicos campos que pueden ser editados en la cuota son los límites soft y hard. Los otros campos son informativos solamente.
A continuación algunos ejemplos de uso de edquota:
- edquota -u [username] edita los límites de username
- edquota -g [groupname] edita los límites de groupname
- edquota -u -p [userproto] [username] copia los valores de cuota del usuario userproto a username
- edquota -g -p [groupproto] [groupname] copia los valores de cuota del grupo groupproto a groupname
- edquota -t configura períodos de gracia
El tercer y cuarto comandos son útiles para ser incluidos en scripts, con el fin de crear cuentas nuevas y configurar cuotas para ellas.
Las cuotas para usuarios y grupos pueden estar configuradas para bloques de discos y/o inodos. Adicionalmente, los límites soft y hard pueden ser configurados como períodos de gracia: el límite soft puede ser excedido por un período de gracia, sin embargo, el límite hard no puede ser excedido en ningún caso.
El período de gracia se configura en función de cada sistema de archivos.
$ sudo edquota gracie
$ sudo edquota -t
La herramienta df (disk free) muestra el uso y la capacidad disponible del sistema de archivos. Por ejemplo:
$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda5 ext4 9.8G 8.1G 1.3G 87% /
tmpfs tmpfs 3.9G 2.3M 3.9G 1% /dev/shm
/dev/sda6 ext4 9.8G 5.0G 4.3G 54% /RHEL6-32
/dev/sda2 ext4 380M 3.2M 353M 1% /boot_master
/dev/mapper/VG-local ext4 24G 16G 7.2G 68% /usr/local
/dev/mapper/VG-src ext4 16G 6.4G 8.6G 43% /usr/src
/dev/mapper/VG-pictures
ext4 12G 8.9G 2.3G 80% /PICTURES
/dev/mapper/VG-dead ext4 59G 35G 22G 62% /DEAD
/dev/mapper/VG-virtual
ext4 222G 162G 49G 77% /VIRTUAL
/dev/mapper/VG-iso_images
ext4 59G 35G 21G 63% /ISO_IMAGES
/usr/src/KERNELS.sqfs
squashfs 3.8G 3.8G 0 100% /usr/src/KERNELS
en donde la opción -h significa "legible para humanos", es decir en KB, MB, GB y no en bytes. La opción -T muestra el tipo de sistema de archivos. La opción -i muestra la información del inodo en vez de bytes.
du (disk usage, o uso del disco) se usa para evaluar cuánto espacio está usando un directorio (y sus subdirectorios) en un sistema de archivos.
Para desplegar el uso del disco del directorio actual: $ du
Para desplegar todos los archivos, no sólo los directorios: $ du -a
Para listar en formato "legible por humanos": $ du -h
Para desplegar el uso del disco para un directorio específico: $ du -h somedir
Para desplegar los totales solamente, suprimiendo la salida de los subdirectorios: $ du -s
Por ejemplo:
$ du -ch /teaching/CRASH
16K /teaching/CRASH/crash-7.0.3/memory_driver
136K /teaching/CRASH/crash-7.0.3/extensions
35M /teaching/CRASH/crash-7.0.3
101M /teaching/CRASH
101M total
Provea la opción correcta para el programa df, con el fin de:
- Listar en formato "legible por humanos".
- Listar la información del inodo en vez del uso de bloques.
Organice los pasos de a continuación en el mejor orden lógico para habilitar las cuotas en un sistemas de archivos existente:
Editar /etc/fstab para agregar la opción de montaje usrquota.
Montar de nuevo el sistema de archivos.
Ejecutar quotaon para habilitar el sistema de cuotas.
Editar de forma individual las cuotas de usuario o grupo con edquota.
En esta sección se presentaron las herramientas básicas para administrar particiones de intercambio. Las preguntas de a continuación son en relación a las tres herramientas básicas para tal efecto:
se usa para formatear una partición de intercambio.
se usa para habilitar una partición de intercambio.
se usa para deshabilitar una partición de intercambio.
Actualmente usted debería ser capaz de:
- Explicar los conceptos de área de intercambio y cuotas.
- Usar las herramientas que ayudan a administrar las cuotas: quotacheck, quotaon, quotaoff, edquota y quota.
- Usar las herramientas df y du.
14. Los sistemas de archivos Ext2/Ext3/Ext4
La familia de sistemas de archivos ext han sido nativos de Linux desde sus primeros días, y los más ampliamente usados de todas las alternativas disponibles. Hasta muy recientemente, ext4 ha sido la alternativa por defecto más frecuente de distribuciones Linux, debido a su excelente combinación de rendimiento, integridad y estabilidad.
Al final de este capítulo usted debería ser capaz de::
- Describir las características principales del sistemas de archivos ext4 y la forma en la que ocupa el disco.
- Explicar los conceptos de grupos de bloques, superbloque, bloques de datos e inodos.
- Usar las herramientas dumpe2fs y tune2fs.
- Enumerar las mejoras del sistema de archivos ext4.
El sistema de archivos ext2 fue una variedad nativa de Linux y está disponible en todos los sistemas Linux, pero rara vez se utiliza hoy en día.
El sistema de archivos ext3 fue la primera extensión de ext2 que incluyó journaling. Tenía el mismo diseño en disco que ext2, excepto por la existencia de un archivo de journal.
El sistema de archivos ext4 se incluyó por primera vez en la versión 2.6.19 del kernel, y su designación como experimental fue quitada en la versión 2.6.28. Incluyó mejoras significativas como el uso de extents para archivos largos, en vez de listas de bloques de archivos.
Un extent es simplemente un grupo de bloques continuos. Su uso puede mejorar el rendimiento de archivos de gran tamaño y reducir la fragmentación.
ext4 es el sistema de archivos por defecto en la mayoría de las distribuciones empresariales de Linux, aunque RHEL 7 adoptó recientemente XFS de forma predeterminada.
Existe una correspondencia cercana de características entre el VFS y los sistemas de archivos ext2/3/4, debido a que cada uno ha sido diseñado sobre la base del otro.
El tamaño del bloque se selecciona cuando el sistema de archivos se construye; puede ser de 512, 1024, 2048, o 4096 bytes. Por defecto, 4096 es usado con frecuencia para discos duros, a menos que la partición sea muy pequeña. A menos de que haya muchos archivos pequeños, los tamaños grandes de bloque pueden ser más eficientes en términos de minimizar accesos al disco duro.
El sistema de gestión de memoria del kernel Linux requiere que solamente un número entero de bloques quepa en una página de memoria; por lo tanto no es posible tener bloques de 8 KB en una plataforma x86 en donde las páginas de memoria son de 4KB de tamaño.
El número de inodos en el sistema de archivos también puede ser ajustado, lo cual podría ahorrar espacio en disco.
Una característica llamada reservación de inodos consiste en reservar un número considerable de inodos cuando un directorio se crea, con la idea de ser usados en el futuro. Esto mejora el rendimiento debido a que cuando se crean nuevos archivos en el directorio, éste tiene ya inodos asignados.
Si la ruta de un enlace simbólico es menor que 60 caracteres, se crea un enlace simbólico rápido, el cual se almacena directamente en el inodo, obviando la necesidad de leer un bloque de datos.
Todos los campos son escritos a disco en orden little-endian, con excepción del journal.
Los bloques de disco se dividen en grupos de bloques, cada uno de los cuales contiene inodos y bloques de dato almacenados de forma adyacente, con lo que se reduce el tiempo de acceso.
El diseño de un grupo de bloques estándar es simple. Para el grupo de bloques 0, los primeros 1024 bytes no se usan (le ceden el espacio a sectores de booteo, etc). El superbloque comenzará en el primer bloque, con excepción del grupo de bloque 0. Luego siguen los descriptores de grupo y un número de bloques GDT (Group Descriptor Table). Estos son seguidos por el mapa de bits de bloques de datos, el mapa de bits de inodos, la tabla de inodos y los bloques de datos.
Los bloques de datos son preasignados a archivos antes de que sean usados. Así cuando el tamaño de un archivo se incrementa, se hace uso de espacio adyacente que ha sido previamente reservado, por lo cual la fragmentación se reduce.
El superbloque del sistema de archivos contiene campos de bit, los cuales son usados para determinar si el sistema de archivos requiere o no verificación cuando se monta por primera vez durante la inicialización del sistema. El estado puede ser:
- clean: el sistema de archivos se desmontó de forma limpia previamente
- dirty: generalmente significa que está montado
- unknown: no se desmontó de forma limpia, como cuando hay un bloqueo o caída del sistema.
En los últimos dos casos fsck será ejecutado para verificar el sistema de archivos y resolver cualquier problema antes de que sea montado.
Otros campos en el superbloque contienen información acerca de la última verificación del sistema de archivos, tanto la fecha como el número de montajes. Una verificación automática es lanzada cuando los límites ajustables exceden esos valores.
El primer bloque en el sistema de archivos es llamado bloque de arranque y está reservado para el sector de arranque de la partición.
Después del bloque de arranque hay una serie de grupos de bloques, en donde cada uno de ellos tiene el mismo tamaño. El diseño de cada grupo de bloques se muestra en la figura siguiente:
Figura 14.1: Diseño de los sistemas de archivos ext2/3/4
Superbloque |
Descriptores de Grupo |
Mapa de Bits de Bloques de Datos |
Mapa de Bits de Inodos |
Tabla de Inodos (n bloques) |
Data Bloques de Datos (n bloques) |
El primer y segundo bloque son los mismos para cada grupo de bloques y comprenden el Superbloque y los Descriptores de Grupo. Bajo circunstancias normales, sólo los bloques que están en el primer grupo son utilizados por el kernel; las copias duplicadas son referenciadas solamente cuando el sistema de archivo está siendo verificado. Si todo está bien, el kernel los copia desde el primer grupo de bloques. Si hay algún problema con las copias maestras, va al siguiente y así sucesivamente hasta que se encuentra uno en buen estado y la estructura del sistema de archivos se reconstruye. Esta redundancia hace que sea muy difícil que un sistema de archivos ext2/3/4 se estropee, siempre y cuando las verificaciones del sistema de archivos se ejecuten de forma periódica.
En las versiones tempranas de la familia ext, cada grupo de bloques contenía los descriptores de grupos de cada uno de ellos, como también una copia del superbloque. Debido a las optimizaciones actuales, no todos los grupos de bloques tienen una copia del superbloque y de los descriptores de grupos. Para ver la situación en el sistema usted podría hacer lo siguiente:
$ sudo dumpe2fs /dev/sda1 | grep superblock
dumpe2fs 1.42.9 (28-Dec-2013)
Primary superblock at 0, Group descriptors at 1-4
Backup superblock at 32768, Group descriptors at 32769-32772
Backup superblock at 98304, Group descriptors at 98305-98308
Backup superblock at 163840, Group descriptors at 163841-163844
Backup superblock at 229376, Group descriptors at 229377-229380
Backup superblock at 294912, Group descriptors at 294913-294916
Backup superblock at 819200, Group descriptors at 819201-819204
Backup superblock at 884736, Group descriptors at 884737-884740
Backup superblock at 1605632, Group descriptors at 1605633-1605636
Backup superblock at 2654208, Group descriptors at 2654209-2654212
Backup superblock at 4096000, Group descriptors at 4096001-4096004
provea un nodo de dispositivo apropiado para que pueda ver las ubicaciones precisas. Esto sucede cuando el sistema de archivos se crea con la opción sparse_super, que es el valor por defecto.
El número de grupos de bloques está limitado debido al hecho que el mapa de bits de bloque - el cual identifica bloques usados y disponibles en el grupo - tiene que caber en un bloque único. Por lo tanto, si un bloque tiene un tamaño de 4096 bytes, un grupo de bloques no puede contener más de 32 K bloques, o 128 MB. Si tomamos el mayor tamaño posible de un grupo de bloques, una partición de 10 GB tendría que tener al menos 80 grupos de bloques.
El asignador de bloques trata de mantener los bloques de cada archivo en el mismo grupo de bloques para disminuir los tiempos de búsqueda.
Como se ha demostrado, es posible usar la herramienta dumpe2fs para obtener información del sistema de archivos; poniendo esto en práctica sobre una partición obtenemos lo siguiente:
$ sudo dumpe2fs /dev/sda1
Filesystem volume name: RHEL7
Last mounted on: /
Filesystem UUID: 9d6b5801-9c7e-4c17-9068-49923952338e
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 1908736
Block count: 7630592
Reserved block count: 381529
Free blocks: 5353383
Free inodes: 1682479
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Reserved GDT blocks: 1024
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
Flex block group size: 16
Filesystem created: Wed Sep 3 03:52:55 2014
Last mount time: Fri Oct 24 09:18:58 2014
Last write time: Fri Oct 24 09:18:58 2014
Mount count: 89
Maximum mount count: -1
Last checked: Wed Sep 3 03:52:55 2014
Check interval: 0 (<none>)
Lifetime writes: 103 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
First orphan inode: 396118
Default directory hash: half_md4
Directory Hash Seed: e488c43e-241c-4014-91d8-6a9d3d6c7784
Journal backup: inode blocks
Journal features: journal_incompat_revoke journal_64bit
Journal size: 128M
Journal length: 32768
Journal sequence: 0x00023592
Journal start: 16394
Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
Checksum 0x2921, unused inodes 7738
Primary superblock at 0, Group descriptors at 1-4
Reserved GDT blocks at 5-1028
Block bitmap at 1029 (+1029), Inode bitmap at 1045 (+1045)
Inode table at 1061-1572 (+1061)
22880 free blocks, 8174 free inodes, 2 directories, 7738 unused inodes
Free blocks: 9381-9672, 10180-32767
Free inodes: 19-8192
Group 1: (Blocks 32768-65535) [INODE_UNINIT, ITABLE_ZEROED]
Checksum 0x473e, unused inodes 8192
Backup superblock at 32768, Group descriptors at 32769-32772
Reserved GDT blocks at 32773-33796
Block bitmap at 1030 (bg #0 + 1030), Inode bitmap at 1046 (bg #0 + 1046)
Inode table at 1573-2084 (bg #0 + 1573)
14918 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
Free blocks: 33797, 33800-33919, 34108-34511, 34521-34559, 34784-34815, 37053-38015, 38039- 38040, 38080-38527, 38529-38911, Free inodes: 8193-16384
.....
Group 196: (Blocks 6422528-6455295) [INODE_UNINIT, ITABLE_ZEROED]
Checksum 0x946d, unused inodes 8192
Block bitmap at 6291460 (bg #192 + 4), Inode bitmap at 6291476 (bg #192 + 20)
Inode table at 6293536-6294047 (bg #192 + 2080)
32768 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
Free blocks: 6422528-6455295
Free inodes: 1605633-1613824
....
Group 232: (Blocks 7602176-7630591) [INODE_UNINIT, ITABLE_ZEROED]
Checksum 0xa174, unused inodes 8192
Block bitmap at 7340040 (bg #224 + 8), Inode bitmap at 7340056 (bg #224 + 24)
Inode table at 7344160-7344671 (bg #224 + 4128)
28416 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
Free blocks: 7602176-7630591
Free inodes: 1900545-1908736
tune2fs puede ser usado para cambiar parámetros del sistema de archivos.
Para cambiar el número máximo de montajes entre verificaciones del sistema de archivos (max-mount-count):
$ sudo tune2fs -c 25 /dev/sda1
Para cambiar el intervalo de tiempo entre verificaciones (interval-between-checks):
$ sudo tune2fs -i 10 /dev/sda1
Para listar el contenido del superbloque incluyendo los valores actuales de los parámetros que pueden ser modificados:
$ sudo tune2fs -l /dev/sda1
El superbloque contiene información global acerca del sistema de archivos, incluyendo:
- Mount count (cuenta de montaje) y maximum mount count (cuenta máxima de montaje). El parámetro mount count se incrementa cada vez que el disco es montado satisfactoriamente y el valor corresponde al número de veces que esa operación se ha realizado desde el último fsck. También es posible forzar la verificación del sistema de archivos luego de 180 días (por defecto), u otro período de tiempo que puede ser configurado con la herramienta tune2fs.
- Tamaño del bloque, el cual no puede ser mayor a una página de memoria. Se configura a través de mkfs.
- Bloques por grupo.
- Cuenta de bloques disponibles.
- Cuenta de inodos disponibles.
- ID del sistema operativo.
Como se comentó anteriormente, el superbloque se almacena de forma redundante en varios grupos de bloques.
El bloque de datos y el mapa de bits de inodos son bloques cuyos bits contienen 0 para cada bloque o inodo libre y 1 para cada uno que está usado. Hay uno de cada uno de estos mapas de bits por grupo de bloques.
La tabla de inodos contiene tantos bloques consecutivos como sea necesario para cubrir el número de inodos en el grupo de bloques. Cada inodo requiere 128 bytes; por lo tanto, un bloque de 4 KB puede contener 32 inodos.
Note que hay espacio reservado para cierta cantidad de información dependiente del sistema operativo; diferentes SOs podrían montar un sistema de archivos ext2/3/4, tal como Linux puede montar muchos sistemas de archivos no nativos.
Tenga en cuenta que el número de inodo no se almacena en esta estructura en el disco; su valor puede ser calculado rápidamente desde el número de grupo de bloque y el offset de la tabla de inodo.
Los sistemas de archivos ext2 y ext3 no han incorporado aún el uso de extents para organizar archivos grandes. En vez de eso, el arreglo de punteros a bloques de datos i_block[], de largo EXT2_N_BLOCKS=15, es descrito por el inodo. La forma en que esto se maneja es algo compleja:
- Los primeros 12 elementos en este arreglo apuntan a los primeros 12 bloques de datos en el archivo.
- El elemento 13avo apunta a un bloque que representa un arreglo de segundo orden de números de bloque; el 14avo a un arreglo de tercen orden y el 15avo a un arreglo de cuarto orden.
Este algoritmo hace que el abordar archivos pequeños sea más rápido, como es de esperar. Por ejemplo, con un tamaño de bloque de 4 KB, un archivo de 48 KB puede ser abordado directamente. Un archivo de 2 MB requiere un proceso de segundo orden, uno de 1 GB uno de tercer orden, uno de 4 GB uno de cuarto orden.
El sistema de archivos ext4:
- Es compatible con ext3 y ext2.
- Incrementa el tamaño máximo del sistema de archivos a 1 EB (desde 16 TB) y el tamaño máximo de un archivo a 16 TB (desde 2 TB). Estos límites aparecen cuando se usa un direccionamiento de 48 bit; direccionamiento completo de 64 bit podría usarse en el futuro, pero hasta la fecha no hay una necesidad real de ello.
- Incrementa de forma ilimitada el número máximo de subdirectorios, el cual estuvo limitado a 32 K en ext3.
- Divide archivos grandes en extents de la máxima longitud en vez de usar mapeo de bloques indirecto. Esto puede mejorar el rendimiento de archivos grandes y reducir la fragmentación.
- Utiliza asignación multibloque, la cual puede asignar todo el espacio de una vez, en vez de hacerlo de a un bloque. Adicionalmente, la asignación demorada puede incrementar el rendimiento también.
- Puede preasignar espacio de disco para un archivo. El espaco asignado está generalmente garantizado y es contiguo.
- Usa allocate-on-flush, una técnica de rendimiento la cual retrasa la asignación de bloques hasta que los datos son escritos en el disco.
- Usa fsck rápido, el cual puede aumentar la velocidad de verificación de un sistema de archivos en un orden de magnitud o más.
- Usa checksums para el journal, lo cual mejora la confiabilidad. Esto también puede evitar esperas de E/S durante el journaling, resultando en una lijera mejora del rendimiento.
- Usa timestamps mejoradas, medidas en nanosegundos.
- Incluye soporte de snapshots.
¿Qué comando puede usarse para ajustar el intervalo de tiempo entre verificaciones del sistema de archivo a 180 días, en un sistema de archivos ext3 o ext4 en /dev/sda1?
Actualmente usted debería ser capaz de:
- Describir las características principales del sistemas de archivos ext4 y la forma en la que ocupa el disco.
- Explicar los conceptos de grupos de bloques, superbloque, bloques de datos e inodos.
- Usar las herramientas dumpe2fs y tune2fs.
- Enumerar las mejoras del sistema de archivos ext4.
15. Los sistemas de archivos XFS y btrfs
Los sistemas de archivos XFS y btrfs han surgido como desafíos importantes a la dominación de ext4 en las distribuciones empresariales de Linux. Estos sistemas de archivos de nueva generación tienen capacidades robustas en relación a manejar tamaños grandes, abarcan múltiples volúmenes físicos y lógicos, como también métricas de rendimiento.
Al final de este capítulo usted debería ser capaz de:
- Describir el sistema de archivos XFS.
- Mantener el sistema de archivos XFS.
- Describir el sistema de archivos btrfs.
XFS fue creado y diseñado originalmente por SGI y usado en el sistema operativo IRIX, y luego portado a Linux. Fue diseñado explícitamente para lidiar con conjuntos de datos grandes como también para manejar tareas en paralelo de E/S muy eficientemente.
Este puede manejar:
- Hasta 16 EB (exabytes) para el total del sistema de archivos
- Hasta 8 EB para un archivo individual.
El alto rendimiento es uno de los elementos clave del diseño de XFS, el cual implementa métodos para:
- Usar E/S de DMA (Direct Memory Access)
- Garantizar una tasa de E/S
- Ajustar tamaño de banda para igualar los dispositivos RAID o LVM subyacentes.
En contraste a los sistemas de archivos tradicionales, XFS puede manejar la información de las cuotas con journaling. Esto conduce a una reducción del tiempo de recuperación cuando un sistema de archivos que tiene cuotas se desmonta de forma fallida. Además, el journal puede estar en un dispositivo externo.
Al igual que otros sistemas de archivos de UNIX y Linux, XFS soporta atributos extendidos.
El realizar mantenimiento a un sistema de archivos XFS se facilita por el hecho de que la mayor parte de este tipo de tareas puede ser llevada a cabo en línea, es decir, con el sistema de archivos montado. Estas incluyen:
- Defragmentar
- Ampliar
- Realizar respaldo/Restaurar.
Para crear respaldos y restaurar se usan las siguientes herramientas nativas de XFS:
- xfsdump
- xfsrestore
los cuales pueden ser pausados de forma conveniente y retomados luego. Debido a que estos programas son multihebra, los respaldos y restauraciones de XFS pueden ser llevadas a cabo muy rápidamente.
Mientras que XFS no soporta directamente snapshots de hardware o software, la herramienta xfs-freeze puede ser usada para poner el sistema de archivos en reposo, permitiendo a algún programa de snapshot trabajar en el dispositivo subyacente. Las herramientas LVM de Linux usan xfs-freeze automáticamente para detener la actividad del sistema de archivos para tomar snapshots.
XFS soporta cuotas y los comandos tradicionales de cuota pueden usarse para manipular las cuotas por sistema de archivos en un volumen XFS. Sin embargo, si usa el comando xfs-quota puede hacer uso de las cuotas por directorio que XFS soporta.
Tanto desarrolladores como usuarios de Linux con sistemas de alto rendimiento y alta capacidad o necesidades específicas, están siguiendo el desarrollo e implementación gradual del sistema de archivos btrfs, el cual fue creado por Chris Mason. El nombre viene de sistema de archivos B-tree. La documentación completa puede ser encontrada en http://btrfs.wiki.kernel.org/index.php/Main_Page .
btrfs apunta a resolver la falta de pooling, snapshots, checksums e integral multi-device spanning en otros sistemas de archivos tales como ext4. Esas características pueden ser cruciales para que Linux escale a configuraciones de almacenamiento más grande de tipo empresarial.
Mientras que btrfs ha estado en el mainline kernel (versión de mantenimiento) desde 2.6.29, ha sido considerado como experimental, aunque unos pocos vendedores lo han usado en productos nuevos.
Una de las características principales es la habilidad de tomar snapshots frecuentes de sistemas de archivos completos, o de subvolúmenes de sistemas de archivos en muy poco tiempo. Debido a que btrfs hace amplio uso de la técnica COW (Copy on Write), un snapshot no involucra mucho espacio inicial para bloques de datos o cualquier otra actividad E/S, con la excepción de algunos metadatos que requieren ser actualizados.
Es posible revertir el sistema a un estado descrito por snapshots anteriores e incluso hacer que el kernel arranque una snapshot anterior del sistema de archivos raíz .
btrfs mantiene su propio framework interno para agregar o remover particiones nuevas y/o medios físicos a sistemas de archivos existentes, de forma similar a como lo hace LVM (Logical Volume Management).
Algunas tareas deben ser terminadas antes de que btrfs esté listo para el trabajo diario en sistemas de archivos críticos. Para revisar la historia de desarrollo de btrfs y la evolución que se espera revise http://lwn.net/Articles/575841.
¿Cuáles son las herramientas por defecto del sistema de archivos XFS para las siguientes operaciones?
- Realizar un respaldo
- Restaurar
Actualmente usted debería ser capaz de:
- Describir el sistema de archivos XFS.
- Mantener el sistema de archivos XFS.
- Describir el sistema de archivos btrfs.
16. Logical Volume Manager (LVM)
LVM permite tener un sistema de archivos lógico sobre múltiples volúmenes físicos y particiones, la cual al usarla se presenta como una sola partición. Cuando se usa LVM es muy fácil contraer y expandir los sistemas de archivos según se necesite; sin embargo, tales operaciones son difíciles de realizar en particiones físicas fijas.
Al final de este capítulo usted debería ser capaz de:
- Explicar los conceptos detrás de LVM.
- Crear volúmenes lógicos.
- Visualizar volúmenes lógicos.
- Redimensionar volúmenes lógicos.
- Usar snapshots de LVM.
LVM (Logical Volume Manager) separa una partición virtual en varias partes, cada de una de las cuales puede estar en distintas particiones y/o discos.
Hay muchas ventajas al usar LVM; en particular, se torna bastante fácil el modificar el tamaño de las particiones lógicas y sistemas de archivos, agregar más espacio de almacenamiento y reorganizarlo.
Uno o más volúmenes físicos (particiones de disco) están agrupadas en un grupo de volúmenes. Luego el grupo de volumen es subdividido en volúmenes lógicos, lo cual imita particiones de disco físicas y pueden ser formateadas para contener sistemas de archivos.
Hay una variedad de herramientas de línea de comandos para crear, eliminar, redimensionar, etc., volúmenes físicos y lógicos. La herramienta gráfica system-config-lvm se usa en la mayoría de distribuciones de Linux. Sin embargo, en RHEL 7 ya no está soportada y no hay ninguna herramienta gráfica que sea confiable con los cambios más recientes de los sistemas de archivos. Afortunadamente, las herramientas de la línea de comandos no son difíciles de usar y son más flexibles.
LVM tiene un impacto en el rendimiento. Hay un costo adicional definido que proviene de la sobrecarga de la capa de LVM. Sin embargo, aún en sistemas sin RAID, si se usa striping (dividir los datos en más de un disco) es posible lograr algunas mejoras de paralelización.
Al igual que RAID (lo cual discutiremos en el próximo capítulo), el uso de volúmenes lógicos es un mecanismo para crear sistemas de archivos que pueden abarcar más de un disco físico.
Para crear volúmenes lógicos primero se ponen todos los dispositivos en un pool grande de espacio de disco (el grupo de volúmenes). Luego de eso, se asigna espacio desde el pool con el cual se crea un volumen lógico.
Los volúmenes lógicos tienen características similares a los dispositivos de RAID. De hecho pueden estar construidos sobre un dispositivo RAID. Esto le daría al volumen lógico la redundancia de un dispositivo RAID con la escalabilidad de LVM.
LVM tiene mejor escalabilidad que RAID: los volúmenes lógicos pueden ser fácilmente redimensionados, tanto para agrandarlos como reducirlos. Si se requiere más espacio, es posible agregar dispositivos adicionales en cualquier momento.
Las particiones son convertidas a volúmenes físicos y múltiples volúmenes físicos se agrupan en grupos de volúmenes; puede haber más de un grupo de volúmenes en el sistema.
El espacio en el grupo de volúmenes se divida en extents, los cuales son por defecto de 4 MB de tamaño, pero puede ser modificado en el momento de la asignación.
Hay una serie de herramientas de línea de comandos que se usan para crear y manipular grupos de volúmenes, cuyos nombres comienzan siempre con vg. Algunas de estas utilidades son:
- vgcreate: Crea grupos de volúmenes.
- vgextend: Agrega volúmenes físicos a un grupo de volúmenes.
- vgreduce: Reduce un grupo de volúmenes.
Las herramientas que agregan o quitan particiones físicas de un grupo de volúmenes comienzan con pv e incluyen:
- pvcreate: Convierte una partición en un volumen físico.
- pvdisplay: Muestra los volúmenes físicos en uso.
- pvmove: Mueve los datos desde un volumen físico a otro, dentro del mismo grupo de volúmenes; esto puede ser requerido si un disco o una partición va a ser eliminada por alguna razón. A continuación podría ejecutarse:
- pvremove: Elimina una partición desde un volumen físico.
Para obtener una lista completa de las herramientas LVM ejecute man lvm.
Hay una serie de herramientas que manipulan volúmenes lógicos. Como era de esperar, todos comienzan con lv. Revisaremos los más utilizados, pero una lista corta puede ser obtenida con:
$ ls -lF /sbin/lv*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvchange -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvconvert -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvcreate -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvdisplay -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvextend -> lvm*
-r-xr-xr-x. 1 root root 1196016 Mar 26 2014 /usr/sbin/lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvmchange -> lvm*
-r-xr-xr-x. 1 root root 7230 Mar 26 2014 /usr/sbin/lvmconf*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvmdiskscan -> lvm*
-r-xr-xr-x. 1 root root 7412 Mar 26 2014 /usr/sbin/lvmdump*
-r-xr-xr-x. 1 root root 48728 Mar 26 2014 /usr/sbin/lvmetad*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvmsadc -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvmsar -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvreduce -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvremove -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvrename -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvresize -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvs -> lvm*
lrwxrwxrwx. 1 root root 3 Sep 3 03:58 /usr/sbin/lvscan -> lvm*
Nota:
- Estas herramientas están en /sbin y no en /usr/sbin , ya que pueden ser necesitados para arrancar o reparar y recuperar un sistema.
- La mayoría de ellas están enlazadas simbólicamente a lvm, un programa al estilo navaja suiza que realiza todo el trabajo y que sabe qué debe hacer basado en el nombre por el cual es invocado. Esto también es válido para la mayoría de las herramientas pv* y vg*, lo cual se puede comprobar fácilmente.
lvcreate asigna volúmenes lógicos desde los grupos de volúmenes. El tamaño puede especificarse ya sea en bytes o número de extents (recuerde que son de 4 MB por defecto). Los nombres son a elección.
lvdisplay informa acerca de los volúmenes lógicos disponibles.
Los sistemas de archivos se localizan en los volúmenes lógicos y se formatean como de costumbre, con mkfs.
Si se comienza con un grupo de volúmenes nuevo, los pasos asociados a la configuración y uso de un volumen lógico nuevo son los siguientes:
- Crear particiones en las unidades de disco (escriba 8e en fdisk) .
- Crear volúmenes físicos desde las particiones.
- Crear el grupo de volúmenes.
- Asignar volúmenes lógicos desde el grupo de volúmenes.
- Montar los volúmenes lógicos (y actualizar /etc/fstab según sea necesario).
Por ejemplo, asumiendo que uno ya creó las particiones /dev/sdb1 y /dev/sdc1 , y que les asignó un tipo 8e:
$ sudo pvcreate /dev/sdb1
$ sudo pvcreate /dev/sdc1
$ sudo vgcreate -s 16M vg /dev/sdb1
$ sudo vgextend vg /dev/sdc1
$ sudo lvcreate -L 50G -n mylvm vg
$ sudo mkfs -t ext4 /dev/vg/mylvm
$ mkdir /mylvm
$ sudo mount /dev/vg/mylvm /mylvm
Asegúrese de agregar la línea
/dev/vg/mylvm /mylvm ext4 defaults 0 0
a /etc/fstab para que el punto de montaje sea persistente.
Los siguientes programas de línea de comandos están disponibles para desplegar información acerca de LVM:
- pvdisplay muestra los volúmenes físicos
$ sudo pvdisplay
$ sudo pvdisplay /dev/sda5
- vgdisplay muestra los grupos de volúmenes
$ sudo vgdisplay
$ sudo vgdisplay /dev/vg0
- lvdisplay muestra los volúmenes lógicos
$ sudo lvdisplay
$ sudo lvdisplay /dev/vg0/lvm1
Si no se proveen argumentos, estas herramientas desplegarán todos los volúmenes físicos, grupos de volúmenes o volúmenes lógicos, según corresponda.
Una de las grandes ventajas de usar LVM es que es fácil y rápido cambiar el tamaño de un volumen lógico, especialmente cuando se intenta hacer lo mismo con una partición física que ya contiene un sistema de archivos.
Cuando se hace esto, los extents pueden agregarse o substraerse desde el volumen lógico, y pueden provenir desde cualquier parte en el grupo de volúmenes; de hecho no necesitan ser de regiones físicas contiguas del disco.
Si el volumen contiene un sistema de archivos, expandirlo o contraerlo es una operación completamente diferente que cambiar el tamaño del volumen:
- Cuando se expande un volumen lógico que tiene un sistema de archivos, se debe expandir primero el volumen y luego el sistema de archivos.
- Cuando se contrae un volumen lógico que contiene un sistema de archivos, primero se debe contraer el sistema de archivos y luego el volumen.
El sistema de archivos no puede estar montado mientras se reduce el tamaño del mismo. Sin embargo, algunos sistemas de archivos permiten ser expandidos mientras están montados.
Obviamente, las herramientas para modificar el tamaño del sistema de archivos dependen del tipo del mismo; para ext4 el programa es resize2fs.
Para extender un volumen lógico con un sistema de archivos ext4:
$ sudo lvextend -L +500M /dev/vg/mylvm
$ sudo resize2fs /dev/vg/mylvm
donde el signo más indica que se está agregando espacio.
Para reducir el sistema de archivos:
$ sudo umount /mylvm
$ sudo fsck -f /dev/vg/mylvm
$ sudo resize2fs /dev/vg/mylvm 200M
$ sudo lvreduce -L 200M /dev/vg/mylvm
$ sudo mount /dev/vg/mylvm
Si usted tiene una versión reciente de las herramientas lvm, puede realizar estas operaciones en un paso en vez de dos, usando la opción -r, como se muestra a continuación:
$ sudo
$ sudo lvextend -r -L +100M /dev/vg/mylvm
$ sudo lvreduce -r -L -100M /dev/vg/mylvm
en donde las cantidades usan el signo más o menos para indicar el cambio requerido. Esto usa la herramienta subyacente fsadm, la cual puede redimensionar cualquier tipo de sistema de archivos para cual cual el sistema operativo tenga soporte. Le recomendamos leer la página man de fsadm.
Es posible reducir un grupo de volúmenes de la siguiente forma:
$ sudo pvmove /dev/sdc1
$ sudo vgreduce vg /dev/sdc1
Las snapshots LVM crean una copia exacta de un volumen lógico.
Son muy útiles para realizar respaldos, probar aplicaciones e implementar VMs (máquinas virtuales). El estado original de la snapshot se mantiene, como por ejemplo el mapa de bloques.
Los snapshots usan espacio para almacenar las diferencias (conocidas como deltas):
- Cuando el volumen lógico original cambia, los bloques de datos originales son copiados a la snapshot.
- Si la información se agrega directamente al snapshot, se almacena ahí solamente.
Para crear una snapshot de un volumen lógico existente:
$ sudo lvcreate -l 128 -s -n mysnap /dev/vg/mylvm
Para crear un punto de montaje y montar la snapshot:
$ mkdir /mysnap
$ mount -o ro /dev/vg/mysnap /mysnap
Para desmontar/usar la snapshot y luego removerla:
$ sudo umount /mysnap
$ sudo lvremove /dev/vg/mysnap
Asegúrese siempre de remover la snapshot cuando va a trabajar con ella. Si no remueve la snapshot y esta se llena a causa de los cambios, será deshabilitada automáticamente. Una snapshot con el tamaño del original nunca se desbordará.
Seleccione la sentencia correcta de las listadas a continuación:
Los PVs están agrupados en VGs. Los VGs se dividen en LVs.
Los VGs están agrupados en PVs. Los PVs se dividen en LVs.
Los LVs están agrupados en VGs. Los VGs se dividen en PVs.
¿Cuál es el mejor orden lógico de acciones necesarias para crear un disco nuevo y hacerlo disponible usando LVM?
Particionar el disco.
Crear un volumen físico.
Crear un grupo de volúmenes.
Asignar un volumen lógico.
Formatear el volumen lógico.
Montar el volumen lógico.
Actualmente usted debería ser capaz de:
- Explicar los conceptos detrás de LVM.
- Crear volúmenes lógicos.
- Visualizar volúmenes lógicos.
- Redimensionar volúmenes lógicos.
- Usar snapshots de LVM.
17. RAID
Al usar RAID se reparte la actividad de E/S en múltiples discos físicos en vez de sólo uno. El propósito de esto es mejorar la integridad y capacidad de recuperación en caso de falla, como también aumentar el rendimiento cuando es usado con dispositivos modernos de almacenamiento. Hay diversos niveles de RAID, los cuales varían en sus fortalezas relativas de seguridad, rendimiento, complejidad y costo.
Al final de este capítulo usted debería ser capaz de:
- Explicar el concepto de RAID.
- Proveer un resumen de los niveles de RAID.
- Configurar un dispositivo RAID usando los pasos esenciales entregados.
- Monitorear dispositivos RAID de múltiples maneras.
- Usar discos de reserva (hot spares).
RAID (Redundant Array of Independent Disks) reparte la carga de E/S en múltiples discos. Esto realmente puede incrementar el rendimiento en interfaces de controladoras de disco modernas, tales como SCSI, las cuales pueden realizar el trabajo en paralelo, de forma eficiente.
RAID puede ser implementado ya sea en software (es una parte madura del kernel Linux) o en hardware. Si su hardware de RAID es conocido por tener una buena calidad, podría ser más eficiente que usar RAID de software. En una implementación de hardware, el sistema operativo no está consciente de que está usando RAID, esto es transparente. Por ejemplo, tres discos duros de 512 GB (dos para datos, uno para paridad) configurados con RAID-5, se verán como un disco único de 1 TB.
Por otro lado, una desventaja de usar RAID de hardware es que si la controladora del disco falla, debe ser reemplazado por una compatible, la cual puede no ser fácil de obtener en todos los casos. Cuando se usa RAID de software, los mismos discos pueden conectarse y funcionar con cualquiera controladora de disco. Tales consideraciones pueden ser relevantes para hardware de gama media y baja.
Tres características esenciales de RAID son:
- mirroring (espejamiento): escribe los mismos datos en más de un disco.
- striping (división): divide o reparte los datos en más de un disco.
- parity (paridad): datos extra son almacenados para permitir la detección y reparación de problemas, proveyendo tolerancia a fallos.
Por lo tanto el uso de RAID puede mejorar tanto el rendimiento y fiabilidad.
Uno de los principales propósitos de RAID es crear un sistema de archivos el cual se reparte en más de un disco. Esto nos permite crear sistemas de archivos que son más grandes que cualquier dispositivo único. Los dispositivos RAID son creados generalmente combinando particiones de diferentes discos juntos.
Otra ventaja de los dispositivos RAID es la habilidad de proveer mejor rendimiento, redundancia o ambos. Striping provee mejor rendimiento al repartir la información sobre múltiples dispositivos, de tal forma que la escritura simultánea es posible. Mirroring o espejamiento escribe la misma información en múltiples discos proveyendo una mejor redundancia.
mdadm se usa para crear y administrar dispositivos RAID.
Una vez creado, el nombre del arreglo /dev/mdX puede ser usado como cualquier otro dispositivo, tal como /dev/sda1.
Existe una serie de especificaciones de RAID de complejidad y uso creciente. Los más comúnmente conocidos son los niveles 0, 1 y 5.
- RAID 0 usa striping solamente. Los datos se reparten a través de discos múltiples. Sin embargo, a pesar del nombre, no hay redundancia y no hay estabilidad o capacidades de recuperación. De hecho, si cualquier disco falla la información se perderá. Pero el rendimiento puede ser mejorada significativamente debido a la paralelización de tareas de E/S.
- RAID 1 usa mirroring solamente; cada disco tiene un duplicado, lo cual es bueno para la recuperación de los datos. Se requieren al menos dos discos.
- RAID 5 usa una banda de paridad de rotación; si una unidad de disco falla, no se producirá una pérdida de datos, solamente se reducirá el rendimiento. Tienen que haber al menos 3 discos.
- RAID 6 tiene discos con stripping y paridad dual; puede soportar la pérdida de dos discos y requiere al menos 4. Debido a que RAID 5 puede imponer un estrés significante sobre los discos, lo cual puede conducir a fallas durante el proceso de recuperación, RAID 6 se ha vuelto más importante.
- RAID 10 es un set de datos con mirroring y striping. Se necesitan al menos 4 discos.
Como regla general, el agregar más discos mejora el rendimiento.
Los pasos esenciales para configurar un dispositivo de RAID de software son:
- Crear las particiones en cada disco (teclee fd en fdisk).
- Crear el dispositivo RAID con mdadm.
- Formatear el dispositivo RAID.
- Agregar el dispositivo a /etc/fstab
- Montar el dispositivo RAID.
- Capturar detalles del RAID para asegurar la persistencia.
El comando:
$ sudo mdadm -S
se usa para detener/desactivar el RAID.
Por ejemplo:
Crear primero dos particiones de tipo fd en los discos sdb and sdc (digamos /dev/sdbX y /dev/sdcX) usando fdisk en cada una de ellas:
$ sudo fdisk /dev/sdb
$ sudo fdisk /dev/sdc
Entonces configure el arreglo, dele formato, agréguelo a la configuración y móntelo:
$ sudo mdadm --create /dev/md0 --level=1 --raid-disks=2 /dev/sdbX /dev/sdcX
$ sudo mkfs.ext4 /dev/md0
$ sudo bash -c "mdadm --detail --scan >> /etc/mdadm.conf"
$ sudo mkdir /myraid
$ sudo mount /dev/md0 /myraid
Asegúrese de agregar una línea en /etc/fstab para el punto de montaje.
/dev/md0 /myraid ext4 defaults 0 2
Puede examinar /proc/mdstat para ver el estado del RAID, tal como se muestra aquí:
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb8[1] sdc7[0]
---------- 521984 blocks [2/2]
unused devices: <none>
Use lo siguiente para detener el dispositivo RAID:
$ sudo mdadm -S /dev/md0
Usted puede monitorear dispositivos RAID de diversas formas:
$ sudo mdadm --detail /dev/md0
$ cat /proc/mdstat
También es posible usar mdmonitor, el cual requiere configurar /etc/mdadm.conf. El siguiente comando mostrará el estado actual del dispositivo RAID /dev/mdX:
$ sudo mdadm --detail /dev/mdX
Otra forma de hacerlo es examinar el sistema de archivos /proc:
$ cat /proc/mdstat
mostrará el estado de todos los dispositivos RAID en el sistema.
También puede darle el siguiente uso al servicio mdmonitor, editando /etc/mdadm.conf y agregando una línea como la siguiente:
MAILADDR eddie@haskell.com
lo anterior le enviará un email a eddie@haskell.com cuando un dispositivo RAID esté experimentando algún problema, tal como un arreglo que falla al iniciar o que cae en un estado degradado de funcionamiento. Lo puede habilitar con:
$ sudo service mdmonitor start
y asegúrese que va a iniciar en el arranque con:
$ sudo chkconfig mdmonitor on
Nota: En sistemas Ubuntu el servicio se llama mdadm en vez de mdmonitor.
Una de las cosas importantes que provee RAID es redundancia. Para asegurar que cualquier reducción en esa redundancia es resuelta lo antes posible, se usa un disco de reserva.
Para crear un disco de reserva cuando se está creando el arreglo RAID:
$ sudo mdadm --create /dev/md0 -l 5 -n3 -x 1 /dev/sda8 /dev/sda9 /dev/sda10 /dev/sda11
La opción -x 1 le indica a mdadm que use un dispositivo de reserva. Tenga en cuenta que un disco de reserva también puede ser agregado más tarde.
El comando:
$ sudo mdadm --fail /dev/md0 /dev/sdb2
probará la redundancia y el disco de de reserva de su arreglo.
Para restaurar la unidad probada o un disco nuevo en caso de una falla legítima, primero remueva el miembro defectuoso y luego agregue el miembro nuevo, como se muestra a continuación:
$ sudo mdadm --remove /dev/md0 /dev/sdb2
$ sudo mdadm --add /dev/md0 /dev/sde2
Supongamos que usted agregó dos discos nuevos a un servidor. ¿En qué orden debería usar los siguientes comandos para crear un dispositivo RAID con /dev/sdb1 y /dev/sdc1, y luego habilitar el RAID usando un sistema de archivos ext4?
fdisk /dev/sdb; fdisk /dev/sdc
mdadm --create /dev/md0 ... /dev/sdb1 /dev/sdc1
mkfs.ext4 /dev/md0
mdadm --detail --scan >> /etc/mdadm.conf
reboot
¿Cuál es el único nivel de RAID que no ofrece redundancia?
RAID 10
RAID 1
RAID 6
RAID 0
RAID 5
Actualmente usted debería ser capaz de:
- Explicar el concepto de RAID.
- Proveer un resumen de los niveles de RAID.
- Configurar un dispositivo RAID usando los pasos esenciales entregados.
- Monitorear dispositivos RAID de múltiples maneras.
- Usar discos de reserva (hot spares).
18. Seguridad del sistema local
Una tarea esencial de cualquier administrador de sistemas es asegurar el o los sistemas contra amenazas tanto internas como externas. El trabajo comienza con el diseño de una política de seguridad apropiada, creada para defenderse contra amenazas esperadas e inesperadas. Adicionalmente se requiere mantener los sistemas en un punto saludable; se necesita realizarles mantención y actualizarlos de forma oportuna, como también protegerlos físicamente de robos. Además, políticas sensatas tienen que garantizar que solo los usuarios apropiados tienen privilegios potencialmente peligrosos, y solo aquellos que son absolutamente necesarios.
Al final de este capítulo usted debería ser capaz de:
- Evaluar los riesgos de seguridad del sistema.
- Implementar políticas y procedimientos de seguridad informática.
- Proteger de forma eficiente la BIOS y el cargador de arranque con contraseñas de acceso.
- Usar de forma apropiada las opciones setuid y setgid del comando mount, para mejorar la seguridad.
Los computadores son inherentemente inseguros y necesitan ser protegidos de la gente que podría inmiscuirse en ellos o atacarlos. Los atacantes suelen hacer esto con el fin de dañar el sistema, denegar servicios o robar información.
Ningún computador puede ser absolutamente seguro. Todo lo que podemos hacer es ralentizar y desalentar a los intrusos con el fin de que abandonen el ataque, para buscar blancos más fáciles, o para atraparlos en el acto y tomar las acciones apropiadas.
La seguridad puede ser definida en términos de la habilidad del sistema para hacer con regularidad lo que se supone que tiene que hacer, su integridad y exactitud, como también en la garantía de que el sistema está disponible solamente para quienes están autorizados a usarlo.
El mayor problema es encontrar la mezcla apropiada entre seguridad y productividad; si las restricciones de seguridad presionan mucho al usuario, son difíciles, no están totalmente claras y básicamente son medidas ineficaces, los usuarios eludirán los procedimientos.
Las cuatro áreas que necesitamos proteger incluyen la física, local, remota y el personal. En esta sección no nos concentraremos en la seguridad de la red, sino más bien en los factores locales.
Es importante crear y dar a conocer en la organización una política de seguridad clara. Esta debería:
- Ser simple y fácil de comprender.
- Ser actualizada constantemente.
- Estar por escrito en un documento, como también en línea de ser necesario.
- Describir tanto políticas como procedimientos.
- Especificar las acciones coercitivas.
- Especificar las accionar a tomar en respuesta a una brecha de seguridad.
Las políticas deben ser genéricas y fáciles de entender, ya que eso las hace más fáciles de seguir. Deben salvaguardar la información que necesita ser protegida, denegar acceso a los servicios asociados y proteger la privacidad de los usuarios.
Estas políticas deberían ser actualizadas regularmente; de hecho las políticas necesitan cambiar en la medida en que los requerimientos lo hacen. Tener una política desactualizada puede ser peor que no tener una.
Una política de seguridad debe incluir métodos de protección de la información, para evitar sea leída o copiada por personal no autorizado. También debería debería incluir protección para que la información no sea alterada o eliminada sin el permiso del dueño. Todos los servicios deberían estar protegidos para que estén disponibles y no degradados de alguna forma sin autorización.
Aspectos esenciales:
- Confidencialidad
- Integridad de los datos
- Disponibilidad
- Consistencia
- Control
- Auditoría.
Debe asegurarse que la información es la correcta y que el sistema se comporta como se espera. En efecto, debería haber procesos para determinar quien está consiguiendo acceso a su sistema. El factor humano es el enlace más débil en la cadena de seguridad; esto requiere la mayor atención a través de una auditoría constante.
El análisis de riesgo está basado en las siguientes tres preguntas:
- ¿Qué quiero proteger?
- ¿Contra quién lo estoy protegiendo?
- ¿Cuánto tiempo, personal y dinero se necesita para brindar la protección adecuada?
Este es el primer paso a tomar para construir una política de seguridad informática. Es un prerrequisito para planear y luego aplicar políticas y procedimientos para proteger sus sistemas.
Existen dos filosofías básicas que se pueden encontrar en la mayoría de ambientes computacionales:
- Cualquier cosa no expresamente permitida es denegada.
- Cualquier cosa que no está expresamente prohibida es permitida.
Usted debe decidir cuál filosofía es la mejor para su organización.
La primera opción es más estricta: un usuario está habilitado para hacer solo lo que está clara y explícitamente especificado como permisible sin privilegios. Esta es la filosofía usada más comúnmente.
La segunda alternativa constituye un ambiente más liberal en donde a los usuarios se les permite hacer todo excepto lo que está expresamente prohibido. Esto implica un alto grado de confianza y se utiliza con menos frecuencia por razones obvias.
A continuación algunas guías generales a recordar durante la implementación de filosofías de seguridad:
- El factor humano es el eslabón más débil.
Debe educar a sus usuarios y mantenerlos contentos. El mayor porcentaje de vulneraciones de seguridad son internos y a menudo no son maliciosos. - No existe un ambiente informático invulnerable.
El único sistema totalmente seguro es el que no está conectado a nada, guardado en una habitación segura y apagado. - La paranoia es buena.
Sospeche, esté atento y sea perseverante al asegurar un sistema informático. Es un proceso continuo al que se le debe prestar atención constantemente. Verifique los procesos, usuarios y fíjese en cualquier cosa que parezca estar fuera de lo normal.
Los usuarios nunca deberían poner el directorio actual en el path. Es decir, no ponga algo como lo siguiente en su archivo ~/.bashrc:
PATH=./:$PATH
Esto tiene un riesgo de seguridad importante; una persona maliciosa podría reemplazar un programa con otro del mismo nombre, el cual podría hacer cosas perjudiciales. Piense en un script llamado ls que contenga solo la siguiente línea:
/bin/rm -rf $HOME
Si usted fuera al directorio que contiene ese archivo y ejecutara ls, borraría todo su directorio de usuario.
Es crítico prestar atención a las actualizaciones de su distribuidor de Linux y aplicarlas tan pronto sea posible.
La mayoría de los ataques explotan agujeros de seguridad conocidos en el período de tiempo entre la revelación del problema y la aplicación de parches. Los ataques de día cero son mucho más raros; en este caso un atacante usa un agujero de seguridad que no ha sido descubierto o para el cual no se ha liberado un parche.
Los administradores de sistemas son reacios a aplicar tales parches inmediatamente después de que han sido liberados, más que nada basados en experiencias negativas con compañías de software privativo, las que pueden causar más problemas que soluciones con los parches que incluyen. Sin embargo, esas regresiones son extremadamente raras en Linux, y probablemente el peligro de retrasar la aplicación de un parche de seguridad no es justificable.
En cualquier momento el hardware que está accesible físicamente puede ser comprometido por:
- Key logging: Almacenar la actividad en tiempo real de un usuario de computador (con un software de tipo keylogger), incluyendo las teclas que presiona. La información capturada puede ser almacenada localmente o transmitida a máquinas remotas.
- Analizador de paquetes de red: Captura y visualización de los datos a nivel de paquetes de red.
- Arrancar con un live CD/DVD o de rescate.
- Montar nuevamente el disco y modificar su contenido.
El acceso físico a un sistema permite a los atacantes aprovechar fácilmente diferentes vectores de ataque, lo cual torna en irrelevantes todas las recomendaciones a nivel de sistema operativo.
Por lo anterior, la política de seguridad debe partir con requerimientos acerca de cómo asegurar apropiadamente el acceso físico a los servidores y estaciones de trabajo.
Los pasos necesarios incluyen:
- Asegurar las estaciones de trabajo y servidores.
- Proteger el acceso a los enlaces de red de personas en las cuales no confía.
- Proteger los teclados en donde las contraseñas son ingresadas para asegurar que no puedan ser alterados.
- Configure protección por contraseña en la BIOS de tal forma que el sistema no pueda ser arrancado con un live CD/DVD, de rescate o un dispositivo USB.
Para computadores de usuario y aquellos en un ambiente del hogar, algunas de las características mencionadas (como prevenir el arranque de medios removibles) pueden ser excesivas y usted podría evitar su uso. Sin embargo, si en su sistema hay información sensitiva que requiere protección, entonces no debe estar ahí, o debería estar mejor protegida utilizando los lineamientos mencionados anteriormente.
La BIOS es el nivel más bajo de software que configura o manipula su sistema. El cargador de arranque accede a la BIOS para determinar cómo arrancar la máquina. La BIOS:
- Es el nivel más bajo de seguridad.
- Debe ser protegido por el uso de una contraseña.
- Debe estar actualizada.
Configurar una contraseña en la BIOS protege de que personas sin autorización cambien las opciones de arranque para ganar acceso al sistema. Sin embargo, solo importa si alguien puede conseguir acceso físico a la máquina, ya que esto requiere de presencia local.
También se recomienda generalmente que la BIOS se mantenga al día con la última versión del firmware. Sin embargo, la mayoría de las actualizaciones de las BIOS no tienen relación con el tema de seguridad y los administradores de sistemas suelen instalar esos parches con mucho cuidado, ya que una pieza de código incompetente en actualizaciones innecesarias podría inutilizar un sistema.
Usted puede asegurar el proceso de arranque con una contraseña segura para prevenir que alguien evite el paso de autenticación de usuario. Esto puede funcionar en conjunto con una protección por contraseña de la BIOS.
Tenga en cuenta que al usar una contraseña en el cargador de arranque va a prevenir que un usuario edite la configuración del mismo durante el proceso de arranque, sim embargo no prevendrá que un usuario arranque desde un medio alternativo, tales como CDs/DVDs o dispositivos USB. Por lo anterior, esto debería ir acompañado con una contraseña en la BIOS para tener una protección total en esta etapa.
Para sistemas que usan GRUB:
- Para la versión 1 de GRUB (la antigua), ejecute grub-md5-crypt. Esta herramienta le pedirá una contraseña, la cual cifrará y desplegará.
Luego de eso edite /boot/grub/grub.conf y agregue la línea siguiente debajo de la línea que contiene la entrada timeout:
password --md5 $1$Wnvo.1$qz781HRVG4jUnJXmdSCZ30
en donde debe ingresar la contraseña cifrada que desplegó la salida de grub-md5-crypt. Note que es posible forzar el uso de la contraseña solamente para algunas opciones de arranque, en vez de todas. - Para la versión 2 de GRUB (la actual) las cosas son más complicadas. Sin embargo, existe una mayor flexibilidad y es posible hacer cosas como configurar contraseñas individuales de usuario, las cuales incluso pueden ser las del inicio de sesión.
Como es usual en la versión 2, nunca edite el archivo de configuración directamente (/boot/grub/grub.cfg). En vez de eso, edite los archivos de configuración en /etc/grub.d y luego ejecute update-grub. Una explicación de esto puede encontrarse aquí: https://help.ubuntu.com/community/Grub2/Passwords.
Cuando un sistema de archivos se monta, ya sea desde la consola con un comando mount, o automáticamente a través de /etc/fstab, hay varias opciones que se pueden especificar para incrementar la seguridad:
- nodev
No interprete caracteres o dispositivos especiales de bloque en el sistema de archivos. - nosuid
Los bits set-user-identifier y set-group-identifier no tienen efecto. Vamos a discutir en breve setuid y setgid. - noexec
Restringe la ejecución directa de cualquier binario en el sistema de archivos montado.
- ro
Monta el sistema de archivos en modo de solo lectura, como se muestra a continuación:
$ mount -o ro,noexec,nodev /dev/sda2 /mymountpt
o en /etc/fstab:
/dev/sda2 /mymountpt ext4 ro,noexec,nodev 0 0
Normalmente un programa corre con los privilegios del usuario que lo ejecutó. Esto significa que sin importar quien es el dueño del binario que está corriendo, el proceso de todas formas tiene privilegios restringidos.
Ocasionalmente puede tener sentido que haya usuarios con capacidades extendidas que no tienen generalmente, tales como la habilidad para iniciar o detener una interfaz de red, o editar un archivo del cual el superusuario es dueño.
Al configurar el bit setuid (set user ID) en un archivo ejecutable, se modifica el comportamiento normal y se otorgan derechos de acceso del dueño en vez del usuario que ejecuta el programa.
Además es posible configurar el bit setgid, de tal forma que el proceso se ejecute con los privilegios del grupo que es dueño del binario, en vez del de quien lo está corriendo.
Quisiéramos enfatizar que esto es generalmente una mala idea y que es recomendable evitarlo en la mayoría de las circunstancias. A menudo es mejor escribir un programa demonio con menos privilegios para este tipo de uso. Algunas distribuciones recientes han deshabilitado completamente esta característica.
Esto se realiza de forma simple con:
$ chmod u+s somefile
$ chmod g+s somefile
en donde el primer ejemplo realiza la operación de setuid y el segundo la de setgid.
En el caso de los directorios, configurar el bit de grupo tiene un efecto diferente; se utiliza para crear un directorio compartido, como se muestra aquí:
$ chmod g+s somedir
Los archivos creados en este directorio pertenecen al grupo del dueño del directorio (y no al grupo del usuario que lo crea).
Tenga en cuenta que efectivamente no puede cambiar el setuid de un script shell; de hecho, no sucederá nada a menos que usted cambie el bit setuid en la consola, lo cual podría ser un tremendo agujero de seguridad. Solo se puede hacer en binarios ejecutables.
El uso de contraseñas para cuentas de usuario es común y es la herramienta básica para seguridad y privacidad. Sin embargo, hay dos contraseñas adicionales que se pueden configurar para incrementar de forma importante la seguridad del sistema. ¿Cuáles son las dos contraseñas adicionales que pueden ser configuradas para evitar que se carguen sistemas operativos desde dispositivos externos tales como un disco USB?
Cifrar el directorio / con LUKS.
Cifrar el directorio /boot con LUKS.
Configurar una contraseña para la BIOS.
Configurar una contraseña para el cargador de arranque.
- Laboratorio 18.1
- Laboratorio 18.2 (código fuente: writeit.c)
Actualmente usted debería ser capaz de:
- Evaluar los riesgos de seguridad del sistema.
- Implementar políticas y procedimientos de seguridad informática.
- Proteger de forma eficiente la BIOS y el cargador de arranque con contraseñas de acceso.
- Usar de forma apropiada las opciones setuid y setgid del comando mount, para mejorar la seguridad.
19. Módulos de seguridad de Linux
Un sistema computacional moderno tiene que ser seguro, pero las necesidades varían de acuerdo a la sensibilidad de la información, número de cuentas de usuario, exposición a redes externas, requerimientos legales y otros factores. La responsabilidad de habilitar buenos controles de seguridad recae tanto en los diseñadores de las aplicaciones, desarrolladores y mantenedores del kernel Linux. Por supuesto, los usuarios también deben seguir los buenos procedimientos establecidos, pero en un sistema gestionado adecuadamente, los usuarios no privilegiados deberían tener una capacidad muy limitada para exponer el sistema a violaciones de seguridad.
En esta sección nos ocuparemos de cómo el kernel Linux mejora la seguridad a través del uso de Módulos de Seguridad de Linux (LSM), particularmente con la implementación de SELinux.
Al final de este capítulo usted debería ser capaz de:
- Comprender cómo funciona y se implementa la infraestructura de los Módulos de Seguridad de Linux.
- Listar las diversas implementaciones disponibles de LSM.
- Describir las principales características de SELinux.
- Explicar los diversos modos y políticas disponibles.
- Comprender la importancia de los contextos, cómo obtenerlos y configurarlos.
- Saber cómo usar las herramientas importantes de SELinux.
Ha habido una serie de ideas acerca de cómo incorporar un módulo de seguridad informática en Linux. La idea es implementar controles de acceso obligatorios sobre una variedad de peticiones realizadas al kernel, de una forma en la que:
- Se minimicen los cambios al kernel.
- Se minimice la sobrecarga sobre el kernel.
- Permita flexibilidad y se pueda elegir entre diferentes implementaciones, cada una de las cuales se presenta como un LSM autónomo (Linux Security Module).
La idea básica es interceptar las llamadas al sistema; insertar código cada vez que una aplicación solicita una transición a modo kernel con el fin de realizar la tarea que requiere habilidades extendidas. Este código se asegura de que los permisos son válidos y que exista protección contra intentos malintencionados. Esto se lleva a cabo al invocar pasos de seguridad funcionales antes y/o después de que una llamada al sistema es satisfecha por el kernel.
Por un largo tiempo el único modelo de seguridad extendida que se implementaba fue SELinux. Cuando el proyecto fue sugerido por primera vez para ser incluido directamente en el kernel, en el 2001, hubo objeciones acerca de usar un solo enfoque a la seguridad extendida.
Como resultado de lo anterior, el método LSM fue adoptado con el fin de que módulos alternativos a SELinux podrían ser usados a medida en que fueran desarrollados. Se incorporó al kernel Linux en 2003.
Las implementaciones actuales de LSM son:
- SELinux: http://selinuxproject.org/page/Main_Page
- AppArmor: http://apparmor.net
- Smack: http://schaufler-ca.com
- TOMOYO: http://tomoyo.sourceforge.jp
Solo un LSM puede ser usado a la vez, ya que potencialmente modifican las mismas partes del kernel Linux.
Nos concentraremos principalmente en SELinux y de forma secundaria en AppArmor, en orden de volumen de uso.
SELinux fue desarrollado originalmente por la NSA de Estados Unidos (National Security Administration) y ha sido parte integral de RHEL por mucho tiempo, lo cual ha traído consigo una gran base de usuarios.
Operacionalmente, SELinux es un conjunto de reglas de seguridad que se usan para determinar qué procesos pueden acceder a cuáles archivos, puertos y otros ítems en el sistema.
Funciona con estas tres cantidades conceptuales:
- Contextos: Son etiquetas a archivos, procesos y puertos. Ejemplos de contextos son usuarios de SELinux, rol y tipo.
- Reglas: Describe el control de acceso en términos de contextos, procesos, archivos, puertos, usuarios, etc.
- Políticas: Son un conjunto de reglas que describen las decisiones de control de acceso aplicables a todo el sistema, las que deberían ser aplicadas por SELinux.
Un contexto de SELinux es un nombre usado por una regla para definir cómo los usuarios, procesos y puertos interactúan entre ellos. Como la política por defecto es denegar cualquier acceso, las reglas se usan para describir las acciones permitidas en el sistema.
SELinux puede correr en uno de los tres modos siguientes:
- Enforcing: Todo el código SELinux está operativo y el acceso está denegado de acuerdo a la política. Todas las violaciones a la misma son auditadas y registradas.
- Permissive: Habilita el código SELinux pero solo audita y advierte acerca de las operaciones que serían denegadas en modo enforcing.
- Disabled: Deshabilita completamente el código para aplicaciones y kernel de SELinux y deja el sistema sin ninguna de estas protecciones.
Estos modos se seleccionan (y explican) en un archivo (generalmente /etc/selinux/config), cuya ubicación varía según la distribución (a menudo se encuentra en /etc/sysconfig/selinux o enlazado desde aquí). El archivo está bien autodocumentado. La herramienta sestatus despliega el modo y política actual.
Para examinar o configurar el modo actual se puede usar getenforce y setenforce:
$ getenforce
Disabled
$ sudo setenforce Permissive
$ getenforce
Permissive
setenforce se usa para cambiar entre modo enforcing y permissive al vuelo, mientras el sistema está en operación. Sin embargo, no se puede habilitar o deshabilitar el modo disabled de esta forma. Mientras que setenforce permite cambiar entre los modos Permissive y Enforcing, no permite deshabilitar SELinux completamente. Hay al menos dos formas diferentes de deshabilitar SELinux:
- Archivo de configuración: edite el archivo de configuración (generalmente /etc/selinux/config) y configure SELINUX=disabled. Este es el método por defecto y debería usarse para deshabilitar SELINUX permanentemente.
- Parámetro del kernel: Agregue selinux=0 a la lista de parámetros del kernel cuando reinicie.
Sin embargo es importante notar que no se recomienda deshabilitar SELinux en sistemas en los cuales va a ser habilitado nuevamente. Es preferible usar el modo Permissive en vez de deshabilitar SELinux, para evitar que el sistema de archivos sea reetiquetado completamente, lo cual podría consumir bastante tiempo.
El mismo archivo de configuración, generalmente /etc/sysconfig/selinux, también configura la política de SELinux. Se permiten múltiples políticas, pero solo una puede estar activa a la vez. Cambiar la política puede requerir un reinicio del sistema y un reetiquetado del contenido del sistema de archivos, lo cual puede ser lento. Cada política tiene archivos que deben ser instalados bajo /etc/selinux/[SELINUXTYPE].
Las políticas más comunes son:
- targeted: La política por defecto en la cual SELinux es más restringida a procesos específicos. Los procesos de usuario e init no están dentro de los objetivos. SELinux impone restricciones de memoria para todos los procesos, lo cual reduce la vulnerabilidad ante ataques de desbordamiento de búfer (buffer overflow).
- minimum: Una modificación sobre la política targeted en donde solo los procesos seleccionados están protegidos.
- MLS: La política de seguridad de múltiples niveles es mucho más restrictiva; todos los procesos se ponen en dominios de seguridad específicos con políticas particulares.
Como se mencionó anteriormente, los contextos son etiquetas que se aplican a archivos, directorios, puertos y procesos. Estas etiquetas se usan para describir reglas de acceso. Existen cuatro contextos de SELinux:
- User (usuario)
- Role (rol)
- Type (tipo)
- Level (nivel).
Sin embargo, nos focalizaremos en type (tipo), el cual es el contexto más usado comúnmente. La convención de nombres de etiquetas determina que las etiquetas de contexto type deben terminar con _t, como en kernel_t.
Muchos comandos estándar de la línea de comandos, como ls y ps, fueron extendidos para soportar SELinux y las secciones correspondientes fueron agregadas a las páginas man, explicando los detalles. A menudo el parámetro Z se pasa a las herramientas estándar de línea de comandos, como en:
$ ps axZ
LABEL PID TTY STAT TIME COMMAND
system_u:system_r:init_t:s0 1 ? Ss 0:04 /usr/lib/systemd/systemd --switched-root ...
system_u:system_r:kernel_t:s0 2 ? S 0:00 [kthreadd]
...
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2305 ? D 0:00 sshd: peter@pts/0
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2306 pts/0 Ss 0:00 -bash
...
system_u:system_r:httpd_t:s0 7490 ? Ss 0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 7491 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
...
$ ls -Z /home/ /tmp/
/home/:
drwx------. peter peter unconfined_u:object_r:user_home_dir_t:s0 peter
/tmp/:
-rwx------. root root system_u:object_r:initrc_tmp_t:s0 ks-script-c4ENhg
drwx------. root root system_u:object_r:tmp_t:s0 systemd-private-0ofSvO
-rw-------. root root system_u:object_r:initrc_tmp_t:s0 yum.log
Otras herramientas que fueron extendidas para soportar SELinux incluyen cp, mv y mkdir.
Tenga en cuenta que si SELinux está deshabilitado, no se mostrará información relevante en los campos asociados a esas herramientas.
Los archivos nuevos heredan el contexto del directorio padre, pero al mover o copiar archivos, el contexto del directorio fuente es el cual debe ser preservado, lo cual puede causar problemas.
Continuando con el ejemplo anterior, vemos que el contexto de tmpfile no ha cambiado al mover el archivo desde /tmp a /home/peter:
$ cd /tmp/
$ touch tmpfile
$ ls -Z tmpfile
-rw-rw-r--. peter peter unconfined_u:object_r:user_tmp_t:s0 tmpfile
$ cd
$ touch homefile
$ ls -Z homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
$ mv /tmp/tmpfile .
$ ls -Z
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_tmp_t:s0 tmpfile
El ejemplo clásico en el cual se crea un problema en SELinux al mover archivos es cuando son movidos al directorio DocumentRoot del servidor httpd. En sistemas que tienen habilitado SELinux, el servidor web solo puede acceder a archivos con las etiquetas de contexto adecuadas. Si se crea un archivo en /tmp y luego se mueve al directorio DocumentRoot, estará inaccesible para el servidor httpd hasta que el contexto SELinux del archivo se modifique.
La herramienta restorecon restablece los contextos de un archivo, basado en la configuración del directorio padre. En el siguiente ejemplo, restorecon restablece la etiqueta por defecto recursivamente para todos los archivos en el directorio home.
$ ls -Z
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_tmp_t:s0 tmpfile
$ restorecon -Rv /home/peter
restorecon reset /home/peter/tmpfile context \
unconfined_u:object_r:user_tmp_t:s0->unconfined_u:object_r:user_home_t:s0
$ ls -Z
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 tmpfile
Note que el contexto de tmpfile fue reconfigurado al contexto por defecto para archivos creados en el directorio home. El tipo fue cambiado desde user_tmp_t a user_home_t.
Otro problema es cómo configurar el contexto por defecto para un directorio nuevo. La herramienta semanage fcontext (proveída por el paquete policycoreutils-python) despliega y cambia el contexto por defecto de archivos y directorios. Tenga en cuenta que semanage fcontext cambia la configuración por defecto solamente y no se aplica a objetos existentes. Esto requiere ejecutar restorecon luego. Por ejemplo:
[root@rhel7 /]# mkdir /virtualHosts
[root@rhel7 /]# ls -Z
...
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 virtualHosts
[root@rhel7 /]# semanage fcontext -a -t httpd_sys_content_t /virtualHosts
[root@rhel7 /]# ls -Z
...
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 virtualHosts
[root@rhel7 /]# restorecon -RFv /virtualHosts
restorecon reset /virtualHosts context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
[root@rhel7 /]# ls -Z
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 virtualHosts
Por lo tanto, el cambio del contexto desde default_t a httpd_sys_content_t se lleva a cabo solamente después de haber ejecutado restorecon.
El comportamiento de la política de SELinux puede ser configurada en tiempo de ejecución sin necesidad de reescribir la política. Esto se consigue configurando los Booleanos de SELinux, los cuales son parámetros de políticas que pueden ser habilidados y deshabilitados.
Para listar todos los booleanos de la política actual, incluyendo el estado actual y una descripción corta, haga lo siguiente:
$ sudo semanage boolean -l
SELinux boolean State Default Description
ftp_home_dir (off , off) Allow ftp to home dir
smartmon_3ware (off , off) Allow smartmon to 3ware
mpd_enable_homedirs (off , off) Allow mpd to enable homedirs
xdm_sysadm_login (off , off) Allow xdm to sysadm login
xen_use_nfs (off , off) Allow xen to use nfs
mozilla_read_content (off , off) Allow mozilla to read content
...
nfs_export_all_rw (on , on) Allow nfs to export all rw
pcp_bind_all_unreserved_ports (off , off) Allow pcp to bind all unreserved ports
postgresql_selinux_transmit_client_label (off , off) Allow postgresql to selinux transmit client label
collectd_tcp_network_connect (off , off) Allow collectd to tcp network connect
cobbler_use_cifs (off , off) Allow cobbler to use cifs
mcelog_server (off , off) Allow mcelog to server
httpd_setrlimit (off , off) Allow httpd to setrlimit
squid_connect_any (on , on) Allow squid to connect any
ssh_sysadm_login (off , off) Allow ssh to sysadm login
domain_fd_use (on , on) Allow domain to fd use
virt_use_samba (off , off) Allow virt to use samba
cluster_use_execmem (off , off) Allow cluster to use execmem
nfs_export_all_ro (on , on) Allow nfs to export all ro
cron_can_relabel (off , off) Allow cron to can relabel
sftpd_anon_write (off , off) Allow sftpd to anon write
Un ejemplo de cambio no persistente usando setsebool:
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> off
$ sudo setsebool ssh_chroot_rw_homedirs on
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> on
$ sudo reboot
...
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> off
Un ejemplo de cambio persistente usando setsebool -P:
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> off
$ sudo setsebool -P ssh_chroot_rw_homedirs on
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> on
$ sudo reboot
...
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> on
Una alternativa para desplegar la información booleana que produce una salida más simple, es getsebool -a, la cual imprime solo el nombre booleano y su estado actual.
setsebool se usa para cambiar el estado booleano. El comportamiento por defecto es aplicar los cambios inmediatamente y no son persistentes luego del reinicio. Sin embargo, el parámetro -P puede ser proveído para hacer que los cambios sean persistentes.
SELinux viene con un conjunto de herramientas que recopilan información acerca de problemas en tiempo de ejecución; registran esos problemas y proponen soluciones para prevenir que esos problemas ocurran de nuevo. Estas herramientas son proveídas por el paquete setroubleshoot-server. Aquí hay un ejemplo de su uso:
[root@rhel7 ~]# echo 'File created at /root' > rootfile
[root@rhel7 ~]# mv rootfile /var/www/html/
[root@rhel7 ~]# wget -O - localhost/rootfile
--2014-11-21 13:42:04-- http://localhost/rootfile
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2014-11-21 13:42:04 ERROR 403: Forbidden.
[root@rhel7 ~]# tail /var/log/messages
Nov 21 13:42:04 rhel7 setroubleshoot: Plugin Exception restorecon
Nov 21 13:42:04 rhel7 setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file .
For complete SELinux messages. run sealert -l d51d34f9-91d5-4219-ad1e-5531e61a2dc3
Nov 21 13:42:04 rhel7 python: SELinux is preventing /usr/sbin/httpd from getattr access on the file .
***** Plugin catchall (100. confidence) suggests **************************
If you believe that httpd should be allowed getattr access on the file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
[root@rhel7 ~]# sealert -l d51d34f9-91d5-4219-ad1e-5531e61a2dc3
SELinux is preventing /usr/sbin/httpd from getattr access on the file .
***** Plugin catchall (100. confidence) suggests **************************
If you believe that httpd should be allowed getattr access on the file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
Additional Information:
Source Context system_u:system_r:httpd_t:s0
Target Context unconfined_u:object_r:admin_home_t:s0
Target Objects [ file ]
Source httpd
Source Path /usr/sbin/httpd
Port <Unknown>
Host rhel7
Source RPM Packages httpd-2.4.6-18.el7_0.x86_64
Target RPM Packages
Policy RPM selinux-policy-3.12.1-153.el7_0.11.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name rhel7
Platform Linux rhel7 3.10.0-123.9.3.el7.x86_64 #1 SMP Thu
Oct 30 00:16:40 EDT 2014 x86_64 x86_64
Alert Count 2
First Seen 2014-11-21 12:34:13 CET
Last Seen 2014-11-21 13:42:04 CET
Local ID d51d34f9-91d5-4219-ad1e-5531e61a2dc3
Raw Audit Messages
type=AVC msg=audit(1416573724.395:1598): avc: denied { getattr } for pid=20180 comm="httpd"
path="/var/www/html/rootfile" dev="dm-0" ino=70624441 scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=SYSCALL msg=audit(1416573724.395:1598): arch=x86_64 syscall=lstat success=no exit=EACCES
a0=7f2896ed0578 a1=7fffcc64fb30 a2=7fffcc64fb30 a3=0 items=0 ppid=20178 pid=20180
auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none)
ses=4294967295 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null)
Hash: httpd,httpd_t,admin_home_t,file,getattr
Tenga en cuenta que en RHEL 7 se sugiere ejecutar lo siguiente:
$ grep httpd /var/log/audit/audit.log | audit2allow -M mypol
audit2allow es una herramienta que genera reglas de políticas de SELinux desde registros de operaciones denegadas. Una herramienta similar es audit2why, la cual traduce los mensajes de auditoría de SELinux en descripciones de porqué el acceso fue denegado.
El ejemplo siguiente muestra cómo resolver este problema usando la herramienta restorecon, la cual fue descrita anteriormente. Siéntase libre de intentar ambas aproximaciones para resolver el problema encontrado en SELinux.
[root@rhel7 ~]# restorecon -Rv /var/www/html/
restorecon reset rootfile context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
[root@rhel7 ~]# wget -q -O - localhost/rootfile
File created at /root
En esta sección hemos cubierto las tareas de administración de sistemas básicas y más comunes relacionadas a SELinux. Existen recursos gratuitos que están disponibles en línea para ítems avanzados de SELinux, los cuales incluyen (documentación disponible en inglés):
- Red Hat Enterprise Linux 7 SELinux User's and Administrator's Guide (https://access.redhat.com/ documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/)
- Red Hat Enterprise Linux 6 Security-Enhanced Linux (https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Security-Enhanced_Linux/)
AppArmor es una alternativa LSM a SELinux. El soporte para ésta fue incorporado en el kernel Linux desde 2006. Ha sido usado por SUSE, Ubuntu y otras distribuciones.
AppArmor:
- Provee Control de Acceso Obligatorio (MAC).
- Habilita a administradores a asociar un perfil de seguridad a un programa, lo cual restringe sus capacidades.
- Es considerado más fácil de usar (por algunos, pero no todos) que SELinux.
- Se considera como neutral al sistema de archivos (no requiere etiquetas de seguridad).
AppArmor complementa el modelo tradicional de Control de Acceso Discrecional de UNIX (DAC) al proveer Control de Acceso Obligatorio (MAC).
De forma adicional a la capacidad de especificar perfiles de forma manual, AppArmor incluye un modo de aprendizaje, en el cual las violaciones al perfil son registradas, pero no prevenidas. Este registro puede ser convertido en un perfil, basado en el comportamiento típico del programa.
¿Cuál de las sentencias de a continuación describe mejor las diferencias entre los modos Permissive y Enforcing de SELinux?
El modo Enforcing de SELinux restringe qué procesos pueden ser accedidos, pero no tiene efectos en los puertos de red.
El modo Enforcing de SELinux deniega acceso a todo pero lo permite a aquello que se ha habilitado de forma explícita.
Los modos Enforcing y Permissive de SELinux son similares, pero el modo Permissive registra los errores.
El modo Permissive de SELinux deniega acceso a todo pero lo permite a aquello que se ha habilitado de forma explícita.
¿Qué herramienta de SELinux se usa para restablecer el contexto de un archivo para que coincida con el contexto del directorio actual?
Actualmente usted debería ser capaz de:
- Comprender cómo funciona y se implementa la infraestructura de los Módulos de Seguridad de Linux.
- Listar las diversas implementaciones disponibles de LSM.
- Describir las principales características de SELinux.
- Explicar los diversos modos y políticas disponibles.
- Comprender la importancia de los contextos, cómo obtenerlos y configurarlos.
- Cómo usar las herramientas importantes de SELinux.
20. Procesos
Un proceso es la encarnación de una aplicación en ejecución que puede o no consistir de varias hebras. Los procesos tienen atributos y permisos bien definidos. Tienen que estar en uno de un número de procesos enumerados; los más comunes son running (corriendo) o sleeping (durmiendo). Es importante saber cuándo un proceso está corriendo en modo usuario con privilegios limitados o en modo kernel, con privilegios extendidos, incluyendo un acceso más directo al hardware. Hay diversas formas de crear un proceso hijo y tanto configurar como modificar sus prioridades.
Al final de este capítulo usted debería ser capaz de:
- Describir un proceso y los recursos asociados a él.
- Distinguir entre procesos, programas y hebras.
- Comprender los atributos de procesos, permisos y estados.
- Saber la diferencia entre la ejecución de un programa en modo usuario y kernel.
- Describir los procesos demonio (daemon).
- Comprender cómo se crean los procesos nuevos.
- Usar nice y renice para configurar y modificar las prioridades.
Un proceso es un programa en ejecución y los recursos asociados, incluyendo el ambiente, archivos abiertos, manejadores de señales, etc. El mismo programa puede ser ejecutado más de una vez en forma simultánea y por lo tanto es responsable de múltiples procesos.
Al mismo tiempo, dos o más tareas, o hebras de ejecución, pueden compartir diversos recursos, como los espacios completos de memoria (o solo áreas de memoria en particular), archivos abiertos. etc. Cuando hay cualquier circunstancia en la cual se comparten recursos, hablamos de un proceso multihebra.
En otros sistemas operativos puede haber una gran diferencia entre procesos pesados y ligeros (full heavy weight processes/light weight); en forma estricta, los procesos pesados pueden incluir procesos livianos, o solo uno de ellos.
En Linux la situación es bastante diferente. Cada hebra de ejecución se considera individualmente, la diferencia entre un proceso pesado y ligero tiene relación solamente con el uso de recursos compartidos y con la velocidad algo más rápida en la conmutación de contextos entre hebras en ejecución.
A diferencia de otros sistemas operativos, Linux siempre ha hecho un trabajo excepcionalmente rápido al crear, destruir y conmutar entre procesos. Por lo tanto el modelo adoptado para aplicaciones de multihebra se asemeja a procesos múltiples; cada hebra se programa individualmente, como si fuera un proceso independiente normal. Esto se realiza en vez de involucrar más niveles de complejidad como tener un método por separado para la programación de las hebras de un proceso, como también tener método de programación entre diferentes procesos.
Al mismo tiempo, Linux respeta el POSIX y otros estándares de multihebra; por ejemplo, cada hebra devuelve el mismo ID de proceso (llamado internamente como ID de grupo de hebra), mientras que devuelve un ID de hebra distinta (llamado internamente como el ID de proceso). Esto puede conducir a los desarrolladores a una confusión, pero debería ser transparente a los administradores.
El primer proceso de usuario en el sistema es init, el cual tiene ID = 1. Este se inicia tan pronto como el kernel ha sido inicializado y se montado el sistema de archivos raíz.
init se ejecutará hasta que el sistema se apague; este será el último proceso de usuario que será terminado en ese punto. Este sirve como el padre ancestral de todos los demás procesos de usuario, tanto directa como indirectamente.
Un proceso es una instancia de un programa en ejecución. Puede estar en diversos estados, tales como running (en ejecución) o sleeping (durmiendo). Cada proceso tiene un pid (Process ID), un ppid (Parent Process ID) y un pgid (Process Group ID). Adicionalmente, cada proceso tiene un código de programa, datos, variables, descriptores de archivos y un ambiente.
init es generalmente el primer proceso de usuario que se ejecuta en el sistema, y por lo tanto es el antecesor de todos los procesos subsecuentes, con la excepción de aquellos que han sido iniciados directamente por el kernel (los cuales se muestran con [] alrededor del nombre en un listado de ps).
Si el proceso padre muere antes que el hijo, el ppid del hijo se configura en 1; es decir, el proceso es adoptado por init. Nota: en sistemas Linux recientes que usan systemd, el ppid será configurado en 2, lo cual corresponde a una hebra interna del kernel conocida como kthreadd, el que ha asumido de init el rol de adopción de los hijos huérfanos.
Un proceso hijo que termina su ejecución (ya sea normal o anormalente) antes que su padre, el cual no esperó por este ni examinó su código de salida, se conoce como un proceso zombie (o difunto). Los procesos zombies liberan prácticamente todos los recursos y se mantienen en ese estado solo para transmitir su estado de salida. Una función del proceso init consiste en verificar los hijos adoptivos y dejar que mueran de forma adecuada aquellos que ya han terminado. Por lo anterior, a veces se le denomina el asesino de zombies, o de forma más sombría, el segador de niños.
Los procesos son controlados por la programación de los mismos, lo cual es completamente preferente. Solo el kernel tiene el derecho de preferencia sobre un proceso, algo que el resto de los procesos no pueden hacerse entre ellos.
Por razones históricas, el PID más grande ha sido limitado a un número de 16 bit, el cual corresponde a 32768. Es posible modificar este valor cambiando /proc/sys/kernel/pid_max, ya que el valor por defecto puede ser inadecuado para servidores más grandes. A medida en la que los procesos son creados, eventualmente alcanzarán el pid_max, punto en el cual comenzarán de nuevo en PID = 300.
Todos los procesos tienen ciertos atributos:
- El programa que está siendo ejecutado
- Contexto (estado)
- Permisos
- Recursos asociados.
Cada proceso ejecuta algún programa. En cualquier momento el proceso puede tomar una snapshot de sí mismo a través de la captura del estado de los registros de la CPU, dónde se está ejecutando, qué hay en la memoria del proceso y alguna otra información. Esto es el contexto del proceso.
Ya que los procesos pueden ser agendados para entrar y salir del tiempo compartido de CPU con otros (o a veces tienen que ser puestos a dormir mientras esperan que alguna condición se cumpla, tal como una petición de usuario o datos que están por llegar), es posible almacenar el contexto completo cuando cambia la condición del proceso y se restablece su ejecución. Lo anterior es crítico para que el kernel sea capaz de cambiar al contexto que se requiera en un instante determinado.
ulimit está construido sobre la base de un comando bash, el cual despliega o restablece una serie de límites de recursos asociados con procesos corriendo bajo una shell. Si se ejecuta con el argumento -a muestra lo siguiente:
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 31843
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 4096
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Un administrador de sistemas podría necesitar cambiar alguno de estos valores en una u otra dirección:
- Para restringir las capacidades de tal forma que un usuario y/o proceso no pueda acaparar los recursos del sistema, tales como memoria, tiempo de cpu o el número máximo de procesos en el sistema.
- Para ampliar las capacidades de tal forma que un proceso no esté limitado en sus recursos; por ejemplo, para un servidor que maneja muchos clientes el valor por defecto de 1024 archivos abiertos podría hacer que su trabajo sea imposible de realizar.
Hay dos tipos de límites:
- Hard: El valor máximo, que solo el usuario root puede configurar, al que un usuario puede elevar el límite de recursos.
- Soft: El valor del límite actual, el cual un usuario puede modificar, pero que no puede exceder el límite hard.
Es posible configurar cualquier límite en particular haciendo lo siguiente:
$ ulimit [options] [limit]
como en
$ ulimit -n 1600
lo cual aumentaría el número máximo de descriptores de archivos a 1600.
Tenga en cuenta que los cambios afectarán solamente a la shell actual. Para que los cambios sean efectivos para todos los usuarios logueados, es necesario modificar /etc/security/limits.conf, un archivo muy bien autodocumentado, y luego reiniciar.
Cada proceso tiene permisos basados en el usuario específico que lo invocó. Adicionalmente, puede tener permisos basados en el usuario dueño del archivo del programa.
Tal como se comentó en la sección de seguridad local, los programas que están marcados con una s en el bit de ejecución tienen un user id efectivo diferente al de su usuario real. Estos se conocen como programas setuid. Se ejecutan con el user id del usuario que es dueño del programa; los programas que no tienen setuid definidos se ejecutan con los permisos del usuario que los corre. Los programas setuid de los cuales root es dueño tienen el potencial de ser un problema de seguridad conocido.
La herramienta passwd es un ejemplo de un programa setuid. Cualquier usuario puede ejecutarlo. Cuando un usuario ejecuta este programa, el proceso debe correr con permisos de root para poder actualizar los archivos restringidos de escritura /etc/passwd y /etc/shadow, en donde se mantienen las contraseñas de usuario.
Los procesos pueden estar en uno de varios estados posibles. Los principales son los siguientes:
- En ejecución:
El proceso está siendo ejecutado actualmente ya sea en una CPU, o núcleo de CPU o en la cola de ejecución, esperando una nueva tajada de tiempo. Se reanudará cuando el planificador decide que merece utilizar la CPU, o cuando otra CPU queda libre y el planificador migra el proceso a esa CPU. - Durmiendo (es decir, esperando):
El proceso está esperando una solicitud (generalmente E/S) que se realizó y que no puede continuar hasta que se complete. Cuando la petición se ha completado, el kernel despertará el proceso y lo pondrá de vuelta en la cola de ejecución, y se le otorgará una tajada de tiempo en una CPU cuando el planificador decida hacerlo. - Detenido:
El proceso ha sido suspendido. Este estado se experimenta comúnmente cuando un programador quiere examinar la memoria del programa en ejecución, los registros de la CPU, banderas u otros atributos. Una vez que esto se ha realizado el proceso podría ser reanudado. Esto generalmente se realiza cuando el proceso está siendo ejecutado desde un depurador o el usuario teclea Ctrl-Z. - Zombie:
El proceso entra en este estado cuando termina su ejecución y ningún otro proceso (generalmente el padre) ha inquirido acerca de su estado de salida. Tales procesos también se denominan difuntos. Un proceso zombie ha liberado todos sus recursos con excepción de su estado de salida y su entrada en la tabla de procesos. Si el padre de cualquier proceso muere, el proceso es adoptado por init (PID=1) o kthreadd (PID=2).
En un momento dado un proceso (o cualquier hilo en particular de un proceso multihebra) puede ser ejecutado ya sea en modo usuario o modo sistema, el cual es llamado generalmente modo kernel por los desarrolladores del kernel.
Las instrucciones que pueden ser ejecutadas dependen del modo, el cual se aplica a nivel de hardware, no de software.
El modo no es un estado del sistema; es un estado del procesador en un sistema multinúcleo o multi-CPU, en donde cada unidad puede estar en su estado individual.
En la jerga de Intel, el modo usuario se denomina Ring 3, y el modo de sistema, Ring 0.
Con la excepción de cuando se ejecuta una llamada al sistema (lo cual se describirá en la sección siguiente), los procesos se ejecutan en modo usuario, donde tienen menos privilegios que en modo kernel.
Cuando un proceso se inicia, es aislado en su propio espacio de usuario para protegerlo de otros procesos. Esto promueve la seguridad y crea una estabilidad mayor. A veces esto se denomina aislación de recursos del proceso.
Cada proceso que se ejecuta en modo usuario tiene su propio espacio de memoria, partes del cual pueden ser compartidos con otros procesos; excepto para los segmentos de memoria compartida, un proceso de usuario no puede leer desde o escribir hacia el espacio de memoria de cualquier otro proceso.
Incluso un proceso ejecutado por el usuario root o un programa con setuid se ejecuta en modo usuario, excepto cuando realiza una llamada al sistema, caso en el cual tiene una capacidad limitada para acceder al hardware.
En modo kernel (de sistema) la CPU tiene acceso completo a todo el hardware en el sistema, incluyendo periféricos, memoria, discos, etc. Si una aplicación necesita acceso a estos recursos debe realizar una llamada al sistema, lo cual causa un cambio de contexto desde modo usuario a modo kernel. Este procedimiento se debe realizar cuando se lee y escribe archivos, se crean procesos nuevos, etc.
El código de las aplicaciones nunca se ejecuta en modo kernel, solo las llamadas al sistema en sí, lo cual corresponde a código del kernel. Cuando la llamada al sistema está completa, se devuelve un valor y el proceso vuelve a modo usuario con un cambio de contexto en el sentido contrario.
Hay oportunidades en las que el sistema está en modo kernel y no tiene relación con los procesos, tales como manejo de interrupciones de hardware, ejecutar las rutinas del planificador y otras tareas administrativas del sistema.
Un demonio es un proceso que se ejecuta en segundo plano, cuyo único propósito es proveer algún servicio específico a los usuarios del sistema. Los demonios:
- Pueden ser muy eficientes debido a que funcionan solo cuando es necesario.
- Muchos de ellos se inician en el arranque.
- Sus nombres a menudo (aunque no en todos los casos) terminan con d.
- Algunos ejemplos incluyen httpd y udevd.
- Los demonios pueden responder a eventos externos (udevd) o a tiempo transcurrido (crond).
- Generalmente no tienen una terminal de control ni dispositivos estándar de entrada/salida.
- A veces proporcionan un mejor control de la seguridad.
Cuando se usa SysVinit, los scripts en el directorio /etc/init.d inician varios demonios del sistema. Estos scripts invocan comandos como argumentos de una función de shell llamada daemon, definida en el archivo /etc/init.d/functions.
Para ver un ejemplo de cómo se hace esto, mire el script del servicio httpd en el directorio /etc/init.d.
Los sistemas que usan systemd utilizan métodos similares para los demonios.
No todos los procesos son creados (o forked) a raíz de los procesos padre del usuario. El kernel Linux crea directamente dos tipos de procesos por iniciativa propia. Estos son:
- Procesos internos del kernel:
Estos se ocupan de tareas de mantención, tales como asegurar que los buffers fluyen hacia los discos, que la carga se equilibra de manera uniforme en las diferentes CPUs, que los controladores de dispositivos se hacen cargo del trabajo que ha sido encolado para ellos, etc. Estos procesos a se ejecutan mientras el sistema está corriendo y generalmente están durmiendo, a menos de que tengan algo específico que realizar. - Procesos externos de usuario:
Estos son procesos que corren en espacio como las aplicaciones normales, pero que son iniciados por el kernel. Hay muy pocos procesos de este tipo y generalmente tienen una vida corta.
Es fácil ver los procesos de este tipo; cuando se ejecuta el siguiente comando
$ ps -elf
se listan todos los procesos en el sistema y se muestran los IDs de los procesos padres; todos los que tienen PPID = 2 se refieren a kthreadd, el hilo del kernel, cuyo trabajo es crear tales procesos. Los nombres de estos procesos estarán encapsulados en paréntesis cuadrados, como [ksoftirqd/0], por ejemplo.
Un sistema Linux promedio está constantemente creando procesos nuevos. A menudo esto se denomina forking; el proceso original padre continúa ejecutándose mientras que el proceso hijo recién creado se inicia.
Cuando la mayoría de los computadores tenían procesadores individuales solamente, generalmente eran configurados para que el padre realizara una pausa inicial mientras que el hijo se iniciaba; hay una expresión de UNIX que dice "Los niños son lo primero". Sin embargo, con sistemas modernos multi CPU ambos correrán simultáneamente en diferentes CPUs.
A menudo, en vez de un fork, se sigue con un exec, en donde el proceso padre termina y el proceso hijo hereda el ID del proceso padre. Los términos fork y exec se usan tan a menudo que la gente piensa que son la misma palabra.
Los sistemas UNIX antiguos a menudo usan un programa llamado spawn, el cual es similar en diversas formas a fork y exec, pero difiere en algunos detalles. No es parte del estándard POSIX ni de Linux.
Para tener una idea de cómo un proceso podría iniciarse, considera un servidor web que maneja muchos clientes. El servidor web puede lanzar un proceso nuevo cada vez que una conexión nueva se hace a través de un cliente. Por otro lado, podría iniciar simplemente un nuevo hilo como parte del mismo proceso; en Linux realmente no existe mucha diferencia en el aspecto técnico entre crear un proceso completo o solo un hilo nuevo, ya que cada mecanismo toma aproximadamente el mismo tiempo y usa una cantidad similar de recursos.
Otro ejemplo es el demonio sshd: este es iniciado cuando el proceso init ejecuta el script de inicio sshd, el que a su vez es responsable de iniciar el demonio sshd. Este proceso demonio escucha solicitudes ssh de usuarios remotos.
Cuando se recibe una solicitud, sshd crea una copia nueva de sí mismo para atender el requerimiento de servicio. Cada usuario remoto obtiene su propia copia del demonio sshd que está en ejecución, para atender su conexión remota. El proceso sshd inciará el programa login para validar el usuario remoto. Si la autenticación es exitosa, el proceso login hará un fork de shell (por ejemplo, bash) para interpretar los comandos de usuario, y así sucesivamente.
¿Qué sucede cuando un usuario ejecuta un comando en un intérprete de shell, tal como bash?
- Un proceso nuevo se crea, como un fork desde la shell de inicio de sesión del usuario.
- Una llamada al sistema de espera pone a dormir el proceso de la shell padre.
- El comando se carga en el espacio del proceso hijo a través de la llamada al sistema exec. En otras palabras, el código del comando reemplaza el programa bash en el espacio de memoria del proceso hijo.
- El comando completa su ejecución y el proceso hijo muere a través de la llamada al sistema de salida.
- La shell padre se despierta nuevamente por la muerte del proceso hijo y procede a crear un nuevo intérprete de comandos. Entonces la shell padre espera por la próxima solicitud de comando desde el usuario, momento en el cual el ciclo se repetirá.
Si un comando se ejecuta en segundo plano (agregando un signo & al final de la línea de comandos), la shell padre se salta la solicitud de espera y queda libre para crear una nueva shell inmediatamente, permitiendo que el proceso en segundo plano se ejecute en paralelo. Por otro lado, para las solicitudes de primer plano la shell espera hasta que el proceso hijo se ha completado o es detenido a través de una señal.
Algunos comandos de shell (tales como echo y kill) están construidos en la shell misma y no implican la carga de archivos de programa. Para la ejecución de esos comandos no se utiliza fork ni exec.
La prioridad de los procesos puede ser controlada a través de los comandos nice y renice. Desde los primeros días de UNIX la idea ha sido que el proceso nice disminuya su prioridad para cedérsela de los demás. Por lo tanto, a medida en que nice es mayor, la prioridad es menor.
El rango de nice va desde -20 (la prioridad más alta) a +19 (la prioridad más baja). La forma normal de ejecutar nice es la siguiente:
$ nice -n 5 command [ARGS]
lo cual aumentaría nice en 5. Esto es equivalente a hacer lo siguiente:
$ nice -5 command [ARGS]
Si usted no provee un valor para nice, se utilizará el predeterminado, el cual consiste en incrementarlo en 10. Si no da ningún argumento se informará del valor actual. Por ejemplo:
$ nice
0
$ nice cat &
[1] 24908
$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 500 4670 4603 0 80 0 - 16618 wait pts/0 00:00:00 bash
0 S 500 24855 4670 0 80 0 - 16560 wait pts/0 00:00:00 bash
0 T 500 24908 24855 0 90 10 - 14738 signal pts/0 00:00:00 cat
0 R 500 24909 24855 0 80 0 - 15887 - pts/0 00:00:00 ps
Tenga en cuenta que al aumentar el valor de nice de un proceso no significa que este no se ejecutará; incluso podría obtener todo el tiempo de la CPU si no hay nada con lo cual competir.
Si usted provee un gran incremento o decremento que sale del rango -20 a 19, el valor de incremento será truncado.
Por defecto solo un superusuario puede disminuir el valor de nice, es decir, incrementar la prioridad. Sin embargo es posible darle a los usuarios normales la habilidad de disminuir el valor de nice para sus procesos, en un rango predeterminado, lo cual se realiza editando el archivo /etc/security/limits.conf.
Para cambiar el valor de nice de un proceso que está en ejecución, usamos el comando renice, así:
$ renice +3 13848
lo cual incrementará en valor de nice en 3, del proceso con pid = 13848. Puede hacerlo con más de un proceso a la vez y hay algunas otras opciones interesantes que puede ver con man renice.
Los programas están construidos usando bibliotecas de código, desarrolladas con múltiples propósitos, las cuales son reutilizadas en diversos contextos.
Hay dos tipos de bibliotecas:
- Estáticas
El código para las funciones de la biblioteca se inserta en el programa en el momento de la compilación, de tal forma que no cambia después de eso, incluso si la biblioteca es actualizada. - Compartidas
El código para las funciones de la biblioteca se carga en el programa en tiempo de ejecución, y si la biblioteca se cambia en un momento posterior, el programa en ejecución corre con las modificaciones que se han hecho a la biblioteca.
El uso de bibliotecas compartidas es más eficiente porque pueden ser utilizadas por muchas aplicaciones a la vez. El uso de la memoria, el tamaño de los ejecutables y el tiempo de carga de la aplicación se reducen.
Las bibliotecas compartidas también se denominan DLLs (Dynamic Link Library).
Las bibliotecas compartidas necesitan ser versionadas cuidadosamente. Si hay un cambio importante en la biblioteca y un programa no está equipado para manejarlo, es posible esperar que ocurran problemas serios. Esto se suele conocer como Infierno de las DLL.
Por lo tanto, los programas pueden solicitar una versión específica de la biblioteca, en vez de la última disponible en el sistema. Sin embargo, generalmente el programa usará la versión menor en su última actualización disponible.
Algunos proveedores de aplicaciones usan bibliotecas estáticas embebidas en el programa para evitar estos problemas. Sin embargo, si hay mejoras, bugs y agujeros de seguridad que han sido resueltos en las bibliotecas, no van a estar disponibles en las aplicaciones en un tiempo adecuado.
Shared libraries have the extension .so. Typically the full name is something like libc.so.N where N is a major version number.Algunas librerías tienen la extensión .so. Generalmente el nombre completo es algo como libc.so.N, en donde N es un número de una versión principal.
En Linux las bibliotecas compartidas están versionadas cuidadosamente. Por ejemplo:
c7:/usr/lib64>ls -lF libgdbm.so*
lrwxrwxrwx 1 root root 16 Apr 9 2015 libgdbm.so -> libgdbm.so.4.0.0*
lrwxrwxrwx 1 root root 16 Apr 9 2015 libgdbm.so.4 -> libgdbm.so.4.0.0*
-rwxr-xr-x 1 root root 36720 Jan 24 2014 libgdbm.so.4.0.0*
c7:/usr/lib64>
por lo que un programa que solicita libgdm obtiene libgdm.so y las que se especifican como versiones principales y menores.
Un programa que usa bibliotecas compartidas debe ser capaz de encontrarlas en tiempo de ejecución.
ldd puede usarse para determinar qué bibliotecas compartidas requiere un ejecutable. Muestra el nombre de la biblioteca y a qué archivo apunta:
$ ldd /usr/bin/vi
linux-vdso.so.1 => (0x00007fffe55dc000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f0202cc0000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f0202a96000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007f020288c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f02024cb000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f020226a000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f0202044000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f0201e40000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0202f01000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f0201c3b000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0201a1e000)
ldconfig se ejecuta generalmente en el arranque del sistema (aunque puede ser ejecutado en cualquier momento), y usa el archivo /etc/ld.so.conf, el cual lista los directorios en los que se buscarán bibliotecas compartidas. ldconfig debe ejecutarse como root y las bibliotecas compartidas deberían ser almacenadas solamente en directorios del sistema, en donde están seguras y son útiles.
Además de buscar la base de datos construida por ldconfig, el enlazador buscará primero cualquier directorio especificado en la variable de ambiente LD_LIBRARY_PATH, una lista de directorios separados por dos puntos, en la variable PATH. Así es que es posible hacer:
$ LD_LIBRARY_PATH=$HOME/foo/lib
$ foo [args]
o
$ LD_LIBRARY_PATH=$HOME/foo/lib foo [args]
es el proceso con PID =1 y es iniciado por el kernel
durante el .
¿Cuál es el comando para cambiar el número máximo permitido de archivos abiertos?
Actualmente usted debería ser capaz de:
- Describir un proceso y los recursos asociados a él.
- Distinguir entre procesos, programas y hebras.
- Comprender los atributos de procesos, permisos y estados.
- Saber la diferencia entre la ejecución de un programa en modo usuario y kernel.
- Describir los procesos demonio (daemon).
- Comprender cómo se crean los procesos nuevos.
- Usar nice y renice para configurar y modificar las prioridades.
21. Señales
Las señales se usan para emitir notificaciones para que los procesos tomen acción en respuesta a eventos que generalmente son impredecibles. Estos pueden ser generados desde dentro de un proceso, o desde eventos externos y otros procesos. Muchas señales son fatales y resultan en el término del proceso. Sin embargo, la muerte de los procesos se puede evitar si los desarrolladores del programa deciden manejar ciertas señales de finalización.
Por otro lado, muchas señales son más benignas y son informativas solamente o solicitan otro tipo de acciones. Es posible enviar señales (incluyendo aquellas que inducen a la finalización de un proceso) desde la línea de comandos usando kill, killall y pkill.
Al final de este capítulo usted debería ser capaz de:
- Explicar qué son las señales y cómo se usan.
- Conocer los diferentes tipos de señales que están disponible en Linux.
- Usar kill, killall and pkill para enviar señales desde la línea de comandos.
Las señales son uno de los métodos más antiguos de Comunicación Inter-Procesos (IPC) y se usan para notificar procesos acerca de eventos asincrónicos (o excepciones).
Por asincrónico entendemos que el proceso receptor de la señal puede:
- No esperar que ocurra el evento.
- Esperar el evento, pero no saber en qué momento va a ocurrir.
Por ejemplo, si un usuario decide terminar un programa en ejecución, podría enviar una señal al proceso a través del kernel para interrumpir y finalizar el proceso.
Hay dos vías a través de las cuales se envían señales a los procesos:
- Desde el kernel a un proceso de usuario como resultado de una excepción o de un error de programación.
- Desde un proceso de usuario (usando una llamada al sistema) al kernel, el cual la enviará a un proceso de usuario. El proceso que envía la señal puede ser el mismo que la reciba de vuelta.
Las señales solamente pueden enviarse entre procesos de propiedad del mismo usuario, o desde un proceso del superusuario a cualquier proceso.
Cuando un proceso recibe una señal, lo que hará a continuación depende de la forma en la cual el programa está escrito. Puede tomar acciones específicas, codificadas en el programa para manipular la señal, o solo responder de acuerdo a los valores por defecto en el sistema. Dos señales (SIGKILL y SIGSTOP, que se mencionarán en seguida) no pueden ser manipuladas y siempre finalizarán el programa.
Hay una variedad de tipos de señales, y la señal en particular que es enviada indica el tipo de evento (o excepción) ocurrida. Generalmente las señales se usan para manejar dos cosas:
- Excepciones detectadas por el hardware (tal como una referencia ilegal a memoria).
- Excepciones generadas por el ambiente (tal como la finalización prematura de un proceso desde la terminal del usuario).
Para ver una lista de las señales en Linux, junto con los números correspondientes, haga lo siguiente:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
Las señales de SIGRTMIN se denominan como de tiempo real y son una adición relativamente reciente. No tienen un propósito predefinido y difieren de forma importante en algunos aspectos con relación a las señales normales; pueden ser encoladas y son manejadas en orden FIFO (First In First Out).
El significado implícito en el tipo de señal indica qué evento causó que fuera enviada. Mientras los usuarios pueden explícitamente enviar cualquier tipo de señal a uno de sus procesos, el significado implícito podría no estar relacionado al número o tipo de la señal, y puede usarse en cualquier forma que el proceso desea.
man 7 signal le dará mayor información al respecto.
Señal | Valor | Acción por defecto | ¿POSIX? | Significado |
---|---|---|---|---|
SIGHUP | 1 | Finalizar | Sí | Cuelgue detectado en el control de la terminal o muerte del proceso de control. |
SIGINT | 2 | Finalizar | Sí | Interrupción de teclado. |
SIGQUIT | 3 | Volcado de memoria | Sí | Salida desde el teclado. |
SIGILL | 4 | Volcado de memoria | Sí | Instrucción ilegal. |
SIGTRAP | 5 | Volcado de memoria | No | Traza/punto de interrupción para la depuración. |
SIGABRT SIGIOT | 6 | Volcado de memoria | Sí | Finalización anormal. |
SIGBUS | 7 | Volcado de memoria | Sí | Error de bus. |
SIGFPE | 8 | Volcado de memoria | Sí | Excepción de punto flotante. |
SIGKILL | 9 | Finalizar | Sí | Señal de terminación (no puede ser capturada ni ignorada). |
SIGUSR1 | 10 | Finalizar | Sí | Señal 1 definida por el usuario. |
SIGSEGV | 11 | Volcado de memoria | Sí | Referencia de memoria inválida. |
SIGUSR2 | 12 | Finalizar | Sí | Señal 2 definida por el usuario. |
SIGPIPE | 13 | Finalizar | Sí | Tubería rota: escribir en una tubería sin lectores. |
SIGALRM | 14 | Finalizar | Sí | Señal del temporizador de la alarma. |
SIGTERM | 15 | Finalizar | Sí | Finalización de proceso. |
SIGSTKFLT | 16 | Finalizar | No | Falla del stack en coprocesador matemático. |
SIGCHLD | 17 | Ignorar | Sí | Hijo detenido o terminado. |
SIGCONT | 18 | Continuar | Sí | Continuar si es detenido. |
SIGSTOP | 19 | Parar | Sí | Detener el proceso (no puede ser capturada ni ignorada). |
SIGTSTP | 20 | Parar | Sí | Detiene el tipeo en la terminal. |
SIGTTIN | 21 | Parar | Sí | Un proceso en segundo plano requiere una entrada en la terminal. |
SIGTTOU | 22 | Parar | Sí | Un proceso en segundo plano requiere una salida en la terminal. |
SIGURG | 23 | Ignorar | No | Condición urgente en socket (4.2 BSD). |
SIGXCPU | 24 | Volcado de memoria | Sí | Límite de tiempo de CPU excedido (4.2 BSD). |
SIGXFSZ | 25 | Volcado de memoria | Sí | Límite de tamaño de archivo excedido (4.2 BSD). |
SIGVTALRM | 26 | Finalizar | No | Reloj de alarma virtual (4.2 BSD). |
SIGPROF | 27 | Finalizar | No | Perfil de la alarma (4.2 BSD). |
SIGWINCH | 28 | Ignorar | No | Señal de redimensionamiento de la ventana (4.3 BSD, Sun). |
SIGIO SIGPOLL | 29 | Finalizar | No | E/S es posible ahora (4.2 BSD) (System V). |
SIGPWR | 30 | Finalizar | No | Falla de poder (System V). |
SIGSYS SIGUNUSED | 31 | Finalizar | No | Error en la llamada al sistema. Señal no usada. |
Un proceso no puede enviar una señal directamente a otro proceso; este debe pedirle al kernel que envíe la señal mediante la ejecución de una llamada al sistema. Los usuarios (incluyendo el superusuario) pueden enviar señales a otros procesos desde la línea de comandos o scripts usando kill, tal como se muestra a continuación:
$ kill 1991
$ kill -9 1991
$ kill -SIGKILL 1991
en el comando anterior enviamos una señal al proceso con PID = 1991. Si no se provee un número de señal (como en el primer ejemplo), el valor por defecto a enviar es SIGTERM (15), una señal de finalización que puede ser manipulada; el programa puede tomar una acción evasiva o limpiarse a sí mismo en vez de finalizar inmediatamente. Si esta señal es ignorada, el usuario puede enviar una SIGKILL (9), la cual no puede ser ignorada.
El nombre kill es un nombre realmente malo, el cual sobrevive por razones históricas. Aunque a menudo se utiliza para matar (terminar) procesos, la función real del comando es enviar cualquier y todas las señales a los procesos, incluso a los que son benignos y totalmente informativos.
killall termina todos los procesos con un nombre dado, en el caso que el usuario tenga los permisos necesarios. Usa un nombre de comando en vez de un ID de proceso y puede ser ejecutado así:
$ killall bash
$ killall -9 bash
$ killall -SIGKILL bash
pkill envía una señal a un proceso utilizando un criterio de selección:
$ pkill [-signal] [options] [pattern]
Por ejemplo:
$ pkill -u libby foobar
terminará todos los procesos de libby que se llamen foobar.
Otro ejemplo:
$ pkill -HUP rsyslogd
hace que rsyslog relea su archivo de configuración.
¿Cuáles de las siguientes afirmaciones son ciertas?
- kill, killall y pkill aceptan un nombre de proceso como parámetro.
- Pasar -9 o -SIGKILL como parámetro a kill tiene el mismo efecto en el proceso objetivo.
- Si no se especifica, kill enviará la señal por defecto SIGTERM.
- Presionar Ctrl+Z o usar kill -SIGTSTP sobre un proceso en ejecución en una terminal tiene el mismo efecto.
- Laboratorio 21.1 (código fuente: signals.c)
Actualmente usted debería ser capaz de:
- Explicar qué son las señales y cómo se usan.
- Conocer los diferentes tipos de señales que están disponibles en Linux.
- Usar kill, killall and pkill para enviar señales desde la línea de comandos.
22. Monitoreo del sistema
Linux tiene una amplia variedad disponible de herramientas de monitoreo del sistema, incluyendo top, ps y sar. La mayoría de estas herramientas hacen un uso extensivo de los pseudosistemas de archivos montados en /proc y /sys. Si bien es cierto que hay interfaces gráficas (dependientes de la distribución), nos concentraremos en los métodos de la línea de comandos.
Al final de este capítulo usted debería ser capaz de:
- Reconocer y usar las herramientas disponibles de monitoreo del sistema.
- Usar los pseudosistemas de archivos /proc y /sys.
- Usar sar para obtener información de la actividad y rendimiento del sistema, para crear reportes en forma cómoda para su análisis.
Las distribuciones Linux vienen con diversas herramientas estándar instaladas por defecto para medir el rendimiento y visualizar el estado del sistema. Muchas de ellas provienen de otros sistemas operativos tipo UNIX, mientras que otras fueron desarrolladas específicamente para Linux.
La mayoría de estas herramientas hacen uso de pseudosistemas de archivos montados, especialmente /proc, y /sys de forma secundaria (los cuales discutimos anteriormente cuando tratamos los sistemas de archivos y configuración del kernel). En este capítulo trabajaremos con ambos.
Aunque existe una serie de monitores gráficos del sistema, los cuales esconden muchos detalles, en este curso consideraremos solamente las herramientas de la línea de comandos.
Antes de considerar algunas de las herramientas principales veremos un resumen clasificado por tipo; tenga en cuenta que algunas de las herramientas tienen dominios superpuestos de cobertura.
Abajo encontrará un resumen de las principalies herramientas de monitoreo.
Herramienta | Propósito | Paquete |
---|---|---|
top | Actividad de los procesos, actualizada dinámicamente | procps |
uptime | Por cuánto tiempo el sistema ha estado corriendo y la carga promedio | procps |
ps | Información detallada acerca de los procesos | procps |
pstree | Un árbol de los procesos y sus conexiones | psmisc (o pstree) |
mpstat | Uso de procesador múltiple | sysstat |
iostat | Uso de la CPU y estadísticas de E/S | sysstat |
sar | Muestra y recopila información acerca de la actividad del sistema | sysstat |
numastat | Informacion acerca de NUMA (Non-Uniform Memory Architecture) | numactl |
strace | Información acerca de todas las llamadas al sistema que realiza un proceso | strace |
Herramienta | Propósito | Paquete |
---|---|---|
free | Resumen breve del uso de la memoria | procps |
vmstat | Estadísticas detalladas de memoria virtual y bloques de E/S, actualizados dinámicamente | procps |
pmap | Mapa de la memoria de un proceso | procps |
Herramienta | Propósito | Paquete |
---|---|---|
iostat | Uso de CPU y estadísticas de E/S | sysstat |
sar | Muestra y recopila información acerca de la actividad del sistema | sysstat |
vmstat | Estadísticas detalladas de memoria virtual y bloques de E/S, actualizados dinámicamente | procps |
Herramienta | Propósito | Paquete |
---|---|---|
netstat | Estadísticas detalladas de la red | netstat |
iptraf | Obtiene información de las interfaces de red | iptraf |
tcpdump | Análisis detallado de los paquetes de red y tráfico | tcpdump |
wireshark | Análisis detallado del tráfico de la red | wireshark |
Los pseudosistemas de archivos /proc y /sys contienen bastante información acerca del sistema. Por otro lado, muchas de las entradas en estos árboles de directorios son escribibles y pueden usarse para cambiar el comportamiento del sistema; en la mayoría de los casos esto requiere del usuario root.
Estos son pseudosistemas de archivos porque existen totalmente en memoria; si usted revisa la partición del disco cuando el sistema no está en ejecución, se dará cuenta que solo hay un directorio vacío, el cual se usa como punto de montaje.
Por otra parte, la información que se despliega es obtenida solamente cuando se lee; no hay un sondeo constante o periódico para actualizar las entradas.
El pseudosistema de archivos /proc tiene una historia larga; tiene su origen en otras variantes de sistemas operativos tipo UNIX y en un comienzo fue desarrollado para desplegar información acerca de los procesos en el sistema, cada uno de los cuales tiene su propio directorio en /proc, con todas las características importantes de los procesos.
A través del tiempo creció para contener mucha información acerca de las propiedades del sistema, tales como interrupciones, memoria, red, etc, en una forma un tanto anárquica. Todavía es usado de forma extensiva y a menudo nos referiremos a él.
Echemos un vistazo a lo que hay en el pseudosistema de archivos /proc:
$ ls -F /proc
1/ 11214/ 15887/ 19/ 26/ 3706/ 509/ 614/ 7402/ asound/ modules
10/ 12/ 15891/ 1929/ 260/ 3707/ 510/ 619/ 741/ buddyinfo mounts@
1017/ 1284/ 15896/ 1934/ 26218/ 3708/ 511/ 620/ 742/ bus/ mtrr
1018/ 1290/ 15899/ 1959/ 264/ 3709/ 512/ 622/ 743/ cgroups net@
1023/ 13/ 15905/ 19950/ 265/ 3713/ 513/ 623/ 744/ cmdline pagetypeinfo
1031/ 1301/ 15909/ 2/ 267/ 3714/ 514/ 625/ 761/ config.gz partitions
10544/ 14/ 15912/ 2008/ 268/ 375/ 515/ 626/ 763/ consoles sched_debug
10545/ 1400/ 15919/ 2079/ 27/ 396/ 517/ 641/ 7699/ cpuinfo schedstat
1061/ 1444/ 15928/ 21/ 28/ 398/ 519/ 642/ 8/ crypto scsi/
10671/ 1452/ 15938/ 22/ 280/ 414/ 521/ 644/ 8036/ devices self@
10802/ 1465/ 15941/ 2298/ 281/ 42/ 5302/ 645/ 8226/ diskstats slabinfo
10803/ 1484/ 15944/ 23/ 29/ 43/ 537/ 648/ 824/ dma softirqs
10911/ 1490/ 15957/ 237/ 3/ 4555/ 5376/ 649/ 8323/ driver/ stat
11/ 1503/ 15963/ 238/ 30/ 460/ 538/ 651/ 8435/ execdomains swaps
11087/ 15466/ 15966/ 239/ 30170/ 480/ 5503/ 652/ 8443/ fb sys/
11089/ 15471/ 15982/ 24/ 31/ 481/ 5506/ 66/ 8444/ filesystems sysrq-trigger
11090/ 15616/ 16/ 240/ 32/ 482/ 5515/ 67/ 845/ fs/ sysvipc/
11103/ 1563/ 16016/ 241/ 33/ 484/ 5516/ 68/ 8479/ interrupts timer_list
11104/ 15632/ 16030/ 242/ 34/ 485/ 5524/ 684/ 8594/ iomem timer_stats
11105/ 15642/ 16037/ 243/ 35/ 486/ 5525/ 690/ 8633/ ioports tty/
11123/ 15650/ 16039/ 244/ 3557/ 489/ 5530/ 697/ 8643/ irq/ uptime
11124/ 15651/ 16065/ 245/ 3558/ 491/ 5531/ 698/ 8644/ kallsyms version
11125/ 1570/ 16066/ 246/ 3560/ 494/ 5536/ 699/ 8726/ kcore vmallocinfo
11126/ 1571/ 16071/ 247/ 36/ 496/ 559/ 7/ 8903/ keys vmnet/
11163/ 15719/ 16073/ 248/ 3687/ 498/ 560/ 701/ 9/ key-users vmstat
11165/ 15723/ 16089/ 24819/ 3697/ 5/ 5645/ 709/ 9277/ kmsg zoneinfo
11166/ 15791/ 16112/ 24822/ 3698/ 500/ 5665/ 712/ 9284/ kpagecount
11187/ 1582/ 1621/ 24823/ 3699/ 501/ 5678/ 714/ 9816/ kpageflags
11194/ 15837/ 16477/ 24879/ 37/ 502/ 583/ 715/ 9853/ latency_stats
11196/ 15840/ 16515/ 257/ 3702/ 503/ 584/ 717/ 9871/ loadavg
11197/ 15844/ 1654/ 258/ 3703/ 504/ 599/ 718/ 988/ locks
11199/ 15847/ 17/ 259/ 3704/ 505/ 600/ 723/ 9885/ meminfo
11206/ 15871/ 18/ 2591/ 3705/ 507/ 613/ 727/ acpi/ misc
Primero vemos que hay un subdirectorio por cada proceso en el sistema, ya sea si están durmiendo, en ejecución o programados. Revisando uno al azar:
$ ls -lF /proc/16477
total 0
-r-------- 1 coop coop 0 Sep 10 18:11 auxv
-r--r--r-- 1 coop coop 0 Sep 10 12:28 cgroup
--w------- 1 coop coop 0 Sep 10 18:11 clear_refs
-r--r--r-- 1 coop coop 0 Sep 10 08:30 cmdline
-rw-r--r-- 1 coop coop 0 Sep 10 12:28 comm
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 coredump_filter
-r--r--r-- 1 coop coop 0 Sep 10 18:11 cpuset
lrwxrwxrwx 1 coop coop 0 Sep 10 18:11 cwd -> /usr/local/coop7/
-r-------- 1 coop coop 0 Sep 10 18:11 environ
lrwxrwxrwx 1 coop coop 0 Sep 10 08:30 exe -> /usr/lib64/thunderbird/thunderbird*
dr-x------ 2 coop coop 0 Sep 10 08:30 fd/
dr-x------ 2 coop coop 0 Sep 10 18:11 fdinfo/
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 gid_map
-r-------- 1 coop coop 0 Sep 10 18:11 io
-r--r--r-- 1 coop coop 0 Sep 10 18:11 latency
-r--r--r-- 1 coop coop 0 Sep 10 18:11 limits
-r--r--r-- 1 coop coop 0 Sep 10 08:30 maps
-rw------- 1 coop coop 0 Sep 10 18:11 mem
-r--r--r-- 1 coop coop 0 Sep 10 08:30 mountinfo
-r--r--r-- 1 coop coop 0 Sep 10 18:11 mounts
-r-------- 1 coop coop 0 Sep 10 18:11 mountstats
dr-xr-xr-x 4 coop coop 0 Sep 10 18:11 net/
dr-x--x--x 2 coop coop 0 Sep 10 18:11 ns/
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 oom_adj
-r--r--r-- 1 coop coop 0 Sep 10 18:11 oom_score
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 oom_score_adj
-r-------- 1 coop coop 0 Sep 10 18:11 pagemap
-r-------- 1 coop coop 0 Sep 10 18:11 personality
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 projid_map
lrwxrwxrwx 1 coop coop 0 Sep 10 18:11 root -> //
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 sched
-r--r--r-- 1 coop coop 0 Sep 10 18:11 schedstat
-r--r--r-- 1 coop coop 0 Sep 10 18:11 smaps
-r-------- 1 coop coop 0 Sep 10 18:11 stack
-r--r--r-- 1 coop coop 0 Sep 10 08:35 stat
-r--r--r-- 1 coop coop 0 Sep 10 16:59 statm
-r--r--r-- 1 coop coop 0 Sep 10 08:31 status
-r-------- 1 coop coop 0 Sep 10 18:11 syscall
dr-xr-xr-x 35 coop coop 0 Sep 10 10:10 task/
-rw-r--r-- 1 coop coop 0 Sep 10 18:11 uid_map
-r--r--r-- 1 coop coop 0 Sep 10 18:11 wchan
vemos que este corresponde al cliente de correo electrónico thunderbird. Este directorio está lleno de información, tanto acerca del estado y de los recursos que el proceso está usando. Por ejemplo:
$ cat /proc/16477/status
Name: thunderbird
State: S (sleeping)
Tgid: 16477
Ngid: 0
Pid: 16477
PPid: 15912
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 256
Groups: 500
VmPeak: 1262996 kB
VmSize: 1139452 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 241644 kB
VmRSS: 201404 kB
VmData: 435360 kB
VmStk: 224 kB
VmExe: 88 kB
VmLib: 89756 kB
VmPTE: 1488 kB
VmSwap: 0 kB
Threads: 33
SigQ: 1/31853
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000001001000
SigCgt: 0000000f800144ef
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 1
Mems_allowed_list: 0
voluntary_ctxt_switches: 590633
nonvoluntary_ctxt_switches: 5881
Otras entradas proveen información de todo el sistema. Por ejemplo, las estadísticas de interrupciones se muestran aquí:
$ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 127 0 0 0 IO-APIC-edge timer
1: 22610 26632 22019 24652 IO-APIC-edge i8042
8: 0 0 1 0 IO-APIC-edge rtc0
9: 0 0 0 0 IO-APIC-fasteoi acpi
16: 10 13 13 11 IO-APIC-fasteoi uhci_hcd:usb3
18: 81801 33810 269011 97396 IO-APIC-fasteoi ehci_hcd:usb1, uhci_hcd:usb5, uhci_hcd:usb8,enp4s2
19: 0 0 0 0 IO-APIC-fasteoi uhci_hcd:usb7
21: 0 0 0 0 IO-APIC-fasteoi uhci_hcd:usb4
23: 459503 414973 2294258 1886762 IO-APIC-fasteoi ehci_hcd:usb2, uhci_hcd:usb6
43: 7839477 12 17 14 PCI-MSI-edge enp2s0
44: 90833 73862 431567 197408 PCI-MSI-edge ahci
45: 2308942 2324143 2037740 2226651 PCI-MSI-edge nouveau
46: 1706 1853 1806 1740 PCI-MSI-edge snd_hda_intel
NMI: 4021 3150 3201 3076 Non-maskable interrupts
LOC: 8186969 8028365 8257507 7848638 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 4021 3150 3201 3076 Performance monitoring interrupts
IWI: 455847 423644 402570 390176 IRQ work interrupts
RTR: 0 0 0 0 APIC ICR read retries
RES: 6489645 6430364 6430834 6271845 Rescheduling interrupts
CAL: 4816017 4550737 4171364 4829737 Function call interrupts
TLB: 909001 1140883 879189 1152043 TLB shootdowns
TRM: 0 0 0 0 Thermal event interrupts
THR: 0 0 0 0 Threshold APIC interrupts
MCE: 0 0 0 0 Machine check exceptions
MCP: 133 133 133 133 Machine check polls
ERR: 0
MIS: 0
Para cada interrupción vemos su tipo, cuántas veces ha sido manipulada en cada CPU y qué dispositivos están registrados para responder a ella. También obtenemos estadísticas globales.
La mayoría de los parámetros ajustables del sistema pueden encontrarse en el árbol de subdirectorios /proc/sys:
$ ls -F /proc/sys
total 0
dr-xr-xr-x 1 root root 0 Sep 10 18:17 abi/
dr-xr-xr-x 1 root root 0 Sep 10 18:17 debug/
dr-xr-xr-x 1 root root 0 Sep 10 15:53 dev/
dr-xr-xr-x 1 root root 0 Sep 10 02:14 fs/
dr-xr-xr-x 1 root root 0 Sep 10 02:14 kernel/
dr-xr-xr-x 1 root root 0 Sep 10 18:17 net/
dr-xr-xr-x 1 root root 0 Sep 10 16:10 vm/
Cada uno de estos subdirectorios contiene información como también controles que pueden ser ajustados (con cuidado):
- abi/
Contiene archivos con información binaria de aplicaciones; raramente se usa. - debug/
Parámetros de depuración; por ahora solo un control de reportes de excepción. - dev/
Parámetros de dispositivo incluyendo subdirectorios para cdrom, scsi, raid y parport. - fs/
Parámetros de sistemas de archivos, incluyendo cuota, identificadores de archivos usados y máximos, información de inodos y directorios, etc. - kernel/
Parámetros del kernel. Hay muchas entradas importantes aquí. - net/
Parámetros de red. Hay subdirectorios para ipv4, netfilter, etc. - vm/
Parámetros de memoria virtual. Hay muchas entradas importantes aquí.
Ver y cambiar los parámetros puede ser realizarse con comandos simples. Por ejemplo, el número máximo de hilos permitidos en el sistema puede verse así:
$ ls -l /proc/sys/kernel/threads-max
$ cat /proc/sys/kernel/threads-max
129498
Entonces podemos modificar el valor y verificar que el cambio tuvo efecto:
$ sudo bash -c 'echo 100000 > /proc/sys/kernel/threads-max'
$ cat /proc/sys/kernel/threads-max
100000
Recuerde de la discusión acerca de sysctl que lo mismo se consigue con:
$ sudo sysctl kernel.threads-max=100000
Los usuarios normales pueden visualizar los valores, sin embargo para modificarlos se requiere de privilegios de superusuario.
El pseudosistema de archivos /sys es una parte integral de lo que se llama el Modelo Unificado de Dispositivos (Unified Device Model). Conceptualmente está basado en un árbol de dispositivos a través del cual se puede ir y ver los buses, dispositivos, controladores, etc. También contiene información que puede o no estar relacionada estrictamente a los dispositivos, tales como los módulos del kernel.
Tiene una estructura más definida que /proc. La mayoría de las entradas contienen solo una línea de texto, aunque existen excepciones, no llega a ser como su precedesor (/proc), el cual tiene entradas de múltiples líneas cuyo contenido exacto ha ido cambiando entre versiones del kernel. Por lo tanto, la interfaz de /sys es más estable hasta el momento.
Hay propiedades del sistema que tienen entradas tanto en /proc como en /sys; los ítems antiguos se están eliminando gradualmente con el fin de mantener una compatibilidad entre las utilidades de sistema usadas ampliamente.
El soporte para el sistema de archivos virtual sysfs está construido en todos los kernel modernos, y debería montarse bajo /sys. Sin embargo, el modelo unificado de dispositivos no requiere que sysfs sea montado para entrar en operación.
Echemos un vistazo a lo que podemos encontrar usando el kernel 3.18; advertimos que el diseño exacto de este sistema de archivos tiene una tendencia a cambiar. Al visualizar los directorios de nivel superior encontramos:
$ ls -F /sys
block/ bus/ class/ dev/ devices/ firmware/ fs/ kernel/ module/ power/
lo cual despliega la jerarquía básica de dispositivos. La implementación del modelos de dispositivos sysfs también incluye información que no está estrictamente relacionada a hardware.
Los dispositivos de red pueden examinarse con:
$ ls -lF /sys/class/net
total 0lrwxrwxrwx 1 root root 0 Apr 30 11:38 eth0 -> \
../../devices/pci0000:00/0000:00:1c.5/0000:02:00.0/net/eth0/
lrwxrwxrwx 1 root root 0 Apr 30 11:38 eth1 -> \
../../devices/pci0000:00/0000:00:1e.0/0000:04:02.0/net/eth1/
lrwxrwxrwx 1 root root 0 Apr 30 06:38 lo -> \
../../devices/virtual/net/lo/
al mirar la primera tarjeta Ethernet obtenemos:
$ ls -l /sys/class/net/eth0/
total 0
-r--r--r-- 1 root root 4096 Apr 30 13:43 addr_assign_type
-r--r--r-- 1 root root 4096 Apr 30 11:38 address
-r--r--r-- 1 root root 4096 Apr 30 11:38 addr_len
-r--r--r-- 1 root root 4096 Apr 30 13:43 broadcast
-r--r--r-- 1 root root 4096 Apr 30 13:43 carrier
lrwxrwxrwx 1 root root 0 Apr 30 11:38 device -> ../../../0000:02:00.0
-r--r--r-- 1 root root 4096 Apr 30 13:43 dev_id
-r--r--r-- 1 root root 4096 Apr 30 13:43 dormant
-r--r--r-- 1 root root 4096 Apr 30 13:43 duplex
-rw-r--r-- 1 root root 4096 Apr 30 11:38 flags
-rw-r--r-- 1 root root 4096 Apr 30 13:43 ifalias
-r--r--r-- 1 root root 4096 Apr 30 11:38 ifindex
-r--r--r-- 1 root root 4096 Apr 30 13:43 iflink
-r--r--r-- 1 root root 4096 Apr 30 13:43 link_mode
-rw-r--r-- 1 root root 4096 Apr 30 13:43 mtu
-rw-r--r-- 1 root root 4096 Apr 30 13:43 netdev_group
-r--r--r-- 1 root root 4096 Apr 30 13:43 operstate
drwxr-xr-x 2 root root 0 Apr 30 13:43 power
drwxr-xr-x 4 root root 0 Apr 30 11:38 queues
-r--r--r-- 1 root root 4096 Apr 30 13:43 speed
drwxr-xr-x 2 root root 0 Apr 30 13:43 statistics
lrwxrwxrwx 1 root root 0 Apr 30 11:38 subsystem -> ../../../../../../class/net
-rw-r--r-- 1 root root 4096 Apr 30 13:43 tx_queue_len
-r--r--r-- 1 root root 4096 Apr 30 11:38 type
-rw-r--r-- 1 root root 4096 Apr 30 11:38 uevent
$ cat /sys/class/net/eth0/mtu
1500
La intención de sysfs es tener un valor de texto por línea, aunque no se espera que esto se aplique rigurosamente.
El dispositivo y controlador subyacente para la primera interfaz de red pueden encontrarse a través de device y de los enlaces simbólicos de driver (lo cual vamos a revisar pronto). Si vemos el directorio correspondiente a la primera tarjeta Ethernet veremos lo siguiente:
$ ls -l /sys/class/net/eth0/device/
total 0
-rw-r--r-- 1 root root 4096 Apr 30 13:47 broken_parity_status
-r--r--r-- 1 root root 4096 Apr 30 06:38 class
-rw-r--r-- 1 root root 4096 Apr 30 11:38 config
-r--r--r-- 1 root root 4096 Apr 30 13:47 consistent_dma_mask_bits
-r--r--r-- 1 root root 4096 Apr 30 11:38 device
-r--r--r-- 1 root root 4096 Apr 30 13:47 dma_mask_bits
lrwxrwxrwx 1 root root 0 Apr 30 11:38 driver -> ../../../../bus/pci/drivers/sky2/
-rw------- 1 root root 4096 Apr 30 13:47 enable
-r--r--r-- 1 root root 4096 Apr 30 11:38 irq
-r--r--r-- 1 root root 4096 Apr 30 13:47 local_cpulist
-r--r--r-- 1 root root 4096 Apr 30 11:38 local_cpus
-r--r--r-- 1 root root 4096 Apr 30 13:47 modalias
-rw-r--r-- 1 root root 4096 Apr 30 13:47 msi_bus
drwxr-xr-x 3 root root 0 Apr 30 13:47 msi_irqs/
drwxr-xr-x 3 root root 0 Apr 30 11:38 net/
drwxr-xr-x 2 root root 0 Apr 30 13:47 power/
--w--w---- 1 root root 4096 Apr 30 13:47 remove
--w--w---- 1 root root 4096 Apr 30 13:47 rescan
--w------- 1 root root 4096 Apr 30 13:47 reset
-r--r--r-- 1 root root 4096 Apr 30 13:45 resource
-rw------- 1 root root 16384 Apr 30 13:47 resource0
-rw------- 1 root root 256 Apr 30 13:47 resource2
-rw------- 1 root root 131072 Apr 30 13:47 rom
lrwxrwxrwx 1 root root 0 Apr 30 11:38 subsystem -> ../../../../bus/pci/
-r--r--r-- 1 root root 4096 Apr 30 11:38 subsystem_device
-r--r--r-- 1 root root 4096 Apr 30 11:38 subsystem_vendor
-rw-r--r-- 1 root root 4096 Apr 30 06:38 uevent
-r--r--r-- 1 root root 4096 Apr 30 11:38 vendor
-rw------- 1 root root 32768 Apr 30 13:47 vpd
Para ver la gama completa de información que está disponible en sysfs tendrá que examinar el directorio.
sar viene de Systems Activity Reporter (informador de actividad del sistema). Es una herramienta multipropósito para obtener información acerca de la actividad y rendimiento del sistema, como también para crear reportes de lectura fácil.
En los sistemas Linux el backend de sar es sadc (recopilador de información de actividad del sistema), el cual acumula las estadísticas. Este almacena la información en el directorio /var/log/sa, en una frecuencia diaria por defecto, la cual puede ser ajustada. La recolección de información puede ser iniciada desde la línea de comandos, y de forma períodica se realiza desde una tarea de cron almacenada en /etc/cron.d/sysstat.
Entonces sar lee esa información (ya sea desde la ubicación por defecto o usando el archivo especificado con la opción -f) y luego produce un reporte.
sar se ejecuta de la siguiente forma:
$ sar [ options ] [ interval ] [ count ]
en donde el reporte se repite luego de un intervalo de segundos por un número de veces (la cual es 1 por defecto). Sin opciones resulta así:
$ sar 3 3
Linux 3.15.9 (q7) 09/26/2014 _x86_64_ (4 CPU)
12:27:32 PM CPU %user %nice %system %iowait %steal %idle
12:27:35 PM all 1.34 0.00 0.33 0.67 0.00 97.66
12:27:38 PM all 7.08 0.00 2.98 0.34 0.00 89.60
12:27:41 PM all 10.60 0.00 1.09 0.08 0.00 88.23
Average: all 6.32 0.00 1.46 0.37 0.00 91.85
entregando un reporte del uso de la CPU.
Aquí hay una lista de las opciones o modos más importantes de sar, en donde cada una tiene sus propias subopciones:
Opción | Significado |
---|---|
-A | Casi toda la información |
-b | E/S y estadísticas de las tasas de transferencia (similar a iostat) |
-B | Estadísticas de paginación, incluyendo los errores de paǵina |
-x | Actividad de dispositivos de bloque (similar a iostat -x) |
-n | Estadísticas de red |
-P | Estadísticas por CPU (como en sar -P ALL 3) |
-q | Longitud de las colas (cola de ejecución, procesos e hilos) |
-r | Estadísticas de uso de memoria y área de intercambio |
-R | Estadísticas de memoria |
-u | Uso de CPU (por defecto) |
-v | Estadísticas acerca de inodos, archivos e identificadores de archivo. |
-w | Estadísticas de cambio de contexto |
-W | Estadísticas de la memoria de intercambio, página de entrada y salida por segundo |
-f | Extrae información desde el archivo especificado, creado con la opción -o |
-o | Almacena los datos en el archivo especificado, para ser leído más tarde con la opción -f |
Por ejemplo, para obtener las estadísticas de paginación:
$ sar -B 3 3
Linux 3.15.9 (q7) 09/26/2014 _x86_64_ (4 CPU)
12:28:51 PM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
12:28:54 PM 0.00 21.33 82.33 0.00 676.67 0.00 0.00 0.00 0.00
12:28:57 PM 0.00 13.33 43.33 0.00 285.00 0.00 0.00 0.00 0.00
12:29:00 PM 0.00 9.33 428.00 0.00 1029.00 0.00 0.00 0.00 0.00
Average: 0.00 14.67 184.56 0.00 663.56 0.00 0.00 0.00 0.00
para obtener las estadísticas de E/S y tasa de transferencia:
$ sar -b 3 3
Linux 3.15.9 (q7) 09/26/2014 _x86_64_ (4 CPU)
12:29:30 PM tps rtps wtps bread/s bwrtn/s
12:29:33 PM 8.00 5.00 3.00 597.33 72.00
12:29:36 PM 0.00 0.00 0.00 0.00 0.00
12:29:39 PM 16.33 0.00 16.33 0.00 237.33
Average: 8.11 1.67 6.44 199.11 103.11
El programa ksar es una herramienta basada en java para generar gráficos agradables a partir de datos de sar. Puede descargarse desde http://sourceforge.net/projects/ksar .
1. es una herramienta de depuración que muestra cómo un proceso realiza solicitudes al sistema operativo.
2. es una herramienta que muestra por cuánto tiempo el sistema ha estado en ejecución.
3. es una herramienta interactiva para monitorear la actividad de los procesos.
4. es una herramienta que despliega un resumen del uso de la memoria.
Dado el PID 1017, el archivo especial que contiene la línea de comandos usada para iniciar el proceso es:
¿Qué información que no está relacionada a procesos puede encontrarse en /proc? Seleccione todos los ítems que apliquen.
La línea de comandos del kernel.
Información del modelo de la CPU.
Estadísticas de uso de la memoria.
Información de las particiones en los discos.
Todas las alternativas anteriores.
Ninguna de las alternativas anteriores.
El directorio _______________________ almacena archivos especiales de los parámetros de configuración del kernel en tiempo de ejecución.
Actualmente usted debería ser capaz de:
- Reconocer y usar las herramientas disponibles de monitoreo del sistema.
- Usar los pseudosistemas de archivos /proc y /sys.
- Usar sar para obtener información de la actividad y rendimiento del sistema, para crear reportes en forma cómoda para su análisis.
23. Monitoreo de procesos
Realizar un seguimiento de los procesos en ejecución (y durmiendo) es una tarea de administración primordial. El programa ps ha sido la herramienta principal para hacer esto en sistemas basados en UNIX por décadas.
Sin embargo, debido a que la herramienta ha tenido una larga y compleja historia de ser usada de forma diferente en una variedad de sistemas operativos, tiene muchas opciones que al combinarlas pueden llevar a confusión. Otra herramienta valiosa es top, la cual monitorea el estado del sistema de forma interactiva.
Al final de este capítulo usted debería ser capaz de:
- Usar ps para visualizar características y estadísticas asociadas a procesos.
- Identificar diferentes campos de salida de ps y personalizar la salida del comando.
- Usar pstree para obtener una descripción visual de la ascendencia de los procesos y aplicaciones multihilos.
- Usar top para visualizar la carga del sistema interactivamente.
En esta sección nos concentraremos en monitoreo de procesos. Para llevar a cabo esto, los administradores de Linux hacen uso de muchas herramientas, tales como ps, pstree y top, todos los que tienen una larga historia en los sistemas operativos tipo UNIX.
Revisaremos nuevamente la lista de algunas de las herramientas principales para monitoreo de procesos:
Herramienta | Propósito | Paquete |
---|---|---|
top | Actualiza de forma dinámica la actividad de los procesos | procps |
uptime | Por cuánto tiempo ha estado corriendo el sistema y la carga promedio | procps |
ps | Información detallada acerca de los procesos | procps |
pstree | Un árbol de procesos y sus conexiones | psmisc (o pstree) |
mpstat | Uso de procesador múltiple | sysstat |
iostat | Uso de CPU y estadísticas de E/S | sysstat |
sar | Despliegue y recolección de información acerca de la actividad del sistema | sysstat |
numastat | Información de NUMA (Arquitectura de memoria no uniforme) | numactl |
strace | Información acerca de todas las llamadas al sistema realizadas por un proceso | strace |
ps es un caballo de batalla para desplegar características y estadísticas asociadas a procesos, todo lo cual se obtiene desde el directorio asociado al proceso en /proc.
Esta herramienta ha existido en todas las variantes del sistema operativo UNIX y esta diversidad se refleja en la complicada mezcla de opciones que acepta la versión de ps en Linux, las cuales se dividen en tres categorías:
- Opciones UNIX, las cuales deben ser precedidas por -, y que pueden estar agrupadas.
- Opciones BSD, las cuales no deben ser precedidas por -, y que pueden estar agrupadas.
- Las opciones largas de GNU, cada una de las cuales debe ser precedida por --.
Tener todas estas opciones posibles puede tornar la vida del administrador de sistemas un poco confusa. Muchos de ellos tienden a usar una o dos combinaciones estándar para su uso diario.
Un uso típico con la opción de formato BSD para ps es:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 198384 6232 ? Ss 07:14 0:01 /usr/lib/systemd/systemd --switched-root -
root 2 0.0 0.0 0 0 ? S 07:14 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 07:14 0:03 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 07:14 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S 07:14 0:22 [rcu_preempt]
root 8 0.0 0.0 0 0 ? S 07:14 0:00 [rcu_sched]
root 9 0.0 0.0 0 0 ? S 07:14 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S 07:14 0:03 [migration/0]
....
root 237 0.0 0.0 0 0 ? S 07:14 0:00 [scsi_eh_0]
root 238 0.0 0.0 0 0 ? S< 07:14 0:00 [scsi_tmf_0]
root 239 0.0 0.0 0 0 ? S 07:14 0:00 [scsi_eh_1]
root 240 0.0 0.0 0 0 ? S< 07:14 0:00 [scsi_tmf_1]
....
root 684 0.0 0.0 16744 2648 ? SNs 07:15 0:00 /usr/sbin/alsactl -s -n 19 -c -E ALSA_CONF
root 690 0.0 0.0 326396 5472 ? Ssl 07:15 0:00 /usr/sbin/ModemManager
root 697 0.0 0.1 181804 8740 ? Ss 07:15 0:00 /usr/sbin/cupsd -f
....
coop 24400 2.2 0.6 816720 50876 ? Sl 20:19 0:02 /opt/google/chrome/chrome --type=ppapi --c
coop 24819 0.0 0.3 634244 27952 ? Sl 09:01 0:30 /usr/libexec/gnome-terminal-server
coop 30170 0.0 0.0 116660 4816 pts/2 Ss+ 16:14 0:00 bash
....
donde la opción aux muestra todos los procesos. Los comandos que están encerrados en paréntesis cuadrados (como [ksoftirqd/0]) son hilos que existen totalmente en el kernel; si hay uno para cada CPU el comando es seguido por un número entero, especificando la CPU en la cual está ejecutándose.
La mayoría de los campos en el ejemplo anterior se autoexplican. En relación a otros:
- VSZ corresponde al tamaño de la memoria virtual del proceso en KB.
- RSS tamaño de la memoria residente; la memoria física que una tarea está usando en KB
- STAT describe el estado del proceso; en el ejemplo anterior vemos solamente S para los procesos que están durmiendo o R para los que están en ejecución. El caracter adicional en el estado (cuando existe) puede ser:
- < para prioridad alta (lo contrario de nice)
- N para prioridad baja (para nice)
- L indica que tiene páginas bloqueadas en memoria
- s para el líder de la sesión
- l es multihebra
- + está en el grupo de procesos en primer plano.
Si se agrega la opción f se mostrarán los procesos conectados por ascendencia, como se muestra a continuación:
$ ps auxf
....
coop 23666 0.0 0.0 63880 1180 ? S 11:09 0:00 /bin/sh /usr/lib64/thunder
coop 23670 0.0 0.0 63880 1220 ? S 11:09 0:00 \_ /bin/sh /usr/lib64/thu
coop 23675 0.4 2.0 764756 84948 ? Sl 11:09 0:54 \_ /usr/lib64/thunder
.....
Un uso típico con la opción de formato UNIX:
$ ps -elf
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 49596 SYSC_e 07:14 ? 00:00:01 /usr/lib/systemd/systemd --switc
1 S root 2 0 0 80 0 - 0 kthrea 07:14 ? 00:00:00 [kthreadd]
1 S root 3 2 0 80 0 - 0 smpboo 07:14 ? 00:00:03 [ksoftirqd/0]
1 S root 5 2 0 60 -20 - 0 worker 07:14 ? 00:00:00 [kworker/0:0H]
1 S root 7 2 0 80 0 - 0 rcu_gp 07:14 ? 00:00:22 [rcu_preempt]
1 S root 8 2 0 80 0 - 0 rcu_gp 07:14 ? 00:00:00 [rcu_sched]
1 S root 9 2 0 80 0 - 0 rcu_gp 07:14 ? 00:00:00 [rcu_bh]
1 S root 10 2 0 -40 - - 0 smpboo 07:14 ? 00:00:03 [migration/0]
....
1 S root 237 2 0 80 0 - 0 scsi_e 07:14 ? 00:00:00 [scsi_eh_0]
1 S root 238 2 0 60 -20 - 0 rescue 07:14 ? 00:00:00 [scsi_tmf_0]
1 S root 239 2 0 80 0 - 0 scsi_e 07:14 ? 00:00:00 [scsi_eh_1]
1 S root 240 2 0 60 -20 - 0 rescue 07:14 ? 00:00:00 [scsi_tmf_1]
....
0 S root 684 1 0 99 19 - 4186 poll_s 07:15 ? 00:00:00 /usr/sbin/alsactl -s -n 19 -c -E
....
1 S coop 24400 5536 2 80 0 - 204180 futex_ 20:19 ? 00:00:09 /opt/google/chrome/chrome --type
0 S coop 24819 1 0 80 0 - 158561 poll_s 09:01 ? 00:00:31 /usr/libexec/gnome-terminal-serv
0 S coop 30170 24819 0 80 0 - 29165 n_tty_ 16:14 pts/2 00:00:00 bash
....
Tenga en cuenta que en este caso se muestra el PID del proceso padre (PPID) y el factor de nice (NI). En este ejemplo (tomado en RHEL 7, usando systemd) es posible observar que muchos procesos muestran PPID=2, el cual es un proceso interno del kernel, kthreadd, el cual está diseñado para adoptar hijos cuando el proceso padre muere. En sistemas con versiones antiguas del kernel veríamos PPID=1, haciendo mención a /sbin/init, pero básicamente es la misma idea.
Algunas opciones comunes de selección en el formato UNIX son:
- -A o -e: Selecciona todos los procesos.
- -N: Niega la selección (es decir, indica lo contrario).
- -C: Selecciona por nombre de comando.
- -G: Selecciona por ID real de grupo (también soporta nombres).
- -U: Selecciona por ID real de usuario (también soporta nombres).
Si se usa la opción -o seguida de una lista de campos identificadores separados por coma, es posible imprimir una lista personalizada de campos de ps:
- pid: número identificador del proceso.
- uid: número identificador del usuario dueño del proceso.
- cmd: comando con todos los argumentos .
- cputime: tiempo de CPU acumulado.
- pmem: relación de tamaño del conjunto residente a la memoria física de la máquina, expresada como porcentaje.
A continuación un ejemplo:
$ ps -o pid,uid,command
PID UID COMMAND
7989 500 bash
8228 500 ps -o pid,uid,command
Usted puede consultar la página man de ps para obtener muchas otras opciones de salida.
pstree provee una descripción visual de la ascendencia del proceso y aplicaciones multihebra:
$ pstree -aAp 2408
bash,2408
|-emacs,24998 pmonitor.tex
| |-{emacs},25002
| '-{emacs},25003
|-evince,18036 LFS201-SLIDES.pdf
| |-{evince},18040
| |-{evince},18046
| '-{evince},18047
Consulte la página man de pstree para obtener una explicación completa del resto de las opciones; en el ejemplo de arriba solo quisimos mostrar información para el pid=2048.
Tenga en cuenta que uno de sus procesos hijos (evince con pid=18036) tiene tres hijos propios. Otra forma de verlo es la siguiente:
$ ls -l /proc/18036/task
total 0
dr-xr-xr-x 5 coop coop 0 Sep 11 07:15 18036
dr-xr-xr-x 5 coop coop 0 Sep 11 07:15 18040
dr-xr-xr-x 5 coop coop 0 Sep 11 07:15 18046
dr-xr-xr-x 5 coop coop 0 Sep 11 07:15 18047
Cuando se desea saber qué está haciendo el sistema operativo, la primera herramienta que se suele usar es top. Si se ejecuta sin argumentos muestra lo siguiente:
$ top
top - 09:27:44 up 2:09, 4 users, load average: 1.05, 0.35, 0.11
Tasks: 270 total, 3 running, 267 sleeping, 0 stopped, 0 zombie
Cpu(s): 4.0%us, 1.7%sy, 0.3%ni, 90.0%id, 4.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 4045232k total, 3972700k used, 72532k free, 623928k buffers
Swap: 4642048k total, 0k used, 4642048k free, 2370804k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4376 root 20 0 430m 72m 10m R 48.9 1.8 8:59.68 Xorg
4561 coop 20 0 60112 1844 752 S 9.8 0.0 0:00.14 make
4603 coop 20 0 315m 18m 8516 R 2.0 0.5 0:16.45 gnome-terminal
5033 root 20 0 61028 2560 648 S 2.0 0.1 0:00.04 make
5098 coop 20 0 12876 1108 712 R 2.0 0.0 0:00.01 top
5202 root 20 0 60176 1712 712 S 2.0 0.0 0:00.01 make
1 root 20 0 10356 632 536 S 0.0 0.0 0:01.78 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.06 migration/0
4 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0
5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
6 root RT 0 0 0 0 S 0.0 0.0 0:00.15 migration/1
7 root 20 0 0 0 0 S 0.0 0.0 0:00.04 ksoftirqd/1
...
top se refresca cada 3 segundos por defecto.
top es una herramienta antigua y tiene muchísimas opciones, como también comandos interactivos que se inician cuando se presionan ciertas teclas. Por ejemplo, si se presiona 1, cada CPU se muestra por separado. Si se presiona i, solo se muestran los procesos activos. Haciendo ambas cosas se obtiene lo siguiente:
top - 12:51:50 up 1 day, 5:31, 6 users, load average: 0.09, 0.14, 0.22
Tasks: 288 total, 1 running, 287 sleeping, 0 stopped, 0 zombie
%Cpu0 : 3.4 us, 1.3 sy, 0.0 ni, 94.6 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 3.7 us, 0.7 sy, 0.0 ni, 95.0 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 3.6 us, 1.3 sy, 0.0 ni, 95.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 2.3 us, 1.0 sy, 0.0 ni, 96.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 8170032 total, 6360684 used, 1809348 free, 46888 buffers
KiB Swap: 4193776 total, 4848 used, 4188928 free. 4292304 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2036 coop 20 0 1876580 396628 37704 S 8.0 4.9 113:14.62 gnome-shell
15082 coop 20 0 547140 185968 21444 S 3.0 2.3 13:22.17 skype-bin
1648 root 20 0 254972 68920 27208 S 2.3 0.8 33:11.09 Xorg
2301 coop 20 0 642600 32156 18908 S 1.0 0.4 1:16.76 gnome-terminal-
18712 root 20 0 0 0 0 S 0.7 0.0 0:00.25 kworker/1:1
2111 coop 20 0 995392 29424 21076 S 0.3 0.4 0:03.13 nautilus
15465 coop 20 0 1032892 191332 105244 S 0.3 2.3 0:10.88 chrome
18973 coop 20 0 123768 3108 2492 R 0.3 0.0 0:00.04 top
Se tiene mucho control sobre cómo se ordenan los procesos y qué campos se despliegan; hay muchas otras opciones además de las por defecto. Por ejemplo, si se presiona h o ? se obtiene una lista breve de los comandos interactivos y q se usa para salir.
Además es posible terminar una tarea presionando k, o cambiar su prioridad (renice) con r.
Si hace man top obtendrá documentación extensiva acerca de las opciones de configuración y posibilidades interactivas.
Tenga en cuenta que hay alternativas populares al comando estándar top, algunos de los cuales proveen interfaces más visuales o información adicional, tales como htop, ntop y atop. La mayoría de las distribuciones Linux tienen un monitor gráfico del sistema (como gnome-system-monitor o ksysguard), los cuales tienen una ventana de despliegue similar a top.
Seleccione cuáles de las siguientes herramientas monitorean procesos:
sysctl
ps
top
pstree
df
__________________es la herramienta que se usa para configurar la prioridad de un proceso en la cpu.
Actualmente usted debería ser capaz de:
- Usar ps para visualizar características y estadísticas asociadas a procesos.
- Identificar diferentes campos de salida de ps y personalizar la salida del comando.
- Usar pstree para obtener una descripción visual de la ascendencia de los procesos y aplicaciones multihilos.
- Usar top para visualizar la carga del sistema interactivamente.
24. Monitoreo y ajuste de E/S
Existe una fuerte y complicada relación entre E/S y rendimiento del sistema. No es fácil desentrañar la competencia entre procesos por ancho de banda de E/S para almacenamiento, uso de CPU, memoria y cuellos de botella de la red.
Dos herramientas que pueden ayudar a identificar y aislar problemas de este tipo son iostat e iotop. La herramienta ionice puede usarse para ayudar a priorizar la competición entre procesos.
Al final de este capítulo usted debería ser capaz de:
- Usar iostat para monitorear la actividad de dispositivos de E/S del sistema.
- Usar iotop para desplegar una tabla del uso actual de E/S.
- Usar ionice para configurar tanto la clase de planificación de E/S como la prioridad de un proceso dado.
Los problemas de rendimiento de discos pueden acoplarse estrechamente a otros factores, tales como memoria insuficiente o hardware de red y ajustes inadecuados. Solucionar este tipo de problemas puede ser complejo.
Como regla, un sistema puede considerarse como atascado en E/S cuando la CPU está esperando de forma ociosa que alguna operación de E/S se complete para poder continuar. Otra posibilidad es que la red esté esperando a que los búferes se limpien.
Sin embargo, es posible ser engañado. Lo que parece ser memoria insuficiente puede resultar de E/S muy lenta; si los búferes de memoria que están siendo usados para leer y escribir se llenan, esto puede indicar que el problema está en la memoria, cuando el problema real es que los búferes no se están llenando o vaciando lo suficientemente rápido. De manera similar, las transferencias de red pueden estar esperando por operaciones de E/S que tienen que completarse, lo cual tiene un efecto negativo en el rendimiento de red.
Tanto el monitoreo en tiempo real como el seguimiento son herramientas necesarias para localizar y mitigar cuellos de botella. Sin embargo, problemas extraños o que no son reproducibles pueden hacer que estas tareas sean difíciles de lograr.
Hay muchas variables relevantes y el ajuste de E/S es complejo. Consideraremos la planificación de E/S más adelante.
iostat es el caballo de batalla básico para monitoreo de actividad de E/S en el sistema. Puede generar reportes con mucha información, en donde el contenido exacto se controla a través de opciones.
Si se ejecuta iostat sin argumentos obtenemos lo siguiente:
$ iostat
Linux 3.15.9 (q7) 09/11/2014 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait c%stealc %idle
3.07 0.05 1.30 0.66 0.00 94.92
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 12.10 170.52 61.69 2170494 785198
dm-0 5.58 46.32 48.74 589608 620384
dm-2 1.22 4.89 0.00 62208 12
dm-3 0.01 0.06 0.00 728 0
dm-5 0.31 1.24 0.00 15780 12
dm-6 0.05 0.20 0.00 2568 12
dm-7 0.03 0.11 0.00 1436 12
dm-8 0.03 0.13 0.00 1636 12
dm-1 0.00 0.01 0.00 152 0
dm-4 0.01 0.03 0.00 364 0
dm-10 0.01 0.03 0.00 364 0
dm-11 0.33 28.50 0.23 362769 2964
dm-13 0.03 0.10 0.00 1268 12
dm-14 0.03 0.10 0.00 1256 12
dm-15 0.01 0.03 0.00 364 0
Luego de un resumen breve del uso de la CPU, se dan las estadísticas de E/S: tps (transacciones E/S por segundo; las solicitudes lógicas pueden combinarse con solicitudes reales), bloques leídos y escritos por unidad de tiempo, en donde los bloques son generalmente sectores de 512 bytes; y el total de bloques leídos y escritos.
La información está dividida por particiones del disco (y si LVM está siendo usada por particiones lógicas de dm, device mapper).
Si se especifica la opción -k, se genera una vista un tanto diferente, la cual muestra los resultados en KB en vez de bloques:
$ iostat -k
Linux 3.15.9 (q7) 09/11/2014 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
3.07 0.05 1.29 0.66 0.00 94.93
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 12.07 170.00 61.53 2170494 785574
dm-0 5.57 46.18 48.61 589608 620632
dm-2 1.22 4.87 0.00 62208 12
....
Es posible usar la opción -m para obtener los resultados en MB.
Otra opción útil es -N, la cual despliega la información por nombre de dispositivo (o -d para un formato un poco diferente), como se muestra aquí:
iostat -N
Linux 3.18.0 (q7) 12/12/2014 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
4.13 0.00 7.38 1.91 0.00 86.57
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 20.26 3895.58 554.19 95397215 13571286
VG-local 4.04 18.07 45.38 442484 1111280
VG-src 0.03 0.15 0.00 3660 32
VG-dead 0.02 0.07 0.00 1692 12
VG-audio 0.01 0.05 0.00 1313 12
VG-iso_images 0.02 0.07 0.00 1812 12
VG-virtual 15.37 3718.74 481.88 91066729 11800544
VG-P 0.00 0.00 0.00 76 0
VG-pictures 0.28 27.30 0.23 668476 5700
VG-virtual2 0.01 0.05 0.00 1256 12
VG-w7back 0.00 0.01 0.00 364 0
Se puede obtener un informe mucho más detallado si se usa la opción -x (de extendido):
$ iostat -xk
Linux 3.15.9 (q7) 09/11/2014 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
3.06 0.05 1.29 0.66 0.00 94.94
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 1.04 2.61 7.68 4.33 169.34 61.23 38.39 0.16 12.96 10.53 17.27 1.86 2.24
dm-0 0.00 0.00 1.15 4.40 45.92 48.38 34.01 0.03 6.23 7.38 5.92 2.42 1.34
en donde los campos tienen los siguientes significados:
Campo | Significado |
---|---|
Device | Dispositivo o nombre de la partición |
rrqm/s | Número de solicitudes de lectura por segundo, encoladas al dispositivo |
wrqm/s | Número de solicitudes de escritura por segundo, encoladas al dispositivo |
r/s | Número de solicitudes de lectura por segundo, emitidas al dispositivo |
w/s | Número de solicitudes de escritura por segundo, emitidas al dispositivo |
rkB/s | KB por segundo leídos desde el dispositivo |
wkB/s | KB por segundo escritos al dispositivo |
avgrq-sz | Tamaño promedio de solicitud en sectores de 512 bytes por segundo |
avgqu-sz | Longitud promedio de la cola de solicitudes emitidas al dispositivo |
await | Tiempo promedio (en milisegundos) de solicitudes de E/S entre cuando se emite una solicitud y cuando se ha completado: tiempo de la cola más tiempo de servicio |
svctm | Tiempo promedio de servicio (en milisegundos) para solicitudes de E/S |
%util | Porcentaje de tiempo de CPU durante las solicitudes servidas a dispositivos |
Tenga en cuenta que si el porcentaje de utilización se aproxima a 100, el sistema operativo o el de E/S está saturado.
Otra herramienta muy útil es iotop, la cual debe ser ejecutada como root. Esta despliega una tabla del uso actual de E/S y se actualiza periódicamente, de la misma forma que lo hace top. Si se ejecuta sin opciones muestra lo siguiente:
$ sudo iotop
Total DISK READ : 132.32 M/s | Total DISK WRITE : 132.79 M/s
Actual DISK READ: 132.32 M/s | Actual DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
9791 be/4 root 132.32 M/s 132.79 M/s 0.00 % 72.48 % cp /usr/s~.sqfs /tmp
1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd -~rialize 22
2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]
3 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/0]
5 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kworker/0:0H]
2054 be/4 coop 0.00 B/s 0.00 B/s 0.00 % 0.00 % gsd-printer
7 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_preempt]
8 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_sched]
9 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_bh]
10 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [migration/0]
.....
Tenga en cuenta que las entradas be y rt en el campo PRIO se explican en la sección de ionice, y provienen de best effort (mejor esfuerzo) y real time (tiempo real).
Las opciones disponibles se muestran con:
$ sudo iotop --help
Usage: /usr/sbin/iotop [OPTIONS]
DISK READ and DISK WRITE are the block I/O bandwidth used during the sampling
period. SWAPIN and IO are the percentages of time the thread spent respectively
while swapping in and waiting on I/O more generally. PRIO is the I/O priority at
which the thread is running (set using the ionice command).
Controls: left and right arrows to change the sorting column, r to invert the
sorting order, o to toggle the --only option, p to toggle the --processes
option, a to toggle the --accumulated option, i to change I/O priority, q to
quit, any other key to force a refresh.
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-o, --only only show processes or threads actually doing I/O
-b, --batch non-interactive mode
-n NUM, --iter=NUM number of iterations before ending [infinite]
-d SEC, --delay=SEC delay between iterations [1 second]
-p PID, --pid=PID processes/threads to monitor [all]
-u USER, --user=USER users to monitor [all]
-P, --processes only show processes, not all threads
-a, --accumulated show accumulated I/O instead of bandwidth
-k, --kilobytes use kilobytes instead of a human friendly unit
-t, --time add a timestamp on each line (implies --batch)
-q, --quiet suppress some lines of header (implies --batch)
Usar la opción -o puede ser útil para tener una salida más limpia.
La herramienta ionice le permite ajustar tanto la clase de planificación de E/S y la prioridad para un proceso dado. Usa la siguiente sintaxis:
$ ionice [-c class] [-n priority] [-p pid ] [COMMAND [ARGS] ]
Si se pasa un pid a través del argumento -p, el resultado aplica al proceso solicitado, de lo contrario se aplicará al proceso iniciado por COMMAND con los argumentos correspondientes. Si no se proveen argumentos, ionice provee la clase de planificación y prioridad del proceso de shell actual, como se muestra aquí:
$ ionice
idle: prio 7
El parámetro -c especifica la clase de planificación de E/S, la cual puede tener los tres valores que siguen:
Clase de planificación de E/S | valor de -c | Significado |
---|---|---|
Idle | 1 | No tiene acceso a E/S de disco a menos que ningún otro programa lo haya solicitado por un período definido. |
Best effort | 2 | Todos los programas se atienden con el método round-robin, de acuerdo a los ajustes de prioridad. Esta es la configuración por defecto. |
Real Time | 3 | Obtiene acceso primero al disco, lo cual puede desplazar a otros procesos. La prioridad define el tamaño de la tajada de tiempo que recibe cada proceso. |
Las clases Best Effort y Real Time toman el argumento -n, el cual da la prioridad, la que puede estar en un rango de 0 a 7, en donde 0 es la prioridad mayor. Un ejemplo:
$ ionice -c 2 -n 3 -p 30078
Nota: ionice funciona solo cuando se usa el planificador de E/S CFQ, el cual se mencionará en el capítulo siguiente.
_________________ es la herramienta que se usa para configurar la prioridad de E/S de un proceso.
Actualmente usted debería ser capaz de:
- Usar iostat para monitorear la actividad de dispositivos de E/S del sistema.
- Usar iotop para desplegar una tabla del uso actual de E/S.
- Usar ionice para configurar tanto la clase de planificación de E/S como la prioridad de un proceso dado.
25. Planificación de E/S
El rendimiento del sistema a menudo depende profundamente de optimizar la estrategia de planificación de E/S. Muchos factores (que compiten frecuentemente) influyen en el comportamiento; esos incluyen minimizar los tiempos de acceso al hardware, evitando de esta forma el desgaste del medio de almacenamiento, asegurando la integridad de los datos, garantizando el acceso oportuno a las aplicaciones que necesitan realizar operaciones de E/S y priorizando las tareas importantes.
Linux ofrece una variedad de planificadores de E/S a elegir, cada uno de los cuales tiene parámetros ajustables, como también un número de herramientas para generar reportes y analizar el rendimiento de E/S.
Al final de este capítulo usted debería ser capaz de:
- Explicar la importancia de la planificación de E/S y describir los requisitos en conflicto que deben ser resueltos.
- Delinear y contrastar las opciones disponibles en Linux.
- Comprender cómo funcionan los algoritmos CFQ (Completely Fair Queue) y Deadline.
El planificador de E/S provee la interfaz entre la capa genérica de bloques y los controladores de dispositivo físico de bajo nivel. Tanto la VM (memoria virtual) como el VFS (sistema de archivo virtual) realizan solicitudes de E/S a los dispositivos de bloque; es trabajo del planificador de E/S el priorizar y ordenar estas solicitudes antes de que sean enviadas a los dispositivos de bloque.
Cualquier algoritmo planificador de E/S tiene que satisfacer ciertos requerimientos (los que a veces entran en conflicto):
- Los tiempos de acceso al Hardware deben minimizarse; es decir, las solicitudes deben ordenarse de acuerdo a la ubicación física en el disco. Esto conduce a un esquema de ascensor, en donde las solicitudes son insertadas en la cola pendiente en orden físico.
- Las solicitudes deben mezclarse en tanto se pueda para obtener una región contigua del mayor tamaño posible, lo cual también minimiza el tiempo de acceso al disco.
- Las solicitudes deben ser satisfechas con la menor latencia posible; de hecho en algunos casos el determinismo (en el sentido de los plazos) puede ser importante.
- Las operaciones de escritura generalmente pueden esperar a migrar desde caché a disco sin que los procesos se estanquen. Sin embargo, las operaciones de lectura requieren siempre que un proceso espere la finalización antes de seguir adelante. Favorecer las lecturas sobre las escrituras conduce a mejorar las operaciones en paralelo y la capacidad de respuesta del sistema.
- Los procesos deben compartir el ancho de banda de E/S de forma justa, o al menos priorizado de forma consciente; aunque esto signifique cierta desaceleración del rendimiento global de la capa de E/S, el rendimiento de los procesos no debería verse muy afectado.
Debido a que estas demandas pueden ser conflictivas, diversos planificadores de E/S pueden ser apropiados para diferentes cargas de trabajo; por ejemplo, un servidor grande de base de datos vs. un sistema de escritorio. Además, el hardware específico podría ordenar una estrategia diferente. Para proveer flexibilidad, el kernel Linux tiene un esquema orientado a objetos, en el cual punteros a las diversas funciones necesarias son proporcionadas en una estructura de datos. Una en particular que puede ser seleccionada durante el arranque en la línea de comandos del kernel es:
linux ... elevator=[cfq|deadline|noop]
Al menos uno de los algoritmos de planificación de E/S debe estar compilado en el kernel. Las opciones actuales son:
- Completely Fair Queueing (CFQ)
- Deadline Scheduling
- noop (Un esquema simple)
La opción por defecto es una configuración de la compilación; las distribuciones modernas eligen CFQ o Deadline.
La introducción gradual de los dispositivos SSD (discos de estado sólido), los cuales usan memoria flash para emular discos duros, tienen importantes implicancias para la planificación de E/S.
Tales dispositivos no requieren de un esquema de ascensor y se benefician de la técnica conocida como nivelación de desgaste para difundir E/S sobre los dispositivos que tienen ciclos limitados de escritura/borrado.
Es posible examinar /sys/block/<device>/queue/rotational para ver si el dispositivo es SSD o no, como se muestra a continuación:
$ cat /sys/block/sda/queue/rotational
1
Cada uno de los planificadores de E/S presentan parámetros que se pueden usar para ajustar el comportamiento en tiempo de ejecución. Los parámetros se acceden a través del pseudosistema de archivos montado en /sys.
Adicionalmente, es posible usar diferentes planificadores de E/S para diversos dispositivos. La elección puede realizarse fácilmente desde la línea de comandos. Por ejemplo:
$ cat /sys/block/sda/queue/scheduler
noop deadline [cfq]
$ echo noop > /sys/block/sda/queue/scheduler
$ cat /sys/block/sda/queue/scheduler
[noop] deadline cfq
Los parámetros ajustables pueden variar en relación al planificador de E/S en particular, y pueden encontrarse bajo:
/sys/block/<device>/queue/iosched
Para un disco que usa CFQ:
$ ls -l /sys/block/sda/queue/iosched
total 0
-rw-r--r-- 1 root root 4096 Sep 11 11:15 back_seek_max
-rw-r--r-- 1 root root 4096 Sep 11 11:15 back_seek_penalty
-rw-r--r-- 1 root root 4096 Sep 11 11:15 fifo_expire_async
-rw-r--r-- 1 root root 4096 Sep 11 11:15 fifo_expire_sync
-rw-r--r-- 1 root root 4096 Sep 11 11:15 group_idle
-rw-r--r-- 1 root root 4096 Sep 11 11:15 low_latency
-rw-r--r-- 1 root root 4096 Sep 11 11:15 quantum
-rw-r--r-- 1 root root 4096 Sep 11 11:15 slice_async
-rw-r--r-- 1 root root 4096 Sep 11 11:15 slice_async_rq
-rw-r--r-- 1 root root 4096 Sep 11 11:15 slice_idle
-rw-r--r-- 1 root root 4096 Sep 11 11:15 slice_sync
-rw-r--r-- 1 root root 4096 Sep 11 11:15 target_latency
Comentaremos algunos de estos parámetros en breve.
El método CFQ (Completely Fair Queue) tiene el objetivo de propagar un ancho de banda de E/S igual entre todos los procesos.
En teoría, cada proceso tiene su propia cola de E/S, la cual trabaja en conjunto a una cola de despacho que recibe las solicitudes hacia el dispositivo. En la práctica, el número de colas es fijo (64) y un proceso hash basado en el ID del proceso se usa para seleccionar una cola cuando se ingresa una solicitud.
El desencole de las solicitudes se realiza con el mecanismo round robin en todas las colas, cada una de las cuales funciona en orden FIFO (primero en entrar, primero en salir). De esa forma se lleva a cabo el trabajo. Para evitar operaciones excesivas de búsqueda, se selecciona una ronda completa y se pasa a la cola de despacho antes de que las solicitudes reales de E/S se emitan al dispositivo.
En los ejemplos de abajo, el parámetro HZ es una cantidad configurada por el kernel, la que corresponde al número de unidades de tiempo por segundo (jiffies), que el núcleo usa como una medida gruesa de tiempo. Sin entrar en detalles, permítanos decir que la unidad de tiempo HZ/2 es 0.5 segundos y 5 * HZ son 5 segundos, etc.
- quantum
Longitud máxima de la cola en una ronda de servicio (valor por defecto = 4). - queued
Solicitud mínima de asignación por cola (valor por defecto = 8). - fifo_expire_sync
timeout FIFO para solicitudes de sincronización (valor por defecto = HZ/2). - fifo_expire_async
timeout FIFO para solicitudes asincrónicas (valor por defecto = 5 * HZ). - fifo_batch_expire
Velocidad a la cual expira FIFO (valor por defecto = HZ/8). - back_seek_max
Búsqueda hacia atrás máxima, en KB (valor por defecto = 16K). - back_seek_penalty
Penalización por una búsqueda hacia atrás (valor por defecto = 2).
El planificador de E/S Deadline reordena agresivamente solicitudes con los objetivos de mejorar el rendimiento general y prevenir latencias grandes para solicitudes individuales; es decir, limita la inanición por falta de recursos.
Con cada solicitud el kernel asocia una fecha límite. Las solicitudes de lectura obtienen una prioridad más alta que las de escritura.
Se mantienen cinco colas de E/S por separado:
- Se mantienen dos listas ordenadas; una para lectura y otra para escritura, ordenadas por bloque de inicio.
- Se mantienen dos listas FIFO, de nuevo, una para lectura y otra para escritura. Estas listas se ordenan por tiempo de ingreso.
- Una quinta cola contiene las solicitudes que van a ser enviadas al controlador de dispositivo. Esta cola se conoce como la cola de envío.
Exactamente cómo las solicitudes son removidas de las primeras cuatro colas y puestas en la quinta (cola de envío) es donde entra en juego el arte del algoritmo.
Aquí están los parámetros ajustables del planificador Deadline:
- read_expire:
En cuánto tiempo (en milisegundos) se garantiza que ocurra una solicitud de lectura (por defecto = HZ/2 = 500 ). - write_expire:
En cuánto tiempo (en milisegundos) se garantiza que ocurra una solicitud de escritura (por defecto = 5 * HZ = 5000). - writes_starved:
A cuántas solicitudes de lectura se debería dar preferencia por sobre las de escritura (por defecto = 2 ). - fifo_batch:
Cuántas solicitudes deberían moverse desde la lista ordenada del planificador a la cola de envío, cuando los plazos han expirado (por defecto = 16). - front_merges:
Las uniones hacia atrás son más comunes que las hacia adelante, ya que una solicitud contigua generalmente continúa en el bloque siguiente. Si este parámetro se configura en 0, se deshabilita la unión hacia adelante, lo cual puede dar un impulso si usted sabe que no va a ser necesario (por defecto = 1).
¿Cuáles son los planificadores de E/S por defecto en Linux?
Completely Fair Queuing (CFQ)
Ascensor
Planificador Deadline
noop
¿Qué categoría de dispositivos no requiere un esquema planificador de ascensor?
SATA
IDE
SCSI
SAS
SSD
- Laboratorio 25.1 (código fuente: ioscript.sh)
Actualmente usted debería ser capaz de:
- Explicar la importancia de la planificación de E/S y describir los requisitos en conflicto que deben ser resueltos.
- Delinear y contrastar las opciones disponibles en Linux.
- Comprender cómo funcionan los algoritmos CFQ (Completely Fair Queue) y Deadline.
26. Memoria: monitoreo y ajustes
A través del tiempo los sistemas se han vuelto más demandantes de recursos de memoria, al mismo tiempo que los precios de la RAM han disminuido y el rendimiento ha mejorado. De todas formas aún sucede que los cuellos de botella en el rendimiento general del sistema están relacionados a la memoria; las CPUs y el subsistema de E/S podrían estar esperando que los datos se obtengan o escriban a memoria. Hay muchas herramientas para monitoreo, depuración y ajuste del comportamiento de un sistema en relación a su memoria.
Al final de este capítulo usted debería ser capaz de:
- Listar las consideraciones primarias y tareas involucradas en la optimización de la memoria.
- Saber cómo usar las entradas en /proc/sys/vm e interpretar /proc/meminfo.
- Usar vmstat para desplegar información de memoria, paginación, E/S, actividad del procesador y el consumo de memoria de los procesos.
- Comprender cómo el OOM-killer decide cuándo tomar acción y seleccionar qué procesos deben ser finalizados para liberar memoria.
Ajustar el subsistema de memoria puede ser un proceso complejo. Primero que todo hay que notar que el uso de memoria y el rendimiento de E/S están intrínsicamente relacionados, ya que en la mayoría de los casos la memoria se usa para poner en caché el contenido de los archivos en disco.
Por lo tanto, cambiar parámetros de la memoria puede tener grandes efectos en el rendimiento de E/S. Y cambiar parámetros de E/S puede tener un efecto contrario de igual tamaño en el subsistema de memoria virtual.
Al ajustar parámetros en /proc/sys/vm, la mejor práctica suele ser modificar una cosa a la vez y analizar los efectos. Las tareas principales son las siguientes:
- Controlar los parámetros de flujo; es decir, cuántas páginas se permite que estén sucias (en el área de intercambio) y cuán a menudo se vacían al disco.
- Controlar el comportamiento del área de intercambio; es decir, cuántas páginas que reflejan contenidos de archivo pueden permanecer en memoria en comparación a las que necesitan ser escritas a disco debido a que no tienen otra copia de seguridad.
- Controlar cuánto desborde de memoria se permite, ya que muchos programas no necesitan la cantidad total de memoria que solicitan, en particular debido a las técnicas COW (copy on write).
La optimización de memoria a menudo puede ser sutil, y lo que funciona en la situación de un sistema o carga puede no hacerlo de forma óptima en otras circunstancias.
Aquí hay una lista de algunas herramientas básicas importantes para monitorear y optimizar la memoria en Linux:
Herramienta | Propósito | Paquete |
---|---|---|
free | Provee un resumen breve del uso de la memoria | procps |
vmstat | Estadísticas detalladas de memoria virtual y bloques de E/S, actualizados de forma dinámica | procps |
pmap | Mapa de memoria de un proceso | procps |
El directorio /proc/sys/vm contiene muchos ajustes para controlar el sistema de Memoria Virtual. Lo que se encuentra exactamente en este directorio depende en cierto modo de la versión del kernel. El usuario root puede escribir sobre casi todas las entradas aquí.
Recuerde que estos valores pueden modificarse ya sea escribiendo directamente en la entrada o usando la herramienta sysctl. Además, si modifica /etc/sysctl.conf los valores tendrán efecto en cada arranque.
Entrada | Propósito |
---|---|
admin_reserve_kbytes | Cantidad de memoria libre reservada para usuarios con privilegios. |
block_dump | Habilita depuración de bloques de E/S. |
compact_memory | Habilita o deshabilita la compactación de memoria (esencialmente la defragmentación) cuando está configurada como parte del kernel. |
dirty_background_bytes | Umbral de memoria sucia que provoca que las páginas se escriban a disco. |
dirty_background_ratio | Porcentaje total de páginas con el que el kernel comenzará a escribir datos sucios al disco. |
dirty_bytes | La cantidad de memoria sucia que un proceso necesita para iniciar la escritura por sí solo. |
dirty_expire_centisecs | Cuando los datos sucios son los suficientemente antiguos para ser escritos en centésimas de segundo. |
dirty_ratio | Porcentaje de páginas en el cual un proceso de escritura comenzará a escribir datos sucios por sí solo. |
dirty_writeback_centisecs | Intervalo en el cual los demonios de reescritura periódica se despiertan para limpiar. Si se configura en cero, no hay reescritura periódica automática. |
drop_caches | Echo 1 se usa para liberar el caché de páginas, 2 para los cachés dentry e inodo, 3 para liberar todos. Tenga en cuenta que solo las páginas limpias en caché se eliminan; primero haga sync para eliminar las páginas sucias. |
extfrag_threshold | Controla cuando el kernel debe compactar memoria. |
hugepages_treat_as_movable | Se usa para cambiar la forma en la que huge pages es tratada. |
hugetlb_shm_group | Configura un ID de grupo que puede usarse para huge pages System V. |
laptop_mode | Puede controlar una serie de características para ahorrar energía en portátiles. |
legacy_va_layout | Use el diseño antiguo (kernel 2.4) en relación a cómo se muestran las asignaciones de memoria. |
lowmen_reserve_ratio | Controla cuánta memoria baja está reservada para páginas que solo pueden estar ahí; es decir, las páginas que pueden estar en memoria alta lo harán. Solo es importante en sistemas de 32 bit con memoria alta. |
max_map_count | Número máximo de áreas de memoria asignada que puede tener un proceso. El valor por defecto es 64 K. |
min_free_kbytes | Memoria libre mínima que debe estar reservada en cada zona. |
mmap_min_addr | Cuánto espacio de direcciones puede asignar un proceso de usuario. Se usa para propósitos de seguridad, para evitar que bugs del tipo referencias nulas del kernel puedan sobreescribir las primeras páginas en una aplicación. |
nr_hugepages | Tamaño mínimo de un pool de hugepage. |
nr_pdflush_hugepages | Tamaño máximo del pool de hugepage = nr_hugepages *nr_overcommit_hugepages |
nr_pdflush_threads | Número actual de las hebras de pdflush; no se puede escribir. |
oom_dump_tasks | Si está habilitado, se genera un archivo de volcado cuando el oom-killer entra en acción. |
oom_kill_allocating_task | Si está configurado, el oom-killer elimina la tarea que generó la situación de sobrememoria, en vez de tratar de seleccionar el mejor. |
overcommit_kbytes | Es posible configurar ya sea overcommit_ratio o esta entrada, pero no ambas. |
overcommit_memory | Si es 0, el kernel estima cuánta memoria libre queda cuando se realizan las asignaciones. Si es 1, permite todas las asignaciones hasta que la memoria se agota. Si es 2, evitar cualquier sobreasignación. |
overcommit_ratio | Si overcommit_memory = 2, la asignación de memoria puede alcanzar el área de intercambio más este porcentaje de RAM. |
page-cluster | Número de páginas que pueden ser escritas al área de intercambio de una vez, como una potencia de dos. El valor por defecto es 3 (lo cual significa 8 páginas). |
panic_on_oom | Habilita que el sistema se cuelgue en una situación de agotamiento de memoria. |
percpu_pagelist_fraction | Fracción de páginas asignadas para cada cpu en cada zona de máquinas de CPU con hotplug. |
scan_unevictable_pages | Si se escribe aquí, el sistema escaneará e intentará mover páginas para tratar de hacerlas recuperables. |
stat_interval | Con qué frecuencia vmstat actualiza las estadísticas de vm (por defecto en 1 segundo). |
swappiness | Cuán agresivamente el kernel puede usar la memoria de intercambio. |
user_reserve_kbytes | Si overcommit_memory está configurado en 2, esto configura hasta donde el usuario puede extraer recursos de memoria. |
vfs_cache_pressure | Cuán agresivamente el kernel podría reclamar memoria usada para caché de inodo y dentry. El valor por defecto es 100; si es 0, nunca se reclama debido a presión de memoria. |
Usted puede encontrar información completa del directorio /proc/sys/vm en las fuentes del kernel bajo Documentation/sysctl/vm.txt (o en el paquete de documentación del kernel de su distribución).
vmstat es una herramienta multipropósito que despliega información acerca de la memoria, paginación, E/S, actividad del procesador y procesos. Tiene muchas opciones. La forma general del comando es la siguiente:
$ vmstat [options] [delay] [count]
Si delay se provee en segundos, el informe se repite en ese intervalo de tiempo; si no se provee count, vmstat continuará entregando las estadísticas hasta que el proceso sea detenido por una señal, tal como Ctl-C.
Si no se proveen otros argumentos, vmstat despliega lo que sigue:
$ vmstat 2 4
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 4521672 375560 1792484 0 0 49 17 363 275 3 1 95 1 0
0 0 0 4521408 375560 1792516 0 0 0 0 490 352 1 1 98 0 0
0 0 0 4521408 375568 1792516 0 0 0 14 436 316 1 0 99 0 0
1 0 0 4521408 375576 1792516 0 0 0 10 452 330 1 0 98 0 0
donde la primera línea muestra los promedios desde el último reinicio, mientras que las líneas subsiguientes muestran la actividad durante el intervalo especificado.
Los campos que se muestran son:
Campo | Subcampo | Significado |
---|---|---|
Processes | r | Número de procesos en espera para ser ingresados al planificador |
Processes | b | Número de procesos durmiendo |
memory | swpd | Memoria virtual usada (KB) |
memory | free | Memoria libre (ociosa) (KB) |
memory | buff | Memoria usada como búfer (KB) |
memory | cache | Memoria usada como caché (KB) |
swap | si | Memoria de intercambio desde el disco (KB) |
swap | so | Memoria de intercambio hacia el disco (KB) |
I/O | bi | Bloques recibidos desde dispositivos (bloques/seg) |
I/O | bo | Bloques enviados a dispositivos (bloques/seg) |
system | in | Interrupciones/segundos |
system | cs | Cambios de contexto/segundo |
CPU | us | Tiempo de CPU ejecutando código de usuario (porcentaje) |
CPU | sy | Tiempo de CPU ejecutando código del kernel (porcentaje) |
CPU | id | Tiempo ocioso de CPU (porcentaje) |
CPU | wa | Tiempo de espera por E/S (porcentaje) |
CPU | st | Tiempo "robado" desde la máquina virtual (porcentaje) |
Si se provee la opción -S m , las estadísticas de memoria se mostrarán en MB en vez de KB.
Con la opción -a , vmstat despliega información acerca de la memoria activa e inactiva:
$ vmstat -a 2 4
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
1 0 0 4448676 1034556 2153152 0 0 49 16 363 274 3 1 95 1 0
0 0 0 4448412 1034556 2153252 0 0 0 0 736 674 2 1 97 0 0
0 0 0 4445908 1034604 2154868 0 0 0 14 2043 2301 5 3 91 0 0
0 0 0 4445560 1034604 2155224 0 0 0 24 1582 1784 5 2 92 0 0
donde las páginas de memoria activa son aquellas que han sido usadas recientemente; pueden estar limpias (los contenidos en disco están actualizados) o sucias (necesitan ser actualizadas al disco). Por otro lado, las páginas de memoria inactiva no han sido usadas recientemente, posiblemente estén limpias y se liberan antes bajo presión de memoria.
La memoria se puede mover entre las listas de memoria activa e inactiva en tanto hay cambios, o por otra parte, pueden permanecer en su lugar si se deja mucho tiempo entre usos.
Para obtener una tabla de estadísticas de memoria y ciertos contadores de eventos use la opción -s:
$ vmstat -s
8170032 K total memory
3914056 K used memory
2159780 K active memory
1034664 K inactive memory
4255976 K free memory
375984 K buffer memory
1807796 K swap cache
4193776 K total swap
0 K used swap
4193776 K free swap
138381 non-nice user cpu ticks
2408 nice user cpu ticks
58336 system cpu ticks
4126831 idle cpu ticks
31180 IO-wait cpu ticks
0 IRQ cpu ticks
248 softirq cpu ticks
0 stolen cpu ticks
2120046 pages paged in
708910 pages paged out
0 pages swapped in
0 pages swapped out
16047974 interrupts
11926843 CPU context switches
1410434075 boot time
31537 forks
Use la opción -d para obtener una tabla de estadísticas de disco:
$ vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
ram0 0 0 0 0 0 0 0 0 0 0
ram1 0 0 0 0 0 0 0 0 0 0
ram2 0 0 0 0 0 0 0 0 0 0
ram3 0 0 0 0 0 0 0 0 0 0
ram4 0 0 0 0 0 0 0 0 0 0
ram5 0 0 0 0 0 0 0 0 0 0
ram6 0 0 0 0 0 0 0 0 0 0
....
loop0 0 0 0 0 0 0 0 0 0 0
loop1 0 0 0 0 0 0 0 0 0 0
loop2 0 0 0 0 0 0 0 0 0 0
....
sda 98304 13295 4233052 1036054 50011 29441 1422172 915477 0 268
sr0 0 0 0 0 0 0 0 0 0 0
sdb 0 0 0 0 0 0 0 0 0 0
dm-0 14721 0 1175928 108578 50068 0 1126336 313843 0 159
dm-2 15561 0 124416 52057 5 0 24 1184 0 17
dm-3 182 0 1456 7756 0 0 0 0 0 7
dm-5
....
Campo | Subcampo | Significado |
---|---|---|
reads | total | Lecturas en total completadas de forma exitosa |
reads | merged | Lecturas agrupadas (resultando en una E/S) |
reads | ms | Milisegundos gastados en lecturas |
writes | total | Escrituras en total completadas de forma exitosa |
writes | merged | Escrituras agrupadas (resultando en una I/O) |
writes | ms | Milisegundos gastados en escrituras |
I/O | cur | E/S en progreso |
I/O | sec | segundos gastados en E/S |
Si solo desea obtener algunas estadísticas rápidas en una partición, use la opción -p:
$ vmstat -p /dev/sda1 2 4
sda1 reads read sectors writes requested writes
23913 1969794 11412 291672
23913 1969794 11417 291712
23913 1969794 11417 291712
23913 1969794 11419 291736
Como se mencionó anteriormente, en /proc/meminfo se puede encontrar un resumen relativamente largo de estadísticas de memoria:
$ cat /proc/meminfo
MemTotal: 8170032 kB
MemFree: 4506996 kB
MemAvailable: 6747268 kB
Buffers: 376744 kB
Cached: 1865956 kB
SwapCached: 0 kB
Active: 2155424 kB
Inactive: 1036312 kB
Active(anon): 951000 kB
Inactive(anon): 49300 kB
Active(file): 1204424 kB
Inactive(file): 987012 kB
Unevictable: 32 kB
Mlocked: 32 kB
SwapTotal: 4193776 kB
SwapFree: 4193776 kB
Dirty: 48 kB
Writeback: 0 kB
AnonPages: 949168 kB
Mapped: 397340 kB
Shmem: 51312 kB
Slab: 336148 kB
SReclaimable: 302240 kB
SUnreclaim: 33908 kB
KernelStack: 8352 kB
PageTables: 29752 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 8278792 kB
Committed_AS: 3790248 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 327116 kB
VmallocChunk: 34359398732 kB
AnonHugePages: 344064 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 1252800 kB
DirectMap2M: 7135232 kB
Vale la pena ir a través de la tabla siguiente y entender las entradas:
Entrada | Significado |
---|---|
MemTotal | RAM total disponible (memoria física menos la memoria reservada por el kernel) |
MemFree | Memoria libre tanto en zonas bajas como altas |
Buffers | Memoria usada para almacenamiento temporal de bloques de E/S |
Cached | Memoria de caché de páginas, principalmente para E/S de archivos |
SwapCached | Memoria que fue sacada del área de intercambio pero que todavía permanece en el archivo de intercambio |
Active | Memoria usada recientemente, no va a ser recuperada primero |
Inactive | Memoria que no ha sido usada recientemente, más elegible para ser recuperada |
Active(anon) | Memoria activa para páginas anónimas |
Inactive(anon) | Memoria inactiva para páginas anónimas |
Active(file) | Memoria activa para páginas de archivos respaldados |
Inactive(file) | Memoria inactiva para páginas de archivos respaldados |
Unevictable | Páginas que no pueden ser sacadas del área de intercambio ni liberadas |
Mlocked | Páginas que están bloqueadas en memoria |
SwapTotal | Espacio total de intercambio disponible |
SwapFree | Espacio de intercambio que no está en uso |
Dirty | Memoria que necesita ser escrita nuevamente al disco |
Writeback | Memoria que está siendo escrita activamente de nuevo a disco |
AnonPages | Páginas respaldadas (que no corresponden a archivos) en caché |
Mapped | Páginas mapeadas a memoria, tales como bibliotecas |
Shmem | Páginas usadas para memoria compartida |
Slab | Memoria usada en slabs |
SReclaimable | Memoria de caché en slabs que puede ser recuperada |
SUnreclaim | Memoria de caché en slabs que no puede ser recuperada |
KernelStack | Memoria usada en el stack del kernel |
PageTables | Memoria que está siendo usada por estructuras de tabla de página |
Bounce | Memoria usada para búfers de rebote de dispositivos de bloque |
WritebackTmp | Memoria usada por sistemas de archivos FUSE para búfers de reescritura |
CommitLimit | Memoria total disponible para ser usada, incluyendo overcommit |
Committed_AS | Memoria total asignada actualmente, tanto si está en uso o no |
VmallocTotal | Memoria total disponible en el kernel para asignaciones de vmalloc |
VmallocUsed | Memoria realmente usada por asignaciones vmalloc |
VmallocChunk | Mayor área contigua posible de vmalloc |
HugePages_Total | Tamaño total del pool de hugepages |
HugePages_Free | Hugepages que todavía no se asignan |
HugePages_Rsvd | Hugepages que han sido reservadas pero que aún no se usan |
HugePages_Surp | Hugepages que son un excedente, usadas para overcommit |
Hugepagesize | Tamaño de una hugepage |
Tenga en cuenta que las entradas exactas dependerán de la versión específica del kernel en ejecución.
La manera más simple de lidiar con presión de memoria sería permitir las asignaciones de memoria en tanto hay memoria disponible y luego denegarlas cuando la memoria se ha agotado.
La segunda forma más simple es usar un área de intercambio en disco para hacer espacio en memoria; en este caso la memoria disponible total (al menos en teoría) es la RAM más el tamaño del área de intercambio. La parte compleja de esto es determinar qué páginas de memoria van a ir al área de intercambio cuando el sistema esté bajo presión. Bajo este enfoque, una vez que el área de intercambio se se llena, las solicitudes para asignar memoria deben ser denegadas.
Sin embargo, Linux tiene una solución mejor; permite que el sistema realice un overcommit de memoria, de tal forma que puede conceder solicitudes de memoria que exceden el tamaño de la RAM más el área de intercambio. Si bien es cierto esto puede parecer temerario, muchos de los procesos (si no la mayoría) no usan toda la memoria solicitada.
Un ejemplo sería un programa que asigna un búfer de 1 MB y luego usa solo unas pocas páginas de memoria. Otro ejemplo es que cada vez que un proceso hijo es creado, recibe una copia completa del espacio de memoria del padre. Debido a que Linux usa la técnica COW (copy on write), a menos de que uno de los procesos modifique la memoria, no se necesita hacer ninguna copia real. Sin embargo el kernel tiene que asumir que sería necesario realizar esa copia.
Así, el kernel permite el overcommit de memoria, pero solo para páginas dedicadas a procesos de usuario; las páginas usadas en el kernel no van al área de intercambio y siempre se asignan al momento de ser solicitadas.
Es posible modificar e incluso desactivar el overcommit ajustando el valor de /proc/sys/vm/overcommit_memory:
- 0: (valor por defecto) Se permite el overcommit, pero se deniegan overcommits obvios. Se les asigna un poco más de memoria a los usuarios root que a los normales.
- 1: Todas las solicitudes de memoria pueden realizar un overcommit.
- 2: Deshabilita el overcommit. Las solicitudes de memoria serán denegadas cuando el total de memoria requerida alcance el tamaño del área de intercambio más un porcentaje configurable de la RAM (50 por defecto). Este factor puede modificarse en /proc/sys/vm/overcommit_ratio.
Si la memoria se agota, Linux invoca el OOM-killer (Out Of Memory) para decidir qué proceso(s) deben ser terminados para liberar memoria.
No hay una ciencia exacta para esto; el algoritmo debe ser heurístico y no puede satisfacer a todos. En las mentes de muchos desarrolladores, el propósito del OOM-killer es permitir un cierre exitoso, en vez de ser parte de las operaciones normales.
Andries Brouwer escribió algo divertido al respecto (http://lwn.net/Articles/104185/):
"Una compañía de aviones descubrió que era más barato volar sus aviones con menos combustible a bordo. Los aviones serían más livianos y usarían menos combustible, de tal forma que se ahorraría dinero. Sin embargo, en raras ocasiones la cantidad de combustible fue insuficiente y el avión se estrelló. El problema fue resuelto por los ingenieros de la compañía a través del desarrollo del mecanismo especial OOF (out-of-fuel). En casos de emergencia un pasajero era seleccionado y se expulsaba del avión (el proceso se repetía cuando era necesario). Se desarrolló una gran teoría al respecto y muchas publicaciones se dedicaron al problema de elegir adecuadamente la víctima a ser expulsada. ¿La víctima debería ser elegida al azar? ¿O se debería escoger a la persona con mayor peso? ¿O el más viejo? ¿Los pasajeros deberían pagar para no ser expulsados, de tal manera que la víctima sea el más pobre a bordo? Y si en caso de que se eligiera a la persona con mayor peso, ¿debería haber una excepción en caso de que fuera el piloto? ¿Los pasajeros de primera clase deberían estar eximidos? Ahora que el mecanismo OOF existe, podría activarse cada dos por tres y los pasajeros serían expulsados aún cuando no hubiera ninguna escasez de combustible. Los ingenieros todavía están estudiando cómo se produce precisamente este mal funcionamiento".
Para tomar decisiones acerca de quién es sacrificado para mantener vivo el sistema, se calcula un valor llamado maldad (el cual puede ser leerse desde /proc/[pid]/oom_score) para cada proceso en el sistema. El orden para matar los procesos se determina por este valor.
Dos entradas en el mismo directorio pueden usarse para aumentar o disminuir la probabilidad de exterminio. El valor de oom_adj es el número de bits en los cuales los puntos se ajustan. Los usuarios normales pueden incrementar el valor solamente; solo un superusuario puede disminuirlo (un valor negativo de oom_adj). El valor de oom_adj_score ajusta directamente el valor del punto. Tenga en cuenta que ajustar oom_adj es obsoleto actualmente.
¿Cuáles de las siguientes afirmaciones son ciertas?
- Deshabilitar todas las particiones de intercambio incrementa las posibilidades de que el sistema invoque el OOM-killer.
- La memoria usada para caché de archivos tiene más prioridad que la memoria que usan los procesos del sistema. El OOM-killer se invoca si hay memoria insuficiente tanto para caché de archivos y procesos de usuario.
- Lo que se mueve a la partición de intercambio nunca se mueve de nuevo a la memoria principal.
- El campo MemFree en /proc/meminfo muestra la cantidad de memoria que no está en uso, pero el caché de archivos también podría considerarse como memoria libre en la medida en la que el kernel libera esa memoria si las aplicaciones la requieren.
Actualmente usted debería ser capaz de:
- Listar las consideraciones primarias y tareas involucradas en la optimización de la memoria.
- Saber cómo usar las entradas en /proc/sys/vm e interpretar /proc/meminfo.
- Usar vmstat para desplegar información de memoria, paginación, E/S, actividad del procesador y el consumo de memoria de los procesos.
- Comprender cómo el OOM-killer decide cuándo tomar acción y seleccionar qué procesos deben ser finalizados para liberar memoria.
27. Sistemas de gestión de paquetes
Es necesario introducir orden en la forma en que el software se instala, actualiza y remueve en los sistemas Linux. Los sistemas de gestión de paquetes proveen una vía limpia de alcanzar esa meta y puede evitar que los sistemas caigan en un caos, que se vuelvan viejos o se rompan con el tiempo. Además, proveen un método para verificar que el software en el sistema no ha sido corrompido, ya sea maliciosamente o por accidente.
Una función esencial de los distribuidores de Linux es desarrollar, mantener los paquetes y asegurarse que las dependencias son mantenidas apropiadamente con el tiempo.
Al final de este capítulo usted debería ser capaz de:
- Explicar porqué se deberían usar los sistemas de gestión de paquetes.
- Comprender el rol tanto de los paquetes binarios como de las fuentes.
- Listar los principales sistemas de gestión de paquetes disponibles.
- Comprender porqué se necesitan dos niveles de herramientas; uno que se ocupa de los paquetes en sí y otro que se ocupa de las dependencias entre ellos.
- Explicar cómo el crear su propio paquete mejora el control que tiene sobre exactamente lo que sucede con el software y cómo está instalado.
- Comprender el rol de los sistemas de control de versiones, en particular de git.
Los sistemas de gestión de paquetes proveen las herramientas que les permiten a los administradores de sistemas automatizar la instalación, actualización, configuración y eliminación de paquetes de software, todo ello de una forma conocida, predecible y consistente. Estos sistemas:
- Reunir y comprimir archivos de software asociado en un solo paquete (archivo), lo cual puede requerir que uno o más paquetes se instalen primero.
- Permiten que la instalación y eliminación de software sea fácil.
- Puede verificar la integridad del archivo a través de una base de datos interna.
- Puede autenticar el origen de los paquetes.
- Facilita las actualizaciones.
- Agrupa los paquetes por características lógicas.
- Administra las dependencias entre paquetes.
Un paquete puede contener archivos ejecutables, archivos de datos, documentación, scripts de instalación y archivos de configuración. También se incluyen atributos de metadatos tales como número de versión, checksums, información del proveedor, dependencias, descripciones, etc.
Tras la instalación, toda la información se almacena localmente en una base de datos interna, la cual puede ser consultada de forma conveniente para obtener información del estado y la versión.
Los sistemas de gestión de paquetes de software son ampliamente vistos como uno de los avances más grandes que Linux trajo a los ambientes empresariales de IT. Al llevar un registro de archivos y metadatos de forma automatizada, predecible y confiable, los administradores de sistemas pueden usar los sistemas de gestión de paquetes para escalar el proceso de instalación a miles de sistemas sin requerir de trabajo manual en cada sistema por separado. Las características incluyen:
- Automatización: No se necesita realizar instalaciones ni actualizaciones manuales.
- Escalabilidad: Instalar paquetes en uno o en 10.000 sistemas.
- Repetibilidad y predictibilidad.
- Seguridad y auditoría.
Los paquetes vienen en diferentes tipos:
- Los paquetes binarios contienen archivos listos para ser implementados, incluyendo archivos ejecutables y bibliotecas. Estos son dependientes de la arquitectura y deben ser compilados para cada tipo de máquina.
- Los paquetes de código fuente se usan para generar paquetes binarios; uno siempre debería tener la posibilidad de reconstruir un paquete binario (por ejemplo, usando rpmbuild --rebuild en sistemas basados en RPM) desde el código fuente. Un paquete de código fuente puede ser usado en múltiples arquitecturas.
- Los paquetes independientes de la arquitectura contienen archivos y scripts que se ejecutan bajo intérpretes de script, como también documentación y archivos de configuración.
- Los metapaquetes son esencialmente grupos de paquetes asociados que recopilan todo lo necesario para instalar un subsistema relativamente grande, tal como un ambiente de escritorio, o una suite de oficina, etc.
Los administradores de sistema tienen que lidiar la mayoría del tiempo con los paquetes binarios.
En sistemas de 64 bits que pueden ejecutar programas de 32 bits, es posible tener dos paquetes binarios instalados para un programa dado; tal vez uno con x86_64 o amd64 en el nombre y otro con i386 o i686.
Los paquetes de código fuente pueden ser útiles para mantener el seguimiento de los cambios y el código usado que viene en los paquetes binarios. Generalmente no están instalados por defecto en un sistema pero siempre pueden ser obtenidos desde el proveedor de la distribución.
Hay dos tipos muy comunes de sistemas de gestión de paquetes:
- RPM (Red Hat Package Manager)
Este sistema es usado por todas las distribuciones derivadas de Red Hat, tales como Red Hat Enterprise Linux, CentOS, Scientific Linux y CentOS. También por SUSE y la comunidad relacionada a la distribución openSUSE. - dpkg (Debian Package)
Este sistema es usado por Debian y todas las distribuciones derivadas, incluyendo Ubuntu y Linux Mint.
Hay otros sistemas de gestión de paquetes: portage/emerge, usados por Gentoo, pacman, usado por Arch y los especializados, los cuales son utilizados por sistemas de Linux embebido y Android.
Un sistema antiguo es simplemente proveer los paquetes como archivos tar comprimidos, sin ninguna gestión real o estrategia de eliminación limpia del paquete; este enfoque es usada todavía por Slackware, una de las distribuciones más antiguas de Linux.
Pero la mayoría de las veces se usa RPM o dpkg, por lo cual esas serán los únicos sistemas que consideraremos en este curso.
Hay dos niveles de sistemas de empaquetamiento:
- Herramienta de bajo nivel: esto simplemente instala o elimina un paquete único o una lista de paquetes en donde cada uno tiene su nombre de forma individual y específica. Las dependencias no están completamente gestionadas, solo se generan advertencias acerca de:
- Si otro paquete necesita ser instalado primero, la instalación fallará.
- Si el paquete es una dependencia de otro, su eliminación fallará. - Las herramientas rpm y dpkg realizan este rol en los sistemas de empaquetamiento que los usan.
- Herramienta de alto nivel. Esta resuelve los problemas de dependencias:
- Si otro paquete o grupo de paquetes necesita ser instalado antes de que el software pueda serlo, tales necesidades serán satisfechas.
- Si la eliminación de un paquete interfiere con otro que ya está instalado, el administrador podrá elegir si abortar la operación o remover todo el software afectado.
Las herramientas yum y zypper (y más recientemente PackageKit) se hacen cargo de la resolución de dependencias para sistemas con rpm. Por otro lado, apt-get, apt-cache y otras herramientas se hacen cargo en sistemas con dpkg.
En este curso discutiremos solamente las interfaces de línea de comandos a los sistemas de gestión de paquetes. Si bien es cierto que las interfaces gráficas usadas por cada distribución Linux pueden ser útiles, nos gustaría estar menos atado a solo una de ellas y también tener más flexibilidad.
Cada distribución tiene uno o más repositorios de paquetes desde donde las herramientas del sistema obtienen software y las actualizaciones de versiones nuevas. Es trabajo de la distribución asegurarse que todos los paquetes en los repositorios interactúan bien unos con otros.
Hay otros repositorios, externos, que pueden agregarse a la lista estándar que soporta la distribución. A veces están estrechamente asociadas a la distribución y raramente generan problemas importantes; un ejemplo puede ser EPEL (Extra Packages for Enterprise Linux), un conjunto de repositorios dependientes de la versión de la distribución, los cuales encajan bien con RHEL ya que su fuente Fedora y los mantenedores de ésta son cercanos a Red Hat.
Sin embargo, algunos repositorios externos no están muy bien construidos o mantenidos. Por ejemplo, cuando un paquete se actualiza en el repositorio principal, las dependencias podrían no estar actualizadas en el repositorio externo, el cual podría conducir a una dependencia infernal de paquetes.
Construir paquetes de software personalizado facilita distribuir e instalar su propio software. Casi todas las versiones de Linux tienen algún mecanismo para realizarlo.
Construir su propio paquete le permite controlar exactamente qué va en el software y cómo se instala. Puede crear el paquete de tal forma que cuando se instale, ejecute scripts para realizar todas las tareas necesarias a fin de instalar el nuevo software y/o eliminar el antiguo. Tales tareas incluyen:
- Creación de los enlaces simbólicos necesarios.
- Creación de directorios según sea necesario.
- Configuración de permisos.
- Cualquier cosa que pueda incluirse en un script y que cumpla una tarea específica.
No vamos a discutir los mecanismos acerca de cómo construir paquetes .rpm o .deb, ya que ese es un asunto que atañe más a desarrolladores de software que a administradores.
Los proyectos de software se vuelven más complejos de gestionar a medida en la que el proyecto se desarrolla y crece, también cuando el número de desarrolladores que trabajan en él aumenta.
Hay muchos sistemas disponibles de control de versiones para organizar las actualizaciones y facilitar la colaboración. Algunas de las características estándar de estos programas incluyen la habilidad para mantener una historia exacta (registro) de los cambios, ser capaz de volver a versiones anteriores, coordinar posibles conflictos de actualización desde más de un desarrollador, etc.
No hay escasez de productos disponibles, tanto propietarios como libres; una pequeña lista de productos bajo una licencia GPL incluye:
Producto | URL |
---|---|
RCS | http://www.gnu.org/software/rcs |
CVS | http://ximbiot.com/cvs/wiki |
Subversion | http://subversion.tigris.org |
git | http://www.kernel.org/pub/software/scm/git |
GNU Arch | http://www.gnu.org/software/gnu-arch |
Monotone | http://www.monotone.ca |
Mercurial | http://mercurial.selenic.com |
PRCS | http://prcs.sourceforge.net |
Pondremos el foco en git solamente, un producto ampliamente que se originó en la comunidad de desarrollo del kernel Linux. Git ha conseguido una posición dominante en el uso de proyectos open source en un tiempo notablemente corto, e incluso a menudo se usa en ambientes de desarrollo cerrado.
El sistema de desarrollo del kernel Linux tiene necesidades especiales debido a que se realiza de forma distribuida a través del mundo, con literalmente miles de desarrolladores involucrados. Además, todo el trabajo se hace de forma pública y bajo la licencia GPL.
Por largo tiempo no existió un sistema de control de versiones real. Entonces los principales desarrolladores del kernel se pasaron al uso de BitKeeper (ver http://www.bitkeeper.com), un proyecto comercial que cedió una licencia de uso restringido para el desarrollo del kernel Linux.
Sin embargo, en una discusión pública acerca de las restricciones de la licencia en la primavera del 2005, el uso libre de BitKeeper fue revocado para el desarrollo del kernel Linux.
La respuesta fue el desarrollo de git, cuyo autor original es Linus Torvalds. El código fuente de git puede obtenerse desde http://www.kernel.org/pub/software/scm/git/ y la documentación completa en http://www.kernel.org/pub/software/scm/git/docs.
Técnicamente git no es un sistema de control de versiones en el sentido usual, y las unidades básicas con las cuales trabaja no son archivos. Cuenta con dos estructuras de datos importantes: una base de datos de objetos y un caché de directorios.
La base de datos de objetos contiene objetos de tres tipos:
- Blobs: Trozos de datos binarios que tienen el contenido del archivo.
- Trees: Conjuntos de blobs que incluyen nombres de archivos y atributos, proveyendo la estructura de los directorios.
- Commits: Cambios que describen las instantáneas de los árboles.
El caché de directorio captura el estado del árbol de directorios.
Al liberar el mecanismo de control de un sistema basado en archivos, se está mejor preparado para gestionar conjuntos de cambios, los que implican muchos archivos.
Git está continuamente bajo un desarrollo rápido y hay interfaces gráficas que también tienen un ritmo similar. Por ejemplo, vea http://www.kernel.org/git/. Ahí es posible navegar fácilmente por los cambios específicos, como también por los árboles de código fuente.
Sitios tales como http://www.github.com alojan literalmente millones de repositorios git, tanto públicos como privados. Hay una gran cantidad de artículos, libros, tutoriales en línea, etc. que se pueden encontrar fácilmente en cuanto a cómo sacarle provecho a git.
1. Red Hat Enterprise Linux, SUSE, CentOS y Fedora usan el sistema de paquetes _______________.
2. Debian, Ubuntu y Mint usan el sistema de paquetes ______________.
Actualmente usted debería ser capaz de:
- Explicar porqué se deberían usar los sistemas de gestión de paquetes.
- Comprender el rol tanto de los paquetes binarios como de las fuentes.
- Listar los principales sistemas de gestión de paquetes disponibles.
- Comprender porqué se necesitan dos niveles de herramientas; uno que se ocupa de los paquetes en sí y otro que se ocupa de las dependencias entre ellos.
- Explicar cómo el crear su propio paquete mejora el control que tiene sobre exactamente lo que sucede con el software y cómo está instalado.
- Comprender el rol de los sistemas de control de versiones, en particular de git.
28. RPM
El Red Hat Package Manager (RPM) es usado por una serie de las distribuciones principales (y sus derivadas) para controlar la instalación, verificación, actualización y eliminación de software en sistemas Linux. El programa de bajo nivel rpm puede realizar todas esas operaciones, ya sea en un solo paquete o en una lista de ellos. Las operaciones que podrían causar problemas no se pueden completar con rpm, tales como remover un paquete del cual depende otro, o instalar un paquete sin haber satisfecho las dependencias primero.
Al final de este capítulo usted debería ser capaz de:
- Comprender cómo está organizado el sistema RPM y conocer las operaciones más importantes que el programa rpm puede realizar.
- Explicar las convenciones de nombre usadas tanto para los archivos rpm binarios y de código fuente.
- Saber cómo consultar, verificar, instalar, desinstalar y actualizar paquetes.
- Comprender porqué los kernels nuevos deberían ser instalados en vez de actualizados.
- Saber cómo usar rpm2cpio para copiar archivos empaquetados en un archivo cpio, como también extraer los archivos sin instalarlos.
RPM (Redhat Package Manager) fue desarrollado por Red Hat (como era de esperar). Todos los archivos relacionados a una tarea específica están empaquetados en un archivo rpm único, el cual también contiene información acerca de cómo y donde instalar/desinstalar los archivos. Las versiones nuevas de software conducen a archivos rpm nuevos, los que se usan para la actualización.
Los archivos rpm también contienen información acerca de las dependencias. Tenga en cuenta que a menos que se especifique una URL para obtener los paquetes, rpm no irá a buscar los paquetes a internet, sino que más bien los instalará desde la máquina local solamente, usando rutas absolutas o relativas para tal efecto.
Los archivos rpm generalmente dependen de la distribución; de hecho instalar un paquete en una distribución diferente para la cual fue creado podría ser difícil o imposible.
RPM le facilita las siguientes tareas a los administradores de sistemas:
- Determinar a qué paquete pertenece un archivo en el sistema (si es el caso).
- Determinar qué versión está instalada.
- Instalar y desinstalar paquetes sin dejar residuos o cabos sueltos.
- Verificar que un paquete se instaló correctamente; esto es útil tanto para solucionar problemas como para la auditoría del sistema.
- Distinguir los archivos de documentación del resto de los archivos del paquete, y opcionalmente decidir no instalarlos para ahorrar espacio en disco.
- Usar ftp o HTTP para instalar paquetes desde internet.
RPM ofrece ventajas para los desarrolladores también:
- El software a menudo está disponible en más de un sistema operativo. Con RPM, la fuente original (sin modificar) se usa como base, pero un desarrollador puede incluir información para construirlo (compilarlo) en Linux.
- Usando un solo paquete de código fuente es posible construir un paquete binario para más de una arquitectura.
Los nombres de los paquetes RPM están basados en campos que representan información específica, tal como se documenta en el estándar RPM (http://www.rpm.org/).
- El formato de nombre estandarizado para un paquete binario es:
<name>-<version>-<release>.<distro>.<architecture>.rpm
sed-4.2.1-10.el6.x86_64.rpm - El formato de nombre estandarizado para un paquete de código fuente es:
<name>-<version>-<release>.<distro>.src.rpm
sed-4.2.1-10.el6.src.rpm
Tenga en cuenta que el campo distro a menudo especifica el repositorio del cual proviene el paquete, dado a que una instalación puede usar varios repositorios de paquetes como discutiremos en la sección de yum y zypper, herramientas que trabajan sobre RPM.
/var/lib/rpm es el directorio por defecto en el sistema, el cual contiene los archivos de la base de datos RPM en la forma de archivos hash de Berkeley DB. Los archivos de la base de datos no deberían ser modificados manualmente; las actualizaciones deberían realizarse solamente a través del programa rpm.
Es posible especificar un directorio alternativo para la base de datos con la opción --dbpath en el programa rpm. Por ejemplo, esto podría ser útil para examinar una base de datos RPM copiada desde otro sistema.
Usted puede usar la opción --rebuilddb para reconstruir los índices de la base de datos desde los headers de los paquetes instalados; esto es más bien una reparación y no una reconstrucción desde cero.
Los programas auxiliares y scripts usados por RPM residen en /usr/lib/rpm. Hay un buen número; por ejemplo, en un sistema RHEL 7:
$ ls /usr/lib/rpm | wc -l
69
donde wc reporta el número de líneas de la salida.
Es posible crear un archivo rpmrc para especificar los ajustes por defecto para rpm. Por defecto, rpm revisa los siguientes archivos, en el orden tal como se muestra a continuación:
- /usr/lib/rpm/rpmrc
- /etc/rpmrc
- ~/.rpmrc
Tenga en cuenta que se leen todos esos archivo; rpm no se detiene tan pronto encuentra uno de esos archivos. Puede especificarse un archivo rpmrc alternativo con la opción --rcfile.
Todas las consultas rpm incluyen la opción -q, la cual puede ser combinada con diversas subopciones, como las que siguen:
- ¿Qué versión de un paquete está instalada?
$ rpm -q bash - ¿De qué paquete proviene este archivo?
$ rpm -qf /bin/bash - ¿Qué archivos instaló este paquete?
$ rpm -ql bash - Muestra información acerca del paquete
$ rpm -qi bash - Muestra información acerca del paquete desde el archivo del paquete en sí, no desde la base de datos.
$ rpm -qip foo-1.0.0.1.noarch.rpm - Lista todos los paquetes instalados en el sistema
$ rpm -qa
Un par de opciones útiles son --requires y --whatprovides.
- Entrega una lista de los prerrequisitos de un paquete:
$ rpm -qp --requires foo-1.0.0-1.noarch.rpm - Muestra qué paquete instalado provee un archivo de requisito en particular:
$ rpm -q --whatprovides libc.so.6
La opción -V de rpm permite verificar si los archivos de un paquete en particular son consistentes con la base de datos de RPM del sistema. Para verificar todos los paquetes instalados en el sistema:
$ rpm -Va
missing /var/run/pluto
....
S.5....T. c /etc/hba.conf
S.5....T. /usr/share/applications/defaults.list
....L.... c /etc/pam.d/fingerprint-auth
....L.... c /etc/pam.d/password-auth
....
.M....... /var/lib/nfs/rpc_pipefs
....
.....UG.. /usr/local/bin
.....UG.. /usr/local/etc
donde la salida anterior muestra solo unos pocos ítems. Tenga en cuenta que este comando podría tomar bastante tiempo ya que examina todos los archivos asociados a cada paquete.
Se genera una salida cuando hay un problema solamente.
Cada uno de los caracteres desplegados arriba denota el resultado de una comparación de atributo(s) del archivo con valor de los atributo(s) almacenados en la base de datos. Un "." único (punto) significa que pasó la prueba, mientras que un "?" único (signo de interrogación al final) indica que la prueba no se pudo realizar (porque por ejemplo los permisos del archivo no permiten la lectura). De otra forma, el caracter denota una falla de la prueba en la verificación correspondiente:
- S: el tamaño de archivo difiere
- M: los permisos del archivo y/o tipo difieren
- 5: el checksum MD5 difiere
- D: discrepancia entre los números mayor/menor
- L: discrepancia de ruta de enlace simbólico
- U: el usuario propietario difiere
- G: el grupo propietario difiere
- T: el tiempo de modificación difiere
- P: las capacidades difieren
Tenga en cuenta que muchos de estas pruebas de verificación no indican un problema. Por ejemplo, muchos archivos de configuración se modifican a medida en que el sistema evoluciona.
Se examinan los nombres de paquete que son pasados como argumento, como en los ejemplos que siguen a continuación:
- No hay salida cuando todo está bien:
$ rpm -V bash - La salida indica que el tamaño de archivo, checksum y tiempo de modificación han cambiado:
$ rpm -V talk
S.5....T in.ntalkd.8 - La salida indica que falta un archivo:
$ rpm -V talk
missing /usr/bin/talk
Instalar un paquete es tan simple como:
$ sudo rpm -ivh foo-1.0.0-1.noarch.rpm
en donde -i es para instalar, -v para tener una salida detallada y -h imprime marcas de control para mostrar el progreso de la tarea.
RPM realiza varias tareas cuando se instala un paquete:
- Verifica las dependencias:
Es necesario debido a que algunos paquetes no funcionarán correctamente a menos que uno o más paquetes estén instalados también. - Realiza comprobaciones de conflictos:
Incluye intentos de instalar un paquete ya instalado o instalar una versión antigua sobre una más reciente. - Ejecuta comandos requeridos antes de la instalación:
El desarrollador que construye un paquete puede especificar ciertas tareas que deben llevarse a cabo antes o después de la instalación. - Lidia inteligentemente con los archivos de configuración:
Cuando se instala un archivo de configuración, si el archivo existe y ha sido modificado desde que se instaló la previa del paquete, RPM guarda la versión antigua con el sufijo .rpmsave. Esto permite integrar los cambios realizados anteriormente en el archivo de configuración antiguo en la versión nueva del archivo. Esta característica depende de que los paquetes RPM hayan sido creados correctamente. - Desempaqueta los archivos desde los paquetes y los instala con los atributos adecuados:
Además de instalar archivos en el lugar correcto, RPM también configura atributos tales como permisos, dueños y hora de modificación. - Ejecuta comandos necesarios después de la instalación:
Realiza cualquier tarea de configuración o inicialización necesaria posterior a la instalación. - Actualiza la base de datos RPM:
Cada vez que RPM instala un paquete se actualiza información en la base de datos. RPM usa esta información cuando verifica conflictos.
La opción -e instruye a rpm que desinstale (borre) un paquete. Normalmente, rpm -e despliega un error cuando falla, como cuando el paquete que se está tratando de desinstalar no está realmente instalado, o si es requerido por otros paquetes en el sistema. Una desinstalación exitosa no produce salida.
$ sudo rpm -e system-config-lvm
package system-config-lvm is not installed
Error debido a dependencias:
$ sudo rpm -e xz
error: Failed dependencies:
xz is needed by (installed) dracut-033-161.el7.x86_64
xz is needed by (installed) sos-3.0-23.el7.noarch
xz is needed by (installed) libvirt-daemon-driver-qemu-1.1.1-29.el7_0.1.x86_64
xz is needed by (installed) rpm-build-4.11.1-16.el7.x86_64
/usr/bin/xz is needed by (installed) kmod-14-9.el7.x86_64
Puede usar la opción --test junto a -e para determinar si la desinstalación tendrá éxito o fallará, sin llegar a realizarla. Si todo indica que la operación va a ser exitosa, rpm no imprime ninguna salida. Agregue la opción -vv para obtener más información.
Tenga en cuenta que el argumento que acompaña al comando que realiza la desinstalación es el nombre del paquete, no el nombre del archivo rpm.
Nota importante (aunque obvia): nunca remueva (borre/desinstale) el paquete rpm en sí. La única forma de resolver este problema es reinstalar el sistema operativo o bootear en un ambiente de rescate.
Una actualización reemplaza el paquete original (si es que está instalado), como se muestra aquí:
$ sudo rpm -Uvh bash-4.2.45-5.el7_0.4.x86_64.rpm
Es posible proveer una lista de paquetes en vez de uno solo.
Al realizar una actualización, el paquete instalado con anterioridad se desinstala luego de que la versión nueva se instala. La única excepción es el archivo de configuración de la instalación original, la cual se mantiene con una extensión .rpmsave.
Si usa la opción -U y el paquete no ha sido instalado anteriormente, simplemente se instalará.
La opción -i no está diseñado para actualizar; si se intenta instalar un paquete RPM nuevo sobre uno más antiguo, fallará y dará un mensaje de error, ya que intenta sobreescribir archivos existentes del sistema.
Sin embargo, diferentes versiones del mismo paquete pueden estar instaladas si cada versión del paquete no contiene los mismos archivos: los paquetes del kernel y de las bibliotecas de otras arquitecturas son generalmente los únicos que pueden estar instalados múltiples veces.
Si desea reemplazar la versión actual de un paquete por una anterior (downgrade) con rpm -U, debe agregar la opción --oldpackage a la línea de comandos.
El siguiente comando:
$ sudo rpm -Fvh *.rpm
intentará refrescar todos los paquetes en el directorio actual. La forma en la cual funciona es la siguiente:
- Si una versión anterior del paquete está instalada, esta será actualizada a la más nueva que está en el directorio.
- Si la versión en el sistema es la misma que está disponible en el directorio, no se hace nada.
- Si no se encuentra ninguna versión instalada del paquete, no se realiza la instalación del mismo.
El refrescar paquetes puede ser útil para aplicar un montón de partes de una vez (para actualizar paquetes, por ejemplo).
Cuando se instala un kernel nuevo en el sistema, se requiere un reinicio para que tome efecto (una de las pocas actualizaciones que lo requieren). No se debería hacer una actualización (-U) de un kernel: una actualización desinstalaría el kernel que está actualmente en ejecución.
Esto en sí mismo no va a deterner el sistema, pero si después de reiniciar el sistema usted tiene cualquier problema, no tendrá la oportunidad de reiniciar con el kernel antiguo, ya que fue desinstalado del sistema. Sin embargo, si usted lo instala (-i), ambos kernels van a coexistir y podrá elegir si arrancar con uno u otro; es decir, puede volver al antiguo si lo necesita.
Para instalar un kernel nuevo haga lo siguiente:
$ sudo rpm -ivh kernel-{version}.{arch}.rpm
reemplace los nombres correctos para la versión y la arquitectura.
Al hacer lo anterior, el archivo de configuración de GRUB será actualizado automáticamente para incluir la versión nueva; este será la opción de arranque por defecto, a menos que reconfigure el sistema para que haga otra cosa.
Una vez que la versión nueva del kernel ha sido probada, usted puede desinstalar la versión antigua si lo desea, aunque no es necesario. A menos que tenga poco espacio en disco, es recomendable que mantenga una o más versiones anteriores del kernel.
Supongamos que necesita extraer archivos desde un rpm pero no desea instalar el paquete.
El programa rpm2cpio puede usarse para copiar archivos desde un rpm a un archivo cpio, como también extraer los archivos si se desea.
Cree el archivo cpio con el siguiente comando:
$ rpm2cpio foobar.rpm > foobar.cpio
Para listar los archivos en un rpm:
$ rpm2cpio foobar.rpm | cpio -t
pero una forma mejor de hacerlo es ésta:
$ rpm -qilp foobar.rpm
Para extraerlo en el sistema:
$ rpm2cpio bash-4.2.45-5.el7_0.4.x86_64.rpm | cpio -ivd bin/bash
$ rpm2cpio foobar.rpm | cpio --extract --make-directories
¿Cuál de las siguientes afirmaciones es la correcta?
yum es la herramienta de bajo nivel que interactúa principalmente con paquetes locales.
rpm es la herramienta de alto nivel que está al tanto de todos los paquetes disponibles, incluyendo los que están disponibles en servidores remotos.
rpm -qa lista todos los paquetes instalados en el sistema.
Usted está inseguro de si el binario /bin/ls ha sido modificado para contener software malicioso. ¿Qué comando rpm usaría para verificar la integridad de /bin/ls?
Nota: /bin/ls es suministrado por el paquete coreutils.
rpm _____________________ coreutils
Actualmente usted debería ser capaz de:
- Comprender cómo está organizado el sistema RPM y conocer las operaciones más importantes que el programa rpm puede realizar.
- Explicar las convenciones de nombre usadas tanto para los archivos rpm binarios y de código fuente.
- Saber cómo consultar, verificar, instalar, desinstalar y actualizar paquetes.
- Comprender porqué los kernels nuevos deberían ser instalados en vez de actualizados.
- Saber cómo usar rpm2cpio para copiar archivos empaquetados en un archivo cpio, como también extraer los archivos sin instalarlos.
29. DPKG
El Debian Package Manager (DPKG) es usado por todas las distribuciones basadas en Debian para controlar la instalación, verificación, actualización y desinstalación de software en sistemas Linux. El programa de bajo nivel dpkg puede realizar todas esas operaciones, ya sea en un solo paquete o en una lista de ellos. Las operaciones que podrían causar problemas (como remover un paquete del cual depende otro, o instalar un paquete sin haber satisfecho las dependencias primero) no se completan.
Al final de este capítulo usted debería ser capaz de:
- Discutir el sistema de empaquetamiento DPKG y sus usos.
- Explicar la convención de nombres usadas tanto para archivos deb binarios y de código fuente.
- Saber cómo lucen los paquetes de código fuente.
- Usar operaciones de consulta y verificación sobre los paquetes.
- Instalar, actualizar y desinstalar paquetes Debian.
DPKG (Debian Package) es el sistema de empaquetamiento usado para instalar, desinstalar y gestionar paquetes de software en Debian y otras distribuciones Linux derivadas de ella. De la misma forma que RPM, no está diseñada para obtener e instalar paquetes directamente en el uso diario, pero sí para instalarlos y desinstalarlos localmente.
Los archivos de paquete tienen un sufijo .deb y la base de datos de DPKG reside en el directorio /var/lib/dpkg.
Tal como rpm, el programa dpkg tiene una vista parcial del universo: solamente sabe qué está instalado en el sistema y cualquier cosa que se provee a través de la línea de comandos. Pero no sabe nada de los otros paquetes disponibles, si están en otro directorio en el sistema o en internet. Como tal, fracasará también si una dependencia no se cumple, o si alguien trata de desinstalar un paquete que otros que están instalados necesitan.
Los nombres de archivo de los paquetes de Debian están basados en campos que representan información específica. El formato estándar de nombres para un paquete binario es el siguiente:
<name>_<version>-<revision_number>_<architecture>.deb
como en Debian:
logrotate_3.8.7-1_amd64.deb
y en Ubuntu:
logrotate_3.8.7-1ubuntu1_amd64.deb
Tenga en cuenta que por razones históricas la arquitectura x86 de 64 bits se llama amd64 en vez de x86_64. Los sistemas tales como Ubuntu insertan el nombre de la distribución en el nombre del paquete.
En el sistema de empaquetamiento de Debian un paquete de código fuente consiste en 3 archivos:
- Un archivo upstream comprimido con tar, terminado en .tar.gz. Esto consiste en las fuentes originales tal como son proporcionadas por los mantenedores del paquete.
- Un archivo de descripción, terminado en .dsc, el cual contiene el nombre del paquete y otros metadatos, tales como la arquitectura y dependencias.
- Un segundo archivo tar que contiene los parches a la fuente de upstream, y también archivos adicionales creados para el paquete, los cuales terminan en .debian.tar.gz o .diff.gz, dependiendo de la distribución.
Por ejemplo, en un sistema Ubuntu es posible descargar un paquete fuente como se muestra a continuación:
$ apt-get source logrotate
y luego es posible ver qué archivos fueron descargados o creados:
$ ls -lR logrotate*
-rw-r--r-- 1 root root 23842 Jan 22 2014 logrotate_3.8.7-1ubuntu1.debian.tar.gz
-rw-r--r-- 1 root root 1936 Jan 22 2014 logrotate_3.8.7-1ubuntu1.dsc
-rw-r--r-- 1 root root 58898 Jan 22 2014 logrotate_3.8.7.orig.tar.gz
logrotate-3.8.7:
total 228
-rw-r--r-- 1 root root 890 Aug 1 2012 basenames.c
-rw-r--r-- 1 root root 219 Aug 1 2012 basenames.h
....
Aquí hay algunos ejemplos de consultas que se pueden realizar:
- Listar todos los paquetes instalados:
$ dpkg -l
También es posible especificar un nombre de paquete. - Listar los archivos instalados con el paquete wget:
$ dpkg -L wget - Mostrar información acerca de un paquete instalado:
$ dpkg -p wget - Mostrar información acerca de un archivo de paquete:
$ dpkg -I webfs_1.21+ds1-8_amd64.deb - Listar los archivos contenidos en un archivo de paquete:
$ dpkg -c webfs_1.21+ds1-8_amd64.deb - Mostrar a qué paquete pertenece /etc/init/networking.conf:
$ dpkg -S /etc/init/networking.conf - Mostrar el estado de un paquete:
$ dpkg -s wget - Verificar la integridad de un paquete instalado:
$ dpkg -V package
Sin argumentos, el comando verificará todos los paquetes en el sistema. Revise la página man para interpretar la salida. Nota: solo versiones recientes de dpkg (1.17+) soportan esta opción.
El comando:
$ sudo dpkg -i foobar.deb
puede usarse ya sea para instalar o actualizar el paquete foobar.
Si el paquete no está instalado actualmente, entonces se instalará. Si el paquete es más nuevo que el instalado actualmente, entonces se actualizará.
El comando:
$ sudo dpkg -r package
se usa para desinstalar por completo un paquete instalado, con excepción de los archivos de configuración.
El comando:
$ sudo dpkg -P package
se usa para desinstalar por completo un paquete instalado, incluyendo los archivos de configuración. Nota: -P significa limpiar.
¿Cuál de las siguientes afirmaciones es la correcta?
apt-get es la herramienta de bajo nivel la que principalmente interactúa con paquetes locales.
dpkg es la herramienta de alto nivel que está al tanto de todos los paquetes disponibles, incluyendo aquellos en servidores remotos.
dpkg -l lista todos los paquetes instalados en el sistema.
Actualmente usted debería ser capaz de:
- Discutir el sistema de empaquetamiento DPKG y sus usos.
- Explicar la convención de nombres usadas tanto para archivos deb binarios y de código fuente.
- Saber cómo lucen los paquetes de código fuente.
- Usar operaciones de consulta y verificación sobre los paquetes.
- Instalar, actualizar y desinstalar paquetes Debian.
30. yum
El programa yum provee un nivel de servicios inteligentes mayor para usar el programa subyacente rpm. Puede resolver dependencias automáticamente al instalar, actualizar y desinstalar paquetes. Accede repositorios de software externos, sincronizándose con ellos, obteniendo e instalando software a medida en que se necesita.
Al final de este capítulo usted debería ser capaz de:
- Discutir los instaladores de paquetes y sus características.
- Explicar qué es yum.
- Configurar yum para usar repositorios.
- Conocer las consultas que pueden realizarse con yum.
- Usar yum para verificar, instalar, desinstalar y actualizar paquetes.
Las herramientas de bajo nivel tales como rpm y dpkg lidian con los detalles de instalar archivos de paquetes de software específico y gestionan el software que ya está instalado.
Los sistemas de gestión de paquetes de alto nivel (tales como yum, apt y zypper) trabajan con bases de datos de software disponible e incorporan las herramientas necesarias para encontrar, instalar, actualizar y desinstalar software de una forma inteligente. Realizan lo siguiente:
- Pueden usar repositorios tanto locales como remotos. También paquetes de código fuente para instalar y actualizar paquetes binarios y de código fuente.
- Son usados para automatizar la instalación, actualización y desinstalación de paquetes de software.
- Resolver dependencias automáticamente.
- Ahorran tiempo porque no hay necesidad tanto de descargar los paquetes manualmente o de buscar información acerca de las dependencias.
Los repositorios de software son proporcionados por distribuciones y otros proveedores independientes de software. Los instaladores de paquetes mantienen bases de datos del software disponible, provenientes de catálogos almacenados en los repositorios. A diferencia de las herramientas de paquetes de bajo nivel, tienen la habilidad de encontrar e instalar dependencias automáticamente, lo cual es una característica fundamental.
En esta sección hablaremos acerca de yum; abordaremos zypper y apt en capítulos siguientes.
yum provee una interfaz a rpm. Su tarea principal es obtener paquetes desde múltiples repositorios remotos y resolver dependencias entre paquetes. Es usado por la mayoría de las distribuciones que usan rpm (aunque no todas), incluyendo RHEL, CentOS, Scientific Linux y Fedora.
yum almacena en caché información y la base de datos para incrementar el rendimiento. Para eliminar alguna o toda la información en caché, ejecute el siguiente comando:
$ yum clean [ packages | metadata | expire-cache | rpmdb | plugins | all ]
yum tiene una serie de extensiones modulares (plugins) y programas complementarios que pueden encontrarse en /usr/bin/yum* y /usr/sbin/yum*.
Nos concentraremos en el uso de yum en la línea de comandos y no consideraremos las interfaces gráficas que las distribuciones proveen.
Los archivos de configuración de los repositorios se encuentran en /etc/yum.repos.d/ y tienen una extensión .repo. Por ejemplo, en un sistema RHEL 6:
$ ls -l /etc/yum.repos.d
total 40
-rw-r--r-- 1 root root 957 Nov 4 2012 epel.repo
-rw-r--r-- 1 root root 1056 Nov 4 2012 epel-testing.repo
-rw-r--r-- 1 root root 188 May 28 2013 google-chrome.repo
-rw-r--r-- 1 root root 113 Dec 11 2011 google-earth.repo
-rw-r--r-- 1 root root 128 Dec 23 2013 google-talkplugin.repo
-rw-r--r-- 1 root root 477 Jan 29 2012 nux-dextop.repo
-rw-r--r-- 1 root root 529 Oct 30 2013 rhel-source.repo
-rw-r--r-- 1 root root 1113 Jan 4 2011 rpmforge.repo
-rw-r--r-- 1 root root 256 May 22 07:00 virtualbox.repo
Tenga en cuenta que en RHEL 6 no hay un archivo redhat.repo, pero está presente en RHEL 7:
total 112
drwxr-xr-x. 2 root root 4096 Sep 24 13:44 ./
drwxr-xr-x. 151 root root 12288 Oct 2 12:52 ../
-rw-r--r-- 1 root root 957 Sep 2 11:14 epel.repo
-rw-r--r-- 1 root root 1056 Sep 2 11:14 epel-testing.repo
-rw-r--r-- 1 root root 116 Sep 3 11:40 google-chrome.repo
-rw-r--r-- 1 root root 477 Jul 31 02:50 nux-dextop.repo
-rw-r--r-- 1 root root 37763 Sep 24 13:44 redhat.repo
RHEL 6 y las versiones anteriores manejaban los repositorios suministrados por la distribución de una forma diferente, aunque los clones de RHEL tales como CentOS usaron repositorios convencionales para los paquetes principales de la distribución.
Un archivo muy simple de repositorio podría lucir como el siguiente:
[repo-name]
name=Description of the repository
baseurl=http://somesystem.com/path/to/repo
enabled=1
gpgcheck=1
Algunos ejemplos más complejos pueden encontrarse en /etc/yum.repos.d y le recomendamos que los examine.
Es posible habilitar o deshabilitar un repositorio en particular cambiando el valor de enabled a 0 o 1, o usando las opciones --disablerepo=somerepo y --enablerepo=somerepo al usar yum. También se puede (pero no se debería hacer) deshabilitar la verificación de integridad con la variable gpgcheck.
Tal como rpm, yum puede usarse para realizar consultas y búsquedas; sin embargo puede buscar no solo lo que está instalado en el sistema local, sino que también en repositorios remotos. Algunos ejemplos:
- Búsqueda de paquetes con la palabra keyword en el nombre:
$ sudo yum search keyword
$ sudo yum list "*keyword*"
Estos dos comandos proporcionan información un tanto diferente. El primero provee más información acerca de los paquetes en sí, mientras que el segundo se enfoca en lo que está instalado y en lo disponible. - Despliega información acerca de un paquete:
$ sudo yum info package
La información incluye tamaño, versión, repositorio y URL de origen, y una descripción larga. Es posible proveer comodines como en yum info "libc*" para la mayoría de los comandos yum. Tenga en cuenta que no es un requisito que el paquete esté instalado, a diferencia de las consultas que se realizan con rpm -q. - Lista todos los paquetes, o solo aquellos que están instalados, disponibles o actualizaciones que aún no han sido instaladas.
$ sudo yum list [installed | updates | available] - Muestra información acerca de grupos de paquetes instalados, disponibles, etc.:
$ sudo yum grouplist [group1] [group2]
$ sudo yum groupinfo group1 [group2] - Muestra paquetes que contienen un cierto nombre de archivo:
$ sudo yum provides
como en
$ sudo yum provides "/logrotate.conf"
Tenga en cuenta que es necesario usar al menos un / en el nombre de archivo, lo cual puede ser confuso.
La verificación de paquetes requiere la instalación del paquete yum-plugin-verify, para lo cual puede realizar lo siguiente:
$ sudo yum install yum-plugin-verify
Tenga en cuenta que este es una extensión de yum, no un ejecutable. Hay muchos otros plugins disponibles para yum, los cuales extienden el set de comandos y argumentos que puede tomar.
- Para verificar un paquete, entregando la mayor información posible:
$ sudo yum verify [package] - Para imitar exactamente rpm -V:
$ sudo yum verify-rpm [package] - Para listar todas las diferencias, incluyendo archivos de configuración:
$ sudo yum verify-all [package]
Si no se proveen argumentos en el comando anterior, este verificará todos los paquetes instalados en el sistema.
Por defecto, los comandos de verificación ignoran los archivos de configuración, los cuales pueden cambiar con el uso normal. Hay otras opciones; para acceder a ellas haga man yum-verify.
Aquí hay algunos ejemplos de operaciones que se realizan generalmente:
- Instalar uno o mas paquetes desde los repositorios, resolver e instalar cualquier dependencia necesaria:
$ sudo yum install package1 [package2] - Instalar desde un rpm local:
$ sudo yum localinstall package-file
Lo anterior no es lo mismo que:
$ rpm -i package-file
porque esto intentara resolver dependencias mediante el acceso a repositorios remotos. - Instalar un grupo de software especifico desde un repositorio, resolver e instalar cualquier dependencia necesaria para cada paquete en el grupo:
$ sudo yum groupinstall group-name
o
$ sudo yum install @group-name - Desinstalar paquetes del sistema:
$ sudo yum remove package1 [package2]
Hay que ser cuidadoso con la desinstalación de paquetes, ya que yum no solo removerá los paquetes seleccionados, sino que también los que dependen de él. Puede que usted no desee esto, por lo cual no ejecute yum remove con la opción -y, la cual asume una confirmación automática de desinstalación. - Acualizar un paquete desde un repositorio:
$ sudo yum update [package]
Si no se provee un nombre de paquete, todos los paquetes son actualizados (de existir actualizaciones para todos ellos).
Durante la instalación (o actualización), si un paquete tiene un archivo de configuración que va a ser actualizado, el archivo con la configuración antigua será renombrado con una extensión .rpmsave. Si el archivo con la configuración antigua va a funcionar con el software nuevo, el archivo de configuración nuevo será renombrado con una extensión .rpmnew. Usted puede buscar estas extensiones de nombres de archivo (la mayoría en el árbol de subdirectorios /etc) para determinar si necesita llevar a cabo alguna reconciliación, haciendo:
$ sudo find /etc -name "*.rpm*"
Tenga en cuenta que las consideraciones anteriores se aplican también a la herramienta subyacente rpm.
Es posible tener una gama amplia de capacidades adicionales de yum, de acuerdo a qué extensiones están instaladas. Puede listarlas con:
$ sudo yum list "yum-plugin*"
En particular:
- Mostrar una lista de los repositorios habilitados:
$ sudo yum repolist - Iniciar una shell interactiva para ejecutar múltiples comandos yum:
$ sudo yum shell [text-file]
Si se provee text-file, yum leerá y ejecutará los comandos del archivo en vez de la terminal. - Descargue los paquetes pero no los instale, almacénelos en el directorio /var/cache/yum, u otro directorio a especificar:
$ sudo yum install --downloadonly package
Para que esto funcione hay que instalar el paquete yum-plugin-downloadonly. También es posible hacer lo siguiente:
$ sudo yumdownloader package
lo cual descargará la última versión de package en el directorio de trabajo actual. Opcionalmente uno puede calcular y descargar todas las dependencias necesarias. - Para ver la historia de los comandos yum, con las opciones correctas, incluso deshacer o rehacer comandos anteriores:
$ sudo yum history
¿Cuáles de las siguientes afirmaciones son ciertas?
- yum install <package> se usa para instalar un paquete nuevo.
- yum update no acepta un paquete como argumento.
- yum provides <file path> no puede usarse para determinar qué paquete provee el archivo especificado como argumento.
- yum search se usa para buscar por nombre de paquete y una descripción corta.
Actualmente usted debería ser capaz de:
- Discutir los instaladores de paquetes y sus características.
- Explicar qué es yum.
- Configurar yum para usar repositorios.
- Conocer las consultas que pueden realizarse con yum.
- Usar yum para verificar, instalar, desinstalar y actualizar paquetes.
31. zypper
En sistemas basados en SUSE, el programa zypper provee un alto nivel de servicios inteligentes para usar el programa subyacente rpm, y juega el mismo rol que yum en sistemas basados en Red Hat. Puede resolver dependencias automáticamente al instalar, actualizar y desinstalar paquetes. Accede a repositorios externos de software, sincronizándose con ellos, obteniendo e instalando software según se necesario.
Al final de este capítulo usted debería ser capaz de:
- Explicar qué es zypper.
- Discutir las consultas que zypper puede hacer.
- Instalar, desinstalar y actualizar paquetes usando zypper.
zypper es la herramienta de la línea de comandos para instalar y gestionar paquetes en SUSE Linux y openSUSE. Es muy similar a yum en cuanto al funcionamiento, incluso en la sintaxis básica, y también trabaja con paquetes rpm.
zypper obtiene los paquetes desde los repositorios, instala, desinstala, actualiza y resuelve cualquier dependencia necesaria. En la práctica es equivalente a yum y apt-get en cuanto a que obtiene paquetes desde un repositorio y que resuelve dependencias.
Aquí hay algunos ejemplos de las operaciones de consulta más comunes:
- Muestra una lista de actualizaciones disponibles:
$ zypper list-updates - Lista los repositorios disponibles:
$ zypper repos - Busca repositorios por el texto string:
$ zypper search <string> - Despliegue información acerca de un paquete:
$ zypper info <package> - Buscar en los repositorios para determinar qué paquetes proveen un archivo:
$ zypper search --provides <file>
A continuación se muestran algunos ejemplos de operaciones que se realizan comúnmente:
- Instalar o actualizar un paquete(s):
$ sudo zypper install package - No solicite confirmación al instalar o actualizar:
$ sudo zypper --non-interactive install <package>
Esto es útil para usarse en scripts y es equivalente a yum -y. - Actualice todos los paquetes instalados:
$ sudo zypper update
Si se proveen nombres como argumentos, se actualizarán estos paquetes solamente y cualquier dependencia requerida. En el siguiente comando se realiza sin solicitar confirmación:
$ sudo zypper --non-interactive update - Desinstale un paquete del sistema:
$ sudo zypper remove <package>
Tal como con yum, es necesario ser cuidadoso con el comando de desinstalación, ya que cualquier paquete que necesite del que se está eliminando va a ser removido también.
A veces es necesario ejecutar una serie de comandos zypper en secuencia. Para evitar volver a leer todas las bases de datos para cada comando, es posible ejecutar zypper en modo shell, como se muestra aquí:
$ sudo zypper shell
> install bash
...
> exit
Debido a que zypper soporta la biblioteca readline, es posible usar las mismas funciones disponibles de edición de línea de comandos de la shell bash en la shell zypper.
Para agregar un repositorio:
$ sudo zypper addrepo URI alias
el cual está ubicado en la URI proporcionada y que se usará con el alias que se pasó como parámetro.
Para eliminar un repositorio de la lista:
$ sudo zypper removerepo alias
usando el alias del repositorio que desea eliminar.
¿Cuáles de las siguientes afirmaciones son ciertas?
- zypper install <package> se usa para instalar un paquete nuevo.
- zypper update no acepta un paquete como argumento.
- zypper what-provides <file path> no puede usarse para determinar qué paquete provee el archivo especificado como argumento.
- zypper search puede usarse para buscar por nombre de paquete y una descripción corta.
Actualmente usted debería ser capaz de:
- Explicar qué es zypper.
- Discutir las consultas que zypper puede hacer.
- Instalar, desinstalar y actualizar paquetes usando zypper.
32. APT
Disponible para sistemas basados en Debian, el conjunto de programas APT (Advanced Packaging Tool) provee un alto nivel de servicios inteligentes para usar el programa subyacente dpkg, y jugar el mismo rol que yum en sistemas basados en Red Hat. Las herramientas principales son apt-get y apt-cache. Puede resolver dependencias automáticamente al instalar, actualizar y desinstalar paquetes. Accede a repositorios externos de software, sincronizádose con ellos, obteniendo e instalando software según se necesario.
Al final de este capítulo usted debería ser capaz de:
- Explicar qué es APT.
- Usar apt-cache para realizar consultas.
- Instalar, desinstalar y actualizar paquetes usando apt-get.
APT no es un programa en sí mismo: corresponde a las siglas de Advanced Packaging Tool (Herramienta Avanzada de Paquetes), el cual incluye un número de herramientas tales como apt-get y apt-cache. Estas herramientas invocan a su vez al programa de nivel inferior dpkg.
El sistema APT funciona con paquetes Debian, cuyos archivos tienen una extensión .deb. Hay muchas distribuciones que descienden de Debian (incluyendo Ubuntu y Linux Mint), las cuales han adoptado el sistema de empaquetamiento de Debian sin modificaciones esenciales. De hecho no es raro que sus repositorios se usen en distribuciones Linux basadas en Debian.
Una vez más vamos a ignorar interfaces gráficas en el equipo, tales como synaptic, el Centro de Software de Ubuntu u otras interfaces gráficas de APT como aptitude.
De todas formas, se pueden encontrar excelentes recursos basados en internet en http://packages.debian.org y http://packages.ubuntu.com. Estas bases de datos le permiten buscar paquetes, examinar sus contenidos y descargarlos.
apt-get es la herramienta principal de la línea de comandos de APT para gestionar paquetes. Se usa para instalar, gestionar y actualizar paquetes individuales o el sistema completo. Incluso puede actualizar la distribución a una versión completamente nueva, lo cual puede ser una tarea difícil.
Incluso hay extensiones (imperfectas) que le permiten a apt-get trabajar con archivos rpm.
Tal como yum y zypper, apt-get funciona con múltiples repositorios remotos.
Las consultas se realizan usando la herramienta apt-cache:
- Consulte por un paquete llamado apache2 en el repositorio:
$ apt-cache search apache2 - Despliegue información básica acerca del paquete apache2:
$ apt-cache show apache2 - Despliegue información más detallada acerca del paquete apache2:
$ apt-cache showpkg apache2 - Liste todos los paquetes de los cuales depende apache2:
$ apt-cache depends apache2 - Busque un archivo llamado apache2.conf en el repositorio:
$ apt-file search apache2.conf - Liste todos los archivos del paquete apache2:
$ apt-file list apache2
El programa apt-get es el caballo de batalla para instalar, desinstalar y actualizar paquetes:
- Sincronizar el índice de archivos de paquete con el repositorio fuente. Los índices de los paquetes disponibles son obtenidos desde la(s) ubicación(es) especificadas en /etc/apt/sources.list.
$ sudo apt-get update - Instalar un paquete o actualizar uno que ya está instalado:
$ sudo apt-get install [package] - Desinstalar un paquete del sistema sin remover los archivos de configuración:
$ sudo apt-get remove [package] - Desinstalar un paquete del sistema y sus archivos de configuración también:
$ sudo apt-get --purge remove [package] - Aplicar todas las actualizaciones disponibles a los paquetes ya instalados:
$ sudo apt-get upgrade - Hacer una actualización inteligente que realizará una resolución de dependencias más profunda, instalará dependencias nuevas y desinstalará paquetes obsoletos.
$ sudo apt-get dist-upgrade
Esto no actualizará el sistema a una versión completamente nueva de la distribución Linux, como se malentiende comúnmente. - Tenga en cuenta que se debe realizar una operación update antes que upgrade, ya que a diferencia de yum, el cual realiza ambas operaciones al recibir el argumento update, este actualiza los repositorios y luego los paquetes. Esto puede ser confuso para usuarios habituales de yum en sistemas basados en Debian.
- Deshágase de los paquetes que ya no se necesitan, tal como versiones antiguas del kernel Linux:
$ sudo apt-get autoremove - Limpie los archivos del caché y cualquier archivo de paquete que haya sido instalado:
$ sudo apt-get clean
Esto puede ahorrar mucho espacio en disco.
¿Cuáles de las siguientes afirmaciones son ciertas?
- apt-get install <package> se usa para instalar un paquete.
- apt-get update no acepta un paquete como argumento.
- apt-file find <file path> no puede usarse para encontrar qué paquete provee el archivo especificado como argumento.
- apt-cache search puede usarse para buscar por el nombre de un paquete y una descripción corta.
Actualmente usted debería ser capaz de:
- Explicar qué es APT.
- Usar apt-cache para realizar consultas.
- Instalar, desinstalar y actualizar paquetes usando apt-get.
33. Gestión de cuentas de usuario
En un sistema Linux pueden trabajar muchos usuarios simultáneamente. Cada uno tiene su propio espacio de almacenamiento de directorios y archivos, como también scripts de inicio y variables de ambiente. Las contraseñas se eligen o asignan individualmente y cada usuario tiene un conjunto de privilegios bien definido. Bajo ciertas circunstancias, las cuentas de usuario pueden tener privilegios restringidos o estar bloqueadas. El usuario root (conocido como superusuario) tiene habilidades únicas, las cuales deberían usarse raramente y con la mayor precaución posible.
Es posible usar SSH para cifrar el acceso a computadores remotos.
Al final de este capítulo usted debería ser capaz de:
- Explicar el propósito de las cuentas individuales de usuario y listar sus atributos principales.
- Crear cuentas de usuario y modificar propiedades de cuentas existentes, como también eliminar o bloquear cuentas.
- Comprender cómo se configuran las contraseñas de usuario, su cifrado y almacenamiento, y cómo requerir cambios en las contraseñas a través del tiempo por propósitos de seguridad.
- Explicar cómo funciona la shell y las cuentas restringidas.
- Comprender el rol de la cuenta root y saber cuándo usarla.
- Estar familiarizado con el uso de ssh y saber cómo configurarlo para el acceso remoto.
Los sistemas Linux proveen un ambiente multiusuario el cual le permite a personas y procesos tener ambientes de trabajo simultáneos y separados.
Los propósitos de tener cuentas individuales de usuario incluyen:
- Proveer a cada usuario de un espacio individual y privado.
- Crear cuentas de usuario en particular con propósitos específicos.
- Distinguir privilegios entre los usuarios.
Una cuenta de usuario especial es la de root, la cual tiene la capacidad de hacer cualquier cosa en el sistema. Para evitar cometer errores costosos y por razones de seguridad, la cuenta root debe usarse solo cuando es absolutamente necesario.
Las cuentas de usuarios normales son para personas que trabajarán en el sistema. Algunas cuentas de usuario (como la cuenta daemon) existen con el propósito de permitir que procesos como un usuario diferente a root.
En el próximo capítulo vamos a continuar con el tema de gestión de grupos, en donde un subconjunto de usuarios en el sistema pueden compartir archivos, privilegios, etc., de acuerdo a intereses comunes.
Cada usuario en el sistema tiene una línea correspondiente en el archivo /etc/passwd que describe los atributos básicos de la cuenta (vamos a tratar el tema de las contraseñas en este archivo más adelante). Por ejemplo:
....
beav:x:1000:1000:Theodore Cleaver:/home/beav:/bin/bash
warden:x:1001:1001:Ward Cleaver:/home/warden:/bin/bash
dobie:x:1002:1002:Dobie Gillis:/home/dobie:/bin/bash
....
Los siete elementos aquí son:
- Nombre de usuario
El nombre único asignado a cada usuario. - Contraseña de usuario
La contraseña asignada a cada usuario. - Número de identificación de usuario (UID)
Un número único asignado a la cuenta de usuario. El UID es usado por el sistema para una variedad de propósitos, incluyendo la determinación de privilegios de usuario y seguimiento de actividades. - Número de identificación de grupo (GID)
Indica el grupo principal o predeterminado del usuario. - Comentario o información GECOS
Un método definido que usa el campo de comentario para almacenar información de contacto (nombre completo, email, oficina, número de contacto). No se preocupe de qué significa GECOS, es un término muy antiguo. - Directorio home
Para la mayoría de los usuarios este es un directorio único que le ofrece un área de trabajo. Normalmente cada usuario es dueño de su directorio, y con la excepción de root, se encontrará en el sistema bajo /home. - Shell de inicio
Generalmente este es un programa shell tal como /bin/bash o /bin/csh. Sin embargo, en casos especiales se referencia un programa alternativo. En general este campo aceptará cualquier ejecutable.
El comando:
$ sudo useradd stephane
creará una cuenta de usuario llamada stephane, usando los algoritmos predeterminados para asignar el id de usuario y grupo, como también para la elección de shell.
Específicamente, el comando useradd anterior provocará la ejecución de los siguientes pasos:
- El próximo UID mayor a UID_MIN (especificado en /etc/login.defs) es asignado de forma predeterminada como el UID de stephane.
- También se crea un grupo llamado stephane con GID=UID y se asigna como el grupo principal de stephane.
- Se crea un directorio home /home/stephane del cual stephane es propietaria.
- La shell de inicio de stephane será /bin/bash.
- Los contenidos de /etc/skel se copian a /home/stephane. De forma predeterminada, /etc/skel incluye archivos de inicio para bash y para el sistema X Window.
- Una entrada de ya sea !! o ! se pone en el campo password del archivo /etc/shadow en la entrada de stephane, lo cual requiere que el administrador le asigne una contraseña a la cuenta para que la misma se pueda usar.
Los valores predeterminados pueden modificarse fácilmente a través del uso de opciones en useradd, como se muestra aquí:
$ sudo useradd -s /bin/csh -m -k /etc/skel -c "Bullwinkle J Moose" bmoose
donde se ha suministrado valores no predeterminados para algunos de los atributos de usuario.
El usuario root puede eliminar cuentas de usuario usando el comando userdel:
$ sudo userdel isabelle
Todas las referencias al usuario isabelle serán eliminadas desde /etc/passwd, /etc/shadow y /etc/group.
Mientras que esto elimina la cuenta, no borra el directorio home (generalmente /home/isabelle), en caso de que la cuenta sea reestablecida más tarde. Si se provee la opción -r a userdel, el directorio home será eliminado también. Sin embargo, permanecerá el resto de los archivos en el sistema que sean propiedad del usuario eliminado.
usermod puede usarse para cambiar características de una cuenta de usuario, tales como la pertenencia a grupos, directorio home, nombre de usuario, contraseña, shell predeterminada, ID de usuario, etc.
Su uso es bastante sencillo. Tenga en cuenta que usermod se hará cargo de cualquier modificación de los archivos en el directorio /etc, según sea necesario.
$ sudo usermod --help
Usage: usermod [options] LOGIN
Options:
-c, --comment COMMENT new value of the GECOS field
-d, --home HOME_DIR new home directory for the user account
-e, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE
-f, --inactive INACTIVE set password inactive after expiration
to INACTIVE
-g, --gid GROUP force use GROUP as new primary group
-G, --groups GROUPS new list of supplementary GROUPS
-a, --append append the user to the supplemental GROUPS
mentioned by the -G option without removing
him/her from other groups
-h, --help display this help message and exit
-l, --login NEW_LOGIN new value of the login name
-L, --lock lock the user account
-m, --move-home move contents of the home directory to the
new location (use only with -d)
-o, --non-unique allow using duplicate (non-unique) UID
-p, --password PASSWORD use encrypted password for the new password
-R, --root CHROOT_DIR directory to chroot into
-s, --shell SHELL new login shell for the user account
-u, --uid UID new UID for the user account
-U, --unlock unlock the user account
-Z, --selinux-user SEUSER new SELinux user mapping for the user account
Linux viene con algunas cuentas del sistema que están bloqueadas, lo cual significa que pueden ejecutar programas, pero no pueden iniciar sesión en el sistema y no tienen una contraseña válida asociada. Por ejemplo, /etc/passwd tiene entradas como:
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
La shell nologin devuelve lo siguiente si un usuario bloqueado intenta iniciar sesión en el sistema:
This account is currently not available.
o cualquier mensaje que esté almacenado en /etc/nologin.txt.
Tales cuentas bloqueadas se crean con propósitos especiales, ya sea para servicios del sistema o aplicaciones; si busca usuarios con la shell nologin en el archivo /etc/passwd de su sistema verá cuales son esas cuentas.
También es posible bloquear una cuenta de usuario en particular de la siguiente forma:
$ sudo usermod -L stephane
lo cual significa que la cuenta se mantiene en el sistema pero que no puede iniciar sesión. Es posible desbloquearla con la opción -U.
Una práctica habitual es bloquear una cuenta de usuario cada vez que dejan la organización o que hacen uso de una ausencia extendida.
Otra forma de bloquear una cuenta es usar chage para cambiar la fecha de expiración de una cuenta a una fecha en el pasado:
$ sudo chage -E 2014-09-11 isabelle
La fecha exacta es irrelevante, siempre y cuando esté en el pasado. Vamos a discutir chage pronto.
Otra aproximación consiste en editar el archivo /etc/shadow y reemplazar el hash de la contraseña con !! o cualquier otro string inválido.
Ya hemos visto que /etc/passwd contiene un registro (una línea) por cada usuario en el sistema, como se muestra aquí:
beav:x:1000:1000:Theodore Cleaver:/home/beav:/bin/bash
rsquirrel:x:1001:1001:Rocket J Squirrel:/home/rsquirrel:/bin/bash
y ya hemos discutido los campos en cuestión. Cada registro consiste en un número de campos separados por dos puntos (:). Los campos son los atributos que mencionamos anteriormente.
Si /etc/shadow no se usa, el campo password contiene el hash de la contraseña. Si se usa, contiene un marcador de posición ("x").
La convención que la mayoría de las distribuciones Linux han usado es que cualquier cuenta con un ID de usuario menor a 1000 se considera especial y pertenece al sistema; las cuentas de usuario normal comienzan en 1000. El valor exacto es definido por UID_MIN según el valor que tiene en /etc/login.defs.
Históricamente, las distribuciones derivadas de Red Hat usaban UID_MIN=500, no 1000, pero con RHEL 7 han adoptado 1000 como valor común.
Si no se especifica un ID de usuario al usar useradd, el sistema asignará los UID en forma incremental, comenzando en UID_MIN.
Adicionalmente, cada usuario obtiene un ID de grupo primario, el cual por defecto es el mismo número que el UID. Estos son llamados a veces Grupos Privados de Usuario (UPG).
Se considera una mala práctica el editar directamente /etc/passwd, /etc/group o /etc/shadow; en vez de eso use la herramienta apropiada, ya sea usermod o el editor especial vipw, ya que se ocupa bien del bloqueo de los archivos involucrados, corrupción de datos, etc.
El archivo /etc/shadow contiene un registro (una línea) por cada usuario, como en:
daemon:*:16141:0:99999:7:::
.....
beav:$6$iCZyCnBJH9rmq7P.$RYNm10Jg3wrhAtUnahBZ/mTMg.RzQE6iBXyqaXHvxxbKTYqj.d
9wpoQFuRp7fPEE3hMK3W2gcIYhiXa9MIA9w1:16316:0:99999:7:::
Los campos separados por dos puntos son:
- username: nombre único de usuario
- password: el valor hash (sha512) de la contraseña
- lastchange: días desde el 1ero de enero de 1970 desde que la contraseña fue cambiada por última vez
- mindays: cantidad mínima de días antes de que la contraseña pueda ser cambiada
- maxdays: cantidad máxima de días luego de lo cual la contraseña debe ser cambiada
- warn: número de días antes de que la contraseña expire en que el usuario es advertido
- grace: número de días después de que la contraseña ha expirado en que la cuenta es deshabilitada
- expire: fecha en que la cuenta será deshabilitada
- reserved: campo reservado
El username en cada registro debe coincidir exactamente lo que se encuentra en /etc/passwd y también debe estar en el mismo orden.
Todas las fechas se almacenan como el número de días desde el 1ero de Enero de 1970 (tiempo UNIX o epoch).
El hash de la contraseña es el string "$6$" seguido por un valor salt de ocho caracteres, el cual luego es seguido por un caracter $ y un hash de 88 caracteres (sha512).
El uso de /etc/shadow habilita la caducacidad de las contraseñas por usuario. Al mismo tiempo permite mantener una mayor seguridad del hash de las contraseñas.
Los permisos predeterminados de /etc/passwd son 644 (-rw-r--r--); cualquiera puede leer el archivo. Esto es desafortunadamente necesario porque los programas de sistema y aplicaciones de usuario necesitan leer la información contenida en el archivo. Estos programas de sistema no se ejecutan como usuario root y ante cualquier evento solo root puede modificar el archivo.
Una preocupación en particular son el hash de las contraseñas en sí. Si están en /etc/passwd, cualquiera podría hacer una copia de los hashes de las contraseñas y usar herramientas tales como Crack y John the Ripper para encontrar las contraseñas en texto plano a raíz de su hash. ¡Esto es un riesgo de seguridad!
/etc/shadow tiene la configuración de permisos en 400 (-r--------), lo cual significa que solo root puede acceder al archivo. Esto hace que sea más difícil que alguien obtenga los hashes de las contraseñas.
A menos de que haya una buena razón para no hacerlo, usted debería usar el archivo /etc/shadow.
Las contraseñas pueden cambiarse con passwd; un usuario normal puede cambiar su contraseña solamente, mientras que root puede cambiar cualquiera. Cuando usted escribe su contraseña, esta no se muestra, ya que desplegarla de vuelta a la pantalla está suprimido.
Por defecto, la contraseña elegida es examinada por pam_cracklib, la cual se encarga de que elijamos buenas contraseñas.
Un usuario normal cambiando su contraseña:
$ passwd
Changing password for clyde
(current) UNIX password: <clyde's password>
New UNIX password: <clyde's-new-password>
Retype new UNIX password: <clyde's-new-password>
passwd: all authentication tokens updated successfully
Note que cuando root cambia una contraseña de un usuario, no se le pide que ingrese la contraseña actual del mismo:
$ sudo passwd kevin
New UNIX password: <kevin's-new-password>
Retype new UNIX password: <kevin's-password>
passwd: all authentication tokens updated successfully
Tenga en cuenta que los usuarios normales no tienen permitido configurar contraseñas malas, tales como las que son muy cortas o están basadas en palabras de diccionario. Sin embargo, root puede hacerlo.
Generalmente se considera importante cambiar las contraseñas periódicamente. Esto limita la cantidad de tiempo que podría tener un intruso para crackear una contraseña, como también puede usarse para bloquear cuentas que no están en uso. La desventaja es que los usuarios podrían encontrar que esta política es molesta y terminarían escribiendo sus contraseñas a medida en que las van cambiando, lo cual facilitaría su robo.
La herramienta que gestiona esto se llama chage:
chage [-m mindays] [-M maxdays] [-d lastday] [-I inactive] [-E expiredate] [-W warndays] user
Ejemplos:
$ sudo chage -l stephane
$ sudo chage -m 14 -M 30 kevlin
$ sudo chage -E 2012-4-1 isabelle
$ sudo chage -d 0 clyde
Solo el usuario root puede usar chage. La única excepción a esto es que cualquier usuario puede ejecutar chage -l para ver la información específica de su cuenta.
Ejemplos:
$ sudo chage -l coop
Last password change : Sep 03, 2014
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
Para forzar a un usuario a cambiar su contraseña en el siguiente inicio de sesión:
$ sudo chage -d 0 USERNAME
En Linux es posible usar una shell restringida, la cual se invoca de la siguiente forma:
$ /bin/bash -r
(Algunas distribuciones pueden definir un comando rbash con el mismo efecto).
Una shell restringida opera en un ambiente más controlado que una shell estándar, pero por lo demás funciona normalmente. En particular:
- Impide que el usuario se cambie a cualquier directorio fuera de su directorio home.
- Impide que el usuario redefina las siguientes variables de ambiente: SHELL, ENV y PATH.
- No permite que el usuario especifique la ruta absoluta o nombres de comandos ejecutables a partir de /.
- Impide que el usuario redireccione la entrada y/o la salida.
Tenga en cuenta que hay otras restricciones; la mejor manera de verlas es hacer man bash y buscar por RESTRICTED SHELL.
Debido a que la shell restringida ejecuta $HOME/.bash_profile sin restricciones, el usuario no debe tener permisos de escritura ni ejecución en el directorio /home.
Hay veces en las que es necesario conceder acceso a un usuario, pero con un alcance limitado. Configurar una cuenta restringida puede ser útil en este contexto. Una cuenta restringida:
- Usa la shell restringida.
- Tiene límites en los programas de sistema disponibles y en las aplicaciones de usuario.
- Tiene límites en los recursos del sistema.
- Tiene límites en los tiempos de acceso.
- Tiene límites en los directorios que puede acceder.
Una shell restringida puede ser invocada desde la línea de comandos o desde un script con /bin/bash -r. Sin embargo, no se puede especificar parámetros en el archivo /etc/passwd. Una forma simple de solucionar esta restricción podría ser una de las siguientes:
$ cd /bin ; sudo ln -s bash rbash
$ cd /bin ; sudo ln bash rbash
$ cd /bin ; sudo cp bash rbash
y luego usar /bin/rbash como la shell en /etc/passwd.
Al configurar cuentas de este tipo, se debería evitar el agregar directorios del sistema a la variable de ambiente PATH; esto concedería al usuario restringido la habilidad de ejecutar otros programas del sistema, tal como una shell no restringida.
Las cuentas restringidas son conocidas también como cuentas limitadas.
La cuenta root debería usarse solamente con propósitos administrativos, cuando sea absolutamente necesario y en ningún caso ser usada como una cuenta normal. Los errores pueden ser muy costosos, tanto para la integridad, estabilidad y seguridad del sistema.
Generalmente el inicio de sesión remoto está prohibido por defecto, debido a razones de seguridad. Es posible permitir inicios de sesión a Secure Shell usando ssh, el cual se configura en /etc/ssh/sshd_config y en PAM (Pluggable Authentication Modules), a través del módulo pam_securetty.so y el archivo asociado /etc/securetty. El inicio de sesión de root se permite solo desde los dispositivos listados en /etc/securetty.
Por lo general se recomienda que todos los accesos a la cuenta root se realicen a través de su o sudo (generando un registro de auditoría de todos los accesos a root a través de sudo). Tenga en cuenta que algunas distribuciones (tales como Ubuntu) prohíben iniciar sesión directamente en la cuenta root.
PAM también puede usarse para restringir a qué usuarios se les permite hacer su a la cuenta root. Podría valer la pena configurar auditd para registrar todos los comandos ejecutados como root.
A menudo es necesario conectarse a sistemas remotos través de la red, ya sea con el mismo nombre de usuario u otro. O cuando se necesita transferir archivos hacia y desde una máquina remota. En cualquier caso, uno desea hacerlo de forma segura, libre de cualquier intercepción.
SSH (Secure SHell) existe para este propósito. Usa un cifrado basado en algoritmos fuertes. Asumiendo que los paquetes ssh apropiados están instalados en el sistema, no es necesario realizar una configuración adicional antes de comenzar a usar ssh.
Para conectarse a un sistema remoto:
$ whoami
student
$ ssh farflung.com
student@farflung.com's password: (escriba aquí)
donde estamos asumiendo que hay una cuenta student en farflung.com. Para conectarse con un usuario diferente:
$ ssh root@farflung.com
root@farflung.com's password: (escriba aquí)
o
$ ssh -l root farflung.com
root@farflung.com's password: (escriba aquí)
Para copiar archivos desde un sistema a otro:
$ scp file.txt farflung.com:/tmp
$ scp file.tex student@farflung.com/home/student
$ scp -r some_dir farflung.com:/tmp/some_dir
(Hemos omitido la solicitud de la contraseña para ahorrar espacio; si usted realiza una configuración apropiada con llaves de cifrado - tema que revisaremos en la sección siguiente - no necesitará proveer de una contraseña).
Para ejecutar un comando en múltiples máquinas simultáneamente:
$ for machines in node1 node2 node3
do (ssh $machines some_command &)
done
Es posible configurar SSH para facilitar su uso, en particular para permitir la conexión sin una contraseña. Los archivos de configuración específicos del usuario se crean bajo cada directorio home, en el directorio oculto .ssh:
$ ls -l ~/.ssh
total 20
-rw-r--r-- 1 hilda hilda 1172 Sep 27 2014 authorized_keys
-rw------- 1 hilda hilda 207 Aug 9 2011 config
-rw------- 1 hilda hilda 1675 Dec 8 2010 id_rsa
-rw-r--r-- 1 hilda hilda 393 Dec 8 2010 id_rsa.pub
-rw-r--r-- 1 hilda hilda 1980 Apr 28 07:36 known_hosts
el cual contiene:
- id_rsa: la clave de cifrado privada del usuario.
- id_rsa.pub: la clave de cifrado pública del usuario.
- authorized_keys: Una lista de claves públicas que tienen permiso para conectarse.
- known_hosts: Una lista de hosts desde los cuales se han aceptado conexiones en el pasado.
- config: Un archivo de configuración para especificar varias opciones.
Primero el usuario tiene que generar sus claves de cifrado privada y pública con ssh-keygen:
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hilda/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hilda/.ssh/id_rsa
Your public key has been saved in /home/hilda/.ssh/id_rsa.pub
The key fingerprint is:
76:da:d3:51:1e:c8:2d:3b:34:28:46:b2:2b:db:d1:c4 hilda@c7
The key's randomart image is:
+--[ RSA 2048]----+
| . . |
| = o o |
| . E . * + |
| = . . * . |
| . o S . + . |
| + o + . o |
| . . . o . |
| . |
| |
+-----------------+
Esto también generará la llave pública, /.ssh/id_rsa.pub.
La llave privada nunca debe ser compartida con nadie.
La llave pública puede ser entregada a cualquier máquina con la cual usted desea permitir acceso sin contraseña. También debería agregarse a su archivo authorized_keys, junto con todas las llaves públicas de otros usuarios que tienen cuentas en su máquina, a los que desea permitirles el acceso sin contraseña a sus cuentas.
El archivo known_hosts se contruye gradualmente a medida en que ocurren los accesos ssh. Si el sistema detecta cambios en los usuarios que están intentando conectarse a través de ssh, le advertirá de ello y le dará la oportunidad de denegar el acceso. Tenga en cuenta que el archivo authorized_keys contiene información acerca de usuarios y máquinas:
$ cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQ
...0000aSd...hilda@sbc
mientras que el known_hosts solo contiene información acerca de computadores:
$ cat known_hosts
192.30.252.129 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSw
....BK6Tb...==
Usted puede examinar las páginas man para ver qué tipos de opciones pueden ir en el archivo de configuración de ssh, config.
En un sistema capaz de caducar las cuentas de usuario, ¿cuál/es de las siguientes formas son válidas para bloquear una cuenta de usuario?
Editar /etc/shadow con vipw -s y reemplazar el último campo con /sbin/nologin
Editar /etc/passwd con vipw y reemplazar el último campo con /sbin/nologin
Editar /etc/shadow con vipw -s y agregar !! al segundo campo
Editar /etc/passwd con vipw y agregar !! al segundo campo
Usar la herramienta chage para expirar la contraseña
Usar la herramienta passwd para bloquear la contraseña
Actualmente usted debería ser capaz de:
- Explicar el propósito de las cuentas individuales de usuario y listar sus atributos principales.
- Crear cuentas de usuario y modificar propiedades de cuentas existentes, como también eliminar o bloquear cuentas.
- Comprender cómo se configuran las contraseñas de usuario, su cifrado y almacenamiento, y cómo requerir cambios en las contraseñas a través del tiempo por propósitos de seguridad.
- Explicar cómo funciona la shell y las cuentas restringidas.
- Comprender el rol de la cuenta root y saber cuando usarla.
- Estar familiarizado con el uso de ssh y saber cómo configurarlo para el acceso remoto.
34. Gestión de grupos
Los sistemas Linux forman colecciones de usuarios los cuales se denominan grupos, cuyos miembros comparten algún propósito. Comparten ciertos archivos y directorios y mantienen privilegios en común; esto los separa de los demás en el sistema, a veces llamados de forma colectiva como el mundo. El uso de grupos ayuda enormemente en proyectos colaborativos.
Al final de este capítulo usted debería ser capaz de:
- Explicar por qué es útil que los usuarios del sistema pertenezcan a uno o más grupos.
- Usar herramientas tales como groupadd, groupdel, groupmod y usermod para crear, eliminar y gestionar grupos y sus miembros.
- Describir los Grupos Privados de Usuario.
- Explicar el concepto de pertenencia al grupo.
Los usuarios en Linux pertenecen a uno o más grupos. Los propósitos de esto incluyen:
- Permitirle a los usuarios compartir un área de trabajo (directorios, archivos, etc.).
- Configurar permisos de archivos para permitir el acceso a los miembros del grupo, pero no al resto de los usuarios.
- Permitirle a ciertos usuarios específicos acceder a recursos que de otra forma no podrían.
Los grupos están definidos en /etc/group, el cual cumple el mismo rol para los grupos como /etc/passwd lo hace para los usuarios. Cada línea del archivo luce de la siguiente forma:
groupname:password:GID:user1,user2,...
donde:
- groupname es el nombre del grupo.
- password es el campo que almacena la contraseña. Es posible configurar contraseñas para los grupos, pero solamente si existe el archivo /etc/gshadow.
- GID es el identificador de grupo. Los valores entre 0 y 99 son para grupos del sistema. Los valores entre 100 y GID_MIN (como está definido en /etc/login.defs, el cual suele ser el mismo que UID_MIN) se consideran especiales. Los valores sobre GID_MIN son para UPG (Grupos Privados de Usuario).
- user1,user2,... es una lista de usuarios separados por coma, quienes son miembros del grupo. El usuario no necesita estar listado aquí si este es su grupo principal.
Los grupos y sus miembros pueden ser gestionados y mantenidos con:
- groupadd: Agrega un grupo.
- groupdel: Elimina un grupo.
- groupmod: Modifica las propiedades del grupo.
- usermod: Modifica la pertenencia a grupos de un usuario (agrega o elimina).
También se puede editar directamente /etc/group, pero es mejor usar la herramienta vigr, la cual generalmente está enlazada simbólicamente a la herramienta vipw, mencionada anteriormente.
Estas herramientas de gestión de grupos modifican /etc/group y /etc/gshadow (en caso de existir), y solo pueden ser ejecutadas por root:
Ejemplos:
$ sudo groupadd -r -g 215 staff
$ sudo groupmod -g 101 blah
$ sudo groupdel newgroup
$ sudo usermod -G student,group1,group2 student
Nota: Sea muy cuidadoso con el comando usermod -G; la lista de grupos que le sigue corresponde a la lista completa, no solo a los cambios que desea realizar. Cualquier grupo que quede afuera de la lista ya no incluirá al usuario. Para evitar ese comportamiento utilice la opción -a, la cual preservará cualquier pertenencia previa a grupos al agregar otros nuevos.
Linux usa Grupos Privados de Usuario (UPG).
La idea detrás de UPG es que cada usuario tendrá su propio grupo. Sin embargo, no se garantiza que los UPG sean privados; miembros adicionales pueden ser agregados al grupo privado de alguien en /etc/group.
Por defecto, los usuarios cuyas cuentas son creadas con useradd tienen: GID principal = UID y el nombre del grupo es idéntico al de usuario.
Como se especifica en /etc/profile, el umask se configura en 002 para todos los usuarios creados con UPG. Bajo este esquema, los archivos de usuario son creados con permisos 644 (rw-rw-r--) y los directorios con 775 (rwxrwxr-x). Vamos a discutir umask en el capítulo siguiente.
Un usuario en Linux tiene un grupo primario; el grupo está en /etc/passwd y también en /etc/group. Un usuario puede pertenecer entre 0 a 15 grupos secundarios.
El grupo primario es el GID, el cual se usa cada vez que el usuario crea archivos o directorios. La pertenencia a grupos secundarios le concede permisos adicionales al usuario.
La pertenencia a grupos puede ser desplegada ejecutando:
$ groups [user1 user2 ...]
$ id -Gn [user1 user2 ...]
Sin argumentos, ambos comandos entregan la información asociada al usuario actual.
¿Cuál/es de las siguientes formas son válidas para agregar un usuario a un grupo existente?
Edite /etc/group con vigr y agregue los nombres de usuario al último campo usando comas entre ellos.
Usando useradd -G <group name> al crear un usuario.
Usando usermod -G <group name> para un usuario existente.
Usando "groups -add <group-name> user".
Actualmente usted debería ser capaz de:
- Explicar por qué es útil que los usuarios del sistema pertenezcan a uno o más grupos.
- Usar herramientas tales como groupadd, groupdel, groupmod y usermod para crear, eliminar y gestionar grupos y sus miembros.
- Describir los Grupos Privados de Usuario.
- Explicar el concepto de pertenencia al grupo.
35. Permisos de archivos y propietarios
En Linux cada archivo tiene un dueño quien tiene privilegios para leer y/o escribir, y/o ejecutar el archivo; estos permisos se asignan de forma independientemente. Tales permisos pueden ser otorgados sobre la base de pertenencia a un grupo o a todos los usuarios en el sistema. Este modelo de permisos de archivos y propietarios es el corazón del modelo de seguridad de Control de Acceso Discrecional.
Al final de este capítulo usted debería ser capaz de:
- Explicar los conceptos de propietario, grupo y mundo.
- Configurar los derechos de acceso a archivos (lectura, escritura y ejecución) para cada categoría.
- Autenticar solicitudes para accesar archivos, respetando los permisos que correspondan.
- Usar chmod para cambiar los permisos de archivos, chown para cambiar el usuario propietario y chgrp para cambiar el grupo propietario.
- Comprender el rol de umask en el establecimiento de permisos deseados en archivos nuevos.
- Usar ACLs para extender el modelo de usuarios, grupos, mundo, lectura, escritura y ejecución.
Cuando usted hace ls -l como aquí:
$ ls -l a_file
-rw-rw-r-- 1 coop aproject 1601 Mar 9 15:04 a_file
después del primer caracter, el cual indica el tipo del objeto archivo, hay nueve más que indican los derechos de acceso a potenciales usuarios de archivos. Estos se agrupan en tres grupos de tres caracteres:
- propietario: el usuario que es dueño del archivo (también llamado usuario).
- grupo: el grupo de usuarios que tiene acceso.
- mundo: el resto del mundo (también llamado otros).
En el ejemplo de arriba, el usuario es coop y el grupo es aproject.
Cada trío puede tener un elemento del siguiente conjunto:
- r: el acceso a lectura está permitido.
- w: el acceso a escritura está permitido.
- x: el acceso a ejecución está permitido.
Si el permiso no está permitido, aparece un - en vez de uno de estos caracteres.
Adicionalmente, existen otros permisos especializados para cada categoría, tales como los permisos setuid/setgid.
De esta forma, en el ejemplo anterior, el usuario coop y los miembros del grupo aproject tienen acceso a lectura y escritura, mientras que el resto tiene solo acceso a lectura.
Estos permisos de acceso a archivos son una parte crítica del sistema de seguridad de Linux. Cualquier solicitud de acceso a un archivo requiere la comparación de las credenciales e identidad del usuario con las del propietario del archivo.
Esta autenticación se concede dependiendo de uno de los siguientes tres conjuntos de permisos, en el siguiente orden:
- Si el solicitante es el propietario del archivo, se usan los permisos del propietario.
- Por otro lado, si el solicitando está en el grupo propietario de los archivos, se examinan los permisos del grupo.
- Si lo anterior no tiene éxito, se examinan los permisos del mundo.
La modificación de permisos de archivos se realiza con chmod. Usted puede cambiar los permisos de los archivos que son de su propiedad solamente, a menos que sea el superusuario.
Hay diversas formas de usar chmod. Por ejemplo, para otorgar permisos de ejecución al propietario y al mundo, y eliminar el permiso de escritura del grupo:
$ ls -l a_file
-rw-rw-r-- 1 coop coop 1601 Mar 9 15:04 a_file
$ chmod uo+x,g-w a_file
$ ls -l a_file
-rwxr--r-x 1 coop coop 1601 Mar 9 15:04 a_file
donde u representa el usuario (propietario), o a otros (mundo) y g el grupo.
Los permisos pueden ser representados ya sea como un mapa de bits, escrito generalmente en octal, o en una forma simbólica. Los mapas de bits octales generalmente lucen como 0755, mientras que las representaciones simbólicas lucen como u+rwx,g+rwx,o+rx.
La sintaxis simbólica puede ser difícil de escribir y recordar, por lo que a menudo se utiliza la abreviatura octal, la cual permite configurar todos los permisos en un paso. Esto se hace un con algoritmo simple, en donde una cifra es suficiente para especificar los tres bits de permisos para cada entidad. Esta cifra es la suma de:
- 4 si se desea otorgar permiso de lectura.
- 2 si se desea otorgar permiso de escritura.
- 1 si se desea otorgar permiso de ejecución.
Por lo tanto, 7 significa lectura/escritura/ejecución, 6 significa lectura/escritura y 5 lectura/ejecución.
Cuando esto se aplica con chmod, es necesario darle un valor para cada uno de los tres dígitos, tal como aquí:
$ chmod 755 a_file
$ ls -l a_file
-rwxr-xr-x 1 coop coop 1601 Mar 9 15:04 a_file
La modificación del propietario de un archivo se hace con chown y la del grupo con chgrp.
Solo el superusuario puede cambiar los propietarios de los archivos. Del mismo modo, usted puede cambiar los propietarios de los grupos de los cuales es miembro.
Cambiar el grupo propietario de un archivo es tan simple como:
$ chgrp aproject a_file
y cambiar el propietario es tan fácil como hacer:
$ chown coop a_file
Usted puede cambiar ambos al mismo tiempo con:
$ chown coop:aproject a_file
en donde se separa el usuario propietario del grupo con dos puntos (o uno).
Estos programas aceptan la opción -R, lo cual significa recursivo. Por ejemplo:
$ chown -R coop:aproject ./
$ chown -R coop:aproject subdir
el primer comando cambiará el usuario propietario y grupo de todos los archivos en el directorio actual. En el segundo comando se realizará la misma operación en el directorio subdir y todos sus subdirectorios.
Los permisos por defecto dados al crear un archivo son lectura/escritura para el propietario, grupo y mundo (0666). Para un directorio es lectura/escritura/ejecución para todos (0777). Sin embargo, si hace lo siguiente:
$ touch afile$ mkdir adir
$ ls -l | grep -e afile -e adir
drwxrwxr-x 2 coop coop 4096 Sep 16 11:18 adir
-rw-rw-r-- 1 coop coop 0 Sep 16 11:17 afile
notará que los permisos actuales cambiaron a 664 para el archivo y 775 para el directorio. Han sido modificados por el umask actual, cuyo propósito es mostrar qué permisos deberían ser denegados. El valor actual se puede mostrar con:
$ umask
0002
el cual es el valor más comúnmente configurado por los administradores de sistema para los usuarios. Este valor se combina con los permisos de creación de archivos para obtener el resultado real, es decir:
0666 & ~002 = 0664; i.e., rw-rw-r--
Puede cambiar el umask en cualquier momento con un comando como el siguiente:
$ umask 0022
Linux tiene una implementación completa de ACLs POSIX (listas de control de acceso), la cual extiende el modelo simple de usuario, grupo, mundo, lectura, escritura y ejecución.
Privilegios en particular pueden ser concedidos a usuarios específicos o grupos de usuarios al acceder ciertos objetos o clases de objetos. Es posible compartir archivos y directorios sin usar permisos 777.
Mientras que el kernel Linux habilita el uso de ACLs, aún debe ser implementado en el sistema de archivos en particular. Todos los sistemas de archivos principales usados en las distribuciones modernas de Linux incorporan las extensiones ACL, y es posible usarlas con la opción -acl al montar el sistema de archivos. Durante la instalación del sistema de archivos se crea un conjunto de ACLs por defecto.
Para ver las ACLs:
$ getfacl file|directory
Ejemplo:
$ getfacl file1
Para configurar ACLs:
$ setfacl options permissions file|directory
Ejemplos:
$ setfacl -m u:isabelle:rx /home/stephane/file1
$ setfacl -x u:isabelle /home/stephane/file
Tenga en cuenta que los archivos nuevos heredan la ACL predeterminada (si ha sido configurada) desde el directorio en el cual residen. Note también que mv y cp -p mantienen las ACLs.
Para eliminar una ACL:
$ setfacl -x u:isabelle /home/stephane/file1
Para establecer el valor predeterminado en un directorio:
$ setfacl -m d:u:isabelle:rx somedir
¿Cuál(es) de los siguientes comandos cambiaría(n) los permisos del archivo priv desde 0664 a -rwx------?
chown 0700 priv
chmod 0700 priv
chmod u+x,g-rw,o-r priv
¿Cuál(es) de los siguientes comandos cambiaría(n) los permisos del archivo priv desde -rwx------ a 0664?
chown 0664 priv
chmod -x
chmod u-x,g+rw,o+r priv
Actualmente usted debería ser capaz de:
- Explicar los conceptos de propietario, grupo y mundo.
- Configurar los derechos de acceso a archivos (lectura, escritura y ejecución) para cada categoría.
- Autenticar solicitudes para accesar archivos, respetando los permisos que correspondan.
- Usar chmod para cambiar los permisos de archivos, chown para cambiar el usuario propietario y chgrp para cambiar el grupo propietario.
- Comprender el rol de umask en el establecimiento de permisos deseados en archivos nuevos.
- Usar ACLs para extender el modelo de usuarios, grupos, mundo, lectura, escritura y ejecución.
36. Pluggable Authentication Modules (PAM)
El sistema Pluggable Authentication Modules provee un mecanismo uniforme para asegurar que usuarios y aplicaciones son identificados y autenticados apropiadamente. Es posible aplicar reglas condicionales para limitar el alcance de permisos, y puede establecerse un control sobre qué hacer en caso de éxito o fracaso. PAM también puede trabajar con LDAP para centralizar la autenticación a través de una red.
Al final de este capítulo usted debería ser capaz de:
- Explicar los conceptos básicos que motivan el uso de PAM.
- Listar los pasos involucrados en el proceso de autenticación.
- Usar y modificar los archivos de configuración de PAM.
- Saber cómo interpretar y crear reglas de PAM.
- Aplicar LDAP para usar y administrar servicios de directorio distribuidos en la red.
Históricamente la autenticación de usuarios se realizaba individualmente por las aplicaciones en sí: por ejemplo, su, login y ssh autenticarían y establecerían cuentas de usuario de forma independiente una de otra.
Las aplicaciones modernas de Linux han sido escritas o reescritas para usar PAM (Pluggable Authentication Modules), de tal forma que la autenticación puede llevarse a cabo de una manera uniforme, usando libpam.
Esta biblioteca de módulos provee una enorme flexibilidad y consistencia en relación a la autenticación, contraseñas, sesión y servicios de la cuenta.
PAM incorpora las siguientes componentes:
- Aplicaciones que trabajan con PAM.
- Archivos de configuración en /etc/pam.d/ .
- Módulos PAM en las bibliotecas libpam*, las cuales se encuentran en /lib/security, /lib/x86_64-linux-gnu o /lib64/security, dependiendo de la distribución.
Cada aplicación o servicio que trabaja con PAM debe ser configurada en relación a PAM, en un archivo de configuración individual en /etc/pam.d.
Son varios los pasos que están involucrados en la autenticación:
- Un usuario invoca a la aplicación que trabaja con PAM, tal como login, ssh o su.
- La aplicación llama a libpam.
- La biblioteca verifica si hay archivos relacionados en /etc/pam.d; estos definen qué módulos PAM se invocarán, incluyendo system-auth.
- Cada módulo referenciado se ejecuta de acuerdo con las reglas del archivo de configuración relevante para esta aplicación.
Cada archivo en /etc/pam.d corresponde a un servicio y cada línea (no comentada) en el archivo especifica una regla. El formato de la regla consiste en una lista de tokens separados por espacios, en donde los dos primeros pueden estar en mayúsculas o minúsculas:
type control module-path module-arguments
A modo de ejemplo, a continuación se muestra el contenido de /etc/pam.d/su en un sistema RHEL 7:
#%PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
#auth required pam_wheel.so use_uid
auth substack system-auth
auth include postlogin
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session include postlogin
session optional pam_xauth.so
Observe que aquí hay una serie de dependencias; su requerirá cargar system-auth, etc.
El módulo type especifica el grupo de gestión al que el módulo estará asociado:
- auth: Le indica a la aplicación que debe pedir la identificación del usuario (nombre de usuario, contraseña, etc). Puede configurar las credenciales y otorgar privilegios.
- account: Verifica aspectos de la cuenta del usuario, tales como envejecimiento de la contraseña, control de acceso, etc.
- password: Es responsable de actualizar el token de autenticación del usuario, generalmente una contraseña.
- session: Se usa para proveer funciones antes y después de que se establece la sesión (tales como la configuración del ambiente, inicio de sesión, etc).
El parámetro control controla cómo el éxito o fracaso de un módulo afecta el proceso general de autenticación:
- required: Debe devolver éxito para que el servicio se otorgue. Si es parte de un conjunto, el resto de módulos serán ejecutados. No se le informa a la aplicación qué módulo o módulos fallaron.
- requisite: Igual a required, con la excepción de que una falla en cualquier módulo termina el stack (conjunto de módulos) y devuelve un estado, el cual se envía a la aplicación.
- optional: El módulo no es requerido. Si este es el único módulo, el estado que se envía a la aplicación puede causar una falla.
- sufficient: Si este módulo termina con éxito no hay módulos subsecuentes a ser ejecutados. Si este falla, no causa una falla general en el resto de módulos, a menos de que sea el único módulo del stack.
Hay otros parámetros para control, tales como include y substack. Por favor haga man pam.d para ver los detalles.
module-path da el nombre del archivo de la biblioteca que se encuentra en /lib*/security, ya que en un forma de ruta absoluta o relativa.
module-arguments puede ser proporcionado para modificar el comportamiento del módulo PAM.
LDAP (Protocolo Ligero de Acceso a Directorios) es un protocolo estándar de la industria para usar y administrar servicios de directorios distribuidos sobre la red, el cual fue creado para ser abierto y neutral al proveedor.
Al usar LDAP para autenticación centralizada, cada sistema (o cliente) se conecta a un servidor LDAP centralizado para la autenticación del usuario. El uso de TLS hace que sea una opción segura y recomendada.
LDAP usa PAM y system-config-authentication o authconfig-tui. Es necesario especificar el servidor, base de búsqueda de DN (nombre de dominio) y TLS (Seguridad de la Capa de Transporte). También se requiere openldap-clients, pam_ldap y nss-pam-ldapd.
Se modifican cinco archivos al configurar un sistema para autenticación con LDAP:
/etc/openldap/ldap.conf
/etc/pam_ldap.conf
/etc/nslcd.conf
/etc/sssd/sssd.conf
/etc/nsswitch.conf
Usted puede editar estos archivos manualmente o usar uno de los programas disponibles (system-config-authentication o authconfig-tui).
¿Cuáles de las siguientes afirmaciones son ciertas?
- La diferencia entre los parámetros de control required y requisite es que este último es más permisivo. Cuando un conjunto de módulos que está configurado como requisite falla, el resto de módulos se ejecuta de todas formas.
- Si un módulo termina con éxito, la diferencia entre los parámetros de control optional y sufficient es que el éxito de un módulo configurado en optional no impide que otros módulos en el stack se continúen ejecutando, mientras que un módulo con sufficient lo impide.
Actualmente usted debería ser capaz de:
- Explicar los conceptos básicos que motivan el uso de PAM.
- Listar los pasos involucrados en el proceso de autenticación.
- Usar y modificar los archivos de configuración de PAM.
- Saber cómo interpretar las reglas de PAM y crear nuevas.
- Aplicar LDAP para usar y administrar servicios de directorio distribuidos en la red.
37. Métodos de respaldos y recuperación de la información
Los sistemas que no tienen una estrategia bien definida de copias de seguridad están mal administrados, independientemente de si hospedan un entorno de usuario único o una red empresarial con múltiples sistemas y usuarios. Tarde o temprano la información crítica se va a perder, ya sea debido a una falla de hardware, errores del usuario o del administrador, o a ataques maliciosos. Ser capaz de recuperar el sistema con la mínima pérdida posible de forma rápida y eficiente es una responsabilidad crítica que debe llevarse a cabo.
Nota: se usarán los términos respaldo o copia de seguridad indistintamente.
Al final de este capítulo usted debería ser capaz de:
- Identificar y priorizar la información de la que es necesario tomar una copia de seguridad.
- Emplear diferentes métodos de copia de seguridad, dependiendo de la situación.
- Establecer estrategias eficientes de copia de seguridad y recuperación.
- Usar diferentes herramientas para sacar copias de seguridad, tales como cpio, tar, gzip, bzip2, xz, dd, rsync, dump, restore y mt.
- Describir los dos programas de copia de seguridad más conocidos, Amanda y Bacula.
Ya sea que usted esté administrando solo un sistema personal o una red con muchas máquinas, las copias de seguridad del sistema son muy importantes. Algunas de las razones son las siguientes:
- Los datos son valiosos.
Los datos en disco son producto de trabajo importante y por lo tanto una mercancía que debemos proteger. Recrear datos perdidos cuesta tiempo y dinero. Ciertos datos incluso pueden ser únicos y podría no haber una forma para recrearlos. - Fallas de hardware.
A medida en la que la fiabilidad ha aumentado, también lo ha hecho la capacidad en disco. Aún si la tasa de falla por byte disminuye, todavía se producirían fallas impredecibles. Puede ser pesimista decir que hay solo dos tipos de discos: aquellos que fallaron y los que fallarán, pero es esencialmente cierto. El uso de RAID ayuda, pero las copias de seguridad aún son necesarias. - Fallas de software.
Ningún software es perfecto. Algunos bugs pueden destruir o corromper la información. Aún los programas estables que se han usado por mucho tiempo pueden tener problemas. - La gente comete errores.
Todos han escuchado alguna vez ¡OOPS! (o algo mucho peor) del cubículo de al lado (o desde su propia boca). A veces un simple error de tipeo puede causar una destrucción de archivos e información a gran escala. - Personas maliciosas pueden causar daño deliberadamente.
Podría ser el empleado descontento canónico o un hacker externo con un objetivo específico. Las preocupaciones de seguridad y las capacidades de realizar copias de seguridad están estrechamente relacionadas. - Eventos inexplicables.
Los archivos pueden desaparecer sin que usted sepa cómo, quién o incluso cuándo ocurrió. - Las copias de seguridad anteriores pueden ser útiles.
A veces restaurar a una snapshot anterior de una parte o todo el sistema puede ser requerido.
Es crítico respaldar ciertos datos, otros son menos críticos y de algunos no se necesita tomar una copia de seguridad. En orden de prioridad:
- Definitivamente:
- Datos relacionados con el negocio.
- Archivos de configuración del sistema.
- Archivos de usuarios (generalmente en /home). - Tal vez:
- Directorios de cola (para imprimir, email, etc).
- Archivos del registro (que se encuentran en /var/log y en otras partes). - Probablemente no:
- Software que puede ser reinstalado fácilmente; en un sistema bien gestionado esto sería prácticamente todo.
- El directorio /tmp, porque su contenido está pensado para ser temporal solamente. - Definitivamente no:
- Pseudosistemas de archivos tales como /proc, /dev y /sys.
- Cualquier partición o archivo de intercambio.
Obviamente los archivos esenciales de su organización requieren ser respaldados. Los archivos de configuración pueden cambiar frecuentemente, y junto a los archivos de los usuarios requieren una copia de seguridad también.
Los archivos del registro pueden ser importante si usted tiene que investigar la historia del sistema, lo cual puede ser particularmente importante para detectar intrusiones y otras violaciones a la seguridad.
Las unidades de cinta no son tan comunes como solían ser. Son relativamente lentas y permiten el acceso secuencial solamente. En cualquier configuración moderna rara vez se utilizan como respaldo primario. A veces se usan para almacenamiento fuera de línea para disponer de referencias en el largo plazo. Sin embargo, las cintas magnéticas tienen un ciclo de vida finito antes de que se degraden físicamente y comiencen a perder datos.
Los dispositivos modernos de cinta son generalmente del tipo LTO (Linear Tape Open), cuyas primeras versiones aparecieron a fines de los '90 como una alternativa de estándares abiertos; la mayoría de los primeros formatos fueron propietarios. Las versiones tempranas almacenaban hasta 100 GB; las versiones más nuevas pueden contener 2.5 TB o más en un cartucho del mismo tamaño.
Día a día las copias de seguridad son tomadas con alguna forma de NAS (Network Attached Storage) o con soluciones basadas en la nube, lo cual hace que las instalaciones basadas en cintas sean cada vez menos atractivas. Sin embargo, todavía se pueden encontrar sistemas que las usan y los administradores de sistemas podrían requerir trabajar con ellas.
De aquí en adelante trataremos de no enfocarnos en algún tipo particular de equipo para el medio de respaldo, por lo cual nos referiremos a ello de forma abstracta.
No se debe tener todas las copias de seguridad en el mismo lugar físico que el de los sistemas que se están protegiendo. De otra forma, un incendio u otro daño físico podría causar una pérdida completa. En el pasado esto generalmente significaba tener que transportar físicamente las cintas magnéticas a un lugar seguro. Actualmente esto significa más bien transferir las copias de seguridad a través de la red a un lugar físico alternativo. Obviamente esto tiene que realizarse de forma segura, usando cifrado de datos y otras precauciones de seguridad.
Es posible usar diferentes métodos de respaldos, los cuales a menudo trabajan de forma coordinada entre ellos:
- Completo:
Respalda todos los archivos en el sistema. - Incremental:
Respalda todos los archivos que han cambiado desde la última copia de seguridad incremental o completa. - Diferencial:
Respalda todos los archivos que han cambiado desde la última copia de seguridad completa. - Nivel incremental múltiple:
Respalda todos los archivos que han cambiado desde la copia de seguridad previa en el mismo nivel o en uno previo. - Usuario:
Solamente se respalda el contenido del directorio de un usuario específico.
Debemos tener en cuenta que los métodos de respaldo son inútiles sin métodos de recuperación asociados. Uno tiene que considerar la robustez, claridad y facilidad de ambas estrategias al seleccionarlas.
El esquema de copia de seguridad más simple consiste en tomar un respaldo completo una vez, y luego realizar respaldos incrementales de todo lo que cambia posteriormente. Aunque los respaldos pueden tomar mucho tiempo, restaurar la información desde un respaldo incremental puede ser más difícil y de todas formas consume tiempo. Por lo tanto, es posible aplicar una mezcla de ambos para optimizar el tiempo y esfuerzo.
Un ejemplo de una estrategia útil que implica cintas (usted puede sustituir fácilmente por otro medio en la descripción):
- Use la cinta 1 para tomar un respaldo completo el viernes.
- Use las cintas 2-5 para copias de seguridad incrementales de lunes a jueves.
- Use la cinta 6 para un respaldo completo el segundo viernes.
- Use las cintas 2-5 para copias de seguridad incrementales de lunes a jueves (segunda vez).
- No sobreescriba la cinta 1 hasta que complete el respaldo completo en la cinta 6.
- Luego de tener un respaldo completo en la cinta 6, mueva la cinta 1 a un lugar externo para restauración en caso de desastre.
- En el siguiente respaldo completo (próximo viernes) traiga la cinta 1 y reemplácela por la 6.
Una buena regla de oro es disponer de al menos dos semanas en copias de seguridad.
Son varios los programas que se usan con propósitos de realizar copias de seguridad:
- cpio
- tar
- gzip, bzip2, xz
cpio y tar crean y extraen archivos que contienen archivos. Los archivos a menudo están comprimidos con gzip, bzip2, o xz. El archivo contenedor puede escribirse a disco, cinta magnética o cualquier otro dispositivo que pueda almacenar archivos. Los archivos de este tipo son muy útiles para transferir archivos desde un sistema de archivos a otro o entre máquinas. - dd
Esta es una herramienta poderosa que se usa a menudo para transferir datos en bruto entre medios. Es capaz de copiar particiones o discos completos. - rsync
Esta herramienta potente puede sincronizar árboles de subdirectorios o sistemas de archivos completos a través de una red, o entre diferentes lugares del sistema de archivos en una máquina local. - dump y restore
Estas herramientas son antiguas y fueron diseñadas específicamente para realizar copias de seguridad. Leen directamente desde el sistema de archivos, lo cual es más eficiente. Sin embargo, los archivos deben ser restaurados en el mismo tipo de sistema de archivos del cual provienen. Hay alternativas más nuevas. - mt
Es útil para consultar y posicionar cintas antes de realizar copias de seguridad y restaurarlas.
cpio (copy in and out) es una herramienta general de compresión de archivos que ha existido desde los primeros días de UNIX y fue diseñada originalmente para realizar copias de seguridad de cintas. Pese a que se han desarrollado otros programas más nuevos de este tipo (como tar, el cual no es exactamente nuevo) para realizar muchas de las tareas que estaban en el dominio de cpio, este sobrevive todavía.
Por ejemplo, ya hemos visto el uso de rpm2cpio para convertir paquetes RPM en archivos cpio y luego extraerlos. También el kernel Linux usa una versión de cpio internamente para tratar con sistemas de archivos de ram inicial initramfs e initrd, como también con discos durante el arranque. Una de las razones por las cuales cpio vive todavía es que es más liviano que tar y sus sucesores, aunque es un poco menos robusto.
Ejemplos del uso de cpio:
- Crear un archivo: use -o o --create:
$ ls | cpio --create -O /dev/st0 - Extraer un archivo: use -i o --extract:
$ cpio -i -I /dev/st0 somefile - Listar el contenido de un archivo: use -t o --list:
$ cpio -t -I /dev/st0
Usted puede especificar la entrada (-I dispositivo) o salida (-O dispositivo), o usar una redirección en la línea de comandos.
La opción -o o --create instruye a cpio a copiar archivos hacia el archivo comprimido. cpio lee una lista de nombres de archivos (uno por línea) desde la entrada estándar y escribe el archivo a la salida estándar.
La opción -i o --extract instruye a cpio a copiar archivos desde un archivo comprimido, leyendo el archivo desde la entrada estándar. Si usted lista nombres de archivos como patrones (tales como *.c) en la línea de comandos, solo los archivos en el archivo comprimido que coinciden con el patrón van a ser copiados desde el archivo comprimido. Si no se proveen patrones, se extraen todos los archivos.
La opción -t o --list instruye a cpio a listar el contenido del archivo. Si se agrega la opción -v o --verbose se genera un listado largo.
tar es más fácil de usar que cpio:
- Al crear un archivo tar se especifica uno o más directorios como argumentos, cuyos archivos y subdirectorios se incluirán en el archivo.
- Al restaurarlo, este reconstruye los directorios según sea necesario.
- Incluso tiene una opción --newer que permite realizar respaldos incrementales.
- La versión de tar que se usa en Linux también puede manipular respaldos que no caben en una cinta o cualquier dispositivo que utilice.
A continuación hay un ejemplo de cómo usar tar para respaldos:
- Crear un archivo usando -c o --create:
$ tar --create --file /dev/st0 /root
$ tar -cvf /dev/st0 /root
Puede especificar un dispositivo o archivo con las opciones -f o --file. - Crear con la opción de múltiples volúmenes usando -M o --multi-volume si su copia de seguridad no cabe en un solo dispositivo:
$ tar -cMf /dev/st0 /root
Se le pedirá que ponga la cinta siguiente cuando sea necesario. - Verifique los archivos con la opción comparar, usando -d o --compare:
$ tar --compare --verbose --file /dev/st0
$ tar -dvf /dev/st0
Después de hacer una copia de seguridad, asegúrese de que está completa y es la correcta, usando la opción de verificación anterior.
Por defecto tar incluirá recursivamente todos los subdirectorios en el archivo.
Cuando se crea un archivo, tar imprime un mensaje acerca de la eliminación de los slashes de la ruta absoluta del nombre. Si bien es cierto que esto permite restaurar los archivos en cualquier lugar, el comportamiento por defecto puede ser cambiado.
La mayoría de las opciones de tar pueden especificarse en la forma corta con un guión, o de forma larga con dos: -c es completamente equivalente a --create.
Note que también puede combinar opciones (al usar la notación corta), de tal forma que no es necesario tipear cada guión.
Además, las opciones cortas de tar pueden usarse con o sin guiones; es decir, tar cvf file.tar dir1 tiene el mismo resultado que tar -cvf file.tar dir1.
La opción -x o --extract extrae archivos desde un archivo comprimido, todos por defecto. Es posible limitar la lista de extracción al especificar los archivos en particular. Si se especifica un directorio, todos los archivos y subdirectorios incluidos también serán extraídos.
La opción -p o --same-permissions se asegura de que los archivos son restaurados con los permisos originales.
La opción -t o --list lista los archivos incluidos en el archivo comprimido, pero no los extrae.
Ejemplos:
- Extrae un archivo:
$ tar --extract --same-permissions --verbose --file /dev/st0
$ tar -xpvf /dev/st0
$ tar xpvf /dev/st0 - Especificar algunos archivos para restaurar:
$ tar xvf /dev/st0 somefile - Listar el contenido de un respaldo tar:
$ tar --list --file /dev/st0
$ tar -tf /dev/st0
Usted puede hacer respaldos incrementales con tar usando la opción -N (o el equivalente --newer) o --after-date. Cualquiera de estas opciones requiere que se especifique ya sea una fecha o un nombre de archivo de referencia:
$ tar --create --newer '2011-12-1' -vf backup1.tar /var/tmp
$ tar --create --after-date '2011-12-1' -vzf backup1.tar /var/tmp
Cualquiera de estas formas crea una copia de seguridad en /var/tmp de todos los archivos que fueron creados después del 1ero de diciembre de 2011.
Debido a que tar solo revisa la fecha de un archivo, no considera otros cambios al archivo, tales como permisos o nombre de archivo. Para incluir archivos con este tipo de cambios en el respaldo incremental, use find y cree una lista de archivos a ser tomados en cuenta.
Nota: cuando se usa algún parámetro como --newer, usted debe usar el guión en los parámetros como -vzf, de lo contrario tar se confundirá. Esta confusión relacionada al tipo de la especificación del parámetro ocurre con herramientas antiguas de UNIX, tales como ps y tar, las cuales tienen historias complicadas que involucran diferentes familias de UNIX.
A menudo se desea comprimir archivos para ahorrar espacio en disco y/o tiempo de transmisión por la red, especialmente porque las máquinas modernas encontrarán que el ciclo comprimir>transmitir>descomprimir más rápido que simplemente transmitir (o copiar) un archivo sin comprimir.
Hay una serie de esquemas de compresión comunes en Linux. Para incrementar la eficiente de la compresión (lo cual implica tiempos de compresión mayores):
- gzip: Usa un algoritmo Lempel-Ziv (LZ77) y genera archivos .gz.
- bzip2: Usa algoritmos de compresión de Burrows-Wheeler y de codificación de Huffman. Genera archivos .bz2.
- xz: Genera archivos .xz y también soporta formato .lzma.
Los tiempos de descomprensión no varían tanto como los de compresión. Usualmente se usa gzip para el uso diario en archivos más pequeños, ya que es extremadamente rápido. Pero para archivos grandes y para propósitos de almacenamiento de un registro de archivos se usan a menudo los otros dos. Por ejemplo, http://www.kernel.org ya no ofrece kernels Linux en formato gzip.
El formato .zip se usa raramente en Linux excepto para extraer archivos antiguos desde otros sistemas operativos.
Las herramientas de compresión se usan fácilmente y a menudo en combinación con tar:
$ tar zcvf source.tar.gz source
$ tar jcvf source.tar.bz2 source
$ tar Jcvf source.tar.xz source
para generar un archivo comprimido. Note que el primer comando tiene exactamente el mismo efecto que si uno hace:
$ tar cvf source.tar source ; gzip -v source.tar
pero es más eficiente debido a que:
- No hay un almacenamiento intermedio del archivo.
- El archivado y compresión suceden simultáneamente en la tubería (pipeline).
Para descomprimir:
$ tar xzvf source.tar.gz
$ tar xjvf source.tar.bz2
$ tar xJvf source.tar.xz
o aún más simple:
$ tar xvf source.tar.gz
las versiones modernas de tar pueden detectar el método de compresión y hacerse cargo automáticamente.
Obviamente no vale la pena usar estos métodos en archivos cuyos archivos ya están comprimidos, tales como imágenes .jpg, archivos .pdf, etc.
dd es una de las herramientas originales de UNIX y es extremadamente versátil. Si se ejecuta sin parámetros realiza una copia de datos en bruto de archivos o incluso de discos completos. Es capaz de realizar todo tipo de conversiones de datos durante la copia (tales como cambiar el orden de los bytes) y tiene opciones para controlar offsets, número de bytes, tamaño de bloque, etc.
dd se usa a menudo para leer cantidades fijas de datos desde nodos de dispositivos especiales tales como /dev/zero o /dev/random. La sintaxis básica es la siguiente:
$ dd if=input-file of=output-file options
si no se especifican los archivos de entrada o salida, se utiliza por defecto stdin y stdout. Si se hace:
$ dd --help
mostrará una lista de opciones muy larga, algunas usadas frecuentemente y otras en muy raras ocasiones.
Aquí hay algunos ejemplos del uso de dd:
- Crear un archivo de 10 MB lleno con ceros:
$ dd if=/dev/zero of=outfile bs=1M count=10 - Hacer una copia de seguridad de un disco duro completo a otro (datos en bruto):
$ dd if=/dev/sda of=/dev/sdb - Crear una imagen de un disco duro (la cual podría transferirse a otro disco más tarde):
$ dd if=/dev/sda of=sdadisk.img - Respaldar una partición:
$ dd if=/dev/sda1 of=partition1.img - Usar dd en una tubería:
$ dd if=ndata conv=swab count=1024 | uniq > ofile
rsync (sincronización remota) se usa para transferir archivos a través de una red (o entre diferentes lugares en la misma máquina), con la siguiente sintaxis:
$ rsync [options] source destination
La fuente y el destino toman la siguiente forma: target:path, donde target puede estar en el formato [user@]host. La parte user@ es opcional y se usa si el usuario remoto es diferente al local. Por lo tanto, estos son todos los comandos rsync posibles:
$ rsync file.tar someone@backup.mydomain:/usr/local
$ rsync -r a-machine:/usr/local b-machine:/usr/
$ rsync -r --dry-run /usr/local /BACKUP/usr
Tiene que ser muy cuidadoso con rsync en relación a las localizaciones específicas (especialmente si usa la opción --delete), por lo que es altamente recomendado usar la opción dry-run primero y luego llevar a cabo la acción si la proyección luce correcta.
rsync es muy inteligente; verifica los archivos locales contra los remotos en trozos pequeños. Es muy eficiente cuando copia a un directorio destino similar, ya que solo se copian las diferencias a través de la red. Esto sincroniza el segundo directorio con el primero. A menudo se usa la opción -r, la cual causa que rsync copie todo el contenido del directorio recursivamente, por debajo de lo que figura como sourcefile. Por lo tanto una forma muy útil de respaldar un directorio de un proyecto en curso sería similar a:
$ rsync -r project-X archive-machine:archives/project-X
Una estrategia de respaldo simple (también muy efectiva y rápida) consiste en duplicar directorios o particiones a través de la red, con comandos rsync y hacerlo de forma frecuente.
Las herramientas dump y restore han existido desde los primeros días de UNIX y no fueron diseñadas originalmente para hardware, sistemas de archivos y almacenamiento modernos.
A diferencia de cpio y tar, estas herramientas leen y escriben directamente en el sistema de archivos, lo cual es más eficiente y permite que se creen archivos de respaldo sin afectar sus marcas de tiempo.
Las ventajas incluyen:
- Pueden realizar respaldos completos o incrementales.
- Entienden el formato específico del sistema, cómo leer y escribir en él.
- Son eficientes al crear respaldos completos, reduce el movimiento del cabezal.
- Puede especificar el tamaño de salida de la cinta y la densidad, tamaño del bloque y la cuenta, o incluso ambos.
- Puede exportar a cualquier dispositivo o archivo válido. Por defecto lo hace a /dev/tape.
- Los parámetros en /etc/fstab controlan qué se respalda con dump y cuándo.
Las desventajas incluyen:
- Se requieren múltiples pasadas por el sistema de archivos para realizar un respaldo.
- Solo funciona para sistemas de archivos ext2, ext3 y ext4 (otros sistemas de archivos pueden tener sus propias herramientas, tales como xfsdump).
- No se puede ejecutar de forma segura en sistemas de archivos montados.
La falta de flexibilidad en el sistema de archivos es una limitación bastante fuerte, tanto por la multiplicidad de tipos de sistemas de archivos en Linux, como también debido a la tendencia moderna de abstraerse a los detalles, por ejemplo cómo se almacenan los datos.
dump y restore a veces son usados por programas de respaldo de más alto nivel, como Amanda. Cierta familiaridad con estas herramientas antiguas es útil.
dump tiene una serie de opciones, las que incluyen configurar parámetros. Algunas de estas son:
- -0-9
Nivel de dump: Nivel 0 es un respaldo completo y los números mayores son incrementales. - -B records
Registros por volumen. - -b blocksize
KB por registro. - -f file
Dispositivo o archivo de salida. - -u
Actualiza /etc/dumpdates. - -W
Imprime la fecha más recientes de dump de cada sistema de archivos en /etc/dumpdates.
Los valores de los parámetros no necesitan ser suministrados después de la opción, pero deben incluirse en el mismo orden en que las opciones los especifican.
Aquí hay un ejemplo muy simple de un dump completo de nivel 0 de una partición /dev/sda2 montada en /boot_master:
$ sudo dump -0uf /tmp/boot_backup /boot_master
DUMP: Date of this level 0 dump: Mon Nov 3 12:54:40 2014
DUMP: Dumping /dev/sda2 (/boot_master) to /tmp/boot_backup
DUMP: Label: boot
DUMP: Writing 10 Kilobyte records
DUMP: mapping (Pass I) [regular files]
DUMP: mapping (Pass II) [directories]
DUMP: estimated 985 blocks.
DUMP: Volume 1 started with block 1 at: Mon Nov 3 12:54:40 2014
DUMP: dumping (Pass III) [directories]
DUMP: dumping (Pass IV) [regular files]
DUMP: Closing /tmp/boot_backup
DUMP: Volume 1 completed at: Mon Nov 3 12:54:40 2014
DUMP: Volume 1 1030 blocks (1.01MB)
DUMP: 1030 blocks (1.01MB) on 1 volume(s)
DUMP: finished in less than a second
DUMP: Date of this level 0 dump: Mon Nov 3 12:54:40 2014
DUMP: Date this dump completed: Mon Nov 3 12:54:40 2014
DUMP: Average transfer rate: 0 kB/s
DUMP: DUMP IS DONE
$ cat /etc/dumpdates
/dev/sda2 0 Mon Nov 3 12:54:40 2014 -0600
restore se usa para leer archivos comprimidos, cintas o archivos que fueron creados con dump. Por ejemplo, para restaurar todos los archivos que fueron objeto de dump, en relación al directorio actual:
$ sudo restore -rvf /tmp/boot_backup
Parámetros útiles de restore:
- -r
Restaura todo. Se lee el material creado con dump y el contenido completo se carga en el directorio actual. - -t
Los archivos y directorios especificados son listados en la salida estándar si están en el respaldo. Si no se especifica un archivo como parámetro, se lista el directorio raíz en la copia de seguridad. Esta opción en realidad no restaura archivos. - -x
Los archivos y directorios nombrados se extraen desde la copia de seguridad. Si el archivo mencionado coincide con un directorio en el respaldo, el directorio se extrae recursivamente. Si no se proveen argumentos, entonces se extrae todo el contenido desde el respaldo. - -i
Este modo permite la restauración interactiva de archivos desde la copia de seguridad. Después de leer la información del directorio en el respaldo, restore provee una interfaz tipo shell que le permite al usuario moverse a través del árbol de directorios y seleccionar los archivos a extraer.
No se puede usar -r y -x al mismo tiempo.
La herramienta mt se usa para controlar dispositivos de cintas magnéticas. Se usa con mayor frecuencia para consultar o posicionar la cinta antes o después de realizar copias de seguridad y restaurar datos. Por defecto, mt usa la unidad de cinta definida en la variable de ambiente TAPE. También es posible usar el parámetro -f device para especificar la cinta.
Tenga en cuenta que solo el usuario root puede usar mt. La sintaxis es la siguiente:
mt [-h] [-f device] operation [count] [arguments...]
donde
- -h: despliega la ayuda
- -f device: especifica la unidad de cinta
- operation: es una de las operaciones sobre la cinta
- count: se usa para algunas operaciones que se pueden repetir (el valor predeterminado es 1)
- arguments: se usan en algunas operaciones
Abajo hay unos pocos ejemplos del uso de mt:
- Muestra información del estado del dispositivo de cinta:
$ mt status - Rebobinar la cinta:
$ mt rewind - Borrar la cinta:
$ mt erase - Moverse hasta el final del archivo actual:
$ mt fsf
No hay escasez de programas de respaldo disponibles en Linux, incluyendo aplicaciones propietarias o aquellas suministradas por vendedores de almacenamiento, como también aplicaciones de código abierto. Algunas de las que son particularmente bien conocidas son:
- Amanda (Advanced Maryland Automatic Network Disk Archiver) usa herramientas nativas (incluyendo tar y dump) pero es mucho más robusta y manejable.
Amanda está disponible generalmente en sistemas Linux Empresariales a través de los repositorios habituales. Se puede encontrar información completa al respecto en http://www.amanda.org. - Bacula está diseñado para realizar copias de seguridad automáticas en redes heterogéneas. Puede ser más complicado de usar y se recomienda (por los mismos autores) para administradores experimentados solamente.
Bacula está disponible generalmente en sistemas Linux Empresariales a través de los repositorios habituales. Se puede encontrar información completa al respecto en http://www.bacula.org/7.0.x-manuals/en/main/Main_Reference.html. - Clonezilla es un programa de clonación de discos muy robusto, el cual puede crear imágenes de discos y desplegarlas, ya sea para restaurar una copia de seguridad o para proveer una imagen que pueda usarse para instalar muchas máquinas. Se puede encontrar información completa en http://clonezilla.org.
El programa viene en dos versiones: Clonezilla live, la cual es apropiada para realizar respaldos y restauraciones a una máquina. La otra es Clonezilla SE (server edition), la cual puede clonar muchos computadores a la vez.
Clonezilla no es muy difícil de usar y es extremadamente flexible; soporta muchos sistemas operativos (no solo Linux), tipos de sistemas de archivos y cargadores de arranque.
Para las siguientes preguntas considere solo las características de la herramienta, y no lo que podría realizarse conectando múltiples herramientas con pipas "|" o scripts. Ignore los casos en los cuales múltiples invocaciones de la misma herramienta puede habilitar usos exóticos.
¿Cuáles de las siguientes afirmaciones son ciertas?
- tar puede crear un archivo a partir de múltiples archivos.
- tar tiene características embebidas para enviar datos a través de la red.
- tar puede leer discos en bruto tales como /dev/sda.
- tar tiene características embebidas de compresión de datos.
- tar tiene características embebidas para trabajar con cambios incrementales.
- tar tiene características embebidas para copiar múltiples archivos.
- dd puede crear un archivo de múltiples archivos.
- dd tiene características embebidas para enviar datos a través de la red.
- dd puede leer discos en bruto tales como /dev/sda.
- dd tiene características embebidas de compresión de datos.
- dd tiene características embebidas para trabajar con cambios incrementales.
- dd tiene características embebidas para copiar múltiples archivos.
- rsync puede crear un archivo a partir de múltiples archivos.
- rsync tiene características embebidas para enviar datos a través de la red.
- rsync puede leer discos en bruto tales como /dev/sda.
- rsync tiene características embebidas de compresión de datos.
- rsync tiene características embebidas para trabajar con cambios incrementales.
- rsync tiene características embebidas para copiar múltiples archivos.
Actualmente usted debería ser capaz de:
- Identificar y priorizar la información de la que es necesario tomar una copia de seguridad.
- Emplear diferentes métodos de copia de seguridad, dependiendo de la situación.
- Establecer estrategias eficientes de copia de seguridad y recuperación.
- Usar diferentes herramientas para sacar copias de seguridad, tales como cpio, tar, gzip, bzip2, xz, dd, rsync, dump, restore y mt.
- Describir los dos programas de copia de seguridad más conocidos, Amanda y Bacula.
38. Direcciones de red
Las máquinas en red necesitan poder localizarse entre ellas basándose en su dirección única de red. Las direcciones y redes IPv4 todavía son las más comúnmente usadas pero tienen una capacidad de expansión limitada. Las direcciones IPv6, las que aún no son tan ampliamente usadas, superan esa limitante. Las direcciones tienen diferentes clases de acuerdo al tamaño de las redes locales y es importante ser capaz de reconocer la clase basándose en la dirección.
Al final de este capítulo usted debería ser capaz de:
- Explicar el propósito de las direcciones de red.
- Diferenciar entre los distintos tipos de direcciones IPv4 e IPv6.
- Explicar qué clases de direcciones existen e identificarlas.
- Obtener, configurar y cambiar el hostname.
Las direcciones IP se usan para identificar globalmente y de forma única a los nodos en la red. Están registradas a través de los ISPs (Internet Service Providers).
La dirección IP es el número que identifica su sistema en la red. Está presente en dos tipos:
- IPv4: Una dirección de 32 bits, compuesta de 4 octetos (un octeto son 8 bits, o un byte). Ejemplo:
148.114.252.10 - IPv6: Una dirección de 128 bits, compuesta de 16 octetos. Ejemplo:
2003:0db5:6123:0000:1f4f:0000:5529:fe23
En ambos casos se considera un conjunto de direcciones reservadas. A menos que se indique lo contrario, nos enfocaremos en IPv4 solamente.
Los tipos de direcciones IPv4 incluyen:
- Unicast:
Una dirección asociada a un host específico. Puede ser algo como 140.211.169.4 o 64.254.248.193. - Red:
Una dirección cuya posición del host está en cero (todos los dígitos binarios en 0). Ejemplo: 192.168.1.0 (la posición del host puede estar en los últimos 1 a 3 octetos como veremos más adelante. Aquí solo nos referimos al último octeto). - Broadcast:
Una dirección en la cual cada miembro de una red en particular escuchará. Tendrá la sección del host en 1, tal como en 172.16.255.255, 148.114.255.255 o 192.168.1.255 (la posición del host son los dos últimos octetos en los primeros dos casos, y en el tercer caso es el último octeto). - Multicast:
Una dirección en la que los nodos configurados apropiadamente escucharán. La dirección 224.0.0.2 es un ejemplo de dirección multicast. Solo los nodos específicamente configurados para prestar atención a una dirección multicast interpretarán los paquetes para ese grupo multicast.
Ciertas direcciones y rangos de direcciones están reservadas para propósitos especiales:
- 127.x.x.x
Reservada para la interfaz loopback (sistema local), donde 0 <= x <= 254. Generalmente es 127.0.0.1. - 0.0.0.0
Usada por sistemas que aún no conocen su propia dirección. Protocolos como DHCP y BOOTP usan esta dirección cuando intentan comunicarse con un servidor. - 255.255.255.255
Dirección privada genérica de broadcast, reservada para uso interno. Estas direcciones nunca se asignan o registran. Generalmente no son enrutables. - Otros ejemplos de rangos de direcciones reservadas incluyen:
10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255
etc.
Cada uno de estos rangos tiene un propósito. Por ejemplo, el rango de direcciones conocidas 192.168.x.x solo se usa para comunicaciones locales dentro de una red privada.
Puede ver una lista larga de direcciones reservadas tanto para IPv4 como IPv6 en http://en.wikipedia.org/wiki/Reserved_IP_addresses.
Los tipos de direcciones IPv6 incluyen:
- Unicast:
Un paquete se entrega a una interfaz solamente.
- Enlace local: Autoconfigurado para que toda interfaz tenga uno. No enrutable.
- Global: Asignado dinámica o manualmente. Enrutable.
- Reservado para documentación. - Multicast:
Un paquete se entrega a múltiples interfaces. - Anycast:
Un paquete se entrega a la interfaz más cercana de un conjunto (en términos de distancia de enrutamiento). - IPv4-mapped:
Una dirección IPv4 mapeada a IPv6. Por ejemplo ::FFFF:a.b.c.d/96
Adicionalmente, IPv6 tiene algunos tipos especiales de direcciones, tales como loopback, la cual se asigna a la interfaz lo, como ::1/128.
Históricamente, las direcciones IP se han basado en clases definidas. Las clases A, B y C se usan para distinguir la parte de la red de la dirección en relación a la del host. Esto se utiliza con propósitos de enrutamiento.
Clase de Red | Rango de octeto de orden más alto | Notas |
---|---|---|
A | 1-127 | 128 redes, 16,772,214 hosts por red, 127.x.x.x reservado para loopback |
B | 128-191 | 16,384 redes, 65,534 hosts por red |
C | 192-223 | 2,097,152 redes, 254 hosts por red |
D | 224-239 | Direcciones multicast |
E | 240-254 | Rango de direcciones reservadas |
La máscara de red (netmask) se usa para determinar qué porción de la dirección se usa para la red y cuánto para la parte del host. También se usa para determinar las direcciones de la red y de broadcast.
Clase de Red | Decimal | Hexadecimal | Binario |
---|---|---|---|
A | 255.0.0.0 | ff:00:00:00 | 11111111 00000000 00000000 00000000 |
B | 255.255.0.0 | ff:ff:00:00 | 11111111 11111111 00000000 00000000 |
C | 255.255.255.0 | ff:ff:ff:00 | 11111111 11111111 11111111 00000000 |
Las direcciones de Clase A usan 8 bits para la porción de red de la dirección y 24 bits para la del host.
Las direcciones de Clase B usan 16 bits para la porción de red de la dirección y 16 bits para la del host.
Las direcciones de Clase C usan 24 bits para la porción de red de la dirección y 8 bits para la del host.
Las direcciones de Clase D se usan para multicast.
Las direcciones de Clase E no se usan actualmente.
La dirección de red se obtiene a través de una operación AND lógica entre la dirección IP y la máscara de red. Nos interesan las direcciones de red porque definen una red local, la cual consiste en un conjunto de nodos conectados a través del mismo medio de comunicación, compartiendo la misma dirección de red. Los nodos en una misma red se pueden ver entre sí.
Ejemplo:
172.16.2.17 dirección ip
&255.255.0.0 máscara de red
-----------------
172.16.0.0 dirección de red
El hostname es una etiqueta que se usa para identificar un dispositivo en la red, con el fin de diferenciarlo de otros elementos. Históricamente también ha sido llamado nodename (nombre de nodo).
Para efectos del DNS, a los hostnames se les agrega un punto y un nombre de dominio, de tal forma que un hostname llamado antje podría tener un fully qualified domain name (FQDN) como antje.linuxfoundation.org.
El hostname generalmente se configura durante la instalación y puede modificarse en cualquier momento posterior.
En cualquier momento es posible obtener el hostname fácilmente, con el siguiente comando:
$ hostname
wally
Para cambiar el hostname basta con pasar un parámetro:
$ sudo hostname lumpy
lumpy
Cambiar el nombre del hostname de esa manera no es persistente; al reiniciar el sistema, se volverá al valor que tenía antes de la modificación. Tenga en cuenta que en la mayoría de las distribuciones Linux el valor actual se almacena en /etc/hostname (en openSUSE está en /etc/HOSTNAME).
Como es usual, para que los cambios sean persistentes es necesario cambiar un archivo de configuración en el árbol de directorios /etc. En sistemas basados en Red Hat esto se ha hecho desde un comienzo en /etc/sysconfig/network, como se muestra aquí:
$ cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=gilbert
NTPSERVERARGS=iburst
En sistemas basados en Debian se puede editar (como root) el archivo /etc/hostname y especificar un nombre nuevo. En algunos sistemas basados en SUSE esto se hace en /etc/HOSTNAME.
Nota: RHEL 7 ya no tiene el archivo /etc/sysconfig/network. Junto con versiones recientes de Ubuntu tal como 14.04 LTS y sistemas basados en SUSE, esta usa la herramienta hostnamectl, la cual proviene de la infraestructura systemd:
$ hostnamectl --help
hostnamectl [OPTIONS...] COMMAND ...
Query or change system hostname.
-h --help Show this help
--version Show package version
--transient Only set transient hostname
--static Only set static hostname
--pretty Only set pretty hostname
-P --privileged Acquire privileges before execution
--no-ask-password Do not prompt for password
-H --host=[USER@]HOST Operate on remote host
Commands:
status Show current hostname settings
set-hostname NAME Set system hostname
set-icon-name NAME Set icon name for host
set-chassis NAME Set chassis type for host
Cambiar el hostname es tan simple como hacer lo siguiente:
$ sudo hostnamectl set-hostname MYPC
La mayoría de las distribuciones no usan el hostname para nada.
¿Cuáles de las siguientes afirmaciones son ciertas?
- La máscara de red no es importante si las direcciones IP están en la misma clase. La configuración de la máscara se ignora en la comunicación entre los hosts con direcciones 192.168.1.10 y 192.168.1.100.
- IPv4 tiene más direcciones que IPv6.
- 192.168.128.255 es una IP válida para un host en una red local si la máscara de red está configurada en 255.255.255.0.
No hay ejercicios de laboratorio en este capítulo. Solamente se prepara el escenario para el capítulo siguiente sobre la configuración de red, el cual tiene varios laboratorios.
Actualmente usted debería ser capaz de:
- Explicar el propósito de las direcciones de red.
- Diferenciar entre los distintos tipos de direcciones IPv4 e IPv6.
- Explicar qué clases de direcciones existen e identificarlas.
- Obtener, configurar y cambiar el hostname.
39. Configuración de dispositivos de red
Los dispositivos de red tales como conexiones Ethernet e inalámbricas requieren una configuración cuidadosa, especialmente cuando hay múltiples dispositivos del mismo tipo. El asunto de la consistencia y persistencia de los nombres de dispositivos puede tornarse complicado en tales circunstancias. Recientemente, la adopción de nuevos esquemas ha vuelto más predecible la asignación de nombres.
Se usa un número importante de herramientas para activar los dispositivos, configurar sus características, establecer rutas, etc. Y los administradores de sistemas deben convertirse en expertos en su uso.
Al final de este capítulo usted debería ser capaz de:
- Ser capaz de identificar dispositivos de red y entender cómo el sistema operativo les asigna nombres y vincula a tareas específicas.
- Usar ifconfig para configurar, controlar y consultar parámetros de una interfaz red, ya sea desde la línea de comandos o desde scripts de configuración del sistema.
- Usar la herramienta ip para desplegar y controlar dispositivos, enrutamiento, enrutamiento basado en políticas y túneles (tunnelling).
- Saber cómo configurar rutas por defecto y rutas estáticas.
- Configurar la resolución de nombres como también ejecutar herramientas de diagnóstico.
A diferencia de los dispositivos de bloques y caracteres, los dispositivos de red no están asociados a archivos de dispositivos especiales, también conocidos como nodos de dispositivo. En vez de tener entradas asociadas en el directorio /dev, son conocidos por sus nombres.
Estos nombres consisten en un identificador de tipo seguido por un número, como los siguientes:
- eth0, eth1, eth2 etc. para dispositivos Ethernet.
- wlan0, wlan1, wlan2 etc. para dispositivos inalámbricos.
- br0, br1, br2 etc. para interfaces de puente de red (bridge).
- vmnet0, vmnet1, vmnet2, etc. para dispositivos virtuales de VMware para la comunicación con clientes virtuales.
A veces múltiples dispositivos virtuales pueden estar asociados con dispositivos físicos individuales; estos se nombran con dos puntos y números, de tal forma que eth0:0 sería el primer alias en el dispositivo eth0. Esto se hace para soportar múltiples direcciones IP en una tarjeta de red.
Las convenciones clásicas de dispositivos de nombres descritas anteriormente presentaban algunos problemas, particularmente cuando varias interfaces del mismo tipo estaban presentes. Por ejemplo, supongamos que el sistema tiene dos tarjetas de red; una sería nombrada eth0 y la otra eth1. Sin embargo, ¿qué dispositivo físico debería estar asociado a cada nombre?
El método más simple sería que el primer dispositivo encontrado fuera eth0, el segundo eth1, etc. Desafortunadamente el sondeo de los dispositivos no es determinístico en los sistemas modernos y los dispositivos pueden ser ubicados o conectados en un orden impredecible. Por lo anterior, se podría terminar con la interfaz de internet intercambiada con la local. Incluso si el hardware no cambia, el orden en el cual las interfaces se detectan podría variar según la versión del kernel y la configuración.
Muchos administradores de sistemas han solucionado este problema de una manera simple; a través de la inclusión manual de asociaciones entre las direcciones de hardware (MAC) y los nombres de dispositivos en los archivos de configuración del sistema y scripts de arranque. Si bien es cierto que este método ha funcionado por años, requiere de ajuste manual y tiene otros problemas, como cuando las direcciones MAC no eran fijas; esto puede pasar tanto en sistemas embebidos como sistemas virtualizados.
El esquema Nombres Predecibles de las Interfaces de Red está fuertemente relacionado con el uso de udev y la integración con systemd. Actualmente hay 5 tipos de nombres que los dispositivos pueden recibir:
- Incorporando números de índices proporcionados por el Firmware o la BIOS para dispositivos integrados:
Ejemplo: eno1 - Incorporando números de índices de slots hotplug de PCI Express proporcionados por el Firmware o la BIOS:
Ejemplo: ens1 - Incorporando ubicación física y/o geográfica de la conexión de hardware:
Ejemplo: enp2s0 - Incorporando la dirección MAC:
Ejemplo: enx7837d1ea46da - Usando el método clásico:
Ejemplo: eth0
Por ejemplo, en una máquina con dos interfaces de red PCI que habrían sido eth0 y eth1:
$ ifconfig | grep enp
enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
enp4s2: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
Estos nombres están correlacionados con las ubicaciones físicas del hardware en el sistema PCI:
02:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8056 PCI-E Gigabit Ethernet Controller (rev 12)
04:02.0 Ethernet controller: Marvell Technology Group Ltd. 88E8001 Gigabit Ethernet Controller (rev 14)
El trío de números al comienzo de cada línea de la salida lspci es el bus, dispositivo (o slot) y función del dispositivo, información con la cual se obtiene la ubicación física.
De la misma forma, para un dispositivo que anteriormente se hubiese sido llamado wlan0:
$ ifconfig grep wl
wlp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
$ lspci | grep Centrino
03:00.0 Network controller: Intel Corporation Centrino Advanced-N 6205 [Taylor Peak] (rev 34)
Vemos el mismo patrón. Es fácil desactivar el nuevo esquema y volver a los nombres clásicos. Vamos a dejar eso como un proyecto de investigación. De aquí en adelante vamos a usar los nombres clásicos en pro de la claridad y simplicidad.
Una serie de archivos (dependientes de la distribución de Linux) almacenan información de la configuración de las NIC persistentes.
En RHEL 6 tenemos:
$ cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=bethe
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="dhcp"
HWADDR="00:0C:29:26:3F:B3"
IPV6INIT="yes"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="5b52bee2-8fda-450d-729e-3996dd12ef7d"
En openSUSE 13.1 tenemos:
$ cat /etc/sysconfig/network/ifcfg-eno16777736
$ cat /etc/sysconfig/network/ifcfg-eno2ps1
nux-n292:/etc/sysconfig/network> sudo cat ifcfg-enp2s1
BOOTPROTO='dhcp'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR=''
MTU=''
NAME='82545EM Gigabit Ethernet Controller (Copper)'
NETMASK=''
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='auto'
USERCONTROL='no'
En Ubuntu 14.04 (representante de los sistemas basados en Debian):
$ cat /etc/network/interfaces
auto lo
iface lo inet loopback
iface eth0 inet static
address 192.168.1.5
netmask 255.255.255.0
gateway 192.168.1.254
auto eth1
iface eth1 inet dhcp
Tenga en cuenta que puede desactivar directamente una interfaz así:
$ ifdown eth0
o activarla de la siguiente forma:
$ ifup eth0
Las interfaces de red también pueden configurarse al vuelo usando ya sea ifconfig o las herramientas ip. Sin embargo estas configuraciones no son persistentes.
ifconfig es una herramienta de administración de sistemas que se encuentra en sistemas operativos tipo UNIX y que sirve para configurar, controlar y consultar los parámetros de las interfaces de red ya sea desde la línea de comandos o desde scripts de configuración del sistema. También a menudo es invocado por los scripts de inicio de la red. Aquí hay algunos ejemplos:
- Mostrar información de todas las interfaces:
$ ifconfig - Mostrar información de eth0 solamente:
$ ifconfig eth0 - Configurar la dirección IP en 192.168.1.50 en la interfaz eth0:
$ sudo ifconfig eth0 192.168.1.50 - Configurar la máscara de red a 24 bits:
$ sudo ifconfig eth0 netmask 255.255.255.0 - Activar la interfaz eth0:
$ sudo ifconfig eth0 up - Desactivar la interfaz eth0:
$ sudo ifconfig eth0 down - Configurar el MTU (Maximum Transfer Unit) en 1480 bytes en la interfaz eth0:
$ sudo ifconfig eth0 mtu 1480
ip es una herramienta de la línea de comandos más nueva (y lejos más versátil) que la conocida ifconfig. A nivel técnico es más eficiente porque usa sockets netlink en vez de llamadas ioctl al sistema.
ip puede usarse para una amplia variedad de tareas. Puede ser usado para desplegar y controlar dispositivos, enrutamiento, políticas de enrutamiento y túneles (tunneling).
La sintaxis básica es:
ip [ OPTIONS ] OBJECT { COMMAND | help }
ip [ -force ] -batch filename
en donde la segunda forma puede leer comandos desde un archivo especificado.
ip es una herramienta múltiple: el argumento OBJECT describe qué tipo de acción se va a realizar. Los valores posibles de COMMAND dependen de la elección del valor de OBJECT.
OBJECT | Función |
---|---|
address | Dirección del dispositivo de protocolo IPv4 o IPv6 |
link | Dispositivos de red |
maddress | Dirección Multicast |
monitor | Monitorear mensajes netlink |
route | Entrada de la tabla de enrutamiento |
rule | Regla en la base de datos de políticas de enrutamiento |
tunnel | Túnel sobre IP |
La herramienta ip puede usarse de varias formas, tales como:
- Mostrar información de todas las interfaces:
$ ip link - Mostrar información de eth0 solamente:
$ ip -s link show eth0 - Configurar la dirección IP de eth0:
$ sudo ip addr add 192.168.1.7 dev eth0 - Desactivar la interfaz eth0:
$ sudo ip link set eth0 down - Configurar el MTU en 1480 bytes en la interfaz eth0:
$ sudo ip link set eth0 mtu 1480 - Configurar la ruta de red:
$ sudo ip route add 172.16.1.0/24 via 192.168.1.5
Enrutamiento es el proceso de seleccionar vías en una red a través de la cual enviar tráfico de red. La tabla de enrutamiento es una lista de rutas a otras redes manejadas por el sistema. Define vías a todas las redes y hosts, enviando tráfico a routers remotos.
Con el comando route es posible visualizar la tabla de enrutamiento actual:
$ /sbin/route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.1.1 0.0.0.0 UG 1024 0 0 enp2s0
172.16.132.0 0.0.0.0 255.255.255.0 U 0 0 0 vmnet1
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 enp2s0
192.168.113.0 0.0.0.0 255.255.255.0 U 0 0 0 vmnet8
o con ip:
$ ip route
default via 192.168.1.1 dev enp2s0 proto static metric 1024
172.16.132.0/24 dev vmnet1 proto kernel scope link src 172.16.132.1
192.168.1.0/24 dev enp2s0 proto kernel scope link src 192.168.1.100
192.168.113.0/24 dev vmnet8 proto kernel scope link src 192.168.113.1
La ruta por defecto corresponde a la vía por la cual se envían paquetes cuando no hay otra coincidencia en la tabla de enrutamiento para alcanzar la ruta especificada.
Puede obtenerse dinámicamente usando DHCP. Sin embargo, también puede configurarse manualmente (estática). En sistemas basados en Red Hat es posible configurar la ruta por defecto en el archivo /etc/sysconfig/network, en el siguiente parámetro:
GATEWAY=x.x.x.x
o alternativamente en /etc/sysconfig/network-scripts/ifcfg-ethX, en el parámetro del dispositivo específico en el archivo de configuración de la NIC individual. En equivalente en sistemas basados en Debian es:
gateway=x.x.x.x
en /etc/network/interfaces.
En cualquier sistema es posible configurar el router por defecto con un comando como el siguiente:
$ sudo route add default gw 192.168.1.10 enp2s0$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.1.10 0.0.0.0 UG 0 0 0 enp2s0
default 192.168.1.1 0.0.0.0 UG 1024 0 0 enp2s0
172.16.132.0 0.0.0.0 255.255.255.0 U 0 0 0 vmnet1
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 enp2s0
192.168.113.0 0.0.0.0 255.255.255.0 U 0 0 0 vmnet8
Tenga en cuenta que esto podría dejarlo sin conexión a la red. Usted puede restaurarla ya sea reconfigurando la red, o haciendo lo siguiente en relación al ejemplo anterior:
$ sudo route add default gw 192.168.1.1 enp2s0
Estos cambios no son persistentes y no sobrevivirán luego de reiniciar el sistema.
Las rutas estáticas se usan para controlar el flujo de paquetes cuando hay más de un router o ruta. Están definidas para cada interfaz y pueden ser persistentes o no.
Cuando el sistema puede acceder más de una ruta, o tal vez donde hay varias interfaces de red, es útil controlar selectivamente qué paquetes van a qué router.
Se puede usar ya sea el comando route o ip para configurar una ruta no persistente, tal como aquí:
$ sudo ip route add 10.5.0.0/16 via 192.168.1.100$ route
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
10.5.0.0 quad 255.255.0.0 UG 0 0 0 eth0
192.168.1.0 * 255.255.255.0 U 1 0 0 eth0
Una ruta persistente puede ser configurada editando /etc/sysconfig/network-scripts/route-ethX como se muestra aquí:
$ cat /etc/sysconfig/network-scripts/route-eth0
10.5.0.0/16 via 172.17.9.1
En un sistema basado en Debian es necesario agregar líneas al archivo /etc/network/interfaces tales como:
iface eth1 inet dhcp
post-up route add -host 10.1.2.51 eth1
post-up route add -host 10.1.2.52 eth1
En un sistema basado en SUSE es necesario agregar líneas a /etc/sysconfig/network/ifroute-eth0 (o crear el archivo si no existe) como las siguientes:
# Destination Gateway Netmask Interface [Type] [Options]
192.168.1.150 192.168.1.1 255.255.255.255 eth0
10.1.1.150 192.168.233.1.1 eth0
10.1.1.0/24 192.168.1.1 - eth0
en donde los campos están separados por tabs.
La resolución de nombres es el acto de traducir hostnames a la dirección IP de sus sistemas correspondientes. Por ejemplo, un navegador o cliente de correo electrónico recibirá training.linuxfoundation.org y resolverá el nombre de la dirección IP del servidor (o servidores) que sirven training.linuxfoundation.org para transmitir datos a y desde esa ubicación en internet.
Hay dos vías para realizar esta traducción:
- Resolución estática de nombres (usando /etc/hosts).
- Resolución dinámica de nombres (usando servidores DNS).
A veces también se requiere resolución inversa: convertir una dirección IP a un hostname.
/etc/hosts mantiene una base de datos local de hostnames y direcciones IP. Contiene un conjunto de registros (uno por línea), el cual mapea direcciones IP con sus correspondientes hostnames y alias.
Un archivo /etc/hosts típico luce como esto:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.100 hans hans7 hans64
192.168.1.150 bethe bethe7 bethe64
192.168.1.2 hp-printer
192.168.1.10 test32 test64 oldpc
Esta resolución de nombres estática se usa principalmente para redes locales, pequeñas y aisladas. Generalmente se verifica antes de usar un servidor DNS para resolver una dirección; sin embargo, esta prioridad puede ser controlada en /etc/nsswitch.conf.
Si la resolución de nombres no puede realizarse localmente usando /etc/hosts, entonces el sistema consultará a un servidor DNS (Domain Name Server).
El DNS es dinámico y consiste en una red de servidores, los cuales son usados por clientes para buscar nombres. El servicio es distribuido; cada servidor DNS tiene información acerca de su zona de autoridad solamente. Sin embargo, todos ellos juntos pueden colaborar para resolver cualquier nombre.
El uso del cliente DNS se configura en /etc/resolv.conf, el cual históricamente ha tenido una forma como la siguiente:
search example.com aps.org
nameserver 192.168.1.1
nameserver 8.8.8.8
lo cual:
- Puede especificar dominios de búsqueda en particular.
- Define un orden estricto de servidores de nombre para consultar.
- Puede configurarse manualmente o ser actualizado desde un servicio como DHCP (Dynamic Host Configuration Protocol).
La mayoría de los sistemas modernos tienen un archivo /etc/hosts.resolv, el cual es generado automáticamente y luce de la siguiente forma:
# Generated by NetworkManager
192.168.1.1
el cual fue generado por NetworkManager, invocando DHCP en la interfaz de red principal.
Hay una serie de utilidades básicas de red en la caja de herramientas de cada administrador de sistemas, incluyendo:
- ping:
Envía paquetes de prueba de 64 bytes a determinados hosts en la red, y si los encuentra, trata de enviar un reporte de vuelta en relación a los tiempos requeridos para alcanzarlo (en milisegundos). También se incluyen los paquetes perdidos y algunos otros parámetros. Considere que la salida exacta variará de acuerdo al host objetivo, pero al menos podrá ver que la red está funcionando y que el host es accesible. - traceroute:
Se usa para mostrar una ruta de red a un destino. Muestra los paquetes a través de los routers hasta alcanzar el host, como también el tiempo que toma en cada salto (hop). - mtr:
Combina la funcionalidad de ping y traceroute, y muestra una salida continuamente actualizada, como top. - dig:
Es útil para probar la funcionalidad de DNS. Tenga en cuenta que también se puede usar host o nslookup, programas más antiguos que también devuelven información del DNS de un host.
Note que algunas distribuciones recientes (como RHEL 7) requieren privilegios de root (o sudo) para ejecutar las primeras tres herramientas de diagnóstico mencionadas.
Ejemplos:
$ ping -c 10 linuxfoundation.org
$ traceroute linuxfoundation.org
$ mtr linuxfoundation.org
Su estación de trabajo está conectada a la red local de Acme Company. En la red local hay otras estaciones de trabajo, un servidor DNS y un servidor web para el dominio http://intranet.acme.com. La conexión a internet también es suministrada por la red local. Elija verdadero o falso para la sentencia de a continuación.
¿Cuáles de las siguientes afirmaciones son ciertas?
- Eliminar la configuración del router desde su estación de trabajo no tiene impacto en el acceso a los recursos de la red local.
- Eliminar la configuración del router desde su estación de trabajo no tiene impacto en el acceso a los recursos en internet.
- Eliminar la configuración del DNS desde su estación de trabajo no tiene impacto en el acceso a los recursos de la red local.
- Eliminar la configuración del DNS desde su estación de trabajo no tiene impacto en el acceso a los recursos de internet.
- Agregar una entrada a /etc/hosts puede permitir que su estación de trabajo acceda a http://intranet.acme.com cuando el servidor DNS no está funcionando.
Actualmente usted debería ser capaz de:
- Ser capaz de identificar dispositivos de red y entender cómo el sistema operativo les asigna nombres y vincula a tareas específicas.
- Usar ifconfig para configurar, controlar y consultar parámetros de una interfaz red, ya sea desde la línea de comandos o desde scripts de configuración del sistema.
- Usar la herramienta ip para desplegar y controlar dispositivos, enrutamiento, enrutamiento basado en políticas y túneles (tunnelling).
- Saber cómo configurar rutas por defecto y rutas estáticas.
- Configurar la resolución de nombres como también ejecutar herramientas de diagnóstico.
40. Cortafuegos
Los cortafuegos se usan para controlar tanto el acceso entrante como saliente a los sistemas y a la red local. Es un equipo esencial de seguridad en las redes modernas, en donde las intrusiones y otros tipos de ataques son una realidad cotidiana en cualquier computador conectado a internet. Es posible controlar el nivel de confianza que ofrece el tráfico a través de interfaces particulares. y/o con direcciones de red específicas.
Al final de este capítulo usted debería ser capaz de:
- Entender qué es un cortafuegos y porqué son necesarios.
- Saber qué herramientas están disponibles tanto en la línea de comandos como en la interfaz gráfica.
- Familiarizarse con firewalld y el programa firewall-cmd.
- Saber cómo trabajar con zonas, fuentes, servicios y puertos.
Un cortafuegos es un sistema de seguridad de red que monitorea y controla todo el tráfico de la red. Aplica reglas tanto en conexiones de red entrantes como salientes, como también construye barreras flexibles (es decir, cortafuegos) dependiendo del nivel de seguridad de una conexión determinada.
Los cortafuegos pueden estar basados en hardware o software. Se encuentran tanto en enrutadores de red como también en computadores individuales, o nodos de red. Muchos cortafuegos también tienen capacidades de enrutamiento.
Los primeros cortafuegos (que datan de finales de los 80s) estaban basados en filtrado de paquetes; el contenido de cada paquete de red era inspeccionado y era ya sea eliminado, rechazado o enviado. No se tenía en cuenta el estado de la conexión; a qué stream o tráfico pertenecía el paquete.
La siguiente generación de cortafuegos estuvo basada en filtros de estado, los cuales examinaban el estado de la conexión del paquete, entre otras cosas; si era una conexión nueva, parte de una existente o de ninguna. Los ataques de denegación de servicio pueden bombardear este tipo de cortafuegos para tratar de sobrecargarlo y desactivarlo.
La tercera generación de cortafuegos se llama Cortafuegos de Capa de Aplicación, y están conscientes del tipo de aplicación y del protocolo que está usando la conexión. Pueden bloquear cualquier cosa que no debería ser parte del flujo normal.
La configuración del sistema del cortafuegos puede ser realizada con:
- Usando herramientas relativamente de bajo nivel desde la línea de comandos, combinado con la edición de varios archivos de configuración en el árbol de subdirectorios /etc:
iptables
firewall-cmd
ufw - Usando interfaces gráficas robustas:
system-config-firewall
firewall-config
gufw
yast
Trabajaremos con las herramientas de bajo nivel por las siguientes razones:
- Cambian menos a menudo que las herramientas gráficas.
- Tienden a tener un conjunto más amplio de capacidades.
- Varían poco de una distribución a otra, mientras que las GUI tienen a ser muy diferentes y cada una de ellas se limita a una sola familia de distribuciones.
La desventaja es que pueden ser más difíciles de aprender al comienzo. De aquí en adelante vamos a concentrarnos en el uso del paquete moderno firewalld, el cual incluye tanto firewall-cmd como firewall-config. Hay distribuciones que no lo traen por defecto (como RHEL 6), sin embargo no es un problema, ya que puede ser instalado desde las fuentes fácilmente, cosa que haremos como ejercicio de ser necesario.
firewalld es el Administrador Dinámico del Cortafuegos. Utiliza zonas de red/cortafuegos que han definido niveles de confianza para interfaces de red o conexiones. Soporta los protocolos IPv4 e IPv6.
Adicionalmente, separa los cambios a la configuración que se realizan en tiempo de ejecución de los persistentes. También incluye interfaces para servicios o aplicaciones, para agregar reglas al cortafuegos.
Los archivos de configuración se guardan en /etc/firewalld y /usr/lib/firewalld; los archivos en /etc/firewalld anulan los del otro directorio y un administrador de sistemas debería trabajar sobre ellos.
La herramienta de la línea de comando es firewall-cmd, la cual discutiremos pronto. Recomendamos que antes de seguir adelante ejecute:
$ firewall-cmd --help
Usage: firewall-cmd [OPTIONS...]
....
Status Options
--state Return and print firewalld state
--reload Reload firewall and keep state information
--complete-reload Reload firewall and loose state information
--runtime-to-permanent Create permanent from runtime configuration
....
lo cual muestra alrededor de 200 líneas, demasiado largo para incluirlo aquí.
Sin embargo, verá que la mayoría de las opciones son obvias ya que están correctamente nombradas. Como servicio, firewalld reemplaza el antiguo iptables. Es un error ejecutar ambos servicios - firewalld e iptables - al mismo tiempo.
firewalld es un servicio que debe estar en ejecución para usar el cortafuegos, y se habilita/deshabilita, o inicia y detiene de la forma habitual:
$ sudo systemctl [enable/disable] firewalld
$ sudo systemctl [start/stop] firewalld
Es posible mostrar el estado actual de cualquiera de las formas siguientes:
$ sudo systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
Active: active (running) since Tue 2015-04-28 12:00:59 CDT; 5min ago
Main PID: 777 (firewalld)
CGroup: /system.slice/firewalld.service
777 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
Apr 28 12:00:59 CentOS7 systemd[1]: Started firewalld - dynamic firewall daemon.
$ sudo firewall-cmd --state
running
Tenga en cuenta que si tiene más de una interfaz de red al usar IPv4, usted tiene que activar ip forwarding. Puede hacer esto en tiempo de ejecución con una de las dos alternativas:
$ sudo sysctl net.ipv4.ip_forward=1
$ echo 1 > /proc/sys/net/ipv4/ip_forward (necesita ejecutarse como root para que echo funcione apropiadamente)
Sin embargo esto no es persistente. Para hacerlo persistente, tiene que agregar la siguiente línea a
/etc/sysctl.conf:
net.ipv4.ip_forward=1
y luego reincie o ejecute:
$ sudo sysctl -p
para usar la configuración nueva sin tener que reiniciar.
firewalld trabaja con zonas, cada una de las cuales tiene un nivel definido de seguridad y un cierto comportamiento ya definido para paquetes entrantes y salientes. Cada interfaz pertenece a una zona en particular. Normalmente NetworkManager le informa a firewalld acerca de la zona que aplica, pero esto puede modificarse con firewall-cmd o la GUI firewall-config.
Las zonas son:
drop
Todos los paquetes entrantes son eliminados sin una respuesta. Solo se permiten las conexiones salientes.
block
Todas las conexiones entrantes son rechazadas. Las únicas conexiones permitidas son las internas del sistema.
public
No confíe en ningún computador en la red; solo ciertas conexiones entrantes seleccionadas conscientemente están permitidas.
external
Se utiliza cuando masquerading está en uso, como en los routers. Los niveles de confianza son los mismos que en public.
dmz (Zona desmilitarizada)
Se usa cuando algunos (pero no todos) servicios están permitidos al público. Solo se permiten conexiones entrantes en particular.
work
Confía (pero no completamente) en los nodos conectados que no son perjudiciales. Solo se permiten ciertas conexiones entrantes.
home
Usted confía en la mayoría de los demás nodos en la red, pero aún selecciona qué conexiones entrantes están permitidas.
internal
Es similar a la zona work.
trusted
Todas las conexiones de red están permitidas.
Durante la instalación del sistema, la mayoría, por no decir todas las distribuciones Linux seleccionarán la zona pública por defecto para todas las interfaces. Las diferencias entre algunas de las zonas descritas anteriormente no son obvias, pero tampoco necesitamos entrar mucho en detalle, pero tenga en cuenta que no hay que usar una zona más abierta de lo que realmente se necesita.
Obtener la zona por defecto:
$ sudo firewall-cmd --get-default-zone
public
Obtener una lista de las zonas actualmente en uso:
$ sudo firewall-cmd --get-active-zones
public
interfaces: eno16777736
Listar todas las zonas disponibles:
$ sudo firewall-cmd --get-zones
block dmz drop external home internal public trusted work
Para cambiar la zona por defecto a trusted y luego volver atrás:
$ sudo firewall-cmd --set-default-zone=home
success
$ sudo firewall-cmd --set-default-zone=public
success
Para asignar temporalmente una interfaz a una zona en particular:
$ sudo firewall-cmd --zone=internal --change-interface=eno1
success
Para hacerlo permanentemente:
$ sudo firewall-cmd --permanent --zone=internal --change-interface=eno1
success
lo cual crea el archivo /etc/firewalld/zones/internal.xml.
Para determinar la zona asociada con una interfaz en particular:
$ sudo firewall-cmd --get-zone-of-interface=eno1
public
Finalmente, para obtener todos los detalles acerca de una zona en particular:
$ sudo firewall-cmd --zone=public --list-all
public (default, active)
interfaces: eno16777736
sources:
services: dhcpv6-client ssh
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
Cualquier zona puede estar ligada no solo a una interfaz de red, sino que también a una dirección de red en particular. Un paquete está asociado a una zona si:
- Este proviene desde una dirección fuente que ya está asociada a la zona. O por otra parte:
- Este proviene desde una interfaz asociada a la zona.
Cualquier paquete que no encaje en los criterios anteriores se asigna a la zona por defecto (que generalmente es public).
Para asignar una fuente a una zona (permanentemente):
$ sudo firewall-cmd --permanent --zone=trusted --add-source=192.168.1.0/24
success
Esto dice que cualquier paquete con dirección IP 192.168.1.x será agregado a la zona trusted.
Tenga en cuenta que puede remover una fuente previamente asignada a una zona usando la opción --remove-source, o cambiar la zona usando --change-source.
Puede listar las fuentes asociadas a una zona con:
$ sudo firewall-cmd --permanent --zone=trusted --list-sources
192.168.1.0/24
En ambos comandos anteriores, si quita la opción --permanent obtendrá el comportamiento actual en tiempo de ejecución solamente.
Hasta el momento hemos asignado interfaces particulares y/o direcciones a zonas, pero no hemos delineado qué servicios y puertos deben estar accesibles en una zona.
Para ver todos los servicios disponibles:
$ sudo firewall-cmd --get-services
RH-Satellite-6 amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns ftp \
high-availability http https imaps ipp ipp-client ipsec kerberos kpasswd ldap ldaps \
libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi \
pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind samba samba-client smtp ssh \
telnet tftp tftp-client transmission-client vnc-server wbem-https
o para ver aquellos accesibles actualmente en una zona en particular:
$ sudo firewall-cmd --list-services --zone=public
dhcpv6-client ssh
Para agregar un servicio a una zona:
$ sudo firewall-cmd --permanent --zone=home --add-service=dhcp
success
$ sudo firewall-cmd --reload
El segundo comando, con --reload, es necesario para que los cambios sean efectivos. También es posible agregar servicios editando los archivos en /etc/firewalld/services.
La gestión de puertos es muy similar a la de servicios:
$ sudo firewall-cmd --zone=home --add-port=21/tcp
success
$ sudo firewall-cmd --zone=home --list-ports
21/tcp
en donde examinando /etc/services podemos comprobar que el puerto 21 corresponde a ftp:
$ grep " 21/tcp" /etc/services
ftp 21/tcp
Actualmente usted debería ser capaz de:
- Entender qué es un cortafuegos y porqué son necesarios.
- Saber qué herramientas están disponibles tanto en la línea de comandos como en la interfaz gráfica.
- Familiarizarse con firewalld y el programa firewall-cmd.
- Saber cómo trabajar con zonas, fuentes, servicios y puertos.
41. Resolución básica de problemas
Incluso los sistemas Linux mejores administrados presentarán problemas. La resolución básica de problemas puede determinar si un problema proviene de software o hardware, como también si son del sistema local, o provienen desde la red local o internet. Se requiere de un juicio adecuado y experiencia, y si bien es cierto que siempre será una forma de arte, el seguir procedimientos buenos y metódicos realmente puede ayudar a aislar las fuentes de problemas de manera reproducible.
Al final de este capítulo usted debería ser capaz de:
- Resolver problemas básicos en su sistema, siguiendo un número de pasos de forma iterativa hasta que se encuentren soluciones.
- Verificar la red y la integridad de archivos por posibles problemas.
- Resolver problemas cuando hay una falla en el arranque del sistema.
- Reparar y recuperar sistemas de archivos dañados.
- Entender cómo pueden usarse los medios de rescate y recuperación para resolver problemas.
Hay tres niveles en la solución de problemas:
- Pricipiante: Tiene todavía grandes posibilidades de ampliar sus conocimientos.
- Experimentado: Es algo que se consigue luego de algunos años de práctica.
- Experto: Algunas personas piensan que el experto nació para esto, pero no tiene sentido, ya que todas las habilidades necesarias se pueden adquirir. Todas las organizaciones deberían tener al menos una persona en este nivel de experiencia a la cual recurrir cuando sea requerido.
La resolución de problemas involucra realizar una serie de pasos, los cuales necesitan repetirse de forma iterativa hasta encontrar soluciones. Una receta básica podría ser la siguiente:
- Identificar y describir el problema.
- Reproducir el problema.
- Siempre intentar las cosas fáciles primero.
- Descartar las causas posibles de una en una.
- Cambie una sola cosa a la vez; si eso no resuelve el problema, vuelva atrás.
- Verifique el registro del sistema (/var/log/messages, /var/log/secure, etc.) para obtener mayor información.
A veces la filosofía y metodología vigentes requieren de seguir al pie de la letra un procedimiento establecido; no se recomienda dar saltos en función de la intuición. La motivación para usar un procedimiento con una lista de verificación es evitar depender de un experto, y asegurar que cualquier administrador de sistemas sea capaz de resolver un problema si se apega a procedimientos bien conocidos. Porque de lo contrario, si el experto deja la organización, no habrá ninguna persona lo suficientemente capacitada para resolver problemas complejos.
Si por otro lado, decide seguir su intuición y verificar algunas corazonadas, debe asegurarse de recopilar información lo suficientemente rápido para decidir si continuar o abandonar el camino de la intuición, basado en si esto parece que va a ser productivo o no.
Si bien es cierto que ignorar la intuición puede alargar el proceso de resolver un problema, el registro de la persona que solucionaba personas anteriormente es el punto de referencia fundamental para determinar si se continúan invirtiendo recursos de esta forma. En otras palabras, la intuición que resulta en algo útil no viene de forma mágica, sino que se obtiene de la experiencia.
Es necesario verificar los siguientes ítems cuando hay problemas relacionados a la red:
- Configuración de la IP:
Use ifconfig o ip para comprobar si la interfaz está arriba, y si es así, ver si está configurada. - Controlador del dispositivo de red:
Si la interfaz no puede ser levantada, tal vez el controlador de dispositivo adecuado para la(s) tarjeta(s) de red no está cargado. Verifique con lsmod si el controlador asociado está cargado como módulo del kernel, o examine los pseudoarchivos relevantes en /proc y /sys, tales como /proc/interrupts o /sys/class/net. - Conectividad:
Use ping para ver si la red es visible, verifique el tiempo de respuesta y si hay pérdida de paquetes. traceroute puede seguir paquetes a través de la red, mientras que mtr puede hacerlo de forma continua. El uso de estas herramientas puede decirle si el problema es local o está en internet. - Ruta por defecto y configuración del enrutamiento:
Ejecute route -n y vea si la tabla de enrutamiento tiene sentido. - Resolución de hostname:
Ejecute dig o host con una URL y verifique si el DNS está funcionando apropiadamente.
Los problemas de red pueden ser causados ya sea por software o hardware, y puede ser tan simple como que el controlador del dispositivo no está cargado o el cable de red no está conectado. Si la red está arriba pero el rendimiento es terrible, el asunto cae en el canasto de ajuste del rendimiento, no en la resolución de problemas básicos. Los problemas pueden ser externos a la máquina, o requerir el ajuste de varios parámetros de red, incluyendo tamaños del búfer y otros.
Hay una variedad de formas de verificar si hay archivos de configuración y binarios corruptos. Los sistemas de empaquetamiento tienen métodos de comprobar la integridad de archivos y los cambios en ellos, como se discutió anteriormente. Para sistemas basados en RPM:
$ rpm -V some_package
verifica un paquete solamente, mientras que
$ rpm -Va
verifica todos los paquetes en el sistema.
En sistemas basados en Debian es posible verificar la integridad con:
$ debsums options some_package
lo cual verificará los checksums en los archivos del paquete. Sin embargo, no todos los paquetes tienen checksums, de tal forma que esto podría no ser completamente útil. Es posible usar las opciones -V o --verify en las versiones recientes de dpkg.
aide detecta intrusiones y es otra forma de verificar si hay cambios en los archivos:
$ sudo aide --check
ejecutará un análisis de los archivos y los comparará con el último reporte. Por supuesto, tendrá que mantener la base de datos de aide luego de inicializarla.
Si el sistema falla en el arranque, ya sea completamente o si da errores, estar familiarizado con lo que sucede en cada etapa es importante a la hora de identificar fuentes de problemas en particular. Suponiendo que ya ha pasado la etapa de la BIOS, es posible que alcance alguno de estos desafortunados estados:
- No aparece la pantalla del cargador de arranque:
Busque errores de configuración en GRUB, o un sector de arranque dañado. Es posible que tenga que reinstalar el cargador de arranque. - El kernel no carga:
Si se produce un kernel panic durante el proceso de arranque, es probable que el kernel esté mal configurado o se haya dañado, o que se hayan pasado parámetros incorrectos en la línea de comandos del kernel, en el archivo de configuración de GRUB. Si el kernel ha arrancado satisfactoriamente en el pasado, entonces se dañó o la línea de comandos del kernel en el archivo de configuración de GRUB se alteró de una forma improductiva. De ser posible, puede reinstalar el kernel, o entrar en el menú interactivo de GRUB en el arranque y usar parámetros mínimos en la línea de comandos para intentar resolver el problema de esa forma. También puede intentar arrancar con una imagen de rescate, como se describirá en el siguiente capítulo. - El kernel carga pero falla al montar el sistema de archivos raíz:
Las principales causas son
1. El archivo de configuración de GRUB está mal configurado.
2. El archivo /etc/fstab está mal configurado.
3. No hay soporte para el tipo de sistema archivos raíz, ya sea integrado en el kernel o como módulo en el disco inicial ram initramfs o en el sistema de archivos. - Falla durante el proceso init.
Hay muchas cosas que pueden salir mal una vez que init comienza; mire de cerca los mensajes que se despliegan antes que el inicio se detenga. Si todo estaba funcionando antes con un kernel diferente, ya sabe por donde empezar. Revise si hay sistemas de archivos dañados, errores en scripts del inicio, etc. Intente arrancar en un runlevel menor, como 3 (sin interfaz gráfica) o 1 (modo monousuario).
Si durante el proceso de arranque uno o más sistemas de archivos no se pueden montar, fsck puede usarse para intentar repararlos. Sin embargo, antes de hacer eso uno debería verificar que /etc/fstab no contenga errores ni esté dañado. Tenga en cuenta nuevamente que habrá problemas si el kernel no soporta el sistema de archivos en uso.
Si el sistema de archivos se montó, usted puede examinar el archivo, pero / podría haberse montado como solo lectura; para editar el archivo y arreglarlo en caso de ser necesario, usted puede ejecutar:
$ sudo mount -o remount,rw /
para montarlo nuevamente, pero esta vez con permisos de escritura.
Si /etc/fstab parece estar correcto, siga con fsck. Primero debería intentar:
$ sudo mount -a
para intentar montar todos los sistemas de archivos. Si esto no tiene éxito por completo, puede tratar de montar manualmente los que tienen problemas. Primero debería ejecutar fsck solo para examinar; luego de eso puede correrlo de nuevo para intentar reparar cualquier error que pueda haber.
Discutiremos los discos de rescate y recuperación (y otros medios) en el capítulo siguiente; aquí lo veremos en términos de resolución de problemas. Estos medios contienen herramientas valiosas para evaluar y reparar sistemas que presentan problemas.
Las opciones exactas van a variar de una distribución Linux a otra, pero cuando usted arranca desde un CD/DVD de instalación/live o disco USB tiene la posibilidad de seleccionar una opción con un nombre como Rescue Installed System.
La imagen de rescate generalmente contiene un conjunto de herramientas limitado pero poderoso para arreglar problemas en un sistema:
- Herramientas de mantención de discos.
- Herramientas de red.
- Herramientas variadas.
- Acceso a los archivos de registro.
Los discos de rescate contienen muchos programas útiles, incluyendo:
- Herramientas para crear particiones, gestionar dispositivos RAID, gestionar volúmenes locales y crear sistemas de archivos:
fdisk, mdadm, pvcreate, vgcreate, lvcreate, mkfs y muchas otras. - Herramientas de red para identificación de problemas y conectividad de red:
ifconfig, route, traceroute, mtr, host, ftp, scp, ssh. - También están disponibles muchos otros comandos:
bash, chroot, ps, kill, vi, dd, tar, cpio, gzip, rpm, mkdir, ls, cp, mv y rm, por nombrar algunos.
La imagen de rescate realizará una serie de preguntas al iniciar. Una de ellas es si desea o no montar los sistemas de archivos (de ser posible).
De ser así, se montan en alguna parte, generalmente en /mnt/sysimage. Usted puede moverse a ese directorio para acceder a los archivos, o también puede cambiarse a ese ambiente con:
$ sudo chroot /mnt/sysimage.
Para un rescate basado en la red se le puede pedir que monte /mnt/source.
Usted puede instalar paquetes de software desde dentro del ambiente chrooteado. También estará habilitado para instalarlos desde fuera del ambiente chrooteado. Por ejemplo, en un sistema basado en RPM, a través de la opción --root para especificar la ubicación del directorio root:
$ sudo rpm -ivh --force --root=/mnt/sysimage /mnt/source/Packages/vsftpd-2*.rpm
Resolución de problemas de red
¿Cuáles de las siguientes afirmaciones son ciertas?
- Algunos problemas de red tales como lentitud son difíciles de detectar si no hay parámetros disponibles para confirmar si la red está operando adecuadamente. Un ejemplo de un parámetro de este tipo es el tiempo de respuesta para www.google.com.
- ifconfig puede usarse para mostrar la configuración del router.
- lsmod puede usarse para resolver problemas de la red.
Resolución de problemas en el arranque
¿Cuáles de las siguientes afirmaciones son ciertas?
- La resolución de problemas en el arranque puede ser muy difícil, si no imposible, si las contraseñas de la BIOS y del cargador de arranque están configuradas y no se conocen.
- Una configuración incorrecta de la BIOS no puede causar problemas en el arranque.
- Un error en /etc/fstab puede generar un mensaje de advertencia solamente, pero el proceso de arranque continuará de forma normal.
No hay ejercicios de laboratorio en este capítulo. Solamente se resumen los puntos discutidos anteriormente al considerar la configuración y monitoreo del sistema. Adicionalmente, prepara el escenario para el capítulo siguiente sobre el rescate del sistema, el cual tiene varios laboratorios.
Actualmente usted debería ser capaz de:
- Resolver problemas básicos en su sistema, siguiendo un número de pasos de forma iterativa hasta que se encuentren soluciones.
- Verificar la red y la integridad de archivos por posibles problemas.
- Resolver problemas cuando hay una falla en el arranque del sistema.
- Reparar y recuperar sistemas de archivos dañados.
- Entender cómo pueden usarse los medios de rescate y recuperación para resolver problemas.
42. Rescate del sistema
Tarde o temprano un sistema va a caer en una falla importante, como no poder arrancar adecuadamente, montar sistemas de archivos, iniciar un ambiente gráfico de escritorio, etc. Los medios de rescate del sistema en la forma de discos ópticos o unidades USB portables pueden usarse para resolver la situación. Arrancar ya sea en modo de emergencia o monousuario puede permitir el uso completo de las herramientas de Linux para reparar el sistema y devolverlo a su operación normal.
Al final de este capítulo usted debería ser capaz de:
- Explicar en qué formas vienen los medios de rescate del sistema, como se pueden preparar y disponer de ellos.
- Saber cómo entrar en modo de emergencia y qué se puede hacer ahí.
- Saber cómo entrar en modo monousuario, qué se puede hacer ahí, y en qué se diferencia del modo de emergencia.
Los medios de arranque de emergencia son útiles cuando el sistema no arranca debido a algún problema como archivos perdidos, mal configurados o dañados, o un servicio configurado incorrectamente.
Los medios de rescate pueden ser útiles si la contraseña de root se perdió y necesita ser reseteada.
La mayoría de las distribuciones Linux permiten que los medios de instalación y/o Live (CD, DVD, USB) cumplan un doble propósito como disco de rescate, lo cual es muy conveniente. También hay discos disponibles cuyo fin en particular es el rescate de sistemas.
Los medios Live (o vivos, y en cualquier formato) proveen un sistema operativo completo y arrancable, el cual se ejecuta en memoria, en vez de cargar desde el disco. Los usuarios pueden experimentar y evaluar el sistema operativo y/o la distribución Linux sin instalarla realmente, o realizar cualquier cambio al sistema operativo existente en el computador.
Los medios extraíbles Live son únicos en cuanto a que pueden correr en un computador que no tiene un almacenamiento secundario, tal como un disco duro, o con un disco duro o sistema de archivos dañado, permitiendo a los usuarios rescatar datos.
Ya sea que esté usando un medio Live, de instalación o rescate, los procedimientos para entrar en un sistema operativo especial de rescate y recuperación son los mismos, y como hemos señalado, estos tres medios sirven para el mismo propósito.
El modo de rescate/recuperación puede accederse desde una opción en el menú del arranque cuando el sistema inicia desde el medio extraíble. En muchos casos podría tener que escribir rescue en una línea como la siguiente:
boot: Linux rescue
No le podemos decir todas las posibilidades ya que cada distribución tiene algo diferente, pero es fácil determinar el procedimiento a seguir.
Lo siguiente es que puede esperar que se le hagan algunas preguntas tales como el lenguaje a utilizar, como también tomar algunas elecciones dependiendo de su distribución. Entonces se le pedirá seleccionar la ubicación de una imagen válida de rescate: CD/DVD, Disco Duro, NFS, FTP o HTTP.
La ubicación seleccionada debe contener un árbol de instalación válido, y este debe ser de la misma versión Linux que tiene el disco de rescate. Y si está usando medios extraíbles, el árbol de instalación debe ser el mismo desde el cual fue creado el medio en cuestión. Si está utilizando una imagen boot.iso proporcionada por el vendedor, entonces también necesitará un árbol de instalación basado en la red.
Se le realizarán preguntas adicionales acerca de montar los sistemas de archivos. Si son encontrados, se montan bajo /mnt/sysimage. Entonces se le proporcionará una shell y acceso a diversas herramientas para realizar las correcciones apropiadas a su sistema.
Puede usar chroot para acceder de mejor forma al sistema de archivos raíz (/).
Muchas distribuciones proveen un archivo de imagen boot.iso para descargar (el nombre puede cambiar). Usted puede usar dd para copiar el archivo a un dispositivo USB, de la siguiente forma:
$ dd if=boot.iso of=/dev/sdX
asumiendo que su sistema reconoce el dispositivo extraíble como /dev/sdX. Tenga en cuenta que esto borrará el contenido previo existente en el disco.
Asumiendo que su sistema tiene la capacidad de arrancar desde medios USB y que la BIOS está configurada para ello, usted entonces podrá arrancar desde este disco USB. Este funcionará de la misma forma que un CD o DVD de rescate. Sin embargo, tenga en cuenta que el árbol de instalación no estará presente en la unidad USB; por lo tanto este método requiere de un árbol de instalación basado en la red, en el caso de requerirse.
Hay herramientas útiles como livecd-tools y liveusb-creator que permiten especificar una ubicación ya sea un disco local o en internet para obtener e instalar una imagen, y luego hacer todo el trabajo duro de construir una imagen arrancable y crearla en el disco extraíble. Esto es extremadamente conveniente y funciona en prácticamente todas las distribuciones Linux.
En modo de emergencia se arranca en un ambiente lo más mínimamente posible. El sistema de archivos raíz se monta como lectura solamente, no se ejecutan los scripts init y casi nada está configurado.
La principal ventaja del modo de emergencia sobre el modo monousuario (el que se describe en la página siguiente) es que si init está dañado o no funciona, usted todavía puede montar sistemas de archivos para recuperar información que podría perderse durante una reinstalación.
Para entrar en modo de emergencia usted debe seleccionar una entrada desde el menú de arranque de GRUB y luego presionar e para editar. Luego agregue la palabra emergency a la línea de comandos del kernel antes de indicarle al sistema que arranque. Se le pedirá la contraseña de root antes de llevarlo a una shell.
Tenga en cuenta que también puede entrar en modo de emergencia cuando el arranque falla debido a una serie de razones, incluyendo sistemas de archivos dañados.
Si su sistema arranca pero no le permite ingresar cuando el arranque ha finalizado, intente ejecutar el modo monousuario. En este modo:
- init es iniciado.
- Los servicios no se inician.
- La red no se activa.
- Se montan todos los sistemas de archivos que sea posible.
- Se concede acceso a root sin solicitar una contraseña.
- Se presenta una shell de mantención del sistema.
En este modo su sistema arranca en runlevel 1 (en lenguaje SysVinit). Debido a que el modo monousuario intenta montar los sistemas de archivos automáticamente, no lo puede usar cuando el sistema de archivos raíz no puede montarse satisfactoriamente, o si la configuración de init está dañada.
Para arrancar en modo monousuario se usa el mismo método descrito para modo de emergencia, pero con la excepción de reemplazar la palabra emergencia con single.
¿Cuáles de las siguientes afirmaciones son ciertas?
- La red no está disponible en los medios de rescate.
- No es posible rescatar un sistema usando imágenes Live (viva).
- chroot es una herramienta que permite ejecutar comandos tales como rpm y dpkg en situaciones de recuperación del sistema Linux.
- En un sistema en el cual el cargador de arranque fue eliminado accidentalmente, no es posible arrancar en modo de rescate usando solo la red.
Actualmente usted debería ser capaz de:
- Explicar en qué formas vienen los medios de rescate del sistema, como se pueden preparar y disponer de ellos.
- Saber cómo entrar en modo de emergencia y qué se puede hacer ahí.
- Saber cómo entrar en modo monousuario, qué se puede hacer ahí, y en qué se diferencia del modo de emergencia.