El ABC del administrador de sistemas Linux. Pablo Sanz Mercado [usuario@portatil ~]$ hostname [usuario@portatil ~]$ [usuario@portatil ~]$ date [usuario@portatil ~]$ [usuario@portatil ~]$ ls /etc [usuario@portatil ~]$ [usuario@portatil ~]$ ifconfig [usuario@portatil ~]$ [usuario@portatil ~]$ traceroute www.google.com [usuario@portatil ~]$ [usuario@portatil ~]$ iptables -L [usuario@portatil ~]$ more /etc/passwd [usuario@portatil ~]$ [usuario@portatil ~]$ ldconfig [usuario@portatil ~]$ [usuario@portatil ~]$ lspci [usuario@portatil ~]$ Índice general 1. Comparativas de CPUs. 3 2. Preparación de discos duros. 7 3. Instalación de Linux. 3.1. Elección de la distribución. . . . . 3.2. Múltiples instalaciones. . . . . . . 3.2.1. Kickstart. . . . . . . . . . 3.2.2. Creación de imágenes. . . 3.3. Instalación de Linux y Windows. 3.4. Gestor de arranque. . . . . . . . . 3.5. Particionamiento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 12 13 19 23 24 24 4. Reconocimiento de hardware. 4.1. Sistema proc. . . . . . . . . 4.1.1. vmstat . . . . . . . . 4.1.2. partitions . . . . . . 4.1.3. meminfo . . . . . . . 4.1.4. cpuinfo . . . . . . . . 4.2. Comandos. . . . . . . . . . . 4.2.1. iostat . . . . . . . . . 4.2.2. mpstat . . . . . . . . 4.2.3. vmstat . . . . . . . . 4.2.4. top . . . . . . . . . . 4.2.5. lspci . . . . . . . . . 4.2.6. lsusb . . . . . . . . . 4.2.7. fdisk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 26 26 26 27 27 28 28 28 29 29 30 31 31 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5. Directorios en Linux. 33 5.1. /etc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5.1.1. aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 i ÍNDICE GENERAL ii 5.1.2. 5.1.3. 5.1.4. 5.1.5. 5.1.6. 5.1.7. 5.1.8. 5.1.9. 5.1.10. 5.1.11. 5.1.12. 5.1.13. 5.1.14. 5.1.15. 5.1.16. 5.1.17. 5.1.18. 5.1.19. 5.1.20. 5.1.21. 5.1.22. 5.1.23. 5.1.24. 5.1.25. 5.1.26. 5.1.27. 5.1.28. 5.1.29. 5.1.30. 5.1.31. 5.1.32. 5.1.33. 5.1.34. 5.1.35. at.deny y cron.deny . . . . . . . . . . . . . . . . . . cron.hourly, cron.daily, cron.weekly y cron.monthly csh.login y csh.cshrc . . . . . . . . . . . . . . . . . exports . . . . . . . . . . . . . . . . . . . . . . . . . fstab . . . . . . . . . . . . . . . . . . . . . . . . . . group . . . . . . . . . . . . . . . . . . . . . . . . . gshadow . . . . . . . . . . . . . . . . . . . . . . . . host.conf . . . . . . . . . . . . . . . . . . . . . . . . hosts . . . . . . . . . . . . . . . . . . . . . . . . . . hosts.allow y hosts.deny . . . . . . . . . . . . . . . inittab . . . . . . . . . . . . . . . . . . . . . . . . . issue . . . . . . . . . . . . . . . . . . . . . . . . . . issue.net . . . . . . . . . . . . . . . . . . . . . . . . ld.so.conf . . . . . . . . . . . . . . . . . . . . . . . login.defs . . . . . . . . . . . . . . . . . . . . . . . logrotate.conf . . . . . . . . . . . . . . . . . . . . . modprobe.conf . . . . . . . . . . . . . . . . . . . . motd . . . . . . . . . . . . . . . . . . . . . . . . . . mtab . . . . . . . . . . . . . . . . . . . . . . . . . . passwd . . . . . . . . . . . . . . . . . . . . . . . . . profile . . . . . . . . . . . . . . . . . . . . . . . . . rc . . . . . . . . . . . . . . . . . . . . . . . . . . . . rc0.d, rc1.d, rc2.d, rc3.d, rc4.d, rc5.d, rc6.d . . . . . rc.local . . . . . . . . . . . . . . . . . . . . . . . . . rc.sysinit . . . . . . . . . . . . . . . . . . . . . . . . resolv.conf . . . . . . . . . . . . . . . . . . . . . . . securetty . . . . . . . . . . . . . . . . . . . . . . . . services . . . . . . . . . . . . . . . . . . . . . . . . shadow . . . . . . . . . . . . . . . . . . . . . . . . . shells . . . . . . . . . . . . . . . . . . . . . . . . . . sysconfig . . . . . . . . . . . . . . . . . . . . . . . . sysctl.conf . . . . . . . . . . . . . . . . . . . . . . . timezone . . . . . . . . . . . . . . . . . . . . . . . . xinetd.d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 35 36 36 37 38 38 38 39 39 40 41 41 41 42 42 43 43 43 44 44 45 45 45 45 45 46 46 47 47 47 47 48 49 6. Scripts de arranque. 6.1. Configuración y comandos básicos. . . . . . . . . . . . . . . . 6.2. service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3. chkconfig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 52 55 55 7. Creación de usuarios. 57 7.1. Entorno gráfico. . . . . . . . . . . . . . . . . . . . . . . . . . . 58 7.2. Lı́nea de comandos. . . . . . . . . . . . . . . . . . . . . . . . . 58 ÍNDICE GENERAL iii 8. Tcpwrappers 8.1. Configuración. . . . . . . . 8.1.1. Palabras especiales. 8.1.2. Patrones. . . . . . 8.1.3. Operadores. . . . . 8.1.4. Comandos de shell. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9. Cortafuegos 9.1. Estudio previo. . . . . . . . . . . . . . . . . . 9.1.1. Topologı́a de la red a proteger. . . . . 9.1.2. Servicios más accesibles. . . . . . . . . 9.1.3. Equipos fundamentales en mi red. . . . 9.1.4. Tráfico generado. . . . . . . . . . . . . 9.1.5. Presupuesto y personal disponible. . . 9.2. iptables. . . . . . . . . . . . . . . . . . . . . . 9.3. Polı́tica por defecto. . . . . . . . . . . . . . . 9.4. Inicialización. . . . . . . . . . . . . . . . . . . 9.5. Cadena INPUT. . . . . . . . . . . . . . . . . . 9.5.1. Servidores de nombres. . . . . . . . . . 9.5.2. Cadena OUTPUT. . . . . . . . . . . . 9.5.3. IP spoofing. . . . . . . . . . . . . . . . 9.5.4. Conexiones establecidas o relacionadas. 9.5.5. Servidor FTP. . . . . . . . . . . . . . . 9.6. Scripts de inicio. . . . . . . . . . . . . . . . . 9.6.1. Ejemplo de script. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 63 65 66 67 68 . . . . . . . . . . . . . . . . . 71 72 73 75 75 76 76 77 78 79 80 82 82 83 84 85 86 88 10.Accounting. 93 11.Previsión de ataques. 101 11.1. chkrootkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 11.2. Rootkit Hunter. . . . . . . . . . . . . . . . . . . . . . . . . . . 103 12.Backup 12.1. Herramientas propias. 12.1.1. dump . . . . . 12.1.2. tar . . . . . . . 12.1.3. cp/scp . . . . . 12.1.4. rsync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 108 108 109 110 110 13.Control de logs. 113 13.1. rsyslog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 13.2. Logwatch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 14.Sistema de cuotas. 119 15.Wake On Lan. 125 ÍNDICE GENERAL iv 16.Otras tareas administrativas. 16.1. strace . . . . . . . . . . . . . 16.2. Ejecución en varias máquinas. 16.3. Integridad de las particiones. . 16.4. Desfragmentación. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 . 128 . 128 . 129 . 130 17.Actualizaciones. 131 17.1. yum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 17.2. apt-get . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 17.3. yast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Capı́tulo 1 Comparativas de CPUs. 3 4 CAPÍTULO 1. COMPARATIVAS DE CPUS. Una de las decisiones más importantes del responsable de compras de un Centro de Cálculo es la elección del tipo de procesadores a utilizar en las máquinas que vaya a comprar. Muchas veces este tipo de decisiones, muy erróneamente, se dejan al azar, permitiendo que los comerciales de las diferentes empresas que nos muestran presupuestos decidan por nosotros. Un presupuesto más económico no es sinónimo de buena compra, y en estas adquisiciones jamás tendremos que mirar únicamente el precio total de la adquisición, sino sentarnos tranquilamente y pensar durante el tiempo que sea necesario cuál de las ofertas obtenidas es la más interesante para nuestras necesidades. Como veremos, hay muchos tipos de CPUs. Principalmente podemos pensar en los dos principales generadores de procesadores, AMD e Intel, si bien hay otros productores que quizás deberı́amos comprobar antes de tomar cualquier decisión. De ninguna manera podremos guiarnos sin más por una decisión de algún otro responsable que nos haya ofrecido su ayuda, pues lo principal es evaluar las necesidades que nosotros concretamente tenemos. ¿Es primordial tener los procesadores más rápidos? ¿Utilizo programas que primordialmente trabajan con enteros? ¿Utilizo programas que primordialmente trabajan con reales? ¿Tengo algún limitante en el número máximo de equipos que puedo instalar en mis dependencias? Estas y muchas otras preguntas nos las tendremos que hacer para finalmente obtener una respuesta que nos guı́e a una compra correcta para nosotros. Como un caso quizás extremo, podrı́amos pensar en que disponemos de una sala de máquinas muy espaciosa y que tanto el consumo eléctrico como la disipación de calor no son preocupaciones nuestras sino de otro departamento que nos da vı́a libre en la compra. Si esto es ası́, y nuestra necesidad es la de realizar el máximo número de cálculos simultáneos pero sin importarnos la velocidad máxima de cada uno de ellos, es posible que nuestra decisión sea la compra de equipos convencionales. ¿Por qué no comprar equipos de sobremesa? Son extremadamente baratos y con el mismo dinero con el que comprarı́amos servidores de última generación podremos alcanzar un número muy considerable de cpus que finalmente calcuları́an mucho más que los servidores de última generación. Ahora bien, si lo que necesitamos es tener los resultados cuanto antes, ¿cómo nos vamos a decidir por las cpus integradas en equipos de consumo pudiendo elegir cpus diseñadas para el cálculo masivo? Pero es más, si nuestros programas básicamente utilizan cálculos entre enteros, ¿por qué comprar procesadores que se comportan considerablemente bien con cálculos con número de coma flotante? ¿Por qué no centrarnos en procesadores que se comporten bien en cálculos con número enteros? Para llegar a una correcta solución, lo que tendremos que hacer es conseguir una comparativa correcta de las cpus que entran dentro de nuestras 5 necesidades. Un organismo ajeno a cualquier compañı́a y que publica comparativas de cpus es www.spec.org Esta organización (Standard Performance Evaluation Corporation), publica diferentes comparativas de tal forma que podremos comparar fácilmente el comportamiento de dos cpus distintas, pues obtendremos números perfectamente comparable tras haber ejecutado un conjunto de pruebas. Estas pruebas pueden ser con números enteros o con números en coma flotante, de tal forma que podremos comprobar qué procesadores se comportan mejor en cada tipo de cálculos. Si bien podrı́amos pensar que esto ya es suficiente para nosotros, tenemos que tener en cuenta que todavı́a no sabemos cuál es el diseño de los procesadores. Para nosotros, para nuestros cálculos concretamente, ¿me podré fiar de estas medidas? Por supuesto que www.spec.org nos ofrece una información totalmente fiable, pero si tuviéramos la posibilidad de probar dos equipos con el sistema operativo que vamos a instalar, con los compiladores que vamos a utilizar y con los programas que necesitaremos, entonces los gráficos que generarı́amos con las diferentes comparaciones sı́ que nos podrı́an dar una ayuda muy importante y que nos conducirı́a a una decisión final. No obstante nos queda el último punto, el procesador en sı́. ¿Cómo funciona? ¿Qué diferencias hay entre uno y otro procesador? ¿Hay algún motivo en este sentido que me guı́e a utilizar un procesador u otro? En este último caso entonces tendremos que recurrir a la información proporcionada por cada uno de los fabricantes, donde podremos ver la información del número de registros disponibles, de la cantidad de caché a la que podremos optar, de la forma de gestionar la memoria, etc. Si bien en muchas ocasiones esta información nos supera e incluso es superflua para la decisión de compra, es recomendable comprobar todos estos números para no llevarnos sorpresas desafortunadas. Capı́tulo 2 Preparación de discos duros. 7 8 CAPÍTULO 2. PREPARACIÓN DE DISCOS DUROS. El primer paso que debemos dar cuando queremos instalar un sistema operativo en nuestro ordenador, es el particionamiento de nuestro disco duro. Este paso muchas veces se hace de forma rápida y sin un estudio previo de las expectativas que tenemos sobre el sistema, y por tanto es más que posible que necesitemos rediseñar las particiones a posteriori en muchas ocasiones. Con el fin de rediseñar particiones, pero también por supuesto con el fin de crearlas, existen diferentes herramientas disponibles, como por ejemplo Partition Magic. El problema de muchas de estas herramientas es su coste, y es que estas herramientas quizás no tengan un coste elevado, pero si empezamos a sumar los precios de todas y cada una de las herramientas que un administrador deberı́a tener, probablemente la cantidad total supere el presupuesto del que disponemos. Una herramienta equivalente, pero gratis, es gparted http://gparted.sourceforge.net que podremos instalar en nuestro sistema, pero también podemos bajarnos un live-cd de tal forma que simplemente tras meterlo en la lectura de cds y arrancar el sistema, se nos abrirá un entorno gráfico con la aplicación gparted. Esta aplicación es extremadamente sencilla de utilizar, de tal forma que veremos en pantalla la representación de nuestro disco duro de forma lineal, con las diferentes particiones. Podremos por tanto eliminar particiones existentes, crear particiones y modificar (redimensionar por ejemplo) las particiones que tengamos. Esta herramienta es por tanto fundamental para cualquier administrador, con el fin de poder crear las particiones de forma previa a una instalación, por ejemplo, o bien para poder modificar las ya existentes en el caso de que encuentre una mala previsión en el particionado existente. También debemos tener en mente que los sistemas operativos modernos tienen herramientas propias para el redimiensionado de particiones. De esta forma podremos por ejemplo, desde un sistema Windows 7, disminuir una de sus particiones si es que lo necesitamos. También, por ejemplo, podremos realizar esta acción a la hora de instalar una distribución de Linux, ya que en su menú de particionamiento del disco aparecerá una opción que es el redimensionado y que funciona de forma equivalente a lo que habı́amos indicado para gparted. Capı́tulo 3 Instalación de Linux. 3.1. Elección de la distribución. 9 10 CAPÍTULO 3. INSTALACIÓN DE LINUX. Hoy en dı́a tenemos multitud de distribuciones que podremos bajar a nuestro equipo fácilmente. Originalmente fueron tres las distribuciones principales que existı́an, a saber: Debian, Slackware y RedHat. Estas distribuciones han dado lugar a centenares de distribuciones que han ido naciendo, y muriendo, a lo largo de la historia de GNU/Linux. ¿Cuál es la distribución que debo elegir? Realmente esta pregunta no tiene una respuesta concreta, sino que se contesta indicando pros y contras que podremos tener a la hora de utilizar una distribución u otra. Si lo que queremos es tener una distribución GNU/Linux con la que podamos utilizar la lı́nea de comandos y prácticamente nada más, cualquiera de las distribuciones que utilicemos será válida. La lı́nea de comandos prácticamente no tiene diferencia entre distribuciones, y si aprendemos a utilizar los comandos en una distribución, podremos trabajar con cualquier otra sin el más mı́nimo problema. Donde sı́ vamos a encontrar diferencias es en la instalación del sistema operativo, pues hay diferentes entornos de instalación utilizados por diferentes distribuciones. Si nos gusta más un programa de instalación que otro, esta puede ser una buena excusa para utilizar una distribución u otra. Si creemos que esta idea es muy básica, y que no debemos guiarnos por la instalación para centrarnos en la utilización de una u otra distribución, debemos tener presente que otra de las ideas que las diferencia es la forma de actualización del sistema, ası́ como de la instalación de los programas. Por ejemplo distribuciones basadas en Debian utilizan el entorno apt para realizar estas tareas, mientras que las distribuciones basadas en RedHat utilizan yum. ¿Cuál de las dos opciones es mejor? De nuevo necesitamos algo de subjetividad para responder a esta pregunta, ya que en ambos entornos conseguiremos la instalación de programas o la actualización del sistema operativo, y quizás sea la forma / estética de hacerlo lo que nos haga preferir una versión respecto a otra. También podemos seguir con otras diferencias entre distribuciones, que quizás nos permitan ser un tanto más estrictos desde el punto de vista objetivo, con valores cuantificables. Siguiendo esta idea podemos elegir aquella distribución que tenga una buena polı́tica de actualizaciones, ya que este punto es fundamental sobre todo si tenemos un entorno que queremos que vaya evolucionando y sea atractivo al usuario final. Algunas distribuciones nacen con mucha fuerza, con mucho ánimo por parte de sus creadores, pero poco a poco desaparecen debido a la discontinuidad de su producto. Su desaparición es lógica pues a nadie le gusta tener una distribución de GNU/Linux que no haya sido modificada en años. El soporte es otra de estas ideas que podemos cuantificar fácilmente. Hay distribuciones que dan soporte directo, por el que cobran una cierta cantidad de dinero, y que nos permite tener una cierta tranquilidad si tenemos cualquier problema con el sistema operativo. Son estas distribuciones muy 3.1. ELECCIÓN DE LA DISTRIBUCIÓN. utilizadas en entornos que requieren continuidad, que no pueden permitirse ninguna parada, y que pueden permitirse el pago por el mantenimiento. Una distribución que cobra por soporte y que tiene mucho éxito es RedHat. Inicialmente era una distribución de GNU/Linux ajena a la comercialización, pero en un momento determinado se dividió en dos ramas, Fedora Core por una parte y Red Hat Enterprise por otra. La primera es una distribución de la comunidad, totalmente gratuita, y la segunda es una distribución gestionada por un equipo de personas que se mantiene gracias al cobro de soporte. Tras esta separación hubo ciertos fabricantes de servidores, y desarrolladores de software, que realizaron alianzas con RedHat para dar una cierta calidad y continuidad a sus servicios con una distribución de GNU/Linux como RedHat. Esto hizo muy complicada la supervivencia de centros de computación con pocos recursos, en el sentido de que si no pagaban por el mantenimiento de RedHat no podı́an tener acceso al soporte de las empresas de hardware o de los desarrolladores de software cuando tenı́an problemas, pues estos no soportaban otras distribuciones que no fueran RedHat. CentOS, junto con otras, ha sido una distribución que ha diezmado estos problemas. CentOS (Community ENTerprise Operating System) se describe como a free rebuild of source packages from the Red Hat Enterprise Linux, es decir, utilizan el código fuente libre de Red Hat Enterprise Linux y lo recompilan. El resultado por tanto es una distribución totalmente equivalente que podemos utilizar de forma similar a RedHat, y que nos permite interaccionar con hardware y software como si estuviéramos trabajando con RedHat. La diferencia, por supuesto, es que no tenemos soporte, pero el soporte de la comunidad de usuarios de GNU/Linux es tan amplio que podremos tener resuelto un problema en relativo poco tiempo en la mayorı́a de las ocasiones. En cuanto al soporte debemos tener muy presente que si pagamos por él vamos a tener un contrato que nos garantizará una solución en un determinado tiempo. Si no pagamos por el soporte la solución al problema dependerá de lo rápido que seamos buscando en Internet por problemas equivalentes o de lo rápido que sean otros compañeros de profesión a la hora de contestar nuestra pregunta. Dependiendo de las necesidades de continuidad de nuestros servicios, tendremos que considerar una u otra opción. 11 12 3.2. CAPÍTULO 3. INSTALACIÓN DE LINUX. Múltiples instalaciones. 3.2. MÚLTIPLES INSTALACIONES. 3.2.1. Kickstart. Una forma de realizar múltiples instalaciones equivalentes, es mediante kickstart. Esta forma de trabajo es muy utilizado en distribuciones de la rema de Redhat, que permite crear un fichero llamado ks.cfg por defecto, que será utilizado por el entorno de instalación para tomar de forma desatendida todas las decisiones necesarias en una instalación. De esta forma podremos instalar un equipo o varios de la misma forma, con las mismas opciones, permitiendo ası́ poder realizar grandes instalaciones con múltiples servidores de una forma sencilla. Otra ventaja de Kickstart es que haremos una instalación desatendida, pero en definitiva será una instalación. Para entender esto debemos pensar en una instalación desatendida proviniente de una imagen. Esta la haremos instalando un servidor y luego clonándolo una y otra vez. El problema con esta instalación es que los ordenadores donde copiaremos el clon deben ser equivalentes al original. Si no tenemos la misma capacidad de disco duro, por ejemplo, podremos tener un problema. Con la instalación mediante Kickstart nos ahorramos este problema, ya que cada ordenador se instalará con las pautas que le indiquemos en Kickstart. Siguiendo con el ejemplo del disco duro podremos crear diferentes particiones y para crear la última partición podremos indicar que el sistema utilice lo que le quede de disco duro. Si el servidor donde estamos instalando tiene únicamente 1MB libre, utilizará esta capacidad para la nueva partición, pero si tiene 10TB libres será los que utilice. Un truco interesante para tener el perfil de instalción de Kickstart, es decir, el fichero ks.cfg, es instalar un equipo a mano, de forma interactiva, y al final de la instalación podremos comprobar que en el directorio /root nos habrá dejado un fichero llamado anaconda-ks.cfg si estamos utilizando una distribución que utilice Anaconda como gestor de instalación. Este fichero es un perfecto perfil de configuración de Kickstart que podremos utilizar para instalar otros equipos de forma equivalente al primero. La forma de instalar un ordenador utilizando estos perfiles de instalación es sencilla, pues lo único que tendremos que hacer es introducir el comando ks en el indicador de comandos boot con la ruta en la que está el fichero ks.cfg, es decir, cuando arranca el instalador, en vez de pulsar ENTRAR sin más, teclearemos: linux ks=floppy si tenemos este fichero en un disquete, si bien podemos guardar este archivo en otros medios: ks=cdrom:/ks.cfg para especificar que hemos guardado en el directorio principal del cdrom el archivo ks.cfg. 13 14 CAPÍTULO 3. INSTALACIÓN DE LINUX. ks=nfs:servidor:/camino si hemos guardado el archivo en un directorio de un servidor nfs. En este último caso deberı́amos especificar el dispositivo que vamos a utilizar para poder acceder al servidor nfs mediante la opción ksdevice: ksdevice=eth1 si queremos utilizar la tarjeta de red identificada como eth1. Con este tipo de instalación deberemos tener cuidado, como indicamos también en el punto anterior, con la configuración de red ya que será exactamente la misma que en el ordenador del cual obtuvimos el fichero anacondaks.cfg o la que hayamos editado nosotros, por lo tanto deberemos cambiarla antes de conectar el ordenador a la red si esta configuración puede plantear algún conflicto de IP. Un ejemplo de fichero de configuración puede ser: install cdrom lang es_ES.UTF-8 langsupport --default es_ES.UTF-8 es_ES.UTF-8 keyboard es network --device eth0 --bootproto static --ip 192.168.32.99 --netmask 255.255.255.0 --gateway 192.168.32.1 --nameserver 192.168.9.100,192.168.9.200,130.206.1.2 --hostname servidor.dominio rootpw --iscrypted $1$o1DG1PR3$IofHRrWIgA5dL1MgoB6GN. firewall --disabled selinux --disabled authconfig --enableshadow --enablemd5 timezone Europe/Madrid bootloader --location=mbr --append rhgb rhgb quiet # The following is the partition information you requested # Note that any partitions you deleted are not expressed # here so unless you clear all partitions first, this is # not guaranteed to work #clearpart --all #part / --fstype ext3 --size=6000 --ondisk=sda --asprimary #part /home --fstype ext3 --size=2048 --ondisk=sda --asprimary #part /scratch --fstype ext3 --size=500 --grow --ondisk=sda --asprimary #part swap --size=256 --ondisk=sda --asprimary 3.2. MÚLTIPLES INSTALACIONES. %packages @ kde-desktop @ spanish-support @ gnome-desktop @ dialup @ editors @ xemacs @ admin-tools @ system-tools @ base-x @ printing @ ruby @ kernel-development @ xemacs @ development-tools @ ruby @ engineering-and-scientific grub kernel e2fsprogs %post Iremos explicando lı́nea a lı́nea el significado de las mismas. cdrom Mediante esta lı́nea indicamos que la instalación se va a realizar mediante cdrom, es decir, todos los archivos necesarios para realizar la instalación los vamos a proporcionar mediante un juego de cdroms. lang es_ES.UTF-8 La instalación se realizará en castellano. langsupport --default es_ES.UTF-8 es_ES.UTF-8 El sistema operativo se instalará utilizando el idioma castellano como soporte de lenguaje por defecto. keyboard es El teclado que vamos a utilizar es un teclado español. 15 16 CAPÍTULO 3. INSTALACIÓN DE LINUX. network --device eth0 --bootproto static --ip 192.168.32.99 --netmask 255.255.255.0 --gateway 192.168.32.1 --nameserver 192.168.9.100,192.168.9.200,130.206.1.2 --hostname servidor.dominio También tendremos que indicar la configuración de red del equipo. Esta configuración es sencilla de seguir, pues podemos ver fácilmente que la tarjeta de red eth0, la primera tarjeta de red de nuestro sistema, será activada por defecto al arrancar el ordenador y configurada con la ip 192.168.32.99, máscara de red 255.255.255.0, puerta de enlace 192.168.32.1, servidores de nombres 192.168.9.100, 192.168.9.200 y 130.206.1.2 y finalmente el nombre del ordenador en este caso será servidor.dominio. Estos datos tendremos que cambiarlos para cada uno de los nodos, para no provocar conflictos IP al darles a todos los nodos la misma configuración de red. Podremos, por ejemplo, crear varias copias del mismo fichero en las que cambie la configuración de red, iniciando la instalación de cada uno de los nodos con el fichero correspondiente y no teniendo por tanto ningún problema de instalación. rootpw --iscrypted $1$o1DG1PR3$IofHRrWIgA5dL1MgoB6GN. Mediante esta lı́nea estableceremos la contraseña de root. Efectivamente esta será la misma para todos los nodos si utilizamos la misma lı́nea en cada uno de los nodos. Será polı́tica del administrador cambiarla en cada una de las instalaciones o dejar la misma para todos ellos. firewall --disabled selinux disabled Mediante estas lı́neas desactivaremos por defecto la seguridad que nos proporciona la instalación de un firewall en nuestro sistema y la capacidad ofrecida por selinux. Está en nuestra mano por tanto cambiar la opción para permitir la instalación de estas dos funciones. authconfig --enableshadow --enablemd5 La forma de autentificación la estableceremos mediante esta lı́nea, donde especificamos que en nuestro sistema utilizaremos contraseñas de tipo shadow y md5, si bien es posible que queramos utilizar sha512 que nos proporcionará una mejora en la seguridad del equipo. timezone Europe/Madrid Muy importante es esta lı́nea sobre todo a la hora de actualizar sin ningún problema el reloj de nuestro ordenador, ya que al especificar que estamos en Madrid-Europa, esto será tenido en cuenta si realizamos una actualización de hora gracias a NTP, ajustando el desfase horario sin problemas. También es importante en otras tareas del sistema como por ejemplo a la hora de mandar mensajes de correo electrónico, ya que normalmente cuando ordenamos por fecha los mensajes obtenidos se suele tener en cuenta los desfases horarios para que realmente tengamos un orden real. 3.2. MÚLTIPLES INSTALACIONES. bootloader --location=mbr --append rhgb rhgb quiet El cargador del sistema operativo lo instalamos mediante esta lı́nea, en la que decimos que será instalado en el Master Boot Record (mbr) y las opciones que daremos al kernel serán rhgb rhgb quiet. clearpart --all part / --fstype ext3 --size=6000 --ondisk=sda --asprimary part /home --fstype ext3 --size=2048 --ondisk=sda --asprimary part /scratch --fstype ext3 --size=500 --grow --ondisk=sda --asprimary part swap --size=256 --ondisk=sda --asprimary Estas lı́neas son las que nos permiten particionar el disco duro de nuestro ordenador. Tendremos que tener gran cuidado en las mismas para evitar pérdida de datos por una mala configuración en un equipo con una instalación previa. En el ejemplo que tenemos eliminamos todas las particiones si estas existieran (clearpart all) y a continuación creamos cuatro particiones, /, /home, /scratch y swap del tipo ext3 salvo la última, que no tendrá formato ext3 al ser swap. Todas las particiones las creamos en el primer disco duro de nuestro equipo, de ahı́ que escribamos ondisk=sda y forzamos a que sean particiones primarias mediante asprimary. El tamaño de las mismas lo fijamos, para finalizar, mediante la opción size= donde estableceremos el número de megabytes que asignaremos a cada partición, diferenciando la partición /scratch del resto en este caso ya que en la lı́nea correspondiente hemos añadido la opción grow, que permitirá asignar todo el espacio restante del disco duro a esta partición, evitando por tanto tener que saber exactamente el tamaño del disco duro, y pudiendo utilizar esta configuración en ordenadores con discos duros de diferente capacidad ya que permitimos que /scratch tenga una capacidad mayor que 500 Mb dándonos igual el tamaño final de la misma. %packages @ kde-desktop @ spanish-support @ gnome-desktop @ dialup @ editors @ xemacs @ admin-tools @ system-tools @ base-x @ printing @ ruby @ kernel-development @ xemacs 17 18 CAPÍTULO 3. INSTALACIÓN DE LINUX. @ development-tools @ ruby @ engineering-and-scientific grub kernel e2fsprogs A continuación de %packages escribimos las familias de paquetes que vamos a instalar en nuestro equipo si estas van precedidas mediante una arroba, de tal forma que el instalador copiará en nuestro equipo todos los programas que formen parte por defecto de cada una de estas familias. Adicionalmente podremos escribir los paquetes adicionales que queremos instalar en nuestro equipo y que no formen parte, por defecto, de ninguna de las familias que hemos escrito. En este caso escribiremos el nombre de cada uno de los paquetes adicionales pero sin ser precedidos por ningún carácter. %post Finalmente, y precedido por %post, escribiremos todos aquellos comandos que queremos que se ejecuten a posteriori, es decir, una vez realizada la instalación, pudiendo por tanto crear diferentes usuarios en todas las máquinas sin necesidad de teclear absolutamente nada después de la instalación, o modificar el fichero /etc/hosts de forma análoga en todos los nodos instalados o cualquier cosa que se nos ocurra y que queramos realizar de forma automática mediante kickstart y sin interacción por parte del administrador encargado de instalar los equipos, simplificado por tanto enormemente las tareas que siempre hay que realizar tras la instalación de una máquina. 3.2. MÚLTIPLES INSTALACIONES. 3.2.2. Creación de imágenes. Cuando hemos instalado un equipo, el tiempo que hemos invertido puede ser realmente elevado, pues no sólo está el tiempo de instalación del mismo, sino además todo el tiempo de configuración que supera en la mayorı́a de las ocasiones al primero. Es muy posible que queramos guardar una copia exacta de esta instalación para evitar emplear otra vez tal cantidad de tiempo en el caso de necesitar una reinstalación de este equipo, o por ejemplo si necesitamos instalar varios equipos de forma equivalente. En este sentido no debemos preocuparnos pues disponemos de la herramienta partimage, que nos permite realizar una copia exacta y además siendo una herramienta gratuita. Para poder utilizarla nos bajaremos un live cd de la página oficial: http://www.partimage.org/Main_Page ya que este cd nos permitirá arrancar la máquina sin necesidad de hacer uso del disco duro, de la información contenida en él, para este arranque. Con este programa se pueden generar imágenes de cada una de las particiones existentes en el sistema, grabándolas sin comprimir o comprimidas con gzip o bzip2. Además este programa lo podremos utilizar mediante un entorno de menús o por lı́nea de comando, lo que le confiere la posibilidad de poderlo utilizar sin apenas interacción. Tanto si utilizamos el entorno de menús, como la lı́nea de comandos, lo primero que deberemos hacer es, una vez hayamos arrancado el equipo utilizando el LiveCD, montar los dispositivos donde vayamos a grabar las imágenes, por ejemplo un disco duro externo: mkdir /mnt/usb mount -t ext3 /dev/sdb1 /mnt/usb en este sentido comentar que nunca deberemos montar un dispositivo en /mnt, pues este directorio es utilizado por el live cd y podrı́amos dejar inoperativo este sistema operativo, teniendo que reiniciar el equipo para volver a una situación estable. Para obtener el menú de partimage, ejecutaremos este programa sin más: partimage y obtendremos una pantalla en la que aparecen todas las particiones disponibles en el ordenador. Seleccionaremos entonces una de ellas, y en la ventana donde podemos leer Image file to create/use escribiremos el nombre que queremos tenga el archivo imagen que se creará de esta partición. La recomandación en este punto es escribir el nombre con el path completo, es decir, en nuestro caso podrı́amos escribir /mnt/usb/imagen-sda1 por ejemplo. 19 20 CAPÍTULO 3. INSTALACIÓN DE LINUX. En este menú, en el apartado donde podemos leer Action to be done lo dejaremos como Save partition into a new image file, que es la opción que viene por defecto, y pulsaremos F5 para continuar. En la siguiente pantalla seleccionamos bzip2 como herramienta de compresión, pues aunque tardará más la aplicación en generarnos las imágenes, estas ocuparán menos que las generadas con gzip y que por supuesto las no comprimidas. Pulsamos F5 para continuar y empezará a generar la imagen tras pedirnos una descripción de la imagen (un nombre cualquiera, por ejemplo el directorio en el que la montamos, para luego, al escribirlas en disco, ser más fáciles de indentificar). Estas operaciones se hacen para cada una de las particiones que tengamos en el equipo, de tal forma que al final tendremos al menos un archivo, en el disco duro externo donde estamos grabando las imágenes, por cada una de las particiones. A continuación lo que haremos es salvar el Master Boot Record, con el fin de que si luego utilizamos estas imágenes en otro equipo, este pueda arrancar sin mayor problema. Para guardar el MBR utilizaremos el comando dd: dd if=/dev/sda of=/mnt/usb/backup-del-mbr bs=1 count=512 y a continuación guardaremos también la tabla de particiones con sfdisk: sfdisk -d /dev/sda > /mnt/usb/backup-de-la-tabla-de-particiones Si en algún momento lo que queremos hacer son los pasos inversos, es decir, utilizar estas imágenes en otro equipo para crear un clon del original, primero crearemos las particiones necesarias y escribiremos el MBR en el disco destino: sfdisk /dev/sda < /mnt/usb/backup-de-la-tabla-de-particiones dd if=/mnt/usb/backup-del-mbr of=/dev/sda Y a continuación ejecutaremos el programa partimage, pero esta vez lo que haremos es utilizar imágenes ya generadas que grabaremos en el disco duro. Para ello en el primer menú seleccionaremos la partición deseada y escribiremos el nombre de la imagen a restaurar. Seleccionaremos entonces Restore partition from an image file y en el siguiente menú elegiremos Erase free blocks with zero values para que deje el disco vacı́o y sólo con los datos de las imágenes originales. Pasaremos al siguiente menú pulsando F5 y empezará a grabar la imagen en nuestro disco duro. Una vez hecho esto para cada una de las particiones existentes, tendremos un clon perfecto del ordenador original, pero con la ventaja de haber empleado mucho menos tiempo en su consecución. 3.2. MÚLTIPLES INSTALACIONES. La ventaja de partimage es que puedo utilizar la lı́nea de comandos para realizar todos y cada uno de los pasos descritos, y por lo tanto crear un script que, tras ejecutarlo, me realice todos y cada uno de los pasos descritos anteriormente sin interacción. Imaginemos que tenemos un ordenador ya instalado en tiene un disco duro /dev/sda con varias particiones. Este disco duro es el único en el sistema. A parte de este instalaremos un disco duro usb para poder realizar el volcado de las imágenes, y que montaremos en /mnt/usb. El script que podrı́amos crear podrı́a ser: #!/bin/bash cat /proc/partitions|grep da|grep -v " 0 "|awk ’{print $4}’ |while read particion do partimage -z2 -b -o -d save /dev/$particion /mnt/usb/${particion}.bz2 done disco=‘cat /proc/partitions|grep da|grep " 0 " |awk ’{print $4}’‘ dd if=/dev/$disco of=/mnt/usb/backup-mbr-$disco count=1 bs=512 sfdisk -d /dev/$disco > /mnt/usb/backup-particionado-$disco La primera lı́nea lo que hace es encontrar qué particiones tenemos en el disco duro. Como sólo tenemos un disco duro interno, mediante grep da nos quedaremos con la información del fichero /proc/partitions que responda a este patrón, que sólo será la del disco duro /dev/sda. El siguiente grep utilizado lo que hará es quedarse sólo con las particiones, pues en la información obtenida en /proc/partitions también aparece el propio disco /dev/sda El bucle que creamos en esta primera lı́nea será entonces el principal de todo el script, será el que nos permita realizar todas y cada una de las imágenes de las particiones existentes en el disco. Nos fijamos entonces que para cada partición lo que hará es ejecutar el comando partimage diciéndole que creará (save) un imagen de la partición /dev/$partition dándole como nombre /mnt/usb/$partition.bz2.000 (el 000 lo incluirá partimage), sobreescribiendo si ya existı́a (-o), no pidiendo etiqueta de la partición (-d) y además en batch mode (-b), es decir, no requerirá interacción ninguna. A continuación cargamos el valor /dev/sda en la variable disco, y luego utilizaremos esta variable para guardar tanto el MBR como la tabla de particiones. La ejecución de este script no necesita por tanto interacción del administrador, pudiéndolo ejecutar y volver al cabo de cierto tiempo, teniendo el trabajo realizado. 21 22 CAPÍTULO 3. INSTALACIÓN DE LINUX. En el caso de que quisiéramos hacer el paso contrario, es decir, automatizar la clonación de un ordenador con estos ficheros que acabamos de crear, lo que haremos es un script equivalente: #!/bin/bash disco=‘cat /proc/partitions |grep da |grep " 0 " |awk ’{print $4}’‘ dd if=backup-mbr-$disco of=/dev/$disco sfdisk /dev/$disco < backup-particionado-$disco ls *.000 |cut -d . -f 1|while read particion do partimage restore -b /dev/$particion ${particion}.bz2.000 done y rápidamente tendremos el clon creado. 3.3. INSTALACIÓN DE LINUX Y WINDOWS. 3.3. Instalación de Linux y Windows. 23 24 3.4. CAPÍTULO 3. INSTALACIÓN DE LINUX. Gestor de arranque. La instalación de los dos sistemas operativos se puede llevar a cabo sin ningún problema. Para ello Linux dispone de GRUB, que es un gestor de arranque que nos va a permitir, mediante un menú que nos aparecerá en el arranque del ordenador, elegir la carga de Windows o de Linux. GRUB se cargará en el Master Boot Record (MBR) de nuestro disco duro, que será cargado en memoria por la BIOS en el arranque. En este MBR habitualmente se encuentran los cargadores de los diferentes sistemas operativos, que una vez cargados en memoria por la BIOS permiten cargar, también en memoria, la parte del sistema operativo que se necesite. En el MBR vamos a tener un cargador, por lo tanto es conveniente elegir bien cuál queremos para poder realizar la carga del sistema operativo o de los sistemas operativos que queramos tener instalados en nuestro ordenador. La idea, para tener los mı́nimos problemas, es instalar primero Windows en nuestro ordenador y luego Linux. ¿Por qué? Bien, porque si instalamos primero Linux, GRUB se cargará en el MBR y luego Windows se encargará de borrarlo para grabar su propio cargador. Si instalamos Windows primero, al instalar acto seguido Linux, en el MBR se quedará el GRUB, que nos permitirá elegir entre cargar Windows y Linux. A la hora de instalar Windows, crearemos una partición con la capacidad que creamos oportuna, y el resto del disco duro lo dejaremos sin utilizar. A continuación instalaremos Linux creando para ello las particiones que consideremos oportunas, prestando atención a la parte en la que se nos da la opción de instalar GRUB o no. Obviamente elegiremos que queremos instalarlo, y lo configuraremos a nuestro gusto. Habitualmente lo que más se suele modificar en este punto es el nombre que queremos que aparezca en el menú de arranque para identificar la carga de cada uno de los operativos. En este punto cabe destacar que serı́a interesante utilizar una contraseña para GRUB, para evitar que fácilmente se pueda modificar la carga de los operativos y por lo tanto incluso poder entrar a ellos. 3.5. Particionamiento. Cuando instalemos Linux, es un truco interesante no utilizar todo el disco duro restante, sino dejar un espacio libre en disco para poder realizar una partición nueva desde Windows (también la podrı́amos crear desde Linux por supuesto). El truco consiste en tener una partición en la que, escribamos lo que escribamos, pueda ser leı́da y modificada por ambos sistemas operativos. Actualmente Windows NO lee las particiones Linux, salvo que instalemos software adicional que sı́ puede hacerlo, pero Linux es capaz de leer particiones formateadas como vfat o como NTFS. Capı́tulo 4 Reconocimiento de hardware. 25 26 CAPÍTULO 4. RECONOCIMIENTO DE HARDWARE. La información que tiene el sistema operativo acerca del hardware instalado en nuestro ordenador está básicamente ubicada en el directorio /proc que es un claro desconocido para la mayorı́a de los administradores de sistemas. El sistema proc presenta el estado actual del kernel, y es, podrı́amos decir, un sistema de archivos virtual, cambiante permanentemente no fácilmente modificable y cuya modificación puede implicar un colapso inmediato del sistema si se hace incorrectamente. Cuando queramos obtener información del hardware de nuestro sistema, básicamente lo que tendremos que hacer es consultar (mediante el comando cat por ejemplo) los archivos contenidos en esta estructura, o bien utilizar herramientas gráficas o comandos que traten esta información y nos la presenten en pantalla de forma clara. 4.1. Sistema proc. Archivos interesantes que nos podemos encontrar en el directorio /proc son: 4.1.1. vmstat . Que muestra estadı́sticas detalladas de la memoria virtual, como por ejemplo: El número de páginas sucias, bajo reescritura o inestable: nr_dirty 1550 nr_writeback 0 nr_unstable 0 Páginas libres: pgfree 110549163 y ası́ un largo etcétera que nos da información muy apreciada cuando necesitemos saber si la memoria está causando algún tipo de inestabilidad que suframos en nuestro equipo. 4.1.2. partitions En este archivo encontraremos la información de las distintas particiones existentes en nuestros discos duros. La información será el nombre de la partición, los bloques que ocupa y los major number y minor number de las mismas: 4.1. SISTEMA PROC. major minor 8 8 8 8 8 8 8 8 8 4.1.3. 0 1 2 3 4 5 6 7 8 27 #blocks name 58605120 20523006 1 10265535 16434495 6144831 1004031 104391 4128673 sda sda1 sda2 sda3 sda4 sda5 sda6 sda7 sda8 meminfo Si mostramos el contenido de este fichero, obtendremos información sobre la memoria de nuestro equipo, como por ejemplo la memoria total del mismo MemTotal: 481684 kB Memoria libre: MemFree: 52600 kB Swap total: SwapTotal: 1004020 kB Swap disponible SwapFree: 956228 kB etc. 4.1.4. cpuinfo En este fichero encontraremos la información de las cpus disponibles en nuestro servidor. Dichas cpus (o núcleos), estarán numerados empezando con el número 0, pudiendo ası́ identificar cada una de ellas. Un ejemplo de las primeras lı́neas de este fichero bien podrı́a ser: processor vendor_id cpu family model model name : : : : : 0 GenuineIntel 6 13 Intel(R) Pentium(R) M processor 1.60GHz de tal forma que accediendo al contenido de cpuinfo tendremos la información exacta de las caracterı́sticas de nuestras cpus. 28 4.2. CAPÍTULO 4. RECONOCIMIENTO DE HARDWARE. Comandos. Obviamente la información que podemos obtener por comandos, aunque sea la misma que podrı́amos obtener nosotros accediendo a los archivos previamente comentados, por regla general nos será de mayor utilidad al estar mejor estructurada y al tener ciertas herramientas que nos permiten gestionar esta información de forma más cómoda. Comandos hay muchos, ası́ como herramientas gráficas que básicamente en última instancia ejecutan comandos presentando la información en un formato altamente agradable. De todos los comandos existentes comentaremos los más utilizados a la hora de localizar problemas en nuestro equipo: 4.2.1. iostat Este comando lo encontramos en el paquete sysstat, que muchos sistemas no tienen instalado por defecto, pero que es conveniente instalar. iostat nos muestra estadı́sticas de la cpu ası́ como de entrada y salida de dispositivos, particiones y sistemas de archivos de red, por lo tanto nos podemos hacer una buena idea de la potencia de este comando. Si ejecutamos sin más el comando iostat, obtendremos una imagen del estado actual del equipo: avg-cpu: %user 4,53 Device: tps sda 8,25 %nice %system %iowait 0,12 1,11 3,72 Blk_read/s 243,63 Blk_wrtn/s 83,71 %steal 0,00 Blk_read 3128500 %idle 90,52 Blk_wrtn 1074870 no obstante siempre podremos incluir en la ejecución del comando un intervalo, en segundos, de tal forma que nos mostrará esta información cada x segundos que hayamos pedido, por ejemplo: iostat 1 nos mostrarı́a información de la cpu y de los dispositivos cada segundo. 4.2.2. mpstat Al igual que iostat, este comando se encuentra dentro del útil paquete sysstat muy utilizado desde el punto de vista de administración de sistemas. mpstat nos proporciona la actividad de cada una de las cpus que dispongamos, ofreciéndonos algo más de información que el comando iostat y pudiendo también elegir un intervalo de tiempo, de tal forma que a partir de ese momento cada x segundos se mostrarı́a en pantalla las estadı́sticas de las cpus. 4.2. COMANDOS. 4.2.3. vmstat Es un comando que nos muestra estadı́sticas de la memoria virtual. Podrı́amos decir que básicamente es una salida ordenada del contenido de /proc/meminfo pudiendo además elegir un intervalo de tiempo vmstat 1 para que cada segundo (siguiendo el ejemplo especificado), podamos obtener información actualizada. Obviamente podremos elegir el intervalo de tiempo que más se ajuste a nuestras necesidades. 4.2.4. top top es un comando ampliamente utilizado por los administradores de sistemas y existente en prácticamente todos los sistemas operativos Linux y UNIX. Este comando nos muestra en pantalla la situación actual de los procesos del sistema, pudiendo cambiar el intervalo de tiempo para que cada x segundos nos muestre esta información actualizada. Teniendo en cuenta que hoy por hoy la mayorı́a de los ordenadores personales que se venden ya incluyen procesadores con varios núcleos, una de las opciones más interesantes de este comando es 1 Si cuando hemos invocado top, pulsamos 1, encontraremos que la información que encontrábamos en la zona superior que era un resumen de todas las cpus existentes, se despliega para dar información pormenorizada de todas y cada una de las cpus existentes top - 17:27:51 up 153 days, 3:06, 4 users, load average: 1.00, 1.00, 1.02 Tasks: 90 total, 2 running, 88 sleeping, 0 stopped, 0 zombie Cpu0 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si Cpu1 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si Cpu2 : 100.0% us, 0.0% sy, 0.0% ni, 0.0% id, 0.0% wa, 0.0% hi, 0.0% si Cpu3 : 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 2074672k total, 2019472k used, 55200k free, 75196k buffers Swap: 4096564k total, 3360k used, 4093204k free, 1679804k cached 29 30 4.2.5. CAPÍTULO 4. RECONOCIMIENTO DE HARDWARE. lspci lspci es un comando no muy conocido por administradores noveles, y sin embargo es un poderoso comando que nos muestra la información de los dispositivos pci disponibles en nuestro equipo, con la consiguiente facilidad para poder configurarlos gracias a esta información obtenida. Al ejecutar el comando sin ninguna opción, obtendremos un resumen de los dispositivos encontrados, por ejemplo una de las entradas bien podrı́a ser: 02:07.0 FireWire (IEEE 1394): Texas Instruments TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) las dos opciones más utilizadas con este comando son -v y -x, que sirven respectivamente para obtener información más detallada y un volcado hexadecimal del espacio de configuración. Además podemos utilizar varias veces -v, concretamente podrı́amos teclear: lspci -v lspci -vv lspci -vvv obteniendo en cada caso mayor información, por ejemplo la última ejecución nos darı́a el siguiente resultado para el ejemplo que habı́amos utilizado anteriormente: 02:07.0 FireWire (IEEE 1394): Texas Instruments TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) (prog-if 10 [OHCI]) Subsystem: Hewlett-Packard Company Unknown device 3084 Control: I/O- Mem+ BusMaster+ SpecCycleMemWINV+ VGASnoop- ParErr- SteppingSERR+ FastB2BStatus: Cap+ 66MHz- UDF- FastB2BParErr- DEVSEL=medium >TAbort- <TAbort<MAbort- >SERR- <PERRLatency: 64 (500ns min, 1000ns max), Cache Line Size: 32 bytes Interrupt: pin A routed to IRQ 11 Region 0: Memory at e0205000 (32-bit, non-prefetchable) [size=2K] Region 1: Memory at e0200000 (32-bit, non-prefetchable) [size=16K] Capabilities: [44] Power Management version 2 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+, 4.2. COMANDOS. 31 D3hot+,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME+ Con respecto a -x, podremos ejecutar: lspci -x lspci -xxx lspci -xxxx 4.2.6. lsusb Este comando lista los dispositivos USB que tenemos en nuestro sistema, pudiendo utilizar la opción -v para obtener mayor información. La salida del comando bien podrı́a ser: Bus Bus Bus Bus 004 003 002 001 Device Device Device Device 001: 001: 001: 001: ID ID ID ID 0000:0000 0000:0000 0000:0000 0000:0000 obteniendo una cuantiosa información al utilizar la opción -v 4.2.7. fdisk Si bien esta herramienta se suele utilizar la mayorı́a de las veces sólo para realizar modificaciones de la tabla de partición, ejecutando sin más el comando y eligiendo diferentes opciones dentro del prompt que se nos ofrece, puede ser utilizada para obtener información de los discos que disponemos mediante la utilización de la opción -l Disk /dev/sda: 60.0 GB, 60011642880 bytes 255 heads, 63 sectors/track, 7296 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1* 1 2555 20523006 7 HPFS/NTFS /dev/sda2 2556 3972 11382052+ f W95 Ext’d (LBA) /dev/sda3 3973 5250 10265535 c W95 FAT32 (LBA) /dev/sda4 5251 7296 16434495 c W95 FAT32 (LBA) /dev/sda5 2556 3320 6144831 83 Linux /dev/sda6 3321 3445 1004031 82 Linux swap / Solaris /dev/sda7* 3446 3458 104391 83 Linux /dev/sda8 3459 3972 4128673+ 83 Linux 32 CAPÍTULO 4. RECONOCIMIENTO DE HARDWARE. de tal forma que podemos obtener fácilmente y sin posibilidad de dañar nuestro disco información sobre el mismo. Ejecutándolo sin especificar absolutamente nada (sólo utilizando la opción -l), nos mostrará información de todos los discos duros de nuestro sistema. Para obtener información de un disco en concreto, tendremos que especificarlo: fdisk -l /dev/hda Capı́tulo 5 Directorios en Linux. 33 34 CAPÍTULO 5. DIRECTORIOS EN LINUX. Cuando utilizamos Linux, no tenemos una especial obligación en la utilización de un cierto directorio u otro para la ubicación de nuestros trabajos. En cualquier directorio, siempre que tengamos permisos para poder guardar ficheros en él, podemos almacenar nuestra información. Si bien es cierto esto que acabamos de comentar, también lo es que Linux mantiene cierta jerarquı́a, cierta organización de los diferentes directorios. Respetar esta organización muchas veces es obligatorio, pues por ejemplo ciertos ficheros de configuración el sistema los buscará en determinados directorios y en ningún otro sitio (salvo que realicemos un trabajo extra para cambiar el Sistema Operativo), pero otras muchas veces simplemente se respeta esta distribución por el mero hecho de la buena organización. Si nosotros guardamos los ficheros de usuarios en subdirectorios de /home, cualquier administrador que nos tenga que ayudar en un momento determinado no tendrá mayor problema al buscar esta información. Si hubiéramos decidido utilizar /casa, probablemente la persona que nos ayude empleará tiempo en darse cuenta de este cambio y por lo tanto perderemos efectividad. De tal forma entonces comprenderemos que hay ciertos directorios en los que encontraremos básicamente siempre cierta información, sobre todo cuando nos referimos a ficheros de configuración del Sistema, archivos importantes del kernel y librerı́as. 5.1. /etc En el directorio /etc nos encontramos los ficheros de configuración del sistema operativo Linux, de tal forma que cualquier cambio de configuración que queramos hacer, si no sabemos dónde encontrar el fichero para guardar este cambio, deberı́amos buscar primero en /etc antes que en ningún otro sitio. En este directorio nos podemos encontrar ficheros de configuración de librerı́as, de utilización de servicios de red, etc. Además podremos encontrar subdirectorios que incluyen a su vez ficheros de configuración. Algunos de los ficheros de configuración y directorios más importantes son: 5.1.1. aliases Guarda una lista de los alias de correo electrónico que tienen los diferentes usuarios válidos en el sistema, es decir, nos encontraremos ante un fichero organizado en dos columnas, la primera haciendo referencia a un usuario en concreto y la segunda a una dirección de correo electrónico. Cada vez que el usuario reciba correo electrónico en la máquina, este se redireccionará a la cuenta que tengamos asignada. Un ejemplo podrı́a ser: root: [email protected] 5.1. /ETC Fijémonos que después del login encontramos el caracter dos puntos, y a continuación una cuenta de correo electrónico válida. Decimos válida pues si no todo el correo electrónico que se mande a este usuario no se podrá llevar a su destino. Si en este fichero no está definido un usuario, entonces todo el correo electrónico que le llegue será guardado en su cuenta local en el sistema. Debemos tener cuidado especial en no crear ningún bucle, es decir, una configuración: pablo: root root: pablo es decir, el correo electrónico del usuario pablo se envı́a al usuario root, y el del usuario root se envı́a al usuario pablo. Si bien podemos pensar que es imposible tener esta equivocación, hay que tener en cuenta que un fichero aliases puede llegar a contener muchas entradas, de tal forma que podrı́amos tener un descuido de este tipo. Para que los cambios realizados a este fichero tomen efecto deberemos teclear el comando newaliases 5.1.2. at.deny y cron.deny Estos dos ficheros contendrán una lista de usuarios (ordenados en filas), a los que no permitiremos la utilización de at y cron respectivamente. Los ficheros at.allow y cron.allow tienen el significado contrario, es decir, contienen una lista de los usuarios a los que se les permite utilizar at y cron respectivamente. Una forma de configurar estos servicios mediante la utilización de estos ficheros es escribir la lista de los usuarios a los que permitimos utilizar at y cron, de tal forma que aunque no escribamos nada en at.deny y cron.deny, sólo los que estén en at.allow y cron.allow podrán utilizar at y cron respectivamente. En este sentido por tanto nada más instalar nuestro sistema tiene sentido que añadamos el login de root a at.allow y cron.allow, de tal forma que a partir de ese momento sólo root podrá utilizar estas utilidades del sistema, y conforme otros usuarios tengan que utilizarlas se les irá añadiendo. 5.1.3. cron.hourly, cron.daily, cron.weekly y cron.monthly Estos directorios contienen una serie de ejecutables, de tal forma que estos se ejecutarán cada hora, cada dı́a, cada semana o cada mes respectivamente. Los ejecutables que contengan estos directorios bien pueden ser shell scripts (la mayorı́a), pero también pueden ser binarios, y por supuesto podremos localizar enlaces simbólicos que apunten a ejecutables situados en otra zona del árbol de directorios del sistema. 35 36 CAPÍTULO 5. DIRECTORIOS EN LINUX. La forma de mantener tareas programadas en este sentido tiene sus detractores y también sus amantes. En contra podrı́amos decir que a priori (aunque lo podemos descubrir en los ficheros de configuración correspondiente), no sabemos exactamente en qué minuto de cada hora se ejecutarán los ejecutables contenidos en cron.hourly, a qué hora los contenidos en cron.daily, etc. En este sentido la programación mediante cron directamente es mucho más directa. Además tenemos muy restringida la programación, es decir, si queremos afinar un poco la programación (por ejemplo que se ejecute todos los domingos a las doce y un minuto de la noche), nos será imposible utilizar esta forma de programar tareas. A favor tenemos la sencillez, pues simplemente realizando un enlace simbólico al ejecutable que acabamos de instalar en nuestro sistema y que queremos que se ejecute un número determinado de veces (pero nos da un poco igual en qué momento en concreto) tendremos solucionado nuestro requerimiento. Por ejemplo con esta forma de programar tareas podremos ejecutar tareas de búsqueda de troyanos o de control de logs, que se deben hacer todos los dı́as pero que no es muchas veces imprescindible que sea a una hora en concreto. 5.1.4. csh.login y csh.cshrc Son dos ficheros que leerá la shell csh cuando sea llamada, de tal forma que ejecutará lo que se le especifique en estos ficheros, cargando por ejemplo valores en diferentes variables. El fin de estos ficheros por tanto es que los usuarios tengan un entorno homogéneo y es labor del administrador modificarlos consecuentemente con el fin de que los usuarios tengan las mı́nimas preocupaciones a la hora de crearse un perfil correcto de ejecución que funcione perfectamente en la máquina deseada. Los administradores por tanto tendrán que cargar las variables correspondientes que vayan a ser necesarias. Por ejemplo tras la instalación de un programa de cálculo, es posible que para que funcione correctamente los usuarios tengan que cargar alguna variable de alguna forma en concreto. Cargando estos valores en este archivo, ningún usuario tendrá que hacer absolutamente nada en su cuenta. 5.1.5. exports Es el fichero donde tendremos que escribir los recursos que queremos exportar vı́a NFS, ası́ como las propiedades de exportación. Este fichero permanecerá vacı́o siempre y cuando no habilitemos un servidor NFS en nuestra máquina, y deberemos tener extremo cuidado en su configuración si habilitamos el servidor. Un ejemplo bien podrı́a ser: /home maquina.dominio.es(rw) 5.1. /ETC fijándonos especialmente en los espacios que incluı́mos. Entre el nombre del recurso a exportar, y el nombre de la máquina (o conjunto de máquinas), que podrán acceder al recurso, debe haber un espacio, no ası́ entre el nombre de las máquinas y las propiedades de exportación (incluı́das entre paréntesis). 5.1.6. fstab En este fichero incluiremos los sistemas de archivos que vamos a montar en nuestro equipo. Estos no tienen que ser montados automáticamente en el arranque ni mucho menos, sino que podemos tener sus lı́neas correspondientes para hacer más sencillo su montaje cuando sea necesario. Este fichero se compone de diferentes lı́neas (una para cada sistema de archivos que queramos montar), y cada una de ellas está organizada en seis columnas. En la primera columna escribiremos el dispositivo objetivo del montaje, como por ejemplo /dev/sda1 si queremos especificar el montaje de la primera partición del primer disco del sistema. La segunda columna hace referencia al directorio donde se montará esta partición, por ejemplo /home si queremos que la información del dispositivo sea accesible desde este directorio. En la siguiente columna especificaremos el sistema de archivos que vamos a utilizar. Que podamos montar un sistema de archivos o no depende de si está habilitado en el kernel, es decir, si este sabe trabajar con este sistema de archivos. Los más habituales son ext4 y iso9660 (sistemas de archivos de linux y de los CDs/DVDs respecivamente), si bien podrı́amos especificar vfat o ntfs para particiones Windows, etc. En la cuarta columna indicaremos las opciones que se incluirán a la hora de montar este dispositivo. Muchas veces nos encontraremos defaults, ya que ası́ se utilizarán unas opciones que existen por defecto sin necesidad de escribirlas todas, pero podremos especificar todas las opciones que queramos, por ejemplo rw si queremos que sea un sistema de lectura y escritura, user si queremos que cualquier usuario lo pueda montar, noauto si no queremos que se monte automáticamente (con la opción -a de mount), etc. La penúltima columna hace referencia a la utilización del comando dump. Este comando sirve para realizar copias de seguridad y puede ser utilizado de forma general para realizar un backup global del sistema. Si en la quinta columna de un sistema de archivos determinado aparece el número 1, dump podrá realizar el backup global también sobre este sistema de archivos, pero si aparece un 0 no podrá hacerse el backup de esta manera. La sexta y última columna es utilizada por el comando fsck para realizar un chequeo de este sistema de archivos siempre que no hayamos escrito el número 0. En los casos en los que hayamos escrito el número 1 (siempre en el sistema de archivos / ) o 2 (en cualquier otro sistema de archivos), se comprobará mediante fsck cuando sea montado. 37 38 5.1.7. CAPÍTULO 5. DIRECTORIOS EN LINUX. group En este fichero tendremos una lista con todos los grupos creados en nuesto sistema. Se compone de una lı́nea por cada grupo, en cada una de ellas podremos encontrar el nombre del grupo, la contaseña del mismo, el número identificador del grupo (gid) y la lista de los usuarios que pertenecen a este grupo. Todos estos campos se separan con el caracter dos puntos. Es poco habitual que un grupo tenga contraseña, si bien podemos definirla sin mayor problema. Este fichero debe tener permisos de lectura para todos los usuarios del sistema, ya que si un usuario al hacer login en el sistema, no puede acceder a esta información, no podrá acceder al sistema. 5.1.8. gshadow Es el equivalente al fichero shadow pero para los grupos, disponible en sistemas donde tengamos habilitadas las contraseñas shadow. Este sistema aumenta la seguridad del operativo, ya que las contraseñas se separan de los ficheros que tienen que ser accesibles a todos los usuarios del sistema y se alojan en ficheros accesibles sólo a root. Es posible realizar esta separación ya que el proceso de autentificación lo lleva a cabo el superusuario, por lo tanto sólo este usuario necesita tener acceso al fichero, mientras que el resto de los usuarios simplemente necesita saber la información de su login, información que encontrarán sin mayor problema en los ficheros correspondientes y con permisos para que se pueda llevar a cabo esta lectura. Hasta la aparición de shadow, en la mayorı́a de los sistemas encontrábamos las contraseñas, cifradas, en ficheros accesibles, de tal forma que cualquier usuario podı́a hacerse con estos ficheros e intentar por tanto el crackeo de las mismas. 5.1.9. host.conf En este fichero estableceremos el orden en el que se consultará la resolución de nombres. Cuando intentamos realizar una conexión a un equipo, necesitamos saber su IP. Si lo que tenemos es su nombre, debe ser resuelto. Este proceso se puede hacer mediante ficheros de configuración en el propio sistema mediante la consulta en un servidor DNS u otras opciones menos utilizadas. En este fichero estableceremos por tanto el orden en que realizaremos esta consulta, siendo normalmente la primera opción la consulta local en los ficheros del sistema habilitados, y como segunda opción la consulta en servidores de nombres, si bien puede ser cambiado este orden o incluso modificado para incluir otras opciones (por ejemplo utilizando servicio NIS). Un ejemplo tı́pico de este fichero es: 5.1. /ETC 39 order hosts,bind donde hosts indica ficheros locales y bind consulta a un servidor de nombres. 5.1.10. hosts Fichero que contiene relaciones IP/nombre para que el sistema operativo pueda resolver direcciones sin necesidad de hacer consultas a los servidores de nombre. Este fichero está estructurado por lı́neas, de tal forma que en cada una de ellas nos encontraremos una dirección IP, seguida de su nombre correspondiente y a continuación uno o varios alias para esta dirección IP. De esta forma podremos realizar una conexión a una IP en concreto utilizando su nombre equivalente o cualquier alias que hayamos elegido, siempre y cuando este fichero se consulte en primera instancia (ver fichero host.conf). Si tenemos un error en la configuración de este fichero tenemos que tener en cuenta que las conexiones que realicemos pueden no llevarse a cabo o realizarse de forma errónea. Un ejemplo podrı́a ser: 64.233.183.99 www.google.com buscador de tal forma que podremos acceder a la página web de Google escribiendo en nuestro navegador cualquiera de estas tres opciones: http://64.233.183.99 http://www.google.com http://buscador 5.1.11. hosts.allow y hosts.deny Son los ficheros de configuración de la herramienta tcpwrapper. Esta herramienta nos permite realizar un control de acceso a los servicios de nuestra máquina que ofrezcamos mediante el protocolo tcp y estén habilitados. tcpwrapper comprobará la IP del equipo que intenta realizar la conexión y, atendiendo a la configuración de estos ficheros, permitirá el acceso o no. Una configuración por defecto muy utilizada es escribir en el fichero hosts.deny: ALL:ALL que impedirá cualquier conexión, configurando entonces el fichero hosts.allow servicio:IP para permitir que el ordenador con ip IP acceda al servicio servicio. 40 5.1.12. CAPÍTULO 5. DIRECTORIOS EN LINUX. inittab En este fichero se indican qué procesos son ejecutados en el arranque ası́ como durante la operación normal del sistema operativo. Si bien mucha de la información contenida en este fichero permanece invariable desde la instalación del sistema operativo, muchas veces los administradores modifican la lı́nea donde se indica qué nivel de ejecución se alcanzará tras arrancar la máquina, es decir, qué nivel de ejecución tendremos por defecto id:5:initdefault: en este ejemplo tendremos que el nivel de ejecución por defecto es el cinco, si bien podrı́amos cambiarlo a 3 en una máquina de cálculo, para evitar que se arranque el entorno gráfico con el consiguiente consumo de cpu y memoria RAM que conlleva. La sintaxis de las lı́neas incluı́das en este fichero consiste en cuatro campos separados por el caracter dos puntos. El primer campo es un identificador (de cuatro caracteres máximos, o dos para versiones de sysvinit compiladas con libc5 < 5.2.18). Este identificador tiene que ser único en todo el archivo. El segundo campo identifica el nivel de ejecución donde se aplicará esta lı́nea. En este campo podremos tener un sólo nivel de ejecución, varios o ninguno: en el caso de que queramos ejecutar algo sólo al alcanzar un nivel de ejecución, cuando alcancemos varios o cuando arranquemos la máquina respectivamente. El cuarto campo indica el proceso, el comando que se ejecutará. Finalmente el tercer campo indica la acción de lo que queremos realizar. El número de acciones es finito, siendo su significado: respawn. El proceso se rearrancará tan pronto se termine. wait. El proceso se ejecutará cuando se acceda al nivel de ejecución inidicado e init esperará a su ejecución. once. El proceso se ejecutará una vez cuando se alcance el nivel de ejecución indicado. boot. El proceso se ejecutará en el arranque. El campo de los niveles de ejecución será ignorado por tanto. bootwait. El proceso se ejecutará en el arranque, pero en esta ocasión init esperará hasta que se lleve a cabo. El campo de los niveles de ejecución también será ignorado en este caso. off. No tiene efecto. ondemand. Se ejecutará el proceso cuando se llame al nivel de ejecución ondemand. Estos niveles son el a, b y c, y cuando se llaman no conllevan un cambio en el nivel de ejecución. initdefault. Indica el nivel de ejecución al que se accederá cuando la máquina arranque. Si no hay indicación al respecto, el sistema lo preguntará interactivamente en consola. 5.1. /ETC 41 sysinit. El proceso se ejecutará en el arranque antes de cualquier proceso con acción boot o bootwait. El campo de los niveles de ejecución es ignorado por tanto. powerwait. El proceso se ejecutará cuando init recibe una señal de falta de corriente eléctrica (mandada por un sistema de alimentación ininterrumpida por ejemplo). init esperará hasta que se ejecute el proceso indicado. powerfail. Se ejecuta el proceso igual que con powerwait, pero en este caso init no esperará a su final. powerokwait. Se ejecutará el proceso cuando init reciba una señal que indique que se ha restablecido el proceso de alimentación eléctrica. init esperará a su ejecución. powerfailnow. Si el sistema de alimentación ininterrumpida conectado al sistema es capaz de informar a init que su autonomı́a está a punto de terminar, se ejecutará el proceso que se indique con esta acción. ctrlaltdel. Se ejecutará el proceso cuando se reciba la secuencia Ctrl+Alt+Spr. kbrequest. Si hemos asignado una combinación de letras a la acción KeyboardSignal, cuando se utilice esta combinación se detectará y se ejecutará el proceso asignado a esta acción. 5.1.13. issue Es un fichero de texto que se mostrará en pantalla antes del indicador de entrada en el sistema. Podremos modificar su contenido para mostrar mensajes institucionales o con información al usuario. 5.1.14. issue.net Es equivalente a issue, pero su contenido se mostrará en las conexiones telnet que se hagan contra nuestra máquina. Es conveniente sobre todo en este caso no mostrar información sensible de nuestra máquina en este fichero. Hay que tener en cuenta que su contenido se mostrará antes de que se realice un login correcto en nuestro sistema, de tal forma que si dejamos el contenido por defecto (habitualmente la versión de sistema operativo que se está ejecutando), estamos dando una valiosa información a un hacker que quiera acceder a nuestro equipo, pues a partir de ese momento se centrará en las vulnerabilidades que pueda haber en nuestra versión de operativo en vez de intentar cualquier vulnerabilidad conocida. 5.1.15. ld.so.conf En es fichero encontraremos la configuración utilizada por el cargador / enlazador ld.so (o ld-linux.so*), que buscan y cargan las librerı́as compartidas que necesita un programa que se necesite ejecutar. En este fichero por tanto escribiremos la ubicación (directorio), donde se encuentran las librerı́as compartidas que tengamos en nuestro sistema. 42 CAPÍTULO 5. DIRECTORIOS EN LINUX. Cada vez por tanto que instalemos librerı́as compartidas en nuestro sistema, que entendamos que necesiten ser cargadas en algún momento, escribiremos su directorio en este archivo y ejecutaremos el comando ldconfig para que el cambio tenga efecto. Actualmente se utiliza una sintaxis un tanto distinta, pero totalmente equivalente, para tener mayor orden en este sentido. En el fichero ld.so.conf lo que se hace es incluir la lı́nea: include ld.so.conf.d/*.conf de tal forma que al ejecutar ldconfig, al leer este fichero obligaremos a que se lea cualquier fichero, con extensión .conf, existente en el directorio /etc/ld.so.conf.d Por lo tanto cada vez que instalemos una librerı́a compartida en nuestro sistema, crearemos un fichero .conf en el directorio /etc/ld.so.conf.d que contenga el directorio donde se encuentra la (o las) librerı́a compartida. En este sentido la configuración es mucho más sencilla, pues en vez de tener un archivo único con muchas entradas (muchas veces desordenadas y complicadas de comprobar), tendremos varios archivos con nombres caracterı́sticos (deben acabar .conf), que cumplirán la misma función cara al sistema pero que serán mucho más fáciles de ordenar para el administrador. 5.1.16. login.defs Define la configuración que utilizará shadow en la creación de logins. En este fichero indicaremos las caracterı́sticas comunes que tendrán las cuentas que creemos en nuestro sistema, como puede ser la máscara por defecto, la caducidad del login, la creación o no del directorio home, etc. 5.1.17. logrotate.conf Configura la acción de logrotate. Este comando puede rotar los logs del sistema, comprimirlos e inclusos mandarlos por correo electrónico, según lo configuremos en su fichero de configuración. Hay que tener en cuenta que si no realizamos ninguna modificación de los ficheros de log, estos al cabo del tiempo se volverán inmanejables debido a su gran tamaño. En el fichero logrotate.conf configuraremos por tanto si estos ficheros tienen que ser rotados, si tienen que ser comprimidos, etc. Cuando decimos rotar, lo que queremos indicar es que el fichero de log cambiará de nombre, por ejemplo se llamará log.1, el fichero que se llamara log.1 se llamará log.2 y ası́ consecutivamente. El fichero más antiguo se eliminará (por ejemplo), y ası́ tendremos un sistema en el que el fichero de log correspondiente no alcanza un tamaño que le haga inmanejable y donde tendremos un número finito de archivos de log históricos. Una configuración habitual de este fichero de configuración puede ser: 5.1. /ETC 43 weekly rotate 4 create compress donde de forma semanal (weekly) se rotarán los logs, guardando cuatro semanas de antigüedad (rotate 4 ). Como cambiamos de nombre los ficheros de log al rotarlos (les añadiremos la extensión .1, .2, etc), se creará un nuevo fichero de log sin esta extensión para guardar los logs actuales (create), y se comprimirán los ficheros de logs (compress). 5.1.18. modprobe.conf Este fichero indica la configuración necesaria para la herramienta modprobe. Este comando carga en memoria módulos del kernel, pero incluyendo las dependencias si es que las tiene, a diferencia del comando insmod. Estas dependencias son incluidas en este fichero de configuración, ası́ como en ficheros que podremos incluir en el directorio /etc/modprobe.d Además de dependencias, en este fichero podremos incluir alias, es decir, nombres distintos para los módulos que deseemos, ası́ como caracterı́sticas extraordinarias para la carga de módulos. Esta última utilidad, la de incluir caracterı́sticas extra de carga de módulos en memoria, tenemos que configurarlas con mucho cuidado, pues una carga de un módulo de forma incorrecta puede producir errores en el funcionamiento del equipo. Habitualmente es el fabricante del dispositivo al que hace referencia el módulo, o el desarrollador del módulo quien indica qué variables se pueden utilizar en la carga del módulo para modificar su funcionamiento. El realizar nosotros cualquier cambio sin estar seguros de su finalidad última puede acarrear, como hemos indicado, una inestabilidad de la utilidad a la que haga referencia el módulo ası́ como del sistema. 5.1.19. motd motd es el acrónimo de Message Of The Day, es decir, en este fichero podremos escribir la información que nuestros usuarios lean cuando hagan login, y por lo tanto es una buena manera de mantener informados a los usuarios de las noticias que creamos interesantes para ellos. 5.1.20. mtab Es un fichero donde está incluı́da la información de los dispositivos montados en nuestro sistema. Es un fichero que en un principio un administrador no debe modificar en ningún momento, pues es el sistema el que lo modifica cada vez que se monte 44 CAPÍTULO 5. DIRECTORIOS EN LINUX. o desmonte un dispositivo, y cualquier modificación puede llevar consigo un mal funcionamiento del sistema por incongruencia entre lo que se ha montado y lo que el sistema cree que tiene montado (el contenido de este fichero). Algunas veces es necesario modificar el fichero, y normalmente es cuando hay algún problema grave con alguno de los dispositivos montados. Por ejemplo si accedemos a un dispositivo mediante NFS, y en un momento dado perdemos la conexión (pérdida de conectividad por ejemplo), es posible que ciertas caracterı́sticas de nuestro sistema no funcionen correctamente (por ejemplo el comando df podrá colgar una terminal al ser ejecutado, pues no podrá acceder a la información del recurso importado). Un método (quizás agresivo), que nos puede permitir recuperar cierto control en el sistema (pero que también puede hacerle inestable), es eliminar la lı́nea de este fichero que esté provocando la inestabilidad. En este momento el sistema creerá que no tiene montado este dispositivo y por tanto los errores que estuviéramos teniendo dejarán de manifestarse. 5.1.21. passwd Es el fichero donde se encuentra las caracterı́sticas de los login válidos en nuestro sistema. Este fichero está organizado por filas, cada una de ellas conteniendo la información de un login en concreto. La organización de las filas viene indicada por campos separados por el caracter dos puntos. El número de campos es siempre siete. El primer campo siempre es el login del usuario. A continuación tendremos la contraseña encriptada (tendremos el caracter x en el caso de que las contraseñas encriptadas no estén en este fichero sino en el fichero shadow). El tercer campo indica el número identificador del usuario (uid). Seguidamente el cuarto campo indica el número identificador del grupo principal del usuario. A continuación, en el quinto campo, obtendremos una descripción del login (que podremos dejar en blanco si ası́ lo deseamos). El sexto campo es el directorio home del usuario. El séptimo y último campo indica la shell por defecto del usuario. Este fichero es imprescindible en el sistema. Cualquier error en el mismo provocará la imposibilidad de login del usuario afectado, y por lo tanto su ausencia provocará la imposibilidad de ningún usuario pueda acceder al sistema (incluido el superusuario). Como contiene información vital para los usuarios, estos deben tener permiso de lectura sobre el mismo. 5.1.22. profile Su cometido es el al del fichero csh.login, pero para los usuarios de shell bash. 5.1. /ETC 5.1.23. 45 rc Es un script responsable de arrancar/parar servicios cuando un nivel de ejecución cambia. Este script no debe ser modificado salvo que sepamos exactamente lo que estamos haciendo, pues un mal funcionamiento del mismo harı́a que los cambios de nivel de ejecución se realizaran erróneamente. 5.1.24. rc0.d, rc1.d, rc2.d, rc3.d, rc4.d, rc5.d, rc6.d Cada uno de los directorios que consultará el script rc cuando cambiemos al nivel de ejecución al que haga referencia su número. Es decir, si cambiamos al nivel de ejecución 2, el script rc consultará el directorio rc2.d y ejecutará (por orden alfabético), todos los scripts que haya en este directorio (habitualmente enlaces simbólicos que apuntan a scripts ubicados en /etc/init.d o en cualquier otra parte accesible del sistema). Esta ejecución será acompañada con el argumento start si el nombre del fichero empieza por S, o con stop si empieza por K. Como hemos dicho que la ejecución será en orden alfabético, primero se ejecutarán todos los ficheros que empiecen con K, seguidos de los que empiecen por S. 5.1.25. rc.local Es un script que se ejecutará tras el resto de los scripts init, de arranque del sistema, de tal forma que podremos escribir en él ejecutables (o scripts) que queramos se ejecuten, independientemente del nivel de ejecución alcanzado. 5.1.26. rc.sysinit Este script se ejecutará en el arranque, y permite por ejemplo cargar las especificaciones de la red, de usb, etc. Cuando arrancamos el ordenador, el núcleo ejecuta init. Este comando buscará el fichero rc.sysinit y ejecutará su contenido. A continuación se ejecutará, si existe, el fichero rc.serial. Acto seguido se ejecutará los guiones del nivel de ejecución por defecto (establecido en inittab) y finalmente se ejecutará rc.local 5.1.27. resolv.conf Fundamentalmente este fichero contiene la lista de servidores de nombre que consultará el sistema cuando tenga que realizar una resolución de nombres gracias a un servidor externo. La sintaxis es: 46 CAPÍTULO 5. DIRECTORIOS EN LINUX. nameserver IP donde IP es el número ip del servidor de nombre. Podremos escribir tantas lı́neas como queramos, y el orden de consulta será el orden de las lı́neas, es decir, primero se realizará la consulta al servidor de nombres que aparezca en la primera lı́nea, en el caso de que no se produzca correctamente la consulta se utilizará el siguiente, etc. Además de especificar la lista de servidores de nombres que consultará el sistema, también podremos especificar nuestro dominio domain universidad.es el orden de búsqueda search uam.es y podremos especificar también opciones de búsqueda. En cuanto al orden de búsqueda indicar que se utilizará cuanto intentemos una conexión utilizando un nombre de equipo incompleto. Por ejemplo si queremos conectarnos al equipo www.uam.es, si escribimos únicamente www el ordenador se dará cuenta de que no hay ningún equipo válido con ese nombre y entonces intentará buscar el equipo www.uam.es (según hemos indicado con search uam.es). Si encuentra entonces un equipo válido entonces realizará la conexión. Podremos escribir tantas lı́neas search como nos sea necesario, utilizándose por el sistema en orden. Por supuesto si nuestro equipo, antes de realizar una consulta al servidor de nombres, busca la resolución en ficheros locales, si en estos existe un alias que coincida con el nombre corto que hemos utilizado, se utilizará este y no el que se obtenga al usar search. 5.1.28. securetty Es el fichero donde incluiremos las ttys donde root puede hacer login, para evitar que por ejemplo root pueda realizar una conexión mediante telnet o en ciertas consolas. 5.1.29. services Este fichero incluye una lista de los servicios de red de Internet, es decir, en el tendremos una lista del nombre del servicio, el puerto y protocolo utilizado y en algunas ocasiones un alias: http http 80/tcp 80/udp www www-http www www-http Todo programa que necesite realizar una conexión podrá leer este fichero para conocer el puerto que debe utilizar. Cualquier error por tanto en la configuración del mismo acarreará un error en la conexión. Si intentamos realizar una conexión y no existe la lı́nea correspondiente, es posible que esta no pueda llevarse a cabo. 5.1. /ETC 5.1.30. 47 shadow Es el fichero que contiene las contraseñas cifradas cuando utilizamos shadow. En este sentido aumentamos la seguridad del sistema, pues ningún usuario (salvo root por supuesto), podrá leer este fichero (si los permisos del mismo son correctos), y por tanto no se podrá realizar un crackeo de contraseñas, que sı́ se puede llevar a cabo por un usuario no privilegiado del sistema si las contraseñas cifradas se encuentran en el fichero passwd, ya que este debe tener permisos de lectura para los usuarios (aun no siendo privilegiados). El que sea posible que el fichero shadow no tenga permisos de lectura para los usuarios, sólo para root, es debido a que el usuario encargado de la autentificación en el sistema es root, y por lo tanto ningún usuario necesita acceder a esta información. 5.1.31. shells Cualquier shell que quiera ser utilizada en el sistema debe estar contenida en este fichero, organizado en lı́neas. Si realizamos la instalación de una nueva shell en nuestro equipo, esta no funcionará hasta que la incluyamos en este fichero, modificable sólo por root. Ası́ sólo podrán ser utilizadas, en un principio, las shells autorizadas por el superusuario, evitando cualquier tipo de acceso anormal en el sistema. 5.1.32. sysconfig El directorio sysconfig alberga una gran cantidad de ficheros de configuración, donde podremos encontar por ejemplo la configuración de la red. 5.1.33. sysctl.conf Este fichero de configuración, desgraciadamente, es un gran desconocido entre los administradores de sistema. La configuración de este fichero es utilizada por el comando sysctl para configuraciones opciones del kernel existentes en el directorio /proc/sys Lo que podemos modificar en este directorio /proc/sys lo podemos saber ejecutando el comando sysctl -a cuya ejecución nos dará una larga lista de opciones. Modificar cualquiera de estas opciones cambiará ciertos comportamientos que tiene el kernel, cara al sistema de archivos, red, etc. de tal forma que hay que tener cierto cuidado en realizar cambios sólo y exclusivamente cuando estemos seguros de no causar ningún error en el sistema. 48 CAPÍTULO 5. DIRECTORIOS EN LINUX. La forma de cambiar estas caracterı́sticas es modificando los archivos existentes en /proc/sys, que tienen los valores que hemos obtenidos tras la ejecución de sysctl -a Esta modificación la podemos realizar mediante el comando sysctl: sysctl -w a.configurar="valor" o también modificando el fichero correspondiente mediante el comando echo echo "valor" > archivo.a.configurar Al ser /proc un sistema virtual, cualquier modificación se perderá en el siguiente reinicio, por lo tanto si queremos que todas estas modificaciones se realicen siempre que arranque el sistema operativo, las escribiremos en el archivo sysctl.conf y por tanto serán modificadas sin nuestra interacción. Un ejemplo que podrı́amos poner es desactivar la respuesta al ping, es decir, que nuestra máquina no respondiera al ping de otra máquina remota. Esto lo podemos hacer ejecutando: echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all o con el correpondiente comando sysctl. Para evitar tener que teclear esto cada vez que arranquemos el sistema, lo que haremos entonces es incluir en el fichero sysctl.conf la siguiente lı́nea: net/ipv4/icmp_echo_ignore_all=1 donde podemos observar que la sintaxis cambia un poco: Evitamos la inclusión de /proc/sys/ en la ruta del archivo a modificar, y lo que hacemos es añadir el signo igual seguido del valor que queremos incluir en este fichero. 5.1.34. timezone En este fichero tendremos definida la zona horaria donde nos encontramos. Habitualmente no se suele modificar este archivo, pues no es habitual cambiar un ordenador de localización geográfica, y su configuración viene predefinida por la elección que hayamos hecho a la hora de instalar el sistema operativo. No obstante, si lo necesitamos, siempre podremos modificar su contenido para cambiar nuestra zona horaria. Una elección incorrecta de la zona horaria de nuestro sistema no sólo nos dará problemas por ejemplo en la recepción/envı́o de mensajes de correo electrónico (desfasados sus marcas de tiempo debido a esta configuración), sino que afectarán al buen funcionamiento del sistema de colas, por ejemplo, donde integremos el equipo ya que tendrá un desfase horario con respecto al resto de los equipos. También por supuesto podremos tener problemas al utilizar NFS y NIS, y en general con cualquier servicio que necesite una correcta sincronización horaria. 5.1. /ETC 5.1.35. 49 xinetd.d El directorio xinetd.d contiene una serie de archivos que contienen la configuración de diferentes servicios que ofrece el super demonio xinetd Cada uno de los archivos contenidos en este directorio mantiene la configuración de un servicio instalado en nuestro equipo, con el que por ejemplo se podrá permitir o evitar la ejecución de este servicio, controlar el binario que se debe ejecutar, el tipo de seguridad empleado, etc. Capı́tulo 6 Scripts de arranque. 51 52 6.1. CAPÍTULO 6. SCRIPTS DE ARRANQUE. Configuración y comandos básicos. Los niveles de ejecución en Linux son los diferentes estados en los que podemos encontrar un sistema operativo Linux. Cuando arrancamos un sistema Linux,tenemos la posibilidad de que el sistema operativo se comporte por ejemplo de forma monousuario, es decir, que no tengamos que introducir ni siquiera la contraseña del super usuario ya que arranca directamente en esta cuenta, como pasaba con los sistemas operativos DOS o Windows95/98/me. Otra forma que podemos tener de arrancar Linux es que permita que múltiples usuarios puedan conectarse a nuestra máquina, y que arranque un entorno gráfico en el cual pueda trabajar de forma muy agradable la persona que se siente delante de este equipo. Niveles de ejecución tenemos varios, es más, podremos incluso crear nuestro propio nivel de ejecución, totalmente personalizado. Por tanto esta forma de trabajar aumenta la versatilidad que tiene el sistema operativo Linux. Al ser los niveles de ejecución totalmente configurables, es posible que al trabajar en diferentes versiones de Linux veamos diferencias significativas. En la mayorı́a de las distribuciones de Linux vamos a tener que el nivel de ejecución 0 es el de apagado, es decir, si vemos que nuestro equipo está en este nivel de ejecución, inmediatamente tendremos que darnos cuenta de que está produciéndose el apagado del mismo. Otro nivel de ejecución que suele ser el mismo en todas las distribuciones es el número 6, que es el nivel de ejecución de reinicio, es decir, cuando nuestra máquina pasa a estado de ejecución 6 realmente está reiniciándose. Llegados a este punto nos damos perfecta cuenta de que un nivel de ejecución no es una forma de arrancar el sistema operativo, sino un estado del mismo. En muchas distribuciones el nivel de ejecución número 5 es el nivel de ejecución multiusuario con entorno gráfico y es el que se ejecuta por defecto cuando arranca el equipo. No tenemos que querdarnos entonces en que el nivel de ejecución de nuestro equipo es el número 5, sino que en ese justo momento está en el nivel de ejecución 5 y podremos cambiar a otro nivel en el momento que deseemos. También es habitual que en las diferentes distribuciones Linux el nivel de ejecución número 3 sea el de multiusuario sin entorno gráfico. Si bien es posible que en algún sistema Linux este nivel de ejecución no sea el número 3, normalmente nos encontraremos este nivel de ejecución ya que es muy habitual que las máquinas permanezcan la mayorı́a del tiempo en él. Esto suele ocurrir en máquinas destinadas al cálculo, donde es superfluo un entorno gráfico ya que suelen ser administradas en remoto y el tener este entorno aumenta la necesidad en disco pero sobre todo la cantidad de memoria RAM necesaria para las operaciones habituales. Ya que habı́amos hablado del nivel de ejecución monousuario, comentar que en la mayorı́a de las distribuciones suele ser el número 1, es decir, estar en nivel de ejecución número 1 implica necesariamente la imposibilidad de poder conectarnos a esta máquina con más de un usuario, y además este 6.1. CONFIGURACIÓN Y COMANDOS BÁSICOS. 53 (root) debe conectarse directamente en consola. El nivel de ejecución número 2 es multiusuario sin entorno gráfico y sin NFS en muchas distribuciones de Linux, es decir, es como el nivel de ejecución número 3 pero sin la posibilidad de importar/exportar recursos de disco a través de la red. Este nivel de ejecución se suele utilizar si tenemos algún problema con la red, si bien queremos mantener la caracterı́stica de entorno multiusuario en nuestro equipo. Finalmente comentar que el nivel de de ejecución número 4 suele estar reservado para que el administrador del equipo lo adapte a sus propias necesidades, siendo por tanto este nivel de ejecución el personal del administrador, teniendo las caracterı́sticas que este haya querido introducir. Cuando hablamos de nivel de ejecución es posible que lo veamos como un ente extraño y totalmente lejano a nuestras necesidades y posibilidades. Nada más lejano de la realidad. Cuando accedemos a un nivel de ejecución, realmente lo que ocurre es que se ejecutan los scripts contenidos en el directorio rcX.d, donde X es un número que indica el nivel de ejecución al que nos referimos (rc5.d por ejemplo a multiusuario con entorno gráfico). Los directorios rcX.d habitualmente los encontramos directamente en el directorio /etc, si bien en ciertas distribuciones los encontraremos en /etc/init.d, y si comprobamos su contenido nos daremos cuenta de que contienen varios (en muchas ocasiones una gran cantidad) enlaces simbólicos con nombres que siguen una estructura muy caracterı́stica: El primer carácter que nos encontramos es o una K o una S. A continuación tenemos dos caracteres que son números y finalmente tenemos un nombre sin ninguna regla preestablecida, pero que suele ser exactamente igual al nombre del fichero que apunta el enlace simbólico, por ejemplo: K05network Los ficheros a los que apuntan, los scripts a los que apuntan, habitualmente los encontraremos en el directorio /etc/init.d (si bien no es obligatoria esta ubicación), y normalmente responden estos scripts a una estructura tipo case. Cuando pasamos a un nivel de ejecución dado, digamos el número 5, lo que ocurre es que se ejecutan en orden estricto todos y cada uno de los scripts a los que hacen referencia los enlaces simbólicos. Estos scripts se ejecutan con un único argumento, que será start o stop dependiendo de si los enlaces simbólicos empiezan por S o K respectivamente. Es decir, si en el directorio rc5.d tenemos los siguientes enlaces simbólicos: S01network --> /etc/init.d/network S05nfs --> /etc/init.d/nfs K01ypbind --> /etc/init.d/ypbind el orden estricto implica por tanto que el primer script en ejecutarse será /etc/init.d/ypbind (K es anterior a S), seguido de /etc/init.d/network (S01 es anterior a S05) y finalmente /etc/init.d/nfs 54 CAPÍTULO 6. SCRIPTS DE ARRANQUE. La forma de ejecutar estos scripts será por tanto: /etc/init.d/ypbind stop /etc/init.d/network start /etc/init.d/nfs start Lo cual nos da una idea de la sencillez a la hora de incluir scripts personales para que se ejecuten de una determinada manera a la hora de pasar a un nivel de ejecución concreto, pues lo que tendremos que hacer es ubicar nuestro script en el directorio /etc/init.d y realizar un enlace simbólico en el directorio rcX.d que consideremos oportuno, llamando a este script con la sintaxis correcta. Hay que tener en cuenta que al ejecutarse en orden estricto, es conveniente tener en cuenta qué scripts se ejecutan antes y después del que estamos modificando. Por ejemplo deberı́amos tener en cuenta que si nuestro script ejecutará alguna herramienta que necesite de la red para funcionar, deberı́a ejecutarse (si este es el caso), con posterioridad al script que arranca la red, por lo tanto si este último está enlazado como S08network, nuestro script podrı́a ser S09script para que se ejecute con posterioridad al arranque de la red. Muchas veces equivocamos el sentido del fichero /etc/inittab al relacionarlo con los niveles de ejecución. Este fichero indica qué procesos tienen que ejecutarse en el arranque ası́ como en la operación habitual, y una de sus lı́neas indica qué nivel de ejecución se utilizará, por defecto, al arrancar la máquina. La lı́nea a la que hacemos referencia bien podrı́a ser: id:3:initdefault: en la que se indica que el nivel de ejecución por defecto, el que se ejecutará al arrancar la máquina, será el nivel número 3. No obstante nosotros podremos cambiar de nivel de ejecución fácilmente utilizando el comando telinit, telinit 2 harı́a que nuestra máquina pasara al nivel de ejecución número 2, de tal forma que podemos utilizar los comandos halt (o shutdown -h now ) y reboot (o shutdown -r now para apagar la máquina o reiniciarla respectivamente, o bien sus análogos telinit 0 y telinit 6 respectivamente. En cualquier momento, podremos saber en qué nivel de ejecución estamos sin más que teclear, runlevel además nos mostrará el nivel de ejecución previo en el que estuvimos antes. 6.2. SERVICE 6.2. 55 service Estos scripts que tenemos en nuestro sistema pueden ejecutarse con la opción stop o start cuando se cambia de nivel de ejecución, pero también los podremos ejecutar mediante el comando service service httpd start por ejemplo arrancará el servidor web en nuestro ordenador, es decir, buscará el script httpd en el directorio /etc/init.d y lo ejecutará con la opción start, sin tener que escribir nosotros toda la ruta completa. Además de poder darle la opción start, podemos optar por proporcionarle la opción stop o cualquier otra (status por ejemplo), que tuviera configurada el script. 6.3. chkconfig Finalmente, si queremos configurar los distintos scripts que queremos que paren o arranque al pasar a uno u otro nivel de ejecución, pero no nos atrae la idea de estar borrando, modificando o creando enlaces simbólicos en los directorios correspondientes, siempre podremos hacer uso del comando chkconfig La ejecución de este comando con la opción –list chkconfig --list nos mostrará en pantalla una lista con todos y cada uno de los scripts que pueden arrancarse o pararse al cambiar de nivel de ejecución, describiendo su estado para cada nivel de ejecución, es decir, nos indicarán si en el nivel 5, por ejemplo, se arrancan o se paran, etc. Un ejemplo de ejecución podrı́a ser: xfs 3:activo ypbind 3:desactivado 0:desactivado 4:activo 0:desactivado 4:desactivado 1:desactivado 5:activo 1:desactivado 5:desactivado 2:activo 6:desactivado 2:desactivado 6:desactivado Con esta herramienta no sólo podremos listar el estado, sino que también podremos configurar un determinado script para que se le envı́e una señal stop a la hora de pasar a un nivel de ejecución determinado: chkconfig --level 35 sendmail off que configurarı́a los directorios rc3.d y rc5.d de tal forma que se mandarı́a una señal stop al script sendmail al pasar a cualquiera de estos dos niveles de ejecución. Igual que hemos utilizado este comando para parar servicios, lo podrı́amos haber hecho de forma equivalente para que arrancaran servicios cuando pasáramos a estos niveles de ejecución, pues lo único que habrı́a cambiado es off por on. Capı́tulo 7 Creación de usuarios. 57 58 7.1. CAPÍTULO 7. CREACIÓN DE USUARIOS. Entorno gráfico. A la hora de crear usuarios, las diferentes distribuciones de Linux nos suministran herramientas sencillas con entorno gráfico, como por ejemplo system-config-users, que nos permiten realizar estas tareas administrativas sin mayor complicación. Figura 7.1: Aspecto de la herramienta system-config-users, para la creación de usuarios. Estas herramientas además aunan tanto la creación de grupos, como la creación de usuarios y la asignación de contraseñas, de tal forma que son ampliamente utilizadas por los administradores. 7.2. Lı́nea de comandos. El uso de este tipo de herramientas gráficas no debe dejar de lado la necesidad que tiene un administrador de utilizar sus equivalentes no gráficos (comandos), ya que muchas veces los administradores no disponen de terminales gráficos para poder realizar sus tareas, o bien no se dispone del tiempo suficiente para utilizarlas a golpe de ratón, y se necesita realizar algún script para la automatización de las mismas (por ejemplo si habitualmente tenemos que crear varias decenas de cuentas para usuario). Los tres comandos utilizados entonces en este sentido son useradd groupadd passwd 7.2. LÍNEA DE COMANDOS. que nos permiten crear usuarios, grupos y establecer contraseñas respectivamente. Lo primero que tendremos que hacer por tanto es crear un grupo, si es que no lo tenemos ya creado, en el que incluiremos al usuario. El comando groupadd lo invocaremos con la opción -g con el fin de asignar un número identificador al grupo que creemos. Este número debe ser único, es decir, no debe existir ningún grupo que tenga asignado este número. groupadd -g 510 nombregrupo Una vez hayamos creado el grupo correspondiente (que nos servirá para aunar a los usuarios que tengan un perfil equivalente), podremos crear el usuario mediante el comando useradd. Este comando tiene más opciones que groupadd, algunas de las más importantes son: -c A~ nade una descripción a la cuenta creada. -d Especifica el directorio HOME del usuario. -g Indica el grupo principal en el que se incluirá el usuario. -G Indica, separados por comas, los grupos secundarios del usuario. -s Especifica la shell por defecto que tendrá el usuario. -u Asigna el valor numérico del usuario. Por lo tanto una tı́pica ejecución de este comando serı́a: useradd -c "Usuario de calculo" -d /home/usuario -g 510 -G 501,502 -s /bin/bash -u 561 usuario Finalmente especificar que el comando passwd lo utilizaremos para especificar la contraseña de un usuario. El usuario root puede cambiar la contraseña de cualquier usuario, pero un usuario no root sólo podrá cambiar la suya propia. Además, cuando root ejecuta el comando, el sistema no le pedirá la contraseña previa de la cuenta en la que quiere cambiar esta. Sin embargo la ejecución de este comando por otro usuario necesitará, para su correcta ejecución, que le introduzcamos la contraseña previamente. Una de las opciones más desconocidas de este comando es –stdin, que permite que la contraseña sea introducido mediante la entrada estándar sin la necesidad de que esta sea el teclado. Esta utilidad es muy utilizada en la creación de scripts que automatizan la creación de cientos de usuarios por ejemplo. El introducir en estos casos la contraseña mediante el teclado harı́a impracticable el script, ya que se demorarı́a de forma alarmante la ejecución del mismo. Si las contraseñas las 59 60 CAPÍTULO 7. CREACIÓN DE USUARIOS. tenemos escritas en algún fichero (o base de datos por ejemplo), siempre las podremos pasar al comando passwd mediante la entrada estándar sin necesidad por tanto de escribirlas. No obstante comentar que también podrı́amos realizar una automatización de este tipo sin la utilización del comando passwd, pues el propio comando useradd incluye una opción (-p), que permite indicar la contraseña que tendrá este usuario. Esta contraseña tendrá que estar previamente encriptada mediante crypt, por lo tanto muchas veces es más complicado implementar un script mediante la llamada a crypt que utilizando el comando passwd con la opción –stdin. Capı́tulo 8 Tcpwrappers 61 62 CAPÍTULO 8. TCPWRAPPERS Bajo el nombre de tcpwrappers se comprende un sistema de control de accesos para ordenadores, es decir, la forma de poder seleccionar conexiones desde ciertos ordenadores. Normalmente a la hora de levantar un nuevo servicio en nuestro ordenador nos solemos interesar sobremanera en los beneficios que puede reportar este servicio, olvidándonos frecuentemente de las repercusiones negativas, en cuanto a seguridad, que pueden tener. Esta forma de trabajar suele derivar en una ausencia de control en cuanto a qué ordenadores pueden acceder a los servicios que estamos ofreciendo, de tal forma que facilitamos enormemente el trabajo de los hackers, que tienen en los servicios disponibles en nuestro ordenador la forma de acceder fraudulentamente al mismo. Herramientas para mejorar la seguridad de los servicios ofrecidos hay muchas. Una de las más efectivas, siempre que arranquemos un nuevo servicio en nuestro ordenador, es leer detenidamente el manual, haciendo especial hincapié en la lectura de la seguridad del mismo, configurándolo por tanto de forma efectiva con el fin de evitar accesos no deseados. Además de las propias herramientas que nos puedan ofrecer los propios programas, existe la utilización de los tcpwrappers siempre y cuando los programas estén desarrollados con compatibilidad con tcpwrapper. Esta herramienta provoca un filtro entre la petición exterior y el servicio ofrecido por el ordenador servidor (bajo tcp), de tal forma que acepta la petición siempre y cuando se cumplan unas ciertas caracterı́sticas que definiremos en los ficheros de configuración correspondiente. A este respecto hay que tener en cuenta que es una herramienta de seguridad que recarga el sistema, ya que por cada conexión se provocará un fork que hará uso de las capacidades del sistema, de tal forma que un excesivo número de clientes exigirá una máquina con suficiente capacidad para poder asegurar la creación de los sucesivos procesos hijos que se irán creando a instancias de tcpwrapper. Los ficheros de configuración necesarios para la autorización o denegación de la petición son hosts.allow y hosts.deny que se suelen encontrar en el directorio /etc. Cada fichero de acceso consiste en diferentes lı́neas de texto en las que se especifica, en un principio, los ordenadores que pueden o no acceder a nuestros servicios. La forma de atender a estas especificaciones es: * Se procesa el fichero hosts.allow, y a continuación el fichero hosts.deny * Cada una de las lı́neas de estos ficheros se procesa en orden de aparición. * En cuanto se realiza una comparación acertada, se para con la comprobación. es decir, si un ordenador intenta acceder a nuestro servidor web, que está asegurado mediante tcpwrapper, primero se buscará en el fichero hosts.allow si el ordenador que nos pide la conexión está permitido o no, buscando alguna 8.1. CONFIGURACIÓN. lı́nea en la que se autorice esta petición, si no se encuentra ninguna regla que afecte esta conexión, se pasará a la evaluación del fichero hosts.deny. Si no se encuentra ninguna regla que afecte a esta conexión, se permitirá que se realice. Con respecto a lo comentado, cabe destacar que es muy importante poner absoluto cuidado a la hora de crear ambos ficheros. Una forma de trabajar muy utilizada es la de denegación por defecto, en la cual lo que harı́amos es editar el fichero hosts.deny negando la entrada a cualquier ordenador para cualquier servicio, editando el fichero hosts.allow con las reglas oportunas que permitan el acceso a nuestro servidor a los ordenadores que creamos oportunos. Esto nos asegura que en caso de que no hayamos permitido explı́citamente el acceso a un ordenador, su acceso no será permitido, y por lo tanto evitará que por cualquier error a la hora de crear estos ficheros permitamos la entrada a ordenadores no deseados. En el caso de que nos equivoquemos y no facilitemos el acceso a algún ordenador en concreto, tendremos la seguridad de que recibiremos la queja oportuna del usuario que no puede obtener el servicio ofertado, subsanando el error por tanto. Si optáramos por el caso contrario, podremos estar seguros de que no recibiremos nunca la queja de un hacker que haya podido acceder a nuestro ordenador por una sintaxis errónea. Con la configuración de estos ficheros podremos permitir o no diferentes conexiones, y además nos permitirá tomar determinadas acciones ante determinadas peticiones. 8.1. Configuración. A la hora de editar los ficheros de configuración tenemos que tener en cuenta las siguientes indicaciones, como hemos adelantado anteriormente: * Cada fichero de acceso (hosts.allow o hosts.deny), consiste en ninguna o varias lı́neas de texto. * Las lı́neas son procesadas en orden, terminando la comprobación en cuanto se encuentra una concordancia, queden las lı́neas que queden por procesar. * Para permitir una edición más confortable, se permite la entrada de retornos de lı́nea siempre y cuando, si los queremos evaluar en la misma lı́nea, vayan finalizados por \\. * Las lı́neas en blanco o las precedidas por # no serán consideradas, permitiéndonos por tanto la creación de ficheros de acceso con comentarios (lı́neas precedidas por #) o con mayor facilidad de lectura (insertando lı́neas en blanco). Todas las lı́neas deben tener la siguiente sintaxis: 63 64 CAPÍTULO 8. TCPWRAPPERS lista_de_demonios:lista_de_clientes[:comando_de_shell] siendo esto último (los comandos de shell) optativos y donde con lista de demonios nos referimos a una lista con el nombre de uno o varios demonios o palabras clave y con lista de clientes nos referimos a una lista con uno o varios nombres de ordenadores, direcciones de ordenadores, patrones o palabras clave que permitan identificar al ordenador cliente, estos últimos separados por comas o por espacios en blanco. Pasemos entonces a los primeros ejemplos que podemos utilizar en nuestros ficheros de configuración. Recordemos que, a la izquierda de los dos puntos, debemos poner los demonios a los que hacemos referencia, por lo tanto en el fichero hosts.allow, si queremos permitir que el ordenador de ip 192.168.0.101 acceda a nuestro ordenador mediante telnet, lo que escribiremos será: in.telnetd:192.168.0.101 recordemos que podemos escribir más de un cliente al que se le permite acceder a nuestro servicio, por lo tanto, si queremos escribir más de un cliente, fácilmente modificaremos esta lı́nea para obtener: in.telnetd:192.168.0.101,192.168.0.102,192.168.0.103 en la que indicamos que permitimos el acceso a nuestro ordenador mediante telnet, a los ordenadores con ips 192.168.0.101,192.168.0.102 y 192.168.0.103. Si queremos también permitir la entrada a estos ordenadores al servicio ssh, escribiremos: sshd,in.telnetd:192.168.0.101,192.168.0.102,192.168.0.103 y podremos escribir tantas lı́neas sean necesarias con el fin de obtener una configuración acorde a nuestras necesidades, recordando a su vez que podemos partir una lı́nea, para resultar más cómodo a la hora de leer, mediante el uso de \: sshd,in.telnetd:192.168.0.101,192.168.0.102,192.168.0.103,\ 192.168.0.10,192.188.0.102,192.168.0.233,\ 192.168.0.11,192.198.0.102,192.168.0.153,\ 192.168.0.12,192.178.0.102,192.168.0.143 ftpd: 192.168.0.1,192.168.0.2,192.168.0.3 8.1. CONFIGURACIÓN. 8.1.1. Palabras especiales. Nos podrı́amos preguntar cómo podrı́amos permitir el acceso a todos los servicios que ofrecemos desde uno o varios ordenadores, sin tener que describir cada uno de los servicios explı́citamente, ya que esta fórmula es sumamente tediosa. La forma de especificar todos, es mediante el uso de la palabra especial ALL, de tal forma que si queremos que el ordenador con ip 192.168.0.10 pueda acceder a cualquier servicio disponible en nuestro ordenador, escribiremos en el fichero hosts.allow: ALL:192.168.0.10 ahora bien, esta palabra especial también se puede utilizar a la derecha del caracter dos puntos, es decir, haciendo referencia a los clientes que pueden acceder a este servicio. Si tenemos por ejemplo un servidor ftp que ofrece documentos y/o programas que queremos que pueda obtener cualquier cliente, lo que podremos escribir en el fichero hosts.allow es: ftpd:ALL escribiendo en lı́neas consecutivas el resto de restricciones que consideremos oportunas. Con respecto a esta última idea, comentar que se utiliza mucho a la hora de crear el fichero hosts.deny, ya que, como digimos anteriormente, una forma muy extendida de configurar estos ficheros es la de denegación por defecto y luego ir permitiendo poco a poco cada uno de los servicios a los clientes que consideremos oportunos. La denegación por defecto la podemos conseguir mediante la configuración del fichero hosts.deny de la siguiente manera: ALL:ALL ya que negará (recordemos que es el fichero hosts.deny) la entrada a cualquier servicio (ALL a la izquierda de los dos puntos), desde cualquier equipo (ALL a la derecha de los dos puntos). Otras palabras especiales son: LOCAL. Que resulta en una comparación positiva si el nombre del cliente no contiene un punto, es decir, es un ordenador local, de nuestra subred. UNKNOWN. La comparación resulta positiva en este caso cuando el cliente que quiere realizar la conexión resulta desconocido, como por ejemplo cuando no está registrado, un ordenador, en un servidor de nombres. En este sentido hay que destacar que resultarı́a UNKNOWN cualquier ordenador cuyo servidor de nombres esté caı́do, es decir, que no nos permita, temporal o permanente, realizar una consulta y por lo tanto garantizar su inclusión en el servidor de nombres. Podrı́amos utilizar esta palabra especial si quisiéramos 65 66 CAPÍTULO 8. TCPWRAPPERS evitar todos aquellos accesos de ordenadores no registrados a servidores de nombre, casos relacionados normalmente con ordenadores de hackers que intentan provocar malentendidos en cuanto a su identidad real. Debemos tener presente que podemos encontrar estos ejemplos en algunas compañı́as que ofrecen servicios de conectividad a la Internet que no relacionan sus ips con nombres. Además se nos puede plantear el caso de otras compañı́as que descuidan sus servidores de nombres, permaneciendo estos no operativos con cierta frecuencia. KNOWN. Es el caso contrario al ejemplo anterior, de tal forma que se realizará una comparación positiva si se puede realizar una consulta correcta al servidor de nombres en el caso de que intentemos validar un ordenador. También hay que señalar en este caso, como en el anterior, que una caı́da, temporal o permanente, de su servidor de nombres provocarı́a una comparación errónea. PARANOID. En este caso se dará una comparación positiva cuando el cliente se presenta con una ip que no corresponde a su nombre, casos que se pueden producir por una incorrecta inserción en el servidor de nombres o, en la mayorı́a de los casos, por una manipulación de hackers para intentar provocar errores en las interpretaciones de los ordenadores atacados. 8.1.2. Patrones. A la hora de configurar los ficheros hosts.allow y hosts.deny podemos utilizar distintos patrones que nos permiten simplificar la sintaxis de los mismos, pasemos a enumerarlos: * Si una cadena empieza por un punto, se considera que el cliente dará una comparación positiva si los últimos componentes de su nombre coinciden con esta cadena. Por ejemplo si escribimos en el fichero hosts.allow: ALL:.uni.via.edu se permitirá el acceso a todos los servicios del ordenador a los clientes cuyo nombre finalice en .uni.via.edu, como por ejemplo lab1.uni.via.edu * Si una cadena acaba en punto, tenemos un patrón equivalente al anterior pero referido a la ip de los ordenadores clientes, es decir, se dará una comparación positiva si los primeros campos coinciden con esta cadena. En el siguiente ejemplo, encontrado en el fichero hosts.allow: ALL:192.168.10. se permite el acceso a todos los servicios del ordenador a los clientes de la subred 192.168.10.0, es decir, a todos los ordenadores cuyos tres primeros campos en su ip sean 192.168.10 sea cual sea su cuarto campo. 8.1. CONFIGURACIÓN. * Una cadena que comienza con el caracter @ será tratada como un nombre de dominio NIS, de tal forma que se dará una comparación positiva si el cliente pertenece a este dominio NIS. * Una cadena de la forma a.b.c.d/m.n.o.p es interpretada como una pareja ip / máscara de red, de tal forma que una dirección IPv4 de un ordenador dará una comparación positiva si está comprendida dentro de la operación AND entre la pareja ip / máscara, es decir, si por ejemplo tenemos: 192.168.17.0/255.255.255.0 todos los ordenadores de la subred 192.168.17.0, es decir, todos los ordenadores cuyos tres primeros campos de la ip sean 192.168.17 darán una comparación positiva. Este mismo ejemplo se puede extender para el caso de una dirección IPv6, utilizando en este caso la expresión correspondiente para IPv6, n:n:n:n:n:n:n:n/m * Si la cadena comienza con el caracter / , se entenderá que a continuación se especifica un fichero en el que estarán contenidos los nombres o ips que tengan que compararse con los nombres o ips de los ordenadores que quieran utilizar los servicios del ordenador. El fichero puede contener todas las lı́neas que se necesiten (pudiendo estar vacı́o también), y los nombres de ordenadores o direcciones comprendidas en este fichero estarán separadas por caracteres blanco o por comas. * Se podrán utilizar los caracteres * o ? para la comparación de nombres o direcciones ip, pero no podrán ser utilizados junto con definiciones del tipo ip/máscara, o cadenas que empiecen o terminen con el caracter ”.” 8.1.3. Operadores. Podremos utilizar el operador EXCEPT para especificar una excepción tanto en el campo de la lista de los demonios (izquierda del signo dos puntos), como en el campo de la lista de ordenadores (derecha del signo dos puntos), de tal forma que podremos tener ejemplos como: ALL EXCEPT in.telnetd : 192.168.10. en el fichero hosts.allow, de tal forma que todos los ordenadores de la subred 192.168.10.0 tendrán acceso a todos los servicios excepto el telnet, o: ALL: 192.168.10. EXCEPT 192.168.10.1 donde se permite el acceso a todos los servicios del ordenador en cuestión a los clientes de la subred 192.168.10.0 salvo al ordenador de ip 192.168.10.1 67 68 CAPÍTULO 8. TCPWRAPPERS 8.1.4. Comandos de shell. Otra posibilidad interesante que ofrecen los tcpwrappers es la ejecución de comandos de shell, para ello tendremos que especificarlo en la primera regla de control de acceso. La ejecución de los comandos de shell podrá ser ayudada por expansiones que nos permitirán agregar a estos comandos el nombre del cliente, el nombre del servidor, etc, de tal forma que tengamos una mayor comodidad a la hora de especificar los comandos. Las expansiones que podremos realizar son: * %a La dirección del ordenador cliente. * %A La dirección del ordenador servidor. * %c Información del cliente. Dependiendo de qué información esté disponible, esta podrá ser usuario@ordenador, usuario@dirección, un nombre de ordenador o simplemente una dirección. * %d El nombre del demonio que rige el proceso. * %h El nombre del ordenador cliente o su dirección si este no está disponible. * %H El nombre del ordenador servidor o su dirección si este no está disponible. * %n El nombre del ordenador cliente o unknown o paranoid, dependiendo del caso, en el caso de que no esté disponible el nombre. * %N El nombre del ordenador servidor o unknown o paranoid, dependiendo del caso, en el caso de que no esté disponible el nombre. * %s Información del servidor. Dependiendo de qué información esté disponible, esta podrá ser demonio@ordenador, demonio@dirección o el nombre del demonio. * %u El nombe del usuario cliente, o unknown en el caso de que no se conozca. * % % Se expande como un simple % por si se quiere utilizar este caracter como tal. Un ejemplo que podrı́amos tener en este caso es, en el caso del fichero hosts.allow: ftpd : 192.168.10. que permitirı́a acceder al servicio ftp de nuestro ordenador servidor de los ordenadores de la red 192.168.10.0, y en el fichero hosts.deny: ftpd:ALL:spawn(/directorio_correspondiente/safe_finger -l @%h | /directorio_correspondiente/mail -s %d-%h root) & 8.1. CONFIGURACIÓN. en el que ejecutarı́amos el comando safe finger, que es un comando que se facilita con tcpwrappers, y que es prácticamente equivalente al comando finger habitual, pero un tanto más seguro en el sentido que es menos probable bloquear su ejecución, con las opciones explicadas con anterioridad. Si nos fijamos, primero se comprobará la regla del fichero hosts.allow, y si comprobamos que el ordenador cliente no pertenece a ninguna de las reglas contenidas en este fichero, pasaremos a comprobar las reglas del fichero hosts.deny, donde se especifica que para cualquier ordenador se ejecutará el comando safe finger y nos podemos fijar que hemos utilizado un par de las expansiones explicadas anteriormente, para facilitar los argumentos necesarios al comando safe finger y al comando mail. A este respecto cabe comentar varias cosas: * La ejecución del comando se ejecutará bajo shell /bin/sh * No se utilizará el PATH definido, sino que habrá que definirlo explı́citamente en la lı́nea o bien utilizar paths absolutos para los comandos utilizados. * Podremos permitir que se sigan comparando reglas si utilizamos al final de la lı́nea el caracter &, al igual que ocurre en las ejecuciones habituales. * La entrada por defecto ası́ como la salida por defecto y la salida de error se redirigen a /dev/null por defecto. Un caso práctico que también podemos implementar para obtener un log con los intentos de entrada en el sistema puede ser: ALL:150.244.120.:spawn(echo Soy %H intentando entrar en %d desde %h >> /tmp/entradas)& que generarı́a una lı́nea por cada intento de entrada en el fichero /tmp/entradas. En estas lı́neas recogerı́amos el nombre del ordenador servidor, el demonio al que intenta acceder y el nombre del ordenador al que intenta acceder, práctico por ejemplo si tenemos un único fichero de log para todas nuestras máquinas. 69 Capı́tulo 9 Cortafuegos 71 72 CAPÍTULO 9. CORTAFUEGOS El firewall, o cortafuegos en castellano, es un elemento, una herramienta, que se ha ido introduciendo cada vez con mayor fuerza en el vocabulario habitual de los usuarios de ordenadores, si bien este concepto existe desde hace mucho tiempo, y es ampliamente utilizado en redes en las que preocupe la seguridad. Hoy en dı́a prácticamente en la totalidad de los ordenadores personales incorporan cortafuegos personales, que son programas que filtran las conexiones entrantes (y salientes) a nuestro ordenador, intentando que nuestro ordenador no se vea afectado por ningún ataque externo. Ciertamente este tipo de herramientas han mejorado la calidad de vida de los usuarios de estos ordenadores personales, disminuyendo considerablemente el número de entradas no deseadas en este tipo de sistemas. Esto es debido a la proliferación de ataques masivos y automáticos, en los que el hacker programa un ataque y espera a que cada máquina infectada intente infectar al resto, estando mientras tanto cruzado de brazos a la espera de la cosecha, debida probablemente a algún fallo de seguridad en los equipos atacados. De todas formas cuando hablamos de cortafuegos solemos tener en mente algo distinto a los programas para equipos personales, y más bien solemos pensar en una máquina que se encarga de filtrar toda la información de una determinada red. Cortafuegos en este sentido hay muchos, y por ejemplo nos podemos encontrar con las tı́picas soluciones caras y triviales de utilizar que nos ofrecen compañı́as dedicadas a la construcción de las mismas; pero también podemos encontrarnos con cortafuegos que más bien parecen ordenadores personales. 9.1. Estudio previo. Antes de aventurarnos en la adquisición o montaje del cortafuegos, deberı́amos dedicarle algo de nuestro tiempo a la realización de un estudio previo de varios puntos importantes: * Topologı́a de la red a proteger. * Servicios más susceptibles de ser atacados. * Equipos fundamentales en mi red. * Tráfico generado. * Presupuesto disponible. * Personal disponible. 9.1. ESTUDIO PREVIO. 9.1.1. Topologı́a de la red a proteger. Un punto extraordinariamente importante a la hora de realizar el estudio previo es la topologı́a de la red, es decir, cómo están unidos los ordenadores entre sı́ (desde el punto de vista de intercambio de datos). Hoy en dı́a es habitual que los ordenadores tanto de una pequeña empresa como de una gran institución, estén unidos unos con otros gracias a switches. Esta configuración, además de ser muy sencilla de instalar y mantener, es relativamente barata, por lo tanto es la que nos vamos a encontrar en la mayorı́a de los casos, si bien hay que tener en cuenta otro tipo de conexiones, como USB, firewire, modem, etc. Obviamente dependiendo de cómo estén conectados nuestros ordenadores entre sı́, y también, cómo tenemos configurada la unión de nuestra red a la Internet, tendremos que configuar nuestro cortafuegos de manera que sea lo más óptimo posible. Cuando el tipo de conexión es homogénea, la configuración del cortafuegos se hace mucho más sencilla, independientemente de que sea más barata o más cara. Queremos decir con esto que si todos los ordenadores utilizan tarjetas fast ethernet (10/100 MBs), en nuestro cortafuegos tendremos que emplear tarjetas fast ethernet únicamente. De igual forma si todos nuestros equipos se conectan mediante firewire, tendremos que utilizar conectores firewire en nuestro cortafuegos, independientemente de que esta solución sea más o menos barata que la anterior. Sin embargo, si cada equipo de nuestra red tiene un tipo distinto de conexión, en el cortafuegos tendremos que integrar todas, con el fin de asegurarnos un correcto funcionamiento del filtrado de paquetes, haciendo mucho más complicada la configuración del cortafuegos, y probablemente más costosa. Tipo - Velocidad. Centrémonos por ejemplo en tarjetas de red únicamente, ¿tendremos que tener en cuenta algo más?: ¿Tienen todos los equipos el mismo tipo de tarjeta de red? Tenemos que tener en cuenta que no es lo mismo estar pensando en equipos de una oficina, que suelen estar configurados con tarjetas fast ethernet, gracias a las cuales pueden intercambiar datos entre ellos, que estar pensando en un centro de computación en el que sus equipos están trabajando gracias a tarjetas Gigabit Ethernet, Infiniband, etc., que les permiten poder ejecutar cálculos paralelizados. En este sentido tenemos que tener en cuenta que nuestro equipo cortafuegos tendrá un interfaz de red que tendrá que conectarse, de alguna forma, a estos equipos. Este interface tendrá que ser adquirido de forma que se integre perfectamente en esta topologı́a que tenemos, pero también tendremos que tener en cuenta la velocidad del mismo. Si estamos hablando de una oficina en la que todos los equipos poseen tarjetas fast ethernet, es más que probable que el interface de red que conecte nuestro cortafuegos a estos equipos sea una tarjeta de red fast ethernet, ya 73 74 CAPÍTULO 9. CORTAFUEGOS que no provocaremos ningún cuello de botella con su utilización, y es una solución mucho más barata que una tarjeta gigabit de la que no vamos a sacar mayor rendimiento que de esta otra. Si por otro lado estamos en el ejemplo del centro de computación, tendremos que tener en cuenta qué tipo de comunicación van a tener los ordenadores del centro con otros equipos externos, que están al otro lado del cortafuegos. Si se van a intercambiar enormes cantidades de datos entre equipos internos y externos, obviamente el interface de red que debe disponer el cortafuegos no puede ser una tarjeta fast ethernet, ya que provocarı́a un embudo que impedirı́a el perfecto desarrollo de la actividad del centro, sino que habrá que adquirir al menos una tarjeta gigabit (si no más), que permitan la conexión entre los ordenadores internos y los externos a través del cortafuegos. IPs públicas - IPs privadas. Quizás estamos muy acostumbrados a la terminologı́a IP pública - IP privada. Hoy por hoy la mayorı́a de las nuevas configuraciones se realizan mediante la utilización de IPs privadas, reservándose el uso de una (quizás más) IP pública en el equipo que nos comunica con la Internet, suprimiendo por tanto el gasto que supondrı́a la utilización de una IP pública en cada ordenador. A la hora de instaurar un cortafuegos, tenemos que tener en cuenta que no todos los ordenadores tienen que ser protegidos de la misma manera, unos serán más crı́ticos que otros, unos tendrán más restricciones de acceso que otros. Normalmente lo que se suele hacer es repartir las IPs conforme a la utilidad de los equipos, de tal forma que nos permita este reparto hacer una clasificación oportuna conforme a los riesgos potenciales de cada grupo. Si utilizamos IPs privadas esta clasificación la podemos hacer fácilmente. Si utilizamos por ejemplo la red 192.168.0.0/16, podremos implementar en nuestra organización 254 apartados de 254 ordenadores cada uno, de tal forma que podremos separar fácilmente los ordenadores por riesgos, incluso por departamentos si nos interesa, siendo esta clasificación a priori muy útil en la configuración del cortafuegos. En el caso de IPs públicas probablemente no tengamos tan fácil esta clasificación, ya que no es habitual adquirir muchas IPs más de las necesarias a priori, de tal forma que muchas veces disponemos de diferentes partidas de IPs públicas que iremos adquiriendo bajo demanda y que nos harán más difı́cil la clasificación de los equipos mediante familias de IPs. A favor de la utilización de IPs públicas tenemos que en este caso no tendremos que realizar NAT (traducción de direcciones de red), que habitualmente se realiza en el propio cortafuegos, ya que los equipos con IPs públicas pueden comunicarse directamente en la Internet, mientras que en el caso de la utilización de IPs privadas, tendremos que tenerlo en cuenta porque muy probablemente tengamos que configurar en el cortafuegos NAT para que los equipos puedan tener acceso a la Internet. 9.1. ESTUDIO PREVIO. 9.1.2. Servicios más accesibles. Algo a estudiar de forma previa a la adquisición del cortafuegos, es qué servicios estamos ofreciendo (y si hay alguno que queremos ofrecer en un futuro cercano), y qué público tienen estos. Si nosotros estamos ofreciendo información a través de un servidor web a cualquier equipo de la Internet tenemos que darnos cuenta de que tendremos que tratar de forma diferente a este servidor que a un ordenador que está sirviendo directorios a clientes internos. Obviamente en el primer caso tendremos que permitir el acceso a través de nuestro cortafuegos a cualquier IP, mientras que en el segundo caso sólo deberı́amos permitir el acceso al servidor a los ordenadores clientes de nuestra institución. Es por tanto fundamental la enumeración de todos los servicios que estamos ofreciendo, catalogándolos según los equipos que pueden acceder a ellos, tanto equipos internos como externos, para ası́ configurar el cortafuegos con las reglas correspondientes. Habitualmente, siempre que sea posible, los equipos que ofrecen servicios a peticiones externas, suelen ubicarse en una subred distinta del resto de los equipos, ya que esto permite su aislamiento desde el cortafuegos con mayor facilidad, no obstante, estén en una subred o no, el cortafuegos deberı́a estar fı́sicamente entre estos equipos y el resto de los ordenadores de mi institución, es decir, si siguiéramos el cable que une a un equipo con servicios que se ofrecen externamente, antes de llegar a cualquier equipo interno deberı́a toparme con el cortafuegos, ya que ası́, estén en subredes diferentes o no, siempre podré establecer una regla sencilla que impida a ordenadores externos pasar al interface del cortafuegos donde he conectado los equipos internos. Cuando separamos los ordenadores que ofrecen servicios externos, decimos que hemos creado una zona desmilitarizada (ampliamente conocido como DMZ, con sus siglas en inglés), es decir, una zona donde la seguridad no es tan severa como en el resto de las zonas, y siempre conectaremos esta zona a un interface de red en el cortafuegos, diferente del resto de zonas. 9.1.3. Equipos fundamentales en mi red. Aunque repitamos en cierta medida lo expuesto anteriormente, debemos tener en cuenta también qué equipos son fundamentales en nuestra red. Si somos prácticos, aunque un ataque debe evitarse por todos los medios posibles sea el ordenador que sea el objetivo, los ordenadores que contienen información vital para la empresa tienen que ser, necesariamente, más mimados. Este tipo de ordenadores también suelen establecerse, si es posible, en subredes ajenas al resto de los equipos, y siempre conectados al cortafuegos a través de un interface de red distinto al resto de los equipos, ya que ası́ podremos controlar mucho mejor las conexiones que se harán con estos equipos. 75 76 CAPÍTULO 9. CORTAFUEGOS Si en el caso de la zona desmilitarizada tenemos el máximo número de conexiones permitidas, en esta zona tendremos el mı́nimo número de conexiones permitidas. Seguramente, salvo que sea imperativo lo contrario, no permitiremos el acceso de ningún ordenador externo a esta zona, y probablemente de los ordenadores internos no todos podrán acceder a cualquiera de estos ordenadores fundamentales. 9.1.4. Tráfico generado. Hemos introducido ya varias veces la necesidad de instalar diferentes interfaces para las diferentes zonas de nuestra institución. Estos interfaces pueden ser fı́sicos o no, dependiendo de las necesidades, pero algo que tendremos que tener en cuenta, y que nos obligará a utilizar o no diferentes interfaces fı́sicos es el tráfico generado. En condiciones normales, el tráfico generado por los equipos de una institución media pueden ser gestionados sin ningún problema con un interface fı́sico en el cortafuegos, pudiéndose hacer cargo de todas las transacciones que se mantienen. No obstante el tráfico generado tiene que ser estudiado ya que es posible que no podamos gestionar absolutamente todo debido a limitaciones con nuestro interface. En estas ocasiones lo que debemos hacer es instalar más interfaces que permitan aumentar las posibilidades de nuestro cortafuegos. Con los equipos actuales (switches) esta operación es sencilla y podremos tener un equipo cortafuegos con diferentes tarjetas funcionando de forma agregada, pudiendo soportar más tráfico del que soportarı́a con una única tarjeta. En este sentido también tenemos que indicar que las caracterı́sticas del equipo son importantes para llevar a cabo una buena gestión, ya que no es lo mismo utilizar un equipo antiguo como cortafuegos, que un equipo con las últimas prestaciones. En este sentido los grandes protagonistas son el procesador elegido y la memoria RAM. Se suele decir que el procesador en un cortafuegos no es primordial. Es algo que, con ciertas herramientas de creación de cortafuegos, puede ser secundario, pero recordemos que todo el tráfico que atraviesa los interfaces de red del cortafuegos tiene que ser analizado para comprobar si permitimos o no su entrada, salida o reenvı́o, y si tenemos un equipo obsoleto en una institución con un elevado tráfico, podremos tener problemas de accesos no permitidos por desbordamiento del cortafuegos. 9.1.5. Presupuesto y personal disponible. Finalmente entramos en uno de los puntos más delicados a la hora de poner en marcha un cortafuegos, y es el presupuesto del que disponemos y del número de horas que se puede dedicar al cortafuegos. En este sentido cabe decir que existen soluciones finales en el mercado que permiten gestionar el tráfico de cualquier institución mediante unas reglas que se definen fácilmente 9.2. IPTABLES. a través de un entorno gráfico sencillo, parcheándose automáticamente siempre que se descubre alguna vulnerabilidad en el equipo y hayamos pagado la debida cuota de mantenimiento. Este tipo de soluciones son las ideales cuando se dispone de un presupuesto importante pero no de personal, ya que la interacción que se necesita es mı́nima, ya que viene preconfigurada de fábrica. El problema en este sentido es la dificultad de cambio, es decir, si queremos cambiar algo en nuestra red, la adaptación del cortafuegos no va a ser tan inmediata como deseáramos y vamos a tener que volver a desembolsar dinero para que la empresa suministradora lo adapte a nuestras necesidades. Sin embargo, existen soluciones muy baratas (ordenador personal con diferentes tarjetas de red), en las que se pueden implementar soluciones gratuitas (iptables de linux), pero que nos van a requerir un cierto tiempo de configuración, es decir, ya no vamos a tener a nadie que nos lo configure sino que vamos a tener que trabajar nosotros en ello, teniendo a una persona dedicada en parte al cortafuegos para que tenga suficiente pericia para poder realizar cualquier tipo de cambio en nuestra red en tiempo mı́nimo. Esto no quiere decir, ni mucho menos, que una u otra sean las mejores soluciones, cada una tiene sus pros y sus contras que deben ser estudiados en cada caso particular. Al igual que en otros campos de la informática, en este punto, dejando aparte el tema económico y de personal, hay detractores de una u otra solución, alentando la utilización de soluciones cerradas debido a la dedicación exclusiva de personal de la empresa suministradora a la mejora del producto o a la utilización de soluciones de código abierto debido a las ventajas de este. 9.2. iptables. La herramienta por excelencia en código abierto cuando hablamos de cortafuegos es iptables, sucesor directo de ipchains, que a su vez procedı́a de ipfwadm. Realmente no podemos hablar de un programa, iptables no es un programa, sino que podrı́amos decir que es un sistema de selección de paquetes que hace uso de netfilter y con el que se pueden definir unas reglas que se almacenan en memoria, contra las que se comparan los paquetes que pasan por nuestro ordenador, pudiendo desechar los paquetes que no cumplan estas reglas, aceptarlos o pasarlos a un determinado interfaz. iptables lo podemos configurar en nuestro ordenador personal, al igual que las múltiples soluciones aparecidas últimamente para plataformas de Microsoft, aumentando considerablemente la seguridad de nuestro equipo, si bien la idea de iptables es más ambiciosa al poder utilizarse en un ordenador puente en nuestra red, de tal forma que filtre no sólo los paquetes particulares de un ordenador, sino todos los paquetes de una red, bien sea una red pequeña en una casa, bien una red de una empresa o bien la red de una universidad. Lo bueno de iptables es que la generación de las reglas que nos permitirán controlar los paquetes de esta red, tiene la misma complejidad 77 78 CAPÍTULO 9. CORTAFUEGOS que si la generáramos para nuestro equipo personal, es decir, si sabemos filtrar los paquetes que llegan a nuestro ordenador mediante iptables, sabemos filtrar los paquetes que llegan a una institución compleja. 9.3. Polı́tica por defecto. Lo primero que debemos considerar, ya no al configurar un cortafuegos con iptables, sino en cualquier caso, es qué tipo de polı́tica vamos a seguir, si la de aceptación por defecto o la de denegación por defecto. En el primer caso lo que haremos es aceptar todas las conexiones que lleguen a nuestra cortafuegos, e iremos cerrando las conexiones que consideremos. Este tipo de idea conlleva conocer perfectamente nuestro equipo o nuestra red, dependiendo de si tenemos un cortafuegos personal o institucional, asegurando aquellos puertos existentes en nuestra red, y no haciendo absolutamente nada en el resto ya que no existen servicios basados en ellos. En el segundo caso denegaremos absolutamente todo lo que llegue al cortafuegos como polı́tica por defecto, e iremos abriendo los diferentes puertos que nos vayan haciendo falta. Esta segunda forma de trabajar está ampliamente extendida, sobre todo en cortafuegos no personales, casos en los que es muy complicado conocer perfectamente todos los puertos que tienen abiertas las máquinas que protege el equipo cortafuegos. En este caso tendremos la seguridad, salvo mala configuración o gestión, de que no tendremos ningún ataque a puertos de los que desconozcamos su existencia. Sin embargo tendremos que tener muy en cuenta que hasta que tengamos el cortafuegos totalmente operativo, recibiremos un número considerable de quejas de usuarios que no pueden acceder a ciertos servicios o contenidos de otras máquinas al no estar reflejadas todas las posibilidades en el cortafuegos. En cierto sentido esto último puede considerarse, dándole la vuelta a su significado, como un pretexto para no utilizar la aceptación por defecto, ya que ante cualquier instalación nueva de un servicio en cualquiera de los ordenadores bajo nuestro cortafuegos, puede pasar desapercibida en la polı́tica de aceptación por defecto por la habitual falta de comunicación de este tipo de actividades por parte de los usuarios. En una denegación por defecto, sin embargo, estaremos seguros de la comunicación de este tipo de instalaciones ya que el propio usuario (enfadado o no) nos avisará de la imposibilidad de ejecutar correctamente el nuevo software instalado. A la hora de trabajar con iptables, tendremos que comentar primeramente que podremos configurar nuestro cortafuegos con la ejecución de órdenes que irán aplicando las distintas reglas de cortafuegos. Estas órdenes mayoritariamente las daremos mediante el comando iptables, que iremos alimentando con diferentes argumentos que irán permitiendo o negando entradas. A la hora de imponer en nuestro equipo una polı́tica, utilizaremos el argumento -P, a continuación describiremos si la polı́tica afecta a la entrada (INPUT) de paquetes, a la salida (OUTPUT) o a la redirección (FORWARD), 9.4. INICIALIZACIÓN. y finalmente elegiremos qué hacer por defecto con estos paquetes, aceptarlos (ACCEPT), rechazarlos (REJECT) o eliminarlos (DROP). En una polı́tica de aceptación por defecto escribiremos por tanto: iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT mientras que en una polı́tica de denegación por defecto, escribiremos: iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP Con respecto a las diferencias entre REJECT y DROP: Cuando un paquete no es aceptado mediante REJECT, la máquina origen de este paquete obtendrá la información de que el paquete ha sido rechazado, mientras que si utilizamos la opción DROP nunca sabrá qué ha ocurrido con el paquete, pues será como si el paquete se hubiera perdido en la transmisión. En cuanto a utilizar una u otra posibilidad, depende del administrador. Mediante el uso de REJECT estaremos muy probablemente indicando al usuario de la máquina origen que hay un cortafuegos en nuestra institución, que es el causante de que la comunicación no se lleve a cabo, mientras que en el segundo caso, mediante la utilización de DROP, será más complicado saber si ha sido eliminado el paquete, y su respuesta, por un cortafuegos o por un fallo en la red. Depende por tanto de las caracterı́sticas de la institución, de la red y del administrador del cortafuegos, pues hay veces que se prefiere realizar un REJECT para hacer ver que existe un firewall, bien para disuadir a los atacantes, bien para que el usuario de la máquina origen conozca el caso y pida una apertura del puerto correspondiente al administrador del cortafuegos. En el caso de DROP, ampliamente utilizado en la configuración de sistemas cortafuegos, quizás estemos aumentando la seguridad por ocultación, si bién hay muchas crı́ticas en cuanto a la bondad de la seguridad por ocultación. 9.4. Inicialización. Si analizamos convenientemente lo dicho hasta el momento respecto a iptables, podremos darnos cuenta de que estas tres polı́ticas por defecto insertarán tres reglas en memoria para el tratamiento de los paquetes pero, ¿son estas tres reglas nuevas? ¿Hemos tenido otras reglas anteriormente? Es 79 80 CAPÍTULO 9. CORTAFUEGOS decir, ¿no es posible que hayamos ejecutado el comando iptables, con las opciones que sea, anteriormente? En ese caso, ¿qué estará pasando realmente en el cortafuegos? Pues bien, si previamente hemos ejecutado el comando iptables, es posible que aunque creamos que ningún paquete por defecto se va a aceptar, una regla previa tecleada, como prueba, acepte ciertos paquetes, para lo cual o bien antes de teclear nada nos aseguramos de qué reglas tenemos cargadas en memoria, o bien eliminamos cualquier regla aceptada con el uso de iptables, asegurándonos por tanto comenzar en un escenario totalmente limpio. En el primer caso, para conocer las reglas existentes en nuestro sistema, podremos teclear: iptables -L y si queremos en cualquier momento eliminar cualquier regla establecida con anterioridad, teclearemos: iptables -F iptables -Z Donde la opción -F elimina la regla que a continuación escribamos, eliminando la totalidad de reglas establecidas si no escribimos nada más; y la opción -Z pone a cero los contadores de bytes y de paquetes, es decir, empezamos a contabilizar a partir de ese momento. 9.5. Cadena INPUT. A partir de este momento tendremos que ir permitiendo las diferentes conexiones que nos interesen, para ello tendremos que definir ciertos argumentos de iptables: * -s Es la fuente del paquete. Habitualmente ponemos la IP desde la que se origina el paquete, pudiendo poner una máscara que nos interese mediante el uso del caracter / seguido de la máscara. Como ejemplo: 192.168.5.1/32 que especifica exclusivamente el ordenador con IP 192.168.5.1 192.168.5.1/16 que especifica todos los ordenadores de la subred 192.168.5.0 9.5. CADENA INPUT. * -d Es el destino del paquete, estableciéndose este con las mismas reglas establecidas en el punto anterior. * –sport Es el puerto de origen. * –dport Es el puerto de destino. * -i Es el dispositivo de entrada del paquete. * -o Es el dispositivo de salida del paquete. * -p Protocolo del paquete en cuestión. * -A Cadena sobre la que se establece la regla, pudiendo ser INPUT, OUTPUT o FORWARD. * -j Qué es lo que se hará con este paquete, como puede ser ACCEPT, DROP, REJECT. Por tanto estableceremos diferentes posibilidades: Si queremos que todas las conexiones entrantes originadas en el dispositivo lo (loopback), se acepten, lo que tendremos que escribir es: iptables -A INPUT -i lo -j ACCEPT Fijémonos que hemos dicho cualquier tipo de conexión, por lo tanto en este caso no acotaremos qué tipo de protocolo (-p), puerto de origen (–sport), puerto de destino (–dport), etc. vamos a autorizar, sino que cualquier cosa que cumpla que sea originada en el dispositivo lo y sea de entrada al sistema será aceptada. Si tenemos un servidor web configurado, tendremos que permitir todas las conexiones que se hagan a él, concretamente al puerto 80, para ello tendremos que teclear: iptables -A INPUT -p tcp -dport 80 -j ACCEPT En este caso cualquier tipo de conexión tcp dirigida al puerto 80 será aceptada por parte del cortafuegos pero, ¿y si queremos que nuestro servidor sólo sea visto por los ordenadores de nuestra subred (192.168.6.0)? Teclearemos entonces: iptables -A INPUT -p tcp -s 192.168.6.0/24 -dport 80 -j ACCEPT 81 82 9.5.1. CAPÍTULO 9. CORTAFUEGOS Servidores de nombres. Habitualmente no se nos olvida que nuestro ordenador tiene un servidor web arrancado, y por lo tanto deberı́amos permitir la entrada a este puerto, pero hay ciertas conexiones que no las tenemos tan frescas, que ni siquiera tenemos en cuenta, pero que aun ası́ deberı́amos autorizar. Es el caso por ejemplo de las consultas al servidor de nombres, y es que no se nos debe olvidar que cada vez que intentamos hacer una conexión a una máquina mediante su nombre, y no su ip, o cuando alguna comunicación se presenta a nuestro ordenador con el nombre, nuestro ordenador tiene que consultar con el servidor de nombre para poder llevar a cabo la resolución. Para permitir este tipo de conexiones, tendremos que insertar en memoria las siguientes reglas: iptables -A INPUT -s IP_del_DNS -p udp -m udp --sport 53 -j ACCEPT iptables -A OUTPUT -d IP_DEL_DNS -p udp -m udp --dport 53 -j ACCEPT es decir, por una parte permitimos las conexiones entrantes del servidor DNS, y también permitimos las peticiones que hacemos al servidor. 9.5.2. Cadena OUTPUT. En ciertas redes algo que se permite es la salida de cualquier máquina al exterior, es decir, se entiende que no hay ningún problema en que las máquinas internas puedan acceder a cualquier contenido en la Internet. Este tipo de polı́ticas, si bien están muy extendidas, hay que pensarlas a fondo por si son o no convenientes. Normalmente los administradores de los cortafuegos suelen optar por permitir cualquier conexión de salida porque si no sufren un gran número de crı́ticas internas sobre la configuración del cortafuegos, ya que el personal de la empresa o de la institución no puede acceder a ciertos contenidos en la Internet que le son necesarios. La solución quizás no es permitir cualquier salida, ya que hay muchos troyanos en la Internet que una vez que infectan la máquina, en vez de esperar una conexión exterior para permitir la entrada o comenzar una acción determinada, provocan ellos la comunicación, ya que en la mayorı́a de las ocasiones las entradas a la zona interna está prohibida, pero no ası́ la salida. Por esta razón es conveniente hacer un análisis, al igual que cuando hablamos de permitir conexiones entrantes a nuestra red, y ver qué tipo de conexiones salientes deberı́amos permitir y dejar accesible solamente estas salidas y no otras. No obstante no es que esta solución sea la clave para evitar accesos gracias a troyanos, pues muy probablemente tengamos que permitir la salida a puertos 80 (servidores web), y los troyanos pueden utilizar este puerto como destino, por lo tanto además de este tipo de solución, 9.5. CADENA INPUT. deberı́amos incorporar otros localizadores de troyanos para evitar intrusiones aun teniendo cortafuegos. Si hemos optado por permitir cualquier salida al exterior, la polı́tica que escribı́amos en un principio deberı́a cambiar para ser: iptables -P OUTPUT -j ACCEPT dejando las otras dos polı́ticas como habı́amos indicado. En el caso de que prohibiéramos por defecto las salidas, tendrı́amos que ir aceptando cada una de las conexiones que nos interesaran, siguiendo los ejemplos que hemos introducido anteriormente para conexiones entrantes, por ejemplo, si queremos que cualquier ordenador de nuestra red pueda acceder a servidores web, teclearı́amos: iptables -A OUTPUT -s NUESTRA_SUBRED -dport 80 -j ACCEPT Si queremos que se pueda acceder al servidor ssh del ordenador cuya IP es 192.168.9.6, teclearı́amos: iptables -A OUTPUT -s IP_ORIGEN -d 192.168.9.6 -dport 22 -j ACCEPT 9.5.3. IP spoofing. Algo por lo que hemos pasado muy rápidamente, es el uso de -i y -o. Habitualmente se suelen utilizar bastante para poder hacer uso de la topologı́a empleada, ya que cada subred, tanto externa, como DMZ, como subredes internas, puede estar conectada a un interfaz de red distinto, y por lo tanto podremos discriminar las entradas o salidas ya no sólo por IP origen y destino, sino por interfaz origen y destino. Si queremos, por ejemplo, que cualquier conexión que proceda del interfaz de red eth0 pueda salir, lo que tendrı́amos que teclear es: iptables -A OUTPUT -i eth0 -j ACCEPT mientras que si no queremos que la red conectada a la tarjeta eth1 tenga conexión hacia el exterior, tendremos que teclear: iptables -A OUTPUT -i eth1 -j DROP este tipo de ejecuciones las podemos llevar a cabo por ejemplo, cuando confiamos de los ordenadores conectados a la tarjeta eth0 pero no a los que están conectados a la eth1. También se suelen utilizar estas opciones para asegurarnos de que no estamos siendo atacados mediante IP spoofing. Esta técnica se basa en engañar al receptor haciéndole creer que la IP de procedencia es otra de la que realmente deberı́a tener. 83 84 CAPÍTULO 9. CORTAFUEGOS Supongamos por ejemplo que tenemos dos subredes en nuestra institución, una que consideraremos no fiable y otra fiable (aulas de informática y servicio de nóminas por ejemplo). En este caso, si no hacemos ningún tipo de filtrado, nada impedirı́a que un usuario de un ordenador en un aula de informática configurase el ordenador con una IP del servicio de nóminas (de un ordenador apagado por ejemplo, para no provocar alarmas). Habiendo hecho esto, y si el cortafuegos estuviera configurado para permitir la salida a la Internet a todos los ordenadores con IP del servicio de nóminas y a los de aulas de informática solamente para visitas de páginas web, el mal usuario tendria acceso como si su máquina fuera del servicio de nóminas. Para evitar estas situaciones lo que podemos hacer es rechazar todas las conexiones que clamen proceder de donde no deben. Por ejemplo, si a nuestro interfaz de red eth1 están conectados solamente los ordenadores de la subred 192.168.101.0 (aulas de informática) podrı́amos ejecutar: iptables -A OUTPUT -i eth1 -s 192.168.101.0/24 -dport 80 -j ACCEPT iptables -A OUTPUT -i eth1 -j DROP en este orden, pues la primera regla permitirı́a la salida por la tarjeta eth1 de las conexiones procedentes de los ordenadores con IPs correctas (de la subred dedicada a aulas de informática), mientras que el resto negarı́a la salida al resto de conexiones (a todas la que no cumplieran el primer requisito). Por ejemplo tener una IP del servicio de nóminas e intentar acceder a algo distinto al puerto 80. 9.5.4. Conexiones establecidas o relacionadas. Una vez que ya hemos aceptado todas las conexiones entrantes y salientes que consideremos oportunas, ¿podrı́amos tener el ordenador protegido y operativo? Probablemente la primera pregunta serı́a afirmativa, siempre y cuando nos hubiéramos tomado nuestro tiempo para asegurarnos de todas las reglas escritas, pero en cuanto a la segunda, hemos de decir que todavı́a tendrı́amos un problema. Imaginemos que queremos visitar una página web. Para ello nuestro ordenador tiene permitida la salida al exterior sin mayor problema, pero, ¿qué pasará con los datos que nos devuelve el servidor web? Estos datos, ¿cómo podemos autorizarlos para poder ver el resultado de nuestra consulta? Este tipo de conexiones no se establecen a puertos determinados, es decir, cuando hacemos una consulta web, los datos que nos devuelve el servidor web no van a un puerto en concreto, sino que vamos recibiéndolos en puertos no privilegiados (mayores de 1024) que no dependen del tipo de conexión, sino que para cada conexión a un servidor web serán distintos. Es claro que de 9.5. CADENA INPUT. esta manera no podemos abrir un puerto para permitir estas conexiones entrantes, es más, si lo pudiéramos abrir, lo tendrı́amos que abrir para cualquier ordenador, algo que no serı́a del todo práctico. Lo que podemos hacer entonces es autorizar todas las conexiones entrantes que tengan que ver con conexiones autorizadas previas que hayamos tenido. Es decir, una conexión exterior-interior que responda a una previa interior-exterior permitida, será autorizada, permitiendo entonces acceder a los datos que nos presenta el servidor web al que le hemos hecho la petición. La regla que deberı́amos escribir para autorizar este tipo de actuación serı́a: iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT donde nos encontramos con la opción -m que nos permite comprobar un estado para los paquetes que acceden a nuestra máquina, que en este caso alimentamos después de –state con las palabras clave ESTABLISHED y RELATED, es decir, se permiten (-j ACCEPT) las conexiones que se consideren establecidas o que se consideren relacionadas con otras previas. 9.5.5. Servidor FTP. Hay dos formas de realizar una conexión a un servidor FTP, una es la forma pasiva, y otras es la forma activa. Mediante una conexión activa, un cliente se conecta a un servidor FTP mediante el puerto 21 para hacer transferencia de órdenes, y al puerto 20 para hacer transferencia de datos, es decir, se establecen dos puertos por los que fluye información que deberı́amos autorizar mediante el uso de las reglas oportunas: iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT iptables -A INPUT -p tcp --dport 20 -m state --state NEW -j ACCEPT donde hemos permitido conexiones a los puertos destino 21 y 20 respectivamente, conexiones del tipo tcp y cuyo estado sea nuevo. En este tipo de conexiones no deberı́amos tener problema, ahora bien, cuando pasamos a tener conexiones pasivas (muy habituales), el puerto de datos no es el 20, sino que puede ser cualquier puerto, ayudando por tanto este tipo de conexión a la bajada de archivos. El problema está aquı́ en saber qué puerto autorizamos, ya que nunca vamos a saber a priori cuál se va a utilizar. Para solventar este problema no deberemos hacer uso de ninguna regla de iptables, sino que deberemos cargar en memoria un módulo, en concreto el módulo ip conntrack ftp mediante la ejecución: modprobe ip_conntrack_ftp 85 86 CAPÍTULO 9. CORTAFUEGOS que permitirá al cortafuegos seguir las conexiones ftp de datos y pasarlas por la segunda regla que hemos escrito anteriormente, autorizando entonces o no la conexión con arreglo a la misma. Es la primera vez que hemos hecho uso de algo ajeno a iptables, algo que no tenga que ver con iptables, si bien en ciertas ocasiones lo tendremos que hacer. Un ejemplo en este sentido lo tenemos en servidores NFS. Cuando estamos realizando conexiones de tipo NFS, los puertos implicados son los del portmaper (111), nfs (2049) y al menos el de mountd. El puerto asociado a mountd (y a otros demonios asociados a nfs) es aleatorio, es decir, cuando arrancamos el servidor nfs, este elige un puerto desde el que escuchará mountd, y por lo tanto no podemos configurar de esta manera el cortafuegos a priori. Algo que podrı́amos hacer es habilitar en el script de arranque del servidor nfs una lı́nea que comprobara el puerto con el que arranca mountd, y ası́ ejecutar iptables permitiéndole. No obstante en este caso, y en la mayorı́a de los casos de asignación aleatoria de puertos, se puede resolver a nivel de configuración del propio servicio, pudiendo configurar a mano el puerto con el que queremos que arranque el servicio en concreto, y por tanto poder ası́ establecer las reglas correspondientes de la misma forma que el resto. 9.6. Scripts de inicio. Cuando hablamos del arranque de linux, uno de los puntos en los que inmediatamente pensamos es en la ejecución de los diferentes scripts del directorio correspondiente al nivel de ejecución en el que estamos arrancando la máquina. Si por ejemplo la máquina arranca en nivel de ejecución cinco, sabemos que parará todos los servicios que ası́ lo indiquen los archivos ubicados en el directorio /etc/rc5.d que comiencen con el carácter K, mientras que arrancará todos aquellos que comiencen con el carácter S. Este forma de arranque nos permite habilitar cuantas secuencias necesitemos ejecutar en el arranque o cambio de nivel de ejecución de la máquina, ya que podemos escribirlas en un script y que este se ejecute de forma automática, ahorrándonos tener que teclearlo nosotros. En el caso del cortafuegos esta utilidad no puede pasar desapercibida. El cortafuegos obviamente se puede arrancar a mano, tecleando una por una cada una de las reglas del mismo, si bien podrı́amos recoger todas ellas en un script, llamado por ejemplo cortafuegos y ubicarlo en el directorio /etc/init.d Una vez hayamos dado permisos de ejecución a este archivo, podemos crear un enlace simbólico en el directorio que corresponda al nivel de ejecución por defecto, si es el cinco podrı́amos teclear: ln -s /etc/init.d/cortafuegos /etc/rc5.d/S10cortafuegos La estructura que debemos dar a este archivo es la de case, o al menos es la más afortunada para estos casos, y consiste en: 9.6. SCRIPTS DE INICIO. case "$1" in start) # Secuencias para arrancar el cortafuegos. ;; stop) # Secuencias para parar el cortafuegos. ;; restart) $0 stop $0 start ;; *) # Secuencias que se ejecutar\’{a}n si no ejecutamos # el script con el argumento start o stop o restart. ;; esac exit 0 Esta sintaxis significa que dependiendo de lo que se escriba como primer argumento en la ejecución del script, se irá al apartado correspondiente y se ejecutará lo que en él esté escrito hasta que termine. Cada uno de los apartados comienzan con los caracteres que coinciden con este primer argumento seguidos del sı́mbolo ) y acaban con los dos punto y coma, pudiendo escribir cuantas instrucciones queramos entre medias, de tal forma que se ejecutarán cuando sea llamado el script con este argumento. Estos scripts ubicados en /etc/init.d suelen tener cuatro casos: start, stop, restart y *. En el caso start se suele poner aquellos comandos necesarios para arrancar el servicio oportuno, el caso stop los comandos necesarios para pararlos y luego en el caso restart pondremos normalmente las lı́neas: $0 stop $0 start que nos permitirán llamar al script ($0) para ejecutar los comandos del caso stop y luego los del caso start, con el fin de rearrancar los servicios correspondientes. Normalmente se suele poner el caso * con el que nos aseguremos que se ejecute las secuencias correspondientes hasta los dos puntos y coma siempre y cuando el primer argumento que demos al script no coincida con ninguno de los casos, como por ejemplo cuando intentamos arrancar el script 87 88 CAPÍTULO 9. CORTAFUEGOS y nos confundimos, tecleando por ejemplo skart en vez de start. En este caso se suele poner una sentencia echo que nos invite a volver a teclear de nuevo el argumento, indicándonos que nos hemos equivocado previamente. En el caso de los cortafuegos creados con iptables además se suele poner otro caso más que es el paranoico, en el que configuramos las reglas más restrictivas posibles, de tal forma que si entendemos que podemos estar ante un caso de ataque, podamos invocar el script de esta forma y ası́ impedir cualquier conexión. Para finalizar la descripción del script, decir que antes de comenzar la sentencia case, podemos poner las definiciones iniciales que consideremos oportunas. En este sentido podemos definir los comandos a utilizar mediante variables cortas y significativas, ası́ como definir también mediante el uso de variables las ips y los interfaces, truco este que nos servirá además para evitar equivocaciones, pues no es lo mismo escribir intranet, que por ejemplo 192.168.10.0/24 9.6.1. Ejemplo de script. #!/bin/bash #-------------------# Rutas de programas. #-------------------iptables=/sbin/iptables modprobe=/sbin/modprobe #---------------------------# Especificaciones iniciales. #---------------------------# Ips. privilegiadas="192.168.32.204 192.168.34.78 192.168.78.98" case "$1" in start) #---------------------------------------#Finalmente nos ponemos con el firewall. #---------------------------------------# Cargamos el modulo que nos permite hacer FTP pasivo. 9.6. SCRIPTS DE INICIO. $modprobe ip_conntrack_ftp # Nos quitamos todo lo que hubiera. $iptables -F $iptables -Z # Reglas por defecto para el firewall $iptables -P INPUT DROP $iptables -P OUTPUT DROP $iptables -P FORWARD DROP # Configuracion del dispositivo loopback $iptables -A INPUT -i lo -j ACCEPT $iptables -A OUTPUT -o lo -j ACCEPT # Permitimos nuestra salida asi como las entradas #relacionadas y establecidas. $iptables -A OUTPUT -o eth0 -j ACCEPT $iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT # Permitimos el acceso por ssh a unas poquitas maquinas. for maquina in $privilegiadas do $iptables -A INPUT -p tcp -i eth0 --dport 22 -m state --state NEW -s $maquina -j ACCEPT done # Permitimos el acceso por ftp a la red 192.168.0.0/16 $iptables -A INPUT -p tcp -i eth0 --dport 21 -s 192.168.0.0/16 -j ACCEPT $iptables -A INPUT -p tcp -i eth0 --dport 20 -s 192.168.0.0/16 -j ACCEPT ;; stop) 89 90 CAPÍTULO 9. CORTAFUEGOS # Nos quitamos todo lo que hubiera. $iptables -F $iptables -Z # Reglas por defecto para el firewall $iptables -P INPUT ACCEPT $iptables -P OUTPUT ACCEPT $iptables -P FORWARD ACCEPT ;; paranoico) # Nos quitamos todo lo que hubiera. $iptables -F $iptables -Z # Reglas por defecto para el firewall $iptables -P INPUT DROP $iptables -P OUTPUT DROP $iptables -P FORWARD DROP ;; restart) $0 stop $0 start ;; *) echo "Invoque este script con las opciones {start, stop, restart o paranoico}" exit 1 ;; esac 9.6. SCRIPTS DE INICIO. exit 0 Este script es eso, un script, por lo tanto cualquier añadido que queramos incluir, que esté permitido por la shell correspondiente, podrá insertarse sin mayor problema, como por ejemplo el bucle del ejemplo, en el que permitimos el acceso a nuestro cortafuegos a través de ssh a varias máquinas, que previamente hemos cargado, sus IPs, en una variable. 91 Capı́tulo 10 Accounting. 93 94 CAPÍTULO 10. ACCOUNTING. Cuando en un equipo hay más de un usuario, y sobre todo cuando hay usuarios que no son administradores, es conveniente saber qué comandos se han ejecutado en el sistema para tener un poco de control sobre el mismo, saber si los usuarios utilizan comandos no permitidos o incluso están intentando acceder al sistema de forma no permitida compilando y/o utilizando cracks que permitan la escalada de privilegios en el sistema.La forma de controlar este tipo de a ctividades es mediante el accounting, llevado a cabo mediante acct, que lo podemos obtener de: http://ftp.gnu.org/gnu/acct/ Para poderlo instalar en nuestro sistema, nos bajamos de este URL la última versión disponible de acct y la descomprimimos en un directorio temporal. El archivo resultante lo desempaquetamos mediante tar, y accedemos al directorio creado. Ejecutamos entonces: ./configure --prefix=/usr/local/seguridad/accounting/ make make check make install siendo root para ejecutar esta última orden. Esto nos generará una estructura de directorios y archivos a partir del directorio que hemos indicado al script configure. Además de esta estructura, crearemos varios directorios: mkdir /usr/local/seguridad/accounting/logs mkdir /var/account/ mkdir /usr/local/seguridad/accounting/scripts En el primero permanecerán los logs que se vayan generando dı́a a dı́a, en el segundo directorio será el sistema el que vaya guardando la información de accounting que se vaya generando en cada momento y finalmente, en el tercer directorio, guardaremos los scripts que vamos a utilizar para el formateo y tratamiento que hagamos de la información de accounting. Antes de poner todo en funcionamiento, también deberı́amos crear el grupo adm, pues es el que utiliza acct para generar los datos. Este grupo lo crearemos con el comando groupadd Para arrancar y parar el servicio de accounting, utilizaremos el script acct generado inicialmente por Ian Murdock (utilizaremos la versión modificada de Dirk Eddelbuettel) que es distribuido con estas herramientas. El script de arranque de acct es: #! /bin/sh # 95 # # # # # Start or stop process accounting Initial version written by Ian Murdock <[email protected]> This version written by Dirk Eddelbuettel <[email protected]> set -e directorio=/usr/local/seguridad/accounting/sbin/ compare_kernel_version_and_exit_if_needed() { # thanks to Joey Hess for this shell script snippet # -- easier than my previous perl code cmp_major=2 cmp_minor=2 # thanks for Ralf Hildebrandt # <[email protected]> # for a simpler uname -r solution which also works for # hppa #kernel_major=‘uname -a | cut -d’ ’ -f 3 | cut -d. -f 1‘ #kernel_minor=‘uname -a | cut -d’ ’ -f 3 | cut -d. -f 2‘ kernel_major=‘uname -r | cut -d. -f 1‘ kernel_minor=‘uname -r | cut -d. -f 2‘ if [ $kernel_major -gt $cmp_major ] then valid=true elif [ $kernel_major -eq $cmp_major ] && [ $kernel_minor -ge $cmp_minor ] then valid=true else valid=false fi if [ "$valid" = "false" ]; then echo "Skipping process accounting: Package requires kernel 2.2.*." exit 0 fi } test -x $directorio/accton || exit 0 96 CAPÍTULO 10. ACCOUNTING. # If you want to keep acct installed, but not started # automatically, set this variable to 0. Because # /etc/cron.daily/acct calls this file daily, it is # not sufficient to stop acct once after booting if # your machine remains up. START_ACCT=1 if [ $START_ACCT -eq 1 ] then compare_kernel_version_and_exit_if_needed fi case "$1" in start) # We start acct only if the switch variable tells us to if [ $START_ACCT -eq 1 ] then # Have to turn this on to be able to test the return code set +e echo -n "Starting process accounting: " mv /var/account/pacct /var/account/pacct‘date +%d-%m-%Y-%s‘ touch /var/account/pacct chown root:adm /var/account/pacct chmod 640 /var/account/pacct $directorio/accton /var/account/pacct 2>/dev/null rv=$? if [ $rv -eq 0 ] then echo "done." elif [ $rv -eq 38 ] then echo "failed" echo "Process accounting not available on this system." elif [ $rv -eq 16 ] then echo "failed" echo "Process accounting already running on this system." else logger -f /var/log/daemon.log \ "Unexpected error code $rv received in /etc/init.d/acct" 97 fi set -e fi ;; stop) echo -n "Stopping process accounting: " # Have to turn this on to be able to test the return code set +e $directorio/accton 2>/dev/null if [ $? -eq 0 ] then echo "done." else echo "failed." echo "Process accounting not available on this system." fi set -e ;; restart|force-reload) echo -n "Restaring process accounting: " # Have to turn this on to be able to test the return code set +e $directorio/accton 2>/dev/null if [ $? -eq 0 ] then echo "done." else echo "failed." echo "Process accounting not available on this system." fi set -e # We start acct only if the switch variable tells us to if [ $START_ACCT -eq 1 ] then # Have to turn this on to be able to test the return code set +e echo -n "Starting process accounting: " $directorio/accton /var/account/pacct 2>/dev/null rv=$? if [ $rv -eq 0 ] then echo "done." elif [ $rv -eq 38 ] 98 CAPÍTULO 10. ACCOUNTING. then echo "failed" echo "Process accounting not available on this system." elif [ $rv -eq 16 ] then echo " failed" echo "Process accounting already running on this system." else logger -f /var/log/daemon.log \ "Unexpected error code $rv received in /etc/init.d/acct" fi set -e fi ;; *) echo "Usage: /etc/init.d/acct {start|stop|restart |force-reload}" exit 1 esac exit 0 Este script lo copiaremos en /etc/init.d y lo llamaremos acct, dándole por supuesto permisos de ejecución. Requiere atención la variable directorio, que deberá ser cargada con el valor correspondiente a lo que hemos indicado en –prefix a la hora de ejecutar el script configure en la instalación de acct. Este script lo que hará es empezar a guardar en /var/account los datos relativos al accounting, datos que podremos luego procesar para estar informados de los comandos que han utilizado los usuarios del sistema. Para obtener un listado con los comandos ejecutados por los usuarios, programaremos en el cron la siguiente tarea: 0 0 * * * /usr/local/seguridad/accounting/scripts/control > /dev/null 2>&1 siendo el script control al que hace referencia: #!/bin/bash directorio=/usr/local/seguridad/accounting/logs/ log=‘date +%d-%m-%Y-%s‘ maquina=‘hostname‘ direccion=root 99 filtrado="" /etc/init.d/acct stop /etc/init.d/acct start ultimo=‘ls -ltrsia /var/account/pacct-* |awk ’{print $11}’ |tail -1‘ echo > ${directorio}/${log} echo "Control de procesos ejecutados en $maquina." >> ${directorio}/${log} echo >> ${directorio}/${log} echo "El fichero de accounting utilizado es:" >> ${directorio}/${log} echo $ultimo >> ${directorio}/${log} echo >> ${directorio}/${log} echo >> ${directorio}/${log} /usr/local/seguridad/accounting/sbin/sa -a -u -f $ultimo > ${directorio}/${log}.sa 2>&1 cp -f ${directorio}/${log}.sa ${directorio}/tempoa for comando in $filtrado do grep -v " $comando " ${directorio}/tempoa > ${directorio}/ tempob cp -f ${directorio}/tempob ${directorio}/tempoa done cp -f ${directorio}/tempoa ${directorio}/${log}.sa-limpio echo "La salida filtrada es:" >> ${directorio}/${log} echo >> ${directorio}/${log} cat ${directorio}/${log}.sa-limpio |awk ’{print $1,$7,$8}’ |sort -u >> ${directorio}/${log} echo >> ${directorio}/${log} /bin/mail -s "Control de procesos de $maquina" $direccion < ${directorio}/${log} rm -f ${directorio}/tempob ${directorio}/tempoa /usr/bin/bzip2 ${directorio}/${log}* 100 CAPÍTULO 10. ACCOUNTING. que lo que hará es, una vez al dı́a (según hayamos programado en el cron), enviarnos un mensaje de correo electrónico con la información de los procesos ejecutados por los distintos usuarios del sistema, convenientemente formateada e incluso filtrada ya que no mostrará aquellos comandos existentes en la variable filtrado. El filtrar comandos es debido a que muchas veces la lista de los comandos ejecutados en el sistema es tan grande que supera el tiempo que disponemos para leer el mensaje (acordémonos que este script se ejecutarı́a una vez al dı́a en cada una de las máquinas que administremos). Si localizamos los comandos fiables, es decir, carentes de peligro potencial, podemos incluirlos en esta variable y por lo tanto no ser procesados a la hora de enviarnos el mensaje de correo electrónico. Por supuesto el script aquı́ utilizado puede cambiarse con el fin de obtener un mejor resultado cara a la administración, si bien es un buen comienzo para tener el sistema de accounting funcionando desde el primer momento. Para que acct empiece a funcionar deberı́amos teclear: /etc/init.d/acct start o esperar a la ejecución del script control, que en su ejecución para y arranca este script. En nuestra mano queda además realizar un enlace simbólico para que arranque de forma conveniente al pasar al nivel de ejecución por defecto (o utilizar la herramienta chkconfig). Capı́tulo 11 Previsión de ataques. 101 102 CAPÍTULO 11. PREVISIÓN DE ATAQUES. Uno de los problemas de seguridad más graves con los que nos vamos a enfrentar en un sistema operativo linux son los troyanos. Los troyanos son instalados en nuestro ordenador por fallos de seguridad, bien por bugs de programación o bien por una configuración errónea en nuestro sistema. No tener actualizado el sistema operativo o no tener bien acotado el acceso que tienen nuestros usuarios (fı́sico o remoto) al equipo puede ocasionar la instalación de un conjunto de herramientas que permitan la utilización indiscriminada de nuestra máquina sin nuestro consentimiento ni conocimiento. El control exquisito de las actualizaciones del sistema, y el acceso a nuestro ordenador por parte de los usuarios debe ser una de nuestras prioridades más importantes. En el segundo punto, no sólo tendremos que especificar correctamente los permisos en los ficheros susceptibles de autorizar a usuarios hacerse con el control del sistema, sino también impedir el acceso fı́sico al equipo, ya que en el momento que alguien tenga delante nuestro equipo será sólo cuestión de tiempo que se haga con su control. Afortunadamente en el mundo Linux apenas tenemos la amenaza de los virus. Sobre todo esto es debido a la idea que subyace en el funcionamiento de Linux, y es que casi nunca utilizamos la cuenta de root para realizar operaciones cotidianas como la lectura de nuestro correo electrónico personal. Estas tareas llevan consigo la posibilidad de la instalación de software no seguro (virus), que pueden comprometer el equipo al ser instalados con altos privilegios. En otros sistemas operativos, donde la mayorı́a de los usuarios cuentan con cuentas más privilegiadas de lo que deberı́an ser, la instalación de virus en este sentido es un hecho. En el caso de Linux ya no es tan habitual pues deberı́amos ejecutar estos programas desde la cuenta del superusuario, y habitualmente los administradores no suelen caer en este error. De todas formas algo muy habitual en los administradores es instalar software de fuentes no fiables. Es decir, a la hora de buscar software que deseamos instalar en nuestro ordenador una simple búsqueda en www.google.com es admitida por la mayorı́a de los administradores. Las direcciones que nos muestra Google, ¿son las correctas? ¿Pertenecen realmente a los desarrolladores del software? Hay que tener en cuenta que muchas veces no es ası́, y junto con el software que queremos instalar en nuestro equipo nos bajamos software no deseado con comportamiento de virus o troyano. Una forma de controlar si tenemos algún troyano en nuestro equipo es instalar un anti troyanos. Suele haber en la red diferentes posibilidades de anti troyanos, si bien dos de las más utilizadas son chkrootkit y rkhunter. La idea de ambas utilidades, de ambas aplicaciones es comparar los archivos que habitualmente sufren cambios tras la instalación de un troyano, con bases de datos. Si se comprueba que uno de estos archivos contiene información habitual en un troyano, entonces el programa nos avisará y en ese momento deberemos proceder a la limpieza del equipo. 11.1. CHKROOTKIT 11.1. chkrootkit Para bajarnos el código fuente de esta herramienta nos conectaremos a: http://www.chkrootkit.org/download/ Descomprimiendo y desempaquetando el fichero bajado con gunzip y tar. gunzip chkrootkit.tar.gz tar -xvf chkrootkit.tar y compilamos, tecleando directamente: make sense una vez que ha compilado sin problemas, podremos ejecutarlo sin más mediante el comando chkrootkit que se habrá generado en el directorio donde hemos compilado. La ejecución de este comando la deberı́amos programar de tal forma que cada dı́a chequeara nuestro sistema en busca de troyanos, tomando por supuesto las medidas oportunas en el caso de obtener algún positivo. 11.2. Rootkit Hunter. Rootkit Hunter es una herramienta que analiza el sistema en busca de rootkits, puertas traseras y exploits locales ejecutando diferentes pruebas, a saber: * Comparación de marcas MD5. * Comprobación de ficheros caracterı́sticos de rootkits. * Comprobación de permisos erróneos de ciertos binarios. * Comprobación de cadenas sospechosas en módulos LKM y KLD. * Búsqueda de ficheros ocultos. * Comprobación, opcional, de ficheros de texto y binarios. Para instalarlo en nuestro sistema, nos bajaremos una copia del código fuente, en un directorio temporal y la descomprimiremos: gunzip rkhunter.tar.gz a continuació la desempaquetaremos: tar -xvf rkhunter.tar.gz 103 104 CAPÍTULO 11. PREVISIÓN DE ATAQUES. Finalmente accederemos al directorio creado y ejecutaremos el shell script installer.sh que nos instalará ciertos ficheros en el directorio /usr/local/rkhunter A continuación pasaremos a ejecutar rkhunter, para ello teclearemos: /usr/local/bin/rkhunter --versioncheck que comprobará si la versión de nuestro sistema es la última disponible, debiendo actualizarla si no es ası́. A continuación actualizaremos la base de datos, para ello ejecutaremos: /usr/local/bin/rkhunter --update y finalmente ejecutaremos rkhunter en busca de rootkits, puertas traseras y exploits locales en nuestro sistema ejecutando: /usr/local/bin/rkhunter --checkall Este programa también deberı́amos ejecutarlo regularmente, para ello podrı́amos realizar un shell script que fuera ejecutado diariamente, por ejemplo, y mandará al administrador del equipo la información de su ejecución. En este sentido en el script creado a tal efecto deberı́amos reunir las dos primeras lı́neas, y en vez de la ejecución con la opción - -checkall de la tercera lı́nea, podrı́amos utilizar: /usr/local/bin/rkhunter --cronjob --report-warnings-only que son las opciones creadas para la ejecución correcta mediante scripts, de tal forma que nos informe de los positivos en un formato que se pueda mandar fácilmente por correo electrónico o guardar en un log, y no en formato de color, y con excesiva información, como se obtiene la salida de su ejecución con la opción - -checkall Capı́tulo 12 Backup 105 106 CAPÍTULO 12. BACKUP Ya es no sólo conocido, sino totalmente aceptado, la necesidad de realizar backups periódicos de nuestro sistema. Back-up significa respaldar, es decir, tener una copia de lo que consideremos importante. Esta idea la entendemos perfectamente, pero muchas veces no la llevamos a todo su significado. El tener una copia de respaldo es vital, eso lo sabemos, pero ¿de qué hacemos backup? ¿Cómo hacemos el backup? ¿Cuándo hacemos el backup? ¿Cómo guardamos el backup? Todas estas preguntas muchas veces se quedan sin una buena contestación debido a que nada más ponernos a trabajar en este punto intentamos poner en marcha una solución de backup sin más, sin parar a pensar absolutamente nada más. El backup no debemos hacerlo de todo el sistema en la mayorı́a de las ocasiones. ¿Realmente queremos un backup de los archivos temporales de nuestros sistemas? ¿Nuestros usuarios nos van a pedir archivos intermedios de cálculos que hayan realizado? Sin embargo es fundamental realizar una copia (o varias) de respaldo de los ficheros de los usuarios, pero también de los ficheros de configuración de nuestro sistema con el fin de ahorrar mucho trabajo si nuestra máquina colapsa. Algo importante a tener en cuenta es la frecuencia, ¿cada cuánto hacemos backup? Los datos de los usuarios deberı́an tener un respaldo al menos una vez a la semana. Hay que tener en cuenta que estos datos cambian constantemente, por lo tanto cuando más alejemos las copias de seguridad, más posibilidades tendremos de que se pierdan ficheros importantes. Sin embargo los programas que tenemos instalados en nuestro equipo, ¿realmente necesitan ser respaldados semanalmente? En este sentido es posible que sólo sea necesario realizar una copia de seguridad cuando se haga alguna modificación sobre los mismos, que puede ser a diario o bien puede ser cada varias semanas. Es decir, justo en el momento de realizar una modificación (una instalación de un nuevo programa en nuestro sistema), realizaremos la copia de seguridad, y el resto del tiempo no será necesario. ¿Cómo hacemos el backup? Aquı́ realmente nos referimos a dos cuestiones. ¿En qué soporte? ¿Con qué software? Soportes hay muchos en el mercado, desde los disquetes (claramente en desuso hoy en dı́a), hasta las famosas cintas pasando por los discos duros. Por supuesto las cintas de backup son muy utilizadas en este sentido, y no es raro encontrar un CPD en el que haya un robot de backup consistente en un brazo robotizado que se encarga de ir cambiando cintas de backup de una unidad de cinta que está constantemente haciendo backup del sistema. Las cintas tienen la ventaja de poder alojar gran cantidad de información en un espacio realmente reducido, pero tienen la gran desventaja del acceso lineal, que las hace terriblemente lentas a la hora de recuperar datos (si bien hoy en dı́a la velocidad de acceso ha aumentado considerablemente). Un soporte muy utilizado es el DVD, pues debemos tener en cuenta que pueden alcanzar hasta 9GB aproximadamente y son relativamente baratos 107 y con poco volumen. El problema en este sentido es que deberı́amos irnos a utilizar DVDs regrabables pues si no estarı́amos utilizando soportes que deberı́amos tirar una vez se realizar un backup posterior, pues son soportes (los no regrabables) de un sólo uso. Los discos duros, si bien muchas veces no son contemplados como soportes de backup, son elementos que cumplen varias caracterı́sticas interesantes. Son relativamente baratos (teniendo en cuenta la relación capacidad/precio), fáciles de cambiar (alojados en carcasas extraı́bles o con soporte USB o Firewire) y muy rápidos. En este sentido se les puede ver en la mayorı́a de las ocasiones como los dispositivos más interesantes a la hora de realizar backup. Los discos duros, como hemos adelantado, los podemos utilizar en carcasas extraı́bles. En este sentido el problema que vamos a tener es que si queremos realizar un cambio, tendremos que apagar el sistema que los aloja (salvo que sean disco de cambio en caliente). También los podemos utilizar en carcasas USB o Firewire, si bien las velocidades de transferencia serán menores en este caso. El software que podemos utilizar para realizar las copias de seguridad es muy diverso. Si realizamos una comprobación en alguna página dedicada a ofrecer software, encontraremos gran cantidad de herramientas disponibles. ¿Hasta qué punto es necesario una herramienta de este tipo? Esta pregunta nos la tendremos que contestar, por supuesto. Hay muchas herramientas comerciales cuyo coste es prohibitivo para muchos presupuestos. Otras herramientas son gratuitas y por lo tanto fácilmente accesibles, entonces, ¿debemos utilizarlas? Ante esta pregunta hay múltiples respuestas, y todo depende del administrador que se la formule. Si estamos acostumbrados a utilizar alguna de estas herramientas la respuesta será inmediata, y será la instalación de la misma en nuestro sistema, pero sin embargo si estamos acostumbrados a los comandos habituales que Linux tiene en el sistema que nos pueden servir para realizar backups, muchas veces nos decantaremos por realizar el backup a nuestra manera. Sea como fuere el soporte que hayamos utilizado para realizar la copia de seguridad no puede abandonarse. Las cintas, los DVDs, los discos duros, etc., cualquier soporte utilizado deberı́a guardarse en un lugar seguro (siendo aconsejable un armario ignı́fugo para evitar perder la información en un incendio), y fundamentalmente alejados de la fuente. En muchas ocasiones las copias de seguridad se dejan al lado del sistema del que hemos hecho la copia. Esta práctica es totalmente intolerable, pues las copias de respaldo se realizan para evitar la pérdida de información ante imprevistos, y por supuesto si un equipo tiene un imprevisto, la probabilidad de que el soporte cercano también lo tenga es alto. ¿Qué pasa si hay una gotera encima del equipo? ¿Qué ocurre si se declara un fuego? En estos casos habremos perdido el equipo y la copia de respaldo. 108 CAPÍTULO 12. BACKUP Si nos decidimos por soluciones más voluminosas, como por ejemplo un equipo con varios discos duros que realice un backup de algún sistema pesado, entonces la posibilidad de mantener este equipo dentro de un armario ignı́fugo es irreal. En estos casos lo que deberemos hacer es alejar los equipos de respaldo de los equipos de producción, de tal forma que un problema en uno no acarreará la pérdida de datos, pues los antendremos en otro equipo. Por supuesto si realizamos más de una copia de seguridad, guardadas en ubicaciones distintas, entonces podremos decir que realmente el backup es altamente fiable. 12.1. Herramientas propias. Como habı́amos indicado, muchos administradores tienden a no utilizar software externo para realizar copias de seguridad, sino que utilizan herramientas del sistema operativo que permite realizar respaldos sin mayor problema. 12.1.1. dump dump es la herramienta por excelencia de backup en Linux. Si bien a priori podrı́amos pensar que es un comando complicado, su utilización es sencilla una vez entendido su uso. dump realiza una copia de seguridad de los archivos que necesiten ser respaldados. Para saber qué ficheros deben ser respaldados, dump mantiene una base de datos donde tiene información de cuándo fue respaldado un fichero en concreto. Para saber entonces si un fichero tiene que ser respaldado o no, lo que hacemos es utilizar los diferentes niveles de backup que tiene dump. En este sentido comentar que decimos que dump realiza backups de nivel 0, hasta nivel 9. Un backup de nivel 0 es un backup completo, es decir, no nos importa cuándo fue respaldado o modificado un fichero, pues todos serán respaldados en este momento. A partir de este momento, un nivel indica qué ficheros serán respaldados o no. El nivel nos indicará que realicemos un backup de los ficheros que hayan sido modificados después de un backup de nivel inferior. Veamos esto con un ejemplo: El lunes realizamos un backup de grado 0. El lunes por tanto tenemos un backup completo del sistema. El martes realizamos un backup de grado 2. En este sentido todos los ficheros que hayan sido modificados desde el lunes pasarán a formar parte de este backup del martes, pues el grado 0 es de nivel inferior a grado 2. Si el miércoles realizamos un backup de grado 1, entonces sólo respaldaremos lo ficheros que hayan sido modificados respecto a la copia que hicimos el lunes. Todo lo que haya sido modificado después del backup de grado 2 y 12.1. HERRAMIENTAS PROPIAS. que estuviera respaldado con este backup no se guardará, pues el grado 1 es inferior al grado 2. De esta forma podremos configurarnos un sistema de backup muy concreto que tenga en cuenta todas las necesidades de nuestra institución. El backup realizado con dump podremos guardarlos en una cinta (el defecto que utiliza dump si no especificamos ningún otro dispositivo), o en cualquier dispositivo que permita almacenar la información de dump (disquetes, discos duros, etc.) La sintaxis de dump es sencilla, para realizar un backup total, un backup de grado 0, teclearemos: dump 0 -f /tmp/backup.dump /directorio-a-respaldar donde -f indica el dispositivo en el que realizaremos el backup. En este caso hemos elegido el defecto que utiliza dump, que es la unidad de cinta. A la hora de recuperar los archivos del backup, utilizaremos el comando restore. Este comando lo podremos ejecutar de forma interactiva: restore -if /tmp/backup.dump con lo que obtendremos un prompt en el que podremos ir accediendo (cd) y listando (ls) los distintos directorios que conforman el backup. Para recuperar uno de los archivos o directorios que tenemos en el backup tendremos que ejecutar la orden add nombre-directorio y al final, cuando hayamos elegido todos los ficheros / directorios que deseemos, simplemente ejecutaremos la orden extract y para salir quit. Debemos tener muy en cuenta que lo que recuperemos será almacenado en el directorio desde el que lanzamos la orden restore, por lo tanto debemos ser muy cuidadosos en este punto, pues podemos sobreescribir con lo recuperado los archivos que tuviéramos en este directorio. Es más que conveniente, antes de ejecutar la orden restore, crear un directorio temporal donde nos cambiaremos antes de ejecutar el comando restore. 12.1.2. tar El comando tar es muy utilizado a la hora de realizar copias de seguridad, pues es fácil de transportar (el fichero obtenido) y de utilizar en otros sistemas (los ficheros tar se pueden leer en multitud de sistemas operativos). Este comando además tiene la ventaja de guardar la estructura original, pero además guardar tanto los propietarios de los ficheros como sus marcas de tiempo. La forma de trabajar con este comando es equivalente a cualquier uso que podamos haber hecho de este comando, simplemente ejecutaremos: tar -cvf fichero-respaldo.tar /directorio-a-respaldar Al ser una herramienta muy conocida por los administradores de sistemas, es muy utilizada para estas tareas administrativas. 109 110 CAPÍTULO 12. BACKUP 12.1.3. cp/scp Si bien muchas veces no consideramos las herramientas más comunes o habituales para realizar tareas administrativas complejas, para realizar una copia de respaldo los comandos cp o scp dan buenos resultados. El comando cp nos permitirá realizar una copia (utilizando las opciones -r y -p) de estructuras completas que conserve los propietarios de los ficheros. Esta copia la podremos hacer a cualquier dispositivo que tengamos accesible en nuestro sistema, y la utilización de cp es ampliamente conocida por todos los administradores, por lo tanto su implementación en un sistema de backup es trivial. El comando scp es equivalente a cp, pero con la ventaja de que puede utilizarse por red. La velocidad de transferencia de datos mediante scp es muy superior a la de otras herramientas disponibles, y es que por ejemplo realizar copias de seguridad por red, utilizando dump o tar, muchas veces vienen acompañadas del uso de NFS que tiene tasas de transferencia muy lentas y que hacen muy lentas las copias de seguridad. El comando scp nos pedirá la contraseña del equipo remoto con el fin de poder realizar el backup de los archivos desde o hacia este equipo. Esta petición siempre la podremos evitar si configuramos ssh con este fin. Al poder realizar este último paso, muchos administradores prefieren esta herramienta pues es fácilmente aplicable, configurable y genera estructuras muy accesibles. Hay que tener en cuenta que el acceso a información respaldada mediante dump debe ser accedida mediante restore, y la información contenida en un fichero tar debe ser previamente desempaquetada para poder acceder a ella, mientras que las estructuras obtenidas con scp son tal cual las tenı́amos en origen, por lo tanto el acceso a estos respaldos es inmediato. 12.1.4. rsync Este comando es más que interesante a la hora de realizar copia de respaldo, pues realiza una copia completa de un directorio origen a un destino especificado como cp o scp, pero añadiendo ciertas ventajas: rsync nos va a permitir, si lo ejecutamos como root, que los ficheros de respaldo tengan las mismas propiedades (propiedad y marcas de tiempo) que los ficheros originales. Si la copia se interrumpe, podremos volver a lanzar la orden y solo se copiará lo que previamente no se copió. Permite ser ejecutado en sesiones posteriores con el fin de que solo se copien los ficheros que hayan sido creados / modificados con posterioridad, sin necesidad de realizar una copia total de nuevo como en el caso de cp / scp. 12.1. HERRAMIENTAS PROPIAS. Se puede encapsular dentro de una sesión ssh, para poder realizar una copia desde o hacia un equipo remoto. Una ejecución tı́pica de este comando puede ser: rsync -avz -e ssh /directorio-a-respaldar usuario-remoto@maquina-de-backup:/directorio-de-backup Donde la opción a realmente es una combinación de opciones (rlptgoD) que nos permiten realizar backups recursivamente (r), copiar los enlaces simbólicos (l), preservar los permisos (p), preservar la modificación de tiempos (t), preservar el grupo (g), preservar el propietario (o) y preservar los dispositivos y ficheros especiales (D). La opción v se utiliza para trabajar con un mayor control sobre el programa, ya que se nos mostrarán mensajes sobre la ejecución que en condiciones normales no se consideran necesarios (modo verbose). La opción z sirve para comprimir los ficheros en la transferencia. Aumenta la carga en la cpu de origen y de destino, pero minimiza el impacto sobre la red. Como habı́amos indicado rsync permite encapsular mediante ssh, esto lo podemos realizar mediante la opción e seguida de la palabra ssh. Finalmente tenemos una sintaxis parecida a la de scp, donde indicamos un origen y un destino. El origen y el destino pueden ser directorios locales, de tal forma que únicamente tendrı́amos que especificar su nombre, pero también pueden ser directorios en máquinas remotas, de tal forma que tendrı́amos que indicar la forma de llegar a ellos gracias al usuario remoto que nos permitirá el acceso ası́ como la IP o nombre de la máquina remota. 111 Capı́tulo 13 Control de logs. 113 114 CAPÍTULO 13. CONTROL DE LOGS. El sistema de logs de un ordenador es fundamental, y curiosamente es lo menos utilizado. Cualquier anomalı́a que presente el sistema operativo, o la mayorı́a de los programas instalados en nuestro sistema, dejará un rastro, un comentario sobre lo ocurrido, en un fichero de registro, que nos permitirá poder solucionar el problema y ası́ evitar que vuelva a ocurrir. Logs hay de muchos tipos, desde errores mı́nimos en el uso de aplicaciones, hasta intentos fallidos de entrada en el sistema. Nosotros nos centraremos en los logs de seguridad, si bien mucho de lo que se hable a continuación también se puede aplicar a cualquier tipo de registro. Fundamentalmente el demonio que gestiona los logs del sistema es rsyslog, que se debe arrancar al inicio de la máquina y siempre debe estar operativo, es decir, debemos asegurarnos de que en todos los directorios /etc/rc?.d (salvo en los de reinicio y apagado por supuesto), exista un enlace simbólico que comience por S y que apunte al demonio rsyslog (/etc/init.d/rsyslog), pues si no tenemos bien configurado este punto, es posible que cuando cambiemos de nivel de ejecución se pare el demonio rsyslog y por lo tanto perderemos todos los datos que posiblemente nos alerten de intrusiones. Por supuesto lo primero que intenta hacer un hacker al acceder al sistema es hacerse con el sistema de registro. Habitualmente se eliminan los rastros de la entrada en el sistema, y se prepara el demonio para que no registre nada de la actividad del hacker, para que este demonio siga haciendo su trabajo y no alerte su ausencia de registros al administrador, pero que lo que reciba este sea erróneo. Es fundamental por lo tanto que estos registros se transfieran a otro sitio diferente del ordenador cuanto antes, pues el hacker en este tipo de operaciones estará rápidamente atrapado, ya que le será muy complicado evitar que los registros lleguen a manos del administrador si estos se han transferido rápidamente a una cuenta de correo electrónico en un servidor externo, o bien se han transferido los logs tal cual a otro ordenador. Este tipo de actuaciones se pueden realizar directamente desde la configuración del propio rsyslog, con herramientas que procesen los registros de forma rutinaria o bien con trucos de administración como por ejemplo copias programadas o sincronización con otros ordenadores. 13.1. rsyslog. La configuración de este demonio la tenemos en el fichero /etc/rsyslog.conf que está compuesto de lı́neas que definen diferentes polı́ticas de registro. Cada una de estas lı́neas está compuesta de dos columnas. En la primera se define la actividad y el grado de seriedad de los registros y en la segunda dónde quedarán grabados. Por ejemplo podemos tener la lı́nea: cron.* /var/log/cron 13.1. RSYSLOG. con la cual queremos decir que cualquier mensaje que provenga del cron, quedará registrado en el fichero /var/log/cron. Hemos especificado cualquier mensaje porque tenemos el sı́mbolo * después del punto que separa el proceso que genera informes de la gravedad de los mismos. Si queremos registrar solo ciertos mensajes del cron, lo que deberemos hacer es cambiar el asterisco por el ı́ndice de gravedad que deseemos, siendo estos, ordenados de menor a mayor gravedad: * debug. Mensaje de depuración. * info. Mensaje informativo. * notice. Condición normal, pero significativa. * warning. Hay condiciones de advertencia. * warn. El mismo caso que warning. En desuso. * err. Hay condiciones de error. * error. El mismo caso que err. En desuso. * crit. Las condiciones son crı́ticas. * alert. Se debe tomar una acción correctora inmediatamente. * emerg. El sistema está inutilizable. * panic. El mismo caso que emerg. En desuso. Es decir, si queremos que cron registre solamente las entradas informativas en el fichero /var/log/cron.info, tendrı́amos que escribir: cron.info /var/log/cron.info Si precedemos al nombre del fichero donde queremos guardar el registro, el sı́mbolo menos (-), no sincronizaremos el disco después de la escritura, para mejorar las prestaciones de la máquina (sobre todo cuando realizamos muchos registros de este tipo), pero hay que tener en cuenta que una caı́da de la máquina con esta configuración harı́a perder los últimos registros (no sincronizados). Las facilidades sobre las que podemos guardar registros son: * auth. Mensajes de seguridad o autorización. Es conveniente utilizar no obstante authpriv. * authpriv. Mensajes de seguridad o autorización. * cron. Mensajes relacionados con el cron. 115 116 CAPÍTULO 13. CONTROL DE LOGS. * daemon. Mensajes realacionados con otros demonios del sistema. * kern. Mensajes del núcleo. * lpr. Mensajes del subsistema de impresión. * mail. Mensajes del subsistema de correo electrónico. * mark. Para uso interno exclusivamente, no debe usarse en aplicaciones. * news. Mensajes del subsistema de news. * security. El mismo caso que auth. En desuso. * user. Mensajes genéricos del nivel de usuario. * uucp. Mensajes del sistema uucp. * local0. Reservado para uso local. * local7. Reservado para uso local. Es decir, si queremos que todos los mensajes de naturaleza crı́tica, relacionados con el kernel, se queden reflejados en el fichero /var/log/kernel.critico, tendrı́amos que configurar este fichero con la siguiente lı́nea: kern.crit /var/log/kernel.critico En una misma lı́nea podemos incluir diferentes entradas, es decir, podemos volcar a un mismo fichero diferentes fuentes de mensajes, para ello tendremos que separar cada instancia mediante una coma si queremos utilizar el mismo nivel de generación de logs, o mediante un punto y coma si queremos que sea diferente, es decir: kern,mail.crit /var/log/mensajes.criticos registrarı́a todas las entradas crı́ticas de mail y kern en /var/log/mensajes.criticos, mientras que: kern.debug;mail.crit /var/log/mensajes.criticos registrarı́a todas las entradas crı́ticas de mail y las entradas debug de kern en el mismo fichero. Además hay que tener en cuenta que podemos hacer uso de cualquier fichero en nuestro sistema para registrar entradas de log. Como en linux podemos decir que cualquier dispositivo se comporta como un fichero, lo que podemos hacer es pasar mensajes por ejemplo a la consola, para ello lo único que tendremos que hacer es escribir /dev/console en vez del archivo que tuviéramos en mente, haciéndose este tipo de configuraciones para mensajes realmente preocupantes, como todos aquellos mensajes de emergencia que produce el kernel: kern.emerg /dev/console 13.2. LOGWATCH. 13.2. Logwatch. Los logs deberı́an leerse a diario, ya que es la única manera de saber el estado de nuestra máquina. Ya que puede llegar a ser complicado su lectura, ya que estamos hablando de diferentes archivos a los que tendremos que acceder diariamente, discriminando las entradas leı́das con anterioridad de las no leı́das, lo que suele hacerse es instalar (o programar) una herramienta que genere informes de forma rutinaria que sean mandados por correo electrónico, de tal forma que podamos, diariamente por ejemplo, tener una idea correcta del funcionamiento de nuestra máquina. Una herramienta muy utilizada para este fin es Logwatch, herramienta desarrollada con el fin de generar informes sencillos de leer por el administrador. Una vez tenemos instalada esta utilidad, deberı́amos configurarla editando el fichero logwatch.conf debiendo modificar al menos las siguientes tres entradas, si bien, como en todos los ficheros de configuración, deberı́amos examinar cada uno de los defectos que nos aparece para garantizarnos que se acomodan a nuestra configuración. * MailTo = root * Range = yesterday * Detail = High La primera nos sirve para configurar la cuenta de correo electrónico a la que queremos que mande el informe, en el ejemplo se dirigirá al usuario root. En la segunda entrada recogemos el rango del que queremos hacer el informe, si programamos la tarea por ejemplo en el cron, la podemos programar por ejemplo a las doce y un minuto de la noche, y ası́, con este rango, justo en el primer minuto del nuevo dı́a nos mandarı́a un informe con la actividad del dı́a que acaba de terminar. En cuanto a la última lı́nea, comentar que se refiere al detalle con el que queremos que se realice el informe, siendo conveniente que sea un detalle alto para que podamos tener toda la información de nuestro sistema y no sólamente parcial, si bien los informes serán mucho menos rápidos de analizar. 117 Capı́tulo 14 Sistema de cuotas. 119 120 CAPÍTULO 14. SISTEMA DE CUOTAS. Un sistema de archivos que contemple cuotas es imprescindible en muchos sistemas Linux. Hay que tener en cuenta que en un principio no hay discriminación entre usuarios, y que cada uno de ellos puede alcanzar la capacidad máxima del sistema de archivos donde tiene su home. Salvo que tuviéramos un sistema de archivos independiente para cada uno de los usuarios (algo impracticable y carente de sentido), si no existieran cuotas asignadas a los directorios personales de los usuarios, cualquiera de ellos podrı́a ocupar todo el espacio que deseara, con el consiguiente contratiempo para el resto de los usuarios. Hay que tener en cuenta que el sistema de cuotas depende del kernel, por lo tanto lo primero que hay que hacer es recompilar el kernel para que admita la nueva versión de cuotas, para ello lo que necesitamos es que esté activa la variable: CONFIG_QFMT_V2=y que está en el menú File Systems, bajo el apartado VFS v0 quota format support. Es muy probable que esta opción esté ya elegida en el kernel actual, por lo tanto serı́a conveniente, antes de recompilarlo, comprobar en el fichero de configuración que se usó para este kernel si esta opción estaba habilitada o no. Una vez que arrancamos con este kernel nuevo, lo que hacemos es modificar el fichero /etc/fstab incluyendo las opciones usrquota y grpquota en las particiones donde queramos activar las cuotas a usuarios y grupos respectivamente: /dev/sda3 /home ext4 defaults,usrquota,grpquota 1 2 A partir de este momento, cada vez que montemos la partición sda3, se activirán las cuotas de usuario y de grupo de tal forma que podremos hacer uso de ellas e impedir por tanto que cualquier usuario almacene más datos de los que creamos convenientes. Acabamos de comentar que debemos montar esta partición. Si ya estuviera montada, la podremos remontar sin más que teclear: mount -o remount /home y chequeamos este sistema de archivos para que se generen los ficheros de quotas con la información pertinente, esto lo hacemos tecleando: /sbin/quotacheck -avugc que buscará en todos los sistemas de archivos donde estén definidas la opción de cuotas, y creará los ficheros de cuotas. Debemos tener cuidado pues la opción c es crear, aunque existan previamente, los ficheros de cuotas. En futuras ejecuciones de quotacheck deberı́amos preguntarnos si realmente necesitamos 121 esta opción o podemos seguir utilizando los ficheros que ya tenemos. Deberemos prescindir de esta opción por tanto en la mayorı́a de los casos, y sólo utilizarla la primera vez que lo ejecutemos y si hemos tenido algún problema con el sistema de cuotas. Inmediatamente activaremos las quotas, para ello tecleamos: quotaon -a que activa las cuotas en todos los sistemas de archivos que tengan la opción de cuotas. A partir de este momento ya podemos obtener las quotas de los sistemas de archivos tecleando: repquota /sistema-de-archivos para ver las quotas de usuarios y: repquota -g /sistema-de-archivos para ver las quotas de grupos. Podemos modificar las cuotas, tanto de usuarios como de grupos, sin más que teclear edquota usuario o equota -g grupo respectivamente. Si queremos que un usuario recién creado tenga la misma cuota que otro, lo que podemos hacer es teclear: edquota -p usuario-original usuario-nuevo donde usuario-original es un usuario que ya existı́a y usuario-nuevo el usuario recién creado. Si queremos que todos los usuarios tengan las mismas cuotas que tiene el usuario pablo, podremos teclear: cat /etc/passwd|cut -d : -f 1|grep -v pablo|while read user do edquota -p pablo $user done 122 CAPÍTULO 14. SISTEMA DE CUOTAS. Si nos fijamos correctamente, para activar el sistema de cuotas hemos ejecutado un par de comandos (quotacheck y quotaon). Estos comandos por tanto deben ser ejecutados cada vez que la máquina se inicie, por lo tanto la forma más cómoda de llevarlo a cabo es crear un script que ejecute estos comandos ordenadamente, y especificar que se ejecute siempre que se arranque la máquina. Un script que podrı́amos utilizar podrı́a ser: #!/bin/bash . /etc/init.d/functions case "$1" in start) if [ -x /sbin/quotacheck ] then echo "Comprobando las cuotas. Puede llevar su tiempo." /sbin/quotacheck -avug RETVAL=$? fi if [ -x /sbin/quotaon ] then echo "Arrancando las cuotas." /sbin/quotaon -avug RETVAL=$? fi ;; stop) if [ -x /sbin/quotaoff ] then echo "Parando las cuotas." /sbin/quotaoff RETVAL=$? fi ;; *) echo $"Usage: $0 {start|stop}" exit 1 esac exit 0 Si copiamos este script a /etc/init.d, podremos crear los enlaces simbólicos correpondientes, en los directorios rc?.d necesarios, de tal forma que siempre 123 que alcancemos estos niveles de ejecución tendremos la seguridad de tener activado el sistema de cuotas. Capı́tulo 15 Wake On Lan. 125 126 CAPÍTULO 15. WAKE ON LAN. Cuando un administrador tiene un laboratorio de simulación a su cargo, que habitualmente está a cierta distancia de su lugar de trabajo habitual, un proceso que suele llevar bastante tiempo es arrancar todos los ordenadores cuando se va a llevar a cabo un curso en el mismo. Para evitar tener que ir a la sala e ir arrancando ordenador a ordenador, podemos utilizar una facilidad que tienen ya la mayorı́a de los ordenadores existentes, que es Wake On Lan (WOL), que permite arrancarlos en remoto, mandándoles una señal concreta por red. Primero tenemos que activar el WOL en los ordenadores, para ello arrancamos el ordenador y accedemos a la BIOS. Si bien el menú que nos encontremos puede variar mucho de un ordenador a otro, probablemente encontraremos un submenú relacionado con Power Management Setup o Wake On Lan y habilitaremos esta opción, saliendo de la BIOS grabando los cambios realizados (salvo que no estemos seguros de haber realizado cualquier otro cambio). Y a partir de este momento podremos arrancar en remoto cualquiera de estas máquinas, sin más que ejecutar: ether-wake MAC donde MAC es la dirección MAC del ordenador remoto que tiene que ser arrancado. Capı́tulo 16 Otras tareas administrativas. 127 128 CAPÍTULO 16. OTRAS TAREAS ADMINISTRATIVAS. Las tareas del administrador muchas veces no pueden ser catalogadas con un nombre concreto, no podemos decir que todos los lunes debemos hacer algo en concreto, sino más bien el trabajo cotidiano dependerá de tantas variables que es prácticamente determinarle a priori. No obstante hay varios comandos o aplicaciones que vamos a necesitar en muchas ocasiones, o nos van a resultar de bastante ayuda en nuestro trabajo cotidiano: 16.1. strace Este comando nos permite realizar una traza de las llamadas al sistema y señales que tiene la ejecución que pasemos a este comando como argumento. Es muy probable que alguno de nuestros usuarios nos pregunte por qué tiene un problema en concreto con un programa. Muchas veces la solución de estas cuestiones es prácticamente inmediata debido a la diferencia de experiencia entre el usuario y el administrador, pero otras muchas veces es muy complicado conseguir la solución del problema. Para estar seguro de los pasos que realiza un comando en concreto, cada al sistema, podemos utilizar strace, viendo ası́ los posible problemas que podemos estar teniendo en esta ejecución para poder dar una solución correcta al usuario. La ejecución, por ejemplo, del comando hostname sabemos que nos da como resultado una única lı́nea con el nombre de la máquina. Si ejecutamos strace hostname obtendremos unas 64 lı́neas, que nos describirán todos los pasos que ha realizado el sistema para darnos este resultado. Con esto queremos decir que la información obtenida mediante este comando debe ser tomada con tranquilidad, pues muchas veces es extremadamente densa, pero siempre de gran utilidad, pues gracias a ella podremos obervar si hay alguna librerı́a que no es encontrada o que tiene alguna irregularidad, explicaciones que sin la ejecución de strace serı́a claremente complicado obtener. 16.2. Ejecución en varias máquinas. Cuando tenemos que administrar un cluster con varios equipos, la mayorı́a de las veces estos son exactamente iguales, clones los unos de los otros, de tal forma que es muy habitual tener que ejecutar el mismo comando en todos y cada uno de ellos. Esto, que de forma teórica parece terriblemente sencillo, puede ocuparnos mucho tiempo innecesario. Algo que podemos hacer para evitar estas demoras es permitir el acceso mediante ssh sin contraseña. Por su puesto esta práctica es muy insegura, 16.3. INTEGRIDAD DE LAS PARTICIONES. pues si accedemos a la máquina principal, podremos acceder a cualquier otra, pero si tenemos actualizados los sistemas, con anti troyanos, con tcpwrappers y con una configuración robusta de cortafuegos, la inseguridad que se plantea con esta utilidad es menor que las ventajas que obtendremos. Hay que tener en cuenta que lo que necesitamos es que las máquinas del clúster acepten la entrada desde una máquina de administración (lo contrario no es necesario). Para ello lo que haremos en la máquina de administración es ejecutar: ssh-keygen -t rsa Pulsando enter en cada una de las preguntas, para aceptar los defectos (incluso no establecer contraseña). Copiamos entonces el contenido de /var/root/.ssh/id rsa.pub en el archivo $HOME/.ssh/authorized keys de la maquina a la que queramos entrar sin contrasenya, es decir, a todas las máquinas del clúster. De esta forma ya podrı́amos teclear, en la máquina de administración: ssh maquina-remota hostname y ejecutarı́a el comando hostname en la máquina del clúster correspondiente. Por supuesto lo interesante de este punto es crear un programa que nos permita realizar la ejecución de comandos en todos los equipos del clúster, para ello lo que podrı́amos hacer es crear un bucle que ejecutara el comando en todas y cada una de estas máquinas: for maquina in "maquina1 maquina2 maquinan" do ssh $maquina $@ done de tal forma que si este script le hemos llamado entodas, podrı́amos ejecutar: entodas hostname y obtendrı́amos el resultado de esta ejecución en todas y cada una de las máquinas del clúster. 16.3. Integridad de las particiones. Cada vez que arrancamos un equipo, el sistema realiza una comprobación de las particiones si es necesario. Este proceso se realiza cuando ha pasado un número determinado de dı́as desde la última vez que se realizó la comprobación. Teniendo en cuenta que los sistemas con Linux pueden permanecer mucho tiempo arrancados, quizás es necesario realizar esta comprobación sin esperar al reinicio de la máquina. 129 130 CAPÍTULO 16. OTRAS TAREAS ADMINISTRATIVAS. El comando que utilizaremos entonces es fsck, al que daremos la opción -t seguido del tipo de sistema de archivos de la partición que queramos escanear. Esta orden la ejecutaremos sobre cada una de las particiones a analizar, teniendo siempre en cuenta que la mejor forma de comprobarlas es cuando estas no están montadas, pues si lo están la ejecución del comando puede resultar peligrosa, afectando a la información que se genere en el momento de la ejecución. La forma de ejecutarlo entonces es sencilla, si queremos comprobar la partición /dev/sda3 de nuestro sistema, ejecutaremos: fsck -t ext3 /dev/sda3 16.4. Desfragmentación. Si somos usuarios de sistemas operativos de Microsoft, la desfragmentación formará parte de nuestras vidas, pues muchas veces habremos accedido a los programas de desfragmentación facilitados con el fin de aumentar el rendimiento del sistema. Este tipo de utilidades son de gran utilidades en sistemas de archivos como fat32, ya que los archivos son creados al principio del disco y en orden, de tal forma que si queremos aumentar el contenido de un archivo, lo más probable es que no podamos hacerlo a continuación en el disco duro pues seguro que ya tendremos algo más grabado, necesitando por tanto que este archivo se fragmente, es decir, lo que escribamos de nuevo tendrá que ser almacenado no a continuación del archivo, sino donde haya espacio disponible en el disco. En otros sistemas de archivos, como ext3 y ext4 (utilizados en Linux de forma mayoritaria), no existe este tipo de problemas, pues lo que se hace es tender a utilizar todo el disco duro. Cuando escribimos un archivo, este se posiciona en una zona determinada de la partición correspondiente. Al generar otro archivo, el sistema operativo no lo posiciona a continuación del primero, sino en cualquier otra zona del disco. De esta forma podremos modificar el primero, aumentándolo en tamaño, sin tener que fragmentarlo, pues a continuación lo más probable es que no haya nada. Con este método lo que hacemos es permitir la utilización por igual de todas las zonas del disco duro y además evitar la fragmentación en gran medida, por tanto es innecesario desfragmentar archivos en particiones ext3 o ext4. Capı́tulo 17 Actualizaciones. 131 132 CAPÍTULO 17. ACTUALIZACIONES. Las actualizaciones son imprescindibles en cualquier sistema operativo, bien sea de Microsoft, bien sea UNIX, de Apple, Linux, etc. Los sistemas operativos son un compendio de miles de lı́neas de código que contienen errores inevitablemente. Estos errores son descubiertos bien por una búsqueda activa con el fin de mejorar los sistemas operativos o para intentar valerse de vulnerabilidades encontradas para acceder a los sistemas. Una vez es conocido un fallo en el operativo, la publicación de un parche para corregir el error es cuestión de tiempo. Algunos sistemas operativos, como los desarrollados por Microsoft, mantienen la polı́tica de publicar las actualizaciones una vez al mes, mientras que otros sistemas operativos, como Linux, suelen publicar las actualizaciones tan pronto son obtenidas. Cada distribución de Linux suele tener una forma distinta de manejar estas actualizaciones, pero todas tienen la misma idea común: Comprobar qué software tenemos instalado. Buscar nuevas versiones del software. Instalar las nuevas versiones. En las distribuciones Linux no sólo vamos a obtener las actualizaciones del sistema operativo en sı́, sino también de la mayorı́a del software que tenemos instalado en el ordenador, de tal forma que es un proceso mucho más rápido y compacto que en otros sistemas operativos. Las herramientras más utilizadas para la actualización son: yum apt-get yast 17.1. yum yum (Yellowdog Updater Modified), es una herramienta que cada vez se está implementando con mayor intensidad en distribuciones que utilizan paquetes de instalación rpm, como por ejemplo Fedora Core. Esta herramienta nos permite lista el software que tenemos instalado en nuestro equipo, borrar paquetes que no necesitemos, instalar los que creamos oportunos y actualizar por supuesto. Para actualizar el sistema simplemente tendremos que teclear: yum update -y de tal forma que actualizará los paquetes que sean necesarios. La opción y permitirá que yum actualice el sistema sin nuestra interacción, es decir, asumirá yes para las preguntas que tuviera necesidad de plantear en interactivo. Con esta opción por tanto podremos programar esta tarea sin mayor problema, de tal forma que, por ejemplo, todas las noches se ejecute y por lo tanto el sistema se actualice. 17.2. APT-GET 17.2. apt-get Esta aplicación es nativa de la distribución Debian, y por tanto es utilizada en todas las distribuciones que se basan en Debian. Además esta herramienta ha sido portada a otras distribuciones, de tal forma que ya no es necesario utilizar paquetes .deb para poder utilizar esta herramientas, sino que podemos tener sistemas operativos que utilicen paquetes .rpm por ejemplo, y poder utilizar apt-get. La forma de utilizar este comando es equivalente a yum, es decir, tendremos la posibilidad de listar el software que tenemos instalado en nuestro equipo, podremos instalar nuevos paquetes, eliminar los que ya no nos interesen y por supuesto actualizar el equipo. Para realizar este último punto, la actualización del equipo, ejecutaremos: apt-get upgrade -y que realizará una comprobación de las actualizaciones del software instalado en nuestro equipo, y las instalará sin realizar preguntas en interactivo, ya que le hemos incluido la opción -y. Es conveniente sincronizar los paquetes que tenemos con respecto a sus fuentes, para ello antes de ejecutar este comando serı́a interesante ejecutar: apt-get update -y Por supuesto la actualización mediante estos comandos también debe programarse como una tarea diaria, con el fin de tener perfectamente actualizado nuestro sistema. 17.3. yast La herramienta yast la utiliza la distribución SuSE. Esta herramienta es una sucesión de menús que nos permiten realizar prácticamente todas la tareas de administración. Con respecto a yast comentar que hay auténticos forofos de esta herramienta, pero también auténticos detractores, ya que muchas veces actúa como una verdadera caja negra. Cuando arrancamos esta herramienta nos encontramos con una serie de menús (17.1). Para poder programar la actualización del sistema tendremos que elegir por tanto Actualización en lı́nea. Dentro de este menú (17.2), encontraremos que podemos realizar una actualización del sistema en este momento, pero tendremos que elegir Configurar actualización totalmente para programar esta tarea. Finalmente accederemos a un menú (17.3) en el que simplemente tendremos que elegir cuándo queremos realizar esta actualización automática. 133 134 CAPÍTULO 17. ACTUALIZACIONES. Figura 17.1: Aspecto de la herramienta yast. Accederemos al menú Actualización en lı́nea- para realizar una actualización del sistema. 17.3. YAST Figura 17.2: Dentro del menú -Actualización en lı́nea-, elegiremos -Configurar actualización totalmente- para programar la actualización. 135 136 CAPÍTULO 17. ACTUALIZACIONES. Figura 17.3: Para llevar a cabo la actualización automática del sistema, elegiremos la hora a la que querremos que se actualice.