1
INTRODUCCIÓN
La interconexión entre máquinas y las comunicaciones de alta velocidad han
permitido que los recursos que se util icen no estén en el mismo sit io geográfico del
usuario. UNIX (y por supuesto GNU/Linux) es probablemente el máximo exponente
de esta fi losofía, ya que desde su inicio ha fomentado el compartir recursos y la
independencia de ‘dispositivos’.
Esta fi losofía se ha plasmado en algo común hoy en día, que son los servicios. Un
servicio es un recurso (que puede ser universal o no) y que permite bajo ciertas
condiciones obtener información, compartir datos o simplemente procesar la in -
formación remotamente. Nuestro objetivo es analizar los servicios que permiten el
funcionamiento de una red. Generalmente, dentro de esta red existirá una máquina
(o varias, según las configuraciones) que posibil itará el intercambio de información
entre las restantes.
Estas máquinas se denominan servidores y contienen un conjunto de programas que
permiten quela información esté centralizada y sea fácilmente accesible. Estos
servicios propician la reducción de costes y amplían la disponibil idad de la
información, pero se debe tener en cuenta que un servicio centralizado presenta in-
convenientes, ya que puede quedar fuera de línea y dejar sin servicio a todos los
usuarios.
Los servicios se pueden clasificar en dos tipos: de vinculación ordenador-o r d e n a d o r o de
relación hombre-ordenador. En el primer caso se trata deservicios requeridos por otros
ordenadores, mientras que en el segundo, s o n s e r v i c i o s r e q u e r i d o s p o r l o s u s u a r i o s
( a u n q u e h a y s e r v i c i o s q u e p u e d e n actuar en ambas categorías). Dentro del primer tipo
se encuentran servicios de nombres, como el domain name system ( D N S) , e l s e r v i c i o d e
i n f o r m a c ió n d e u s u a r i o s ( N I S YP ) , e l d i r e c t o r i o d e i n f o r m a c ió n L D A P o l o s
s e r v i c i o s d e a lm a c e n a m ie n t o i n t e r m e d i o ( proxies).
Dentro de la segunda categoría, se incluyen servicios de conexión interactiva y ejecución remota
(SSH, telnet), transferencia de ficheros (FTP), intercambio de información a nivel de u s u a r i o ,
c o m o e l c o r r e o e l e c t r ó n i c o ( M T A , I M A P , P O P ) , news, W o r l d W i d e Web, W ik i y
a r c h i v o s ( N F S) . P a r a m o s t r a r l a p o s i b i l i d a d e s d e G N U / L i n u x D e b i a n - F C 6 , s e
d e s c r i b i r á n c a d a u n d e e s t o s s e r v i c i o c o n u n a c o n f i g u r a ción mínima y operativa,
pero sin descuidar aspectos de seguridad y estab i l i d a d .
2
COMANDOS AVANZADOS UTILIZADOS EN LA ADMINISTRACIÓN DE SERVIDORES
ACERCA DE AWK
AWK, cuyo nombre deriva de la primera letra de los apellidos de sus autores Alfred Aho, Peter
Weinberger y Brian Kernighan, es un lenguaje de programación que fue diseñado con el objetivo
de procesar datos basados sobre texto y una de las primeras herramientas en aparecer en Unix.
Utiliza listas en un índice ordenado por cadenas clave (listas asociativas) y expresiones regulares.
Es un lenguaje ampliamente utilizado para la programación de guiones ejecutables pues añade
funcionalidad a las tuberías en los sistemas operativos tipo POSIX. Está incluido en las
instalaciones básicas de prácticamente todas las distribuciones de GNU/Linux.
Estructura de los programas escritos en AWK.
El mandato awk utiliza un archivo o emisión de ordenes y un archivo o emisión de entrada. El
primero indica como procesar al segundo. El archivo de entrada es por lo general texto con algún
formato que puede ser un archivo o bien la salida de otro mandato.
La sintaxis general utilizada para el mandato awk sigue el siguiente patrón:
awk 'expresión-regular { orden }'
Cuando se utiliza el mandato awk, éste examina el archivo de entrada y ejecuta la orden cuando
encuentra la expresión regular especificada.
El siguiente modelo ejecutaría la orden al inicio del programa y antes de que sean procesados los
datos del archivo de entrada:
awk 'BEGIN { orden }'
El siguiente modelo ejecutaría la orden al final del programa y después de que sean procesados
los datos del archivo de entrada:
awk 'BEGIN { orden }'
El siguiente modelo ejecutaría la orden por cada una de las líneas del archivo de entrada:
awk '{ orden }'
3
PROCEDIMIENTOS
A continuación se mostrarán ejemplos del uso de AWK.
El siguiente mandato específica que al inicio se imprima en la salida la frase "Hola mundo" y
terminar el procesamiento.
awk 'BEGIN { print "Hola mundo"; exit }'
Lo anterior deberá devolver una salida como la siguiente:
Hola mundo
Si se genera el archivo prueba.txt del siguiente modo:
echo -e "Columna1\tColumna2\tColumna3\tColumna4\n" > ejemplo.txt
Y se visualiza con el mandato cat:
cat ejemplo.txt
Devolverá el siguiente contenido:
Columna1 Columna2 Columna3 Columna4
Si se utiliza el mandato awk para que solo muestre la columna 1 y la columna 3 del siguiente
modo:
awk '{ print $1, $3}' ejemplo.txt
La salida devolverá lo siguiente:
Columna1 Columna3
4
Si se utiliza el mandato awk para que solo muestre la columna 3 y la columna 1, en ese orden, del
siguiente modo:
awk '{ print $3, $1}' ejemplo.txt
La salida devolverá lo siguiente:
Columna3 Columna1
Si se añaden datos al archivo ejemplo.txt del siguiente modo:
echo -e "Dato1\tDato2\tDato3\tDato4\n" >> ejemplo.txt
echo -e "Dato5\tDato6\tDato7\tDato8\n" >> ejemplo.txt
echo -e "Dato9\tDato10\tDato11\tDato4\12" >> ejemplo.txt
Y se visualiza con el mandato cat:
cat ejemplo.txt
Devolverá el siguiente contenido:
Columna1 Columna2 Columna3 Columna4
Dato1 Dato2 Dato3 Dato4
Dato5 Dato6 Dato7 Dato8
Dato9 Dato10 Dato11 Dato4
Si se utiliza nuevamente el mandato awk para que solo muestre la columna 1 y la columna 3 del
siguiente modo:
awk '{ print $1, $3}' ejemplo.txt
La salida devolverá lo siguiente:
Columna1 Columna3
Dato1 Dato3
Dato5 Dato7
5
Dato9 Dato11
Si se utiliza el mandato awk del siguiente modo para que solo muestre solo la línea cuya columna
contenga la expresión regular Dato5:
awk '/Dato5/ { print }' ejemplo.txt
La salida devolverá lo siguiente:
Dato5 Dato6 Dato7 Dato8
Si se utiliza el mandato awk del siguiente modo para que solo muestre solo la línea cuya columna
contenga la expresión regular Dato5, y además solo las columnas 1 y 4:
awk '/Dato5/ { print $1, $4}' ejemplo.txt
La salida devolverá lo siguiente:
Dato5 Dato8
Si se utiliza el mandato awk del siguiente modo para que muestre solo las líneas con más de 35
caracteres en el archivo /etc/crontab:
awk 'length > 35' /etc/crontab
La salida devolverá lo siguiente:
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
Si se utiliza el mandato awk del siguiente modo para que muestre solo las líneas con menos de 35
caracteres en el archivo /etc/crontab:
6
awk 'length < 35' /etc/crontab
La salida devolverá lo siguiente:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
Utiliza vi para crear el archivo usuario.txt:
vi usuario.txt
Ingrese el siguiente contenido:
Fulano Algo
Calle Mengana 123
Colonia Perengana
Ciudad de Zutano, C.P. 123456
Para que el mandato awk reconozca cada línea como un registro completo, en lugar de considerar
cada palabra como una columna, se utiliza 'BEGIN { FS="\n" ; RS=""}', donde el valor de FS
(Field Separator o separador de campo) se establece como un retorno de carro y el valor de RS
(Record Separator o separador de registro) se establece como una línea vacía. Si utiliza el
siguiente mandato donde se establecen los valores mencionados para FS y RS y se pide se
impriman los valores de cada registro (cada línea) separados por una coma y un espacio:
awk 'BEGIN { FS="\n"; RS="" } { print $1 ", " $2 ", " $3 ", " $4 }' usuario.txt
La salida devolverá lo siguiente:
Fulano Algo, Calle Mengana 123, Colonia Perengana, Ciudad de Zutano, C.P.
123456
7
El mandato awk puede realizar conteo de líneas, palabras y caracteres. El siguiente mandato se
establece que el valor de w sea igual al número de campos (New Field o NF), c sea igual la
longitud de cada campo, y que se imprima el número de campos, el valor de w y el valor de c:
awk '{ w += NF; c += length} \
END { print \
"Campos: " NR , "\nPalabras: " w, "\nCaracteres: " c }' \
usuario.txt
La salida devolverá lo siguiente:
Campos: 4
Palabras: 12
Caracteres: 74
Genere el archivo numeros.txt con el siguiente contenido, donde las columnas serán separadas por
un tabulador:
1 2 3 4
5 6 7 8
9 10 11 12
El mandato awk puede realizar operaciones matemáticas. el siguiente mandato establece que s es
igual a la suma del valor de los campos de la primera columna del archivo numeros.txt, e imprime
el valor de s:
awk '{ s += $1 } END { print s }' numeros.txt
La salida devolverá lo siguiente (resultado de la suma de 1+5+9):
15
Si se hace lo mismo, pero con los valores de la columna 2:
awk '{ s += $2 } END { print s }' numeros.txt
8
La salida devolverá lo siguiente (resultado de la suma de 2+6+10):
18
Para hacer conteo de frecuencia de palabras, Se establece que el valor para FS (Field Separator o
separador de línea) sea igual a expresiones regulares que van desde la a a la z y desde la A a la Z,
se establece que el valor de la variable i es igual a 1 y menor al número de campos.
awk 'BEGIN { FS="[^a-zA-Z]+"} \
{ for (i=1; i<=NF; i++) words[tolower($i)]++ } \
END { for (i in words) print i, words[i] }' /etc/crontab
La salida devolverá lo siguiente:
7
bin 3
run 5
etc 4
sbin 3
bash 1
weekly 1
daily 1
cron 4
usr 2
path 1
shell 1
parts 5
home 1
mailto 1
monthly 1
hourly 1
root 6
9
SED
Se trata de un editor de cadenas, que deriva directamente del comando ed, por lo cual es fácil de
aprender, una vez conocido el propio comando ed. Un editor de cadenas es usado para realizar
transformaciones de texto básicas de una cadena de entrada (un archivo o la salida de un pipe). A
diferencia de otros editores comunes, sed hace solo una revisión sobre cada entrada, por lo cual
es mas eficiente, en especial lo es, cuando filtra texto que pasa por una unión pipe.
Cuando sed filtra un archivo, no altera su contenido, todos los cambios los realiza sobre la salida
que imprime. Sed despliega cada renglón automáticamente y por ello p no se necesita después del
comando de sustitución (s, por ejemplo s/old/new/). Las comillas son indispensables pues existen
metacaracters de sed que tienen significado especial para el shell sobre el cual se ejecuta.
El comando sed tiene una limitación que no se encuentra en ed: no maneja números relativos de
renglón. En particular, + y - no son entendidos como expresiones para indicar números de renglón,
por lo cual resulta imposible de retroceder a uno o mas renglones anteriores o hacer
direccionamientos relativos hacia adelante. Esto se debe a que una vez leído un renglón, el
anterior se pierde para siempre; no hay manera de identificar el penúltimo renglón.
En la lista de comandos puede existir cualquiera de los listados más adelante. Cuando se hace uso
de uno solo, basta con encerrarlo entre comillas simples como sigue:
sed 's/old/new/' archivo
Pero en el caso de que necesitemos ejecutar varios comandos sobre un mismo archivo, es
necesario que estos se encuentren en diferentes líneas, por ejemplo:
sed 's/^/ /3q' archivo
No hay que olvidar que antes de escribir el primer comando, se deben abrir las comillas simples y
las mismas se deben cerrar después de teclear el último comando. También es posible almacenar
los comandos dentro de un archivo y llamarlo a la hora de que se ejecute sed con el parámetro -
f. Por ejemplo:
sed -f cmdarchivo archivo_texto
Se pueden utilizar otros selectores o patrones antes de cada comando, por ejemplo:
10
sed '/patron/q' Imprime cada linea de archivo hasta encontrar aquella que contenga el patron
sed '/patron/d' Cancela todas las lineas que contengan el patron y no se imprimen
Incluso si se desea el resultado inverso a lo que realiza un comando, basta con agregar un '!' antes
del comando. Por ejemplo, para los dos ejemplos anteriores se prosigue como sigue:
sed '/patron/!q' No imprime c/línea de archivo hasta encontrar aquella que contenga el patron
sed '/patron/!d' No cancela todas las lineas que contengan el patron y no se imprimen
Sintaxis
La sintaxis de sed es la siguiente
sed [-n] [-V] [--quiet] [--silent] [--version] [--help]
[-e script] [--expression=script]
[-f script-file] [--file=script-file]
[script-if-no-other-script]
[file...]
-----------------------------------------------------------------------------------------------
-V ó --version
Imprime la versiòn de sed y nota de copyright.
-h ó --help
Imprime un resumen de todas las opciones de sed.
-n ó --quiet ó --silent
Por defecto, sed imprime cada linea cuando termina de editarla. Esta opciòn deshabilita la
impresiòn automàtica y no se produce ninguna salida, excepto que se incluya el comando p.
-e script ó --expression=script
Agrega los comandos de la cadena script, encerrada entre comillas simples, a la lista de comandos
para ser ejecutados mientras se procesa la entrada.
-f script-file ó --file=script-file
Agrega los comandos contenidos en el archivo script para ser procesados sobre la entrada. Si
ninguno de los dos parámetros anteriores es utilizado, en cualquiera de sus formas, sed tomará
como comandos la primera expresión que no sea opción de sed como argumento para ejecutar
como si fuera script.
Comandos
====================================================================
A continuación se presenta una lista de comandos que se pueden utilizar para filtrar una entrada
con sed, así mismo se incluyen algunos ejemplos para una mayor comprensión.
11
** Sustitución **
Su función es sustituir una cadena old por una nueva new en cada linea que procese. Su sintaxis
es la siguiente:
s/old/new/
Ejemplo:
sed 's/casa/carro/' contrato.txt Sustituye la cadena 'casa' por 'carro' en contrato.txt
sed 's/^/.-/' arch.txt Agrega la cadena '.-' al inicio de cada linea de arch.txt
sed 's/^/\
/' arch.txt Agrega un salto de linea al final de cada linea de arch.txt
Otro comando que puede ser útil es y, el cual remplaza cada caracter procedente de old con el
caracter correspondiente proveniente de new. Aqui no se admiten rangos. Su sintaxis es:
y/old/new/
** Borrado **
Su función es borrar a la salida, las lineas que correspondan al patrón escrito. Su sintaxis es la
siguiente:
/patron/d
Ejemplo:
sed '/calvo/d' arch.txt Elimina las lineas que contienen la cadena 'calvo' en arch.txt
sed '/amor/!d' carta.txt Elimina las lineas que no tengan la palabra amor en carta.txt
sed '3d' forma.txt Elimina la linea 3 del archivo forma.txt
** Impresión **
Su función es imprimir la salida de sed. En realidad, sed imprime automáticamente la entrada
filtrada, entonces si se agrega el comando p, cada linea de salida se imprimirá doble. En caso de
que se agregue el parámetro -n a sed, pero se quiera imprimir la salida, se agrega el comando p.
Su sintaxis es la siguiente:
/patron/p
Ejemplo:
who | sed -n '/root/p' Imprime solamente las sesiones de root
who | sed '/root/p' Imprime dos veces cada sesion abierta de root
who | sed -n '2p' Imprime solamente la segunda sesion que se inició en el sistema
12
** Abandonar filtrado **
Otro comando útil para imprimir una parte de la entrada es q. Este comando termina
inmediatamente las operaciones de sed, en base a la correspondencia del patrón con las líneas
que este procesando. Su sintaxis es la siguiente:
/patron/q
Ejemplo:
sed '3q' forma.txt Imprime hasta la linea 3 del archivo forma.txt
sed '/clavo/q' arch.txt Imprime desde la línea 1 de arch.txt hasta encontrar aquella que contiene la
palabra 'clavo'.
** Inserción de texto **
Este comando inserta o agrega texto a cada línea que procesa sed. El texto debe estar localizado
en las siguientes lineas que proceden después del caracter '\'. Su sintaxis es la siguiente:
i \ y a\
[ texto a agregar ]
Ejemplo:
sed 'i \
.' oraciones.txt Agrega un punto final a cada linea de oraciones.txt
sed 'a \
' doble.txt Agrega un salto de linea al final de cada linea de doble.txt
** Guardar la entrada filtrada en un archivo **
Este comando permite salvar la entrada filtrada en otro archivo. Su sintaxis es la siguiente:
/patron/w archivo
Ejemplo:
sed '/pat/w patos.txt
/pat/!w otros.txt animales.txt
Guarda las lineas que concuerden con 'pat' en un archivo llamado patos.txt y los que no
concuerden en el archivo otros.txt
sed 's/UNIX/UNIX(TM)/gw u.out' libros.txt > salida.out
Almacena toda la salida en el archivo salida.out, pero las líneas que fueron modificadas, se
almacenan en u.out
13
Funciones
** Etiqueta **
Permite identificar una etiqueta label, si se realiza un cambio en la línea actual. Esta es
especificada por ':' y seguida del nombre de la etiqueta. Su sintaxis es como sigue:
: label
** Grupo **
Indica un grupo de comandos, que inicia con un carácter '{' y termina con un '}'.
** Lectura de archivos **
Con el comando r, lee un archivo y agrega todo su contenido al final de cada línea de entrada de
sed. Su sintaxis es:
nr archivo, donde n es el número de línea donde pegar el texto de archivo.
** Listar línea **
El comando es l y su función es hacer visibles todos los caracteres no imprimibles de cada línea de
entrada.
** Linea actual **
Se puede imprimir el número de la línea actual, si se agrega el comando '='. Su sintaxis es:
/patron/=
** Salto **
Permite saltar o ir a la línea donde se encuentra una etiqueta label definida y continuar la ejecución
de sed desde ese comando. Su sintaxis es:
b label
Conclusión sobre los usos de sed
En realidad sed tiene bastante utilidad como la comprobación de condiciones, creación de ciclos y
ramificaciones, retención de líneas precedentes y muchos de los comandos de ed. Su uso es
similar al que se ha descrito en este manual, comandos sencillos de edición y no tanto de
secuencias largas o complejas.
14
Sed es adecuado para manejar entradas arbitrariamente grandes de forma rápida, pero ofrece una
forma bastante reducida de memoria, puesto que al filtrar una siguiente línea, ya no recuerda la
anterior, por lo que no se puede regresar a filtrar la anterior y tampoco proporciona recursos para
manipular números. Solo es un editor de texto.
GREP
grep es una utilidad de la línea de comandos escrita originalmente para ser usada con el sistema
operativo Unix. Usualmente, grep toma una expresión regular de la línea de comandos, lee la
entrada estándar o una lista de archivos, e imprime las líneas que contengan coincidencias para la
expresión regular.
Su nombre deriva de un comando en el editor de texto ed que tiene la siguiente forma:
g/re/p
y significa «hacer una búsqueda global para las líneas que encajen con la expresión regular
(regular expression en inglés), e imprimirlas». Hay varios argumentos que se pueden usar con grep
para modificar el comportamiento por defecto.
Existen otros retroacrónimos (incorrectos) para el nombre, entre ellos: General Regular Expression
Parser (analizador general de expresiones regulares), General Regular Expression Print (imprimir
expresión regular general), y Global Regular Expression Print (imprimir expresión regular global),
éste último no tan lejano de la realidad.
Uso:
Código:
grep [opciones] [expresión regular] [archivo]
Grep generalmente ejecuta alguna variante del algoritmo Boyer-Moore (para búsqueda de strings),
utilizando expresiones regulares para definir la consulta. Puede manejar archivos, directorios (y
subdirectorios), o la entrada estándar (stdin).
El programa es configurable por medio de opciones de invocación, pudiendo (por ejemplo) mostrar
las líneas con aciertos, desaciertos, el contexto de la coincidencia, etc.
Parámetros comunes:
-núm Las líneas concordantes se mostrarán acompañadas de núm líneas
anteriores y posteriores. Sin embargo, grep nunca mostrará cualquier línea dada más
de una vez.
15
-A núm , --after-context=NÚM Muestra núm líneas de contexto después de las que
concuerden con el patrón.
-B núm , --before-context=NÚM Muestra núm líneas de contexto antes de las que
concuerden con el patrón.
-C, --context Equivalente a -2.
-V, --version Muestra el número de versión de grep en la salida estándar de
errores. Este número de versión debería incluirse en todos los informes de fallos (vea
más abajo).
-b, --byte-offset Muestra el desplazamiento en bytes desde el principio del fichero de
entrada antes de cada línea de salida.
-c, --count Suprime la salida normal; en su lugar muestra el número de líneas
que concuerdan con el patrón para cada fichero de entrada. Con la opción -v, --
revert-match (vea más abajo), muestra el número de líneas que no concuerden.
-E patrón,--regexp=PATRÓN Emplea patrón como el patrón; útil
para proteger patrones que comiencen con -.
-f fichero,--file=FICHERO Obtiene el patrón de fichero.
-h, --no-filename Suprime la impresión de los nombres de ficheros antes de las líneas
concordantes en la salida, cuando se busca en varios ficheros.
-i, --ignore-case No hace caso de si las letras son mayúsculas o minúsculas ni en el patrón
ni en los ficheros de entrada.
-L, --files-without-match Suprime la salida normal; en su lugar muestra el nombre de cada
fichero de entrada donde no se encuentre ninguna concordancia y por lo tanto de cada
fichero que no produciría ninguna salida. La búsqueda se detendrá al llegar a la primera
concordancia.
-l, --files-with-matches Suprime la salida normal; en su lugar muestra el nombre de cada
fichero de entrada que produciría alguna salida. La búsqueda se detendrá en la primera
concordancia.
-n, --line-number Prefija cada línea de salida con el número de línea de su fichero de
entrada correspondiente.
-q, --quiet Silencioso; suprime la salida normal. La búsqueda finaliza en la primera
concordancia.
-s, --silent Suprime los mensajes de error sobre ficheros que no existen o no se pueden
leer.
-v, --revert-match Invierte el sentido de la concordancia, para seleccionar las líneas
donde no las hay.
-w, --word-regexp Selecciona solamente aquellas líneas que contienen concordancias que
forman palabras completas. La comprobación consiste en que la cadena de caracteres
16
concordante debe estar al principio de la línea o precedida por un carácter que no forme
parte de una palabra. De forma similar, debe estar o al final de la línea o ser seguida por
un carácter no constituyente de palabra. Los caracteres que se consideran como parte
de palabras son letras, dígitos y el subrayado.
-x, --line-regexp Selecciona solamente aquellas concordancias que constan de toda la
línea.
-y Sinónimo obsoleto de -i.
-U, --binary Trata el(los) fichero(s) como binario(s). De forma predetermi- nada, bajo MS-
DOS y MS-Windows, grep intenta adivinar el tipo del fichero mirando los contenidos de
los primeros 32 kB leídos de él. Si grep decide que el fichero es de texto, quita los car-
acteres CR (retorno de carro) de los contenidos originales del fichero (para que las
expresiones regulares con ^ y $ funcionen correctamente). Al especificar -U
deshabilitamos este intento de adivinación del tipo del fichero, haciendo que todos
se lean y pasen al mecanismo de concordancia tal cuales; si el fichero lo es de texto y
tiene al final de cada línea el par de caracteres CR/LF, esto hará que algunas expresiones
regulares fallen. Esta opción sólo tiene sentido en MS-DOS y MS-Windows.
-u, --unix-byte-offsets Informa de desplazamientos de bytes al estilo de Unix. Esta
opción hace que grep muestre los desplazamientos de bytes como si el fichero fuera de
texto al estilo de Unix; o sea, sin los caracteres CR al final de cada línea. Esto producirá
resultados idénticos a ejecutar grep en un sistema Unix. Esta opción no tiene efecto a
menos que se dé también la opción -b; sólo tiene sentido en MS-DOS y MS-Windows.
-o, --only-matching Muestra sólo la cadena buscada por el PATRON
Ejemplos:
Para mostrar todas las líneas que contienen la cadena «tal» en una lista de archivos (donde «*»
representa todos los archivos en el directorio actual):
Código:
grep tal *
Para mostrar todas las líneas que no contengan la cadena «tal», se usa «-v»:
Código:
grep -v tal *
Para mostrar sólo el nombre de tales archivos, se usa «-l»:
Código:
grep -l tal *
17
Para mostrar sólo el nombre de los archivos que no contienen la cadena, se usa «-L»:
Código:
grep -L tal *
Para buscar recursivamente, no sólo en los archivos del directorio actual sino también en los de
sus subdirectorios (donde "." representa el directorio actual), se usa «-r»:
Código:
grep -r tal .
La opción -r puede no estar disponible en todas las plataformas Unix.
Para buscar todas las líneas que comienzan por «Ahora» y terminan con «siempre» seguido de
una cantidad arbitraria de espacio en blanco (nótese que el carácter ^ representa el inicio de la
línea, así como $ representa el final):
Código:
grep '^Ahora.*siempre *$'
Para hacer que grep lea de la entrada estándar, no se especifica archivo alguno. Por ejemplo,
como ps -ef lista todos los procesos actualmente en ejecución, el siguiente comando imprime todos
los procesos que está ejecutando el usuario actual:
Código:
ps -ef | grep $USER
o
Código:
ps -efa | grep $USER
¿QUÉ ES UNA EXPRESIÓN REGULAR?
Si le digo que una expresión regular es un metalenguaje para expresar el conjunto de palabras
aceptadas por los autómatas finitos, a menos que haya estudiado teoría de autómatas puede que
no le diga mucho, pero si le digo que con una expresión regular puede encontrar todas las
18
direcciones de email que hay en un texto cualquiera de forma automática puede que le empiece a
interesar.
Como definición práctica podríamos decir que una expresión regular es un buscador de patrones,
esto es, para cualquier patrón que defina (recuerde el ejemplo del email) la expresión regular
buscará todas las coincidencias.
Como puntualización habría que añadir que las expresiones regulares buscarán coincidencias por
líneas, esto es que la coincidencia de un patrón en el texto tiene que encontrarse en su totalidad en
la misma línea.
Ej:
grep 'hola que tal' archivo
Buscará todos los 'hola que tal' (sin comillas) que aparezcan en el texto en la misma línea, esto es:
Encontrará:
hola que tal estás hoy
Pero no encontrará:
hola
que tal estás hoy
2. Expresiones regulares
2.1. 'carácter'
La expresión regular más sencilla que se puede crear es la compuesta por un carácter o por un
conjunto de carácteres (palabra).
Ej:
grep 'hola' archivo # Busca 'hola' en archivo
grep 'a' archivo # Busca 'a' en archivo
grep 'bienvenido al tutorial' archivo # Busca 'bienvenido al tutorial' en archivo
2.2. Barra invertida
En las expresiones regulares, las barras invertidas "\" normalmente quitan el significado especial de
algún carácter, aunque algunas veces se lo den, esto puede ser un poco complicado al principio
pero se acabará acostumbrando. Como norma general, cualquier carácter con un significado
especial que vea en este tutorial estará en la forma en la que tenga el significado especial, para
quitarle ese significado no tiene más que quitarle la barra si la tiene o ponérsela si no la tiene.
Normalmente a los carácteres precedidos por barra invertida y que sin ella tendrían significado
especial, se llaman escapados.
19
2.3. Punto
El carácter punto "." se sustituye en una expresión regular por cualquier carácter, excepto nueva
línea.
Ejemplos:
echo 'a b' | grep -o '.'
grep encontrará como coincidencias: "a" y "b"
echo 'a b . ;' | grep -o '.'
grep encontrará como coincidencias: "a", "b", "." y ";".
echo 'a b . ;' | grep -o '\.'
grep sólo encontrará como coincidencia: ".", ya que al escapar el patrón ha hecho que este pierda
su significado de cualquier carácter, a tener el significado de: el carácter punto.
quien=tu
echo 'en un'"$quien"' mi' | grep -o '..'
grep encontrará como coincidencias: "en", "un", "tu" y "mi"
echo ';:a una ala uno' | grep -o '..a'
grep encontrará como coincidencias: ";:a", "una", "ala", pero no "uno" ya que no coincide con el
patrón cualquier palabra de tres carácteres siendo el último la "a"
Nótese que con palabra nos referimos a cualquier concatenación de carácteres
echo 'vuela miedo fuera' | grep -o '..e.a'
grep encontrará como coincidencias: "vuela", "fuera", pero no "miedo" ya que aunque cumple la
parte del patrón "..e." no cumple lo de acabar en a.
echo 'Este tutorial de grep me gusta mucho' | grep -o '.e'
Al contrario de lo que se podría esperar no sólo ha encontrado las coincidencias: "de" y "me".
El resultado es cuando menos extraño, si se ha usado la opción -o como en este ejemplo se
20
obtendrán trozos de palabra, en concreto los trozos que concuerdan con el patrón, sin la opción -o
y con el coloreado de grep activado se observará mejor y se podrán inferir las razones.
Lo que ha ocurrido ha sido porque la expresión regular buscaba patrones que coincidieran con ".e"
incluidos los que estuviesen dentro de otras palabras, entonces ¿cómo buscamos únicamente por
las palabras que coincidan con ".e"?
Una posible solución sería añadir espacios a los dos lados del patrón:
echo 'Este tutorial de grep me gusta mucho' | grep -o ' .e '
Esto solucionaría el problema con esta cadena de texto, pero ¿y si una de las palabras que
queremos encontrar con el patrón están al principio o al final de la línea?, en ese caso los espacios
serían un problema ya que pueden faltar. La solución está en usar otro de los meta-caracteres de
las expresiones regulares: \<\>
2.4. \<\>
El metacarácter \<\> hace que todos los patrones dentro de él sólo coincidan con palabras enteras,
esto es, palabras separadas entre sí por espacios. Para este metacarácter los símbolos de
puntuación (.,< etc...) no forman parte de la palabra.
echo 'Este tutorial de grep me gusta mucho' | grep -o '\<..\>'
grep encontrará como coincidencias: "de" y "me", ya que son las únicas palabras enteras que
coinciden con el patrón.
echo 'Ya hemos aprendido algunas cosas' | grep -o '\<....s\>'
grep encontrará como coincidencias: "hemos" y "cosas"
echo 'Ya hemos aprendido algunas cosas' | grep '\<.a\>'
grep encontrará como coincidencia: "Ya", sin embargo si no hubiésemos puesto \<\> entonces el
patrón habría coincidido también con: " a", "na", "sa". La coincidencia con " a" es debida a que
como se explicó antes, el punto es sustituido por cualquier carácter exceptuando nueva línea.
echo '<>' | grep '<..'
grep encontrará como coincidencia: "<echo '<>' | grep '\<..'
21
grep encontrará como coincidencias: "Ya", "he", "ap", "al", "co", esto es, el principio de cada
palabra que encaje con el patrón. Por lo tanto \> hará lo contrario. Veámoslo en un ejemplo.
echo '<>' | grep '..\>'
grep encontrará como coincidencias: "Ya", "os", "do", "as", "as", o lo que es lo mismo el final de las
palabras que encajan con el patrón.
2.5. * (Repitiendo patrones)
Todos los metacarácteres anteriores están muy bien si sabe exáctamente cuántos carácteres tiene
la palabra que quiere buscar, pero ¿qué ocurre si no lo sabe?, pues que habrá que usar el
metacarácter *, * repetirá el patrón que le precede cero o más veces.
echo '4 44 444 444 4444 44444' | grep '4*'
grep encontrará como coincidencias todos y cada uno de los números que contengan cuatros.
echo '4 454 4554554 455545554 4555455545554 44444' | grep '4*'
grep encontrará como coincidencias todos y cada uno de los números que contengan cuatros.
echo '4 454 4554554 455545554 4555455545554 44444' | grep '.*'
grep encontrará como coincidencias todos, ya que el punto se traduce como cualquier carácter y *
(repetido cero o más veces).
echo '.* 44 58.* hhial' | grep '\.\*'
grep encontrará como coincidencias: ".*" debido a que los carácteres están escapados.
echo '4 454 4554554 455545554 4555455545554 44444' | grep '\<4*\>'
grep encontrará como coincidencias sólo los números que contengan únicamente cuatros.
Pero hay que tener cuidado con *, ya que como dice la definición "repetirá el patrón que le precede
cero o más veces."
¿Todavía no ve el peligro?, veámoslo con un ejemplo.
22
echo -e "Línea sin comentario\n#Línea con comentario\nLínea sin comentario" | grep '#*'
echo -e interpreta "\n" como nueva línea, es decir, sería como escribir la frase hasta "\n" darle al
retorno de carro (enter, nueva línea) continuar escribiendo y repetir lo anterior
Con éste patrón debería encontrar las líneas que tengan algún comentario, ¿o no? Como podía
esperar tras toda la preparación anterior: no, pero lo importante es el por qué; esto ha ocurrido
porque como se mencionó anteriormente * repetía el patrón anterior cero o más veces, o lo que es
lo mismo, se buscarían todas las líneas tuvieran o no #.
Para solucionar este problema no habría más que añadir otro # antes del que precede al *:
echo -e "Línea sin comentario\n#Línea con comentario\nLínea sin comentario" | grep '##*'
esto buscará todas las líneas que tengan uno o más # debido a que el metacarácter sólo se aplica
al patrón que le precede, esto es, el segundo #.
2.6. Rango de carácteres []
Gracias al metacarácter [], se pueden elegir diferentes carácteres a los cuáles aplicarles algún otro
patrón de sustitución.
echo '5895 589435 539853 54849' | grep -o '[0123456789]*'
grep encontraría como coincidencias a todos los conjuntos numéricos, ya que es lo que le hemos
indicado con el conjunto de carácteres encerrados entre corchetes.
echo 'hola hhaif aieo uuieo' | grep -o '\<[aeiou]*\>'
grep encontraría como coincidencias a todos los grupos de vocales: "aieo", "uuieo"
En estos casos también se pueden indicar rangos, por ejemplo, para que coincida con cualquier
número se puede poner de la siguiente manera: [0-9], nótese que se empieza en cero; para indicar
cualquier letra (del abecedario inglés) minúscula se puede hacer [a-z], y mayúsculas: [A-Z],
también se pueden combinar: [a-zA-Z] coincidiría con cualquier letra, mayúscula o minúscula.
echo 'hola hhaif AiEo uu66ieo' | grep -o '\<[A-Za-z]*\>'
grep encontraría como coincidencias todas las palabras que sólo contengan letras alfabéticas
(inglesas).
echo 'hola hhAIf AiEo uu66ieo' | grep -o '\<[AIa-z]*\>'
23
grep encontraría como coincidencias todas las palabras que sólo contengan letras alfabéticas
minúsculas (cualquiera) y las letras mayúsculas A e I.
Al utilizarse el guión para indicar rangos, si queremos usarlo como carácter en el grupo debemos
ponerlo al principio o al final, y cualquier metacarácter debe ir escapado.
echo 'hola hh-AIf A-iEo u.u66ieo' | grep '[AIa-z\.-]*'
grep encontraría como coincidencias todas las palabras o subpalabras que sólo contengan letras
alfabéticas minúsculas (cualquiera) y A e I, además de los símbolos "." y "-".
echo 'hola hh-AIf A-iEo u.u66ieo' | grep -o '\<[AIa-z\.-]*\>'
En este caso, con la idea de que coincida cualquier palabra que contenga el conjunto antes
mencionado, se ha usado el metacarácter \<\>, pero el resultado no ha sido el esperado, y su
explicación es que el metacarácter anterior sirve para coincidir con palabras que no contengan
símbolos de puntuación o guiones.
Cabe destacar que existen conjuntos de carácteres POSIX definidos para añadir portabilidad, son
los siguientes:
[:alnum:] Alfanuméricos
[:alpha:] Carácteres alfabéticos
[:upper:] Carácteres en mayúscula
[:lower:] Carácteres en minúscula
[:digit:] Dígitos
[:print:] Carácteres imprimibles
Hay algunos más, pero estos son los más importantes. Ahora reescribiremos algunos ejemplos
anteriores usando estos conjuntos POSIX:
echo '5895 589435 539853 54849' | grep -o '[[:digit:]]*'
Nótese el uso del doble corchete.
echo 'hola hhaif AiEo uu66ieo' | grep -o '\<[[:alpha:]]*\>'
grep encontraría como coincidencias todas las palabras que sólo contengan letras alfabéticas
(inglesas).
24
También se puede elegir el complementario de un conjunto, esto es, los carácteres que no están
en el conjunto. Esto lo haremos con [^conjunto].
echo 'hola 6g hhaif 5345235 AiEo 66' | grep -o '\<[^[:alpha:]]*\>'
grep encontrará como coincidencias todas las palabras que no contengan letras alfabéticas
(inglesas).
echo 'hola hh-AIf EEE5 A-iEo u.u66ieo' | grep -o '\<[^AIh-z]*\>'
grep encontrará como coincidencias todas las palabras que no contengan letras A, I, de h a z.
2.7. Paréntesis \(\)
El metacarácter paréntesis sirve para seleccionar un patrón al que le aplicaremos un metacarácter
modificador, por ejemplo *; tiene además un par de carácterísticas bastante interesantes que
veremos más adelante.
echo 'holaholaholahola holahola adios' | grep -o '\(hola\)*'
grep encontraría como coincidencias todas las palabras que contengan repeticiones de la palabra
hola
echo 'holahelloholahola holahola adios' | grep -o '\<\(hola\)*\>'
grep encontraría como coincidencias todas las palabras que contengan únicamente repeticiones de
la palabra hola
Una de las características interesantes del paréntesis que se mencionó anteriormente es la de
recordar una coincidencia, esto es, el patrón guardará en un registro numérico (del 1 al 9), cada
coincidencia que haya coincidido con un patrón que se encuentre entre paréntesis. Siendo \1 la
primera coincidencia recordada, \2 la siguiente, y así hasta el \9.
echo '6hola6 5hola4 4adios9 7adios7' | grep -o '\<\([0-9]\)[[:alpha:]]*\1\>'
grep encontrará como coincidencias cualquier palabra que empiece con un número y acabe con el
mismo número y entre los números tenga letras.
echo 'NaN LOL Wow TypeT' | grep -o '\<\([[:upper:]]\)[[:alpha:]]*\1\>'
25
grep encontrará como coincidencias cualquier palabra que empiece con una letra mayúscula y
acabe con la misma letra y entre las letras mayúsculas tenga letras.
echo '0990 5785 5775 6996 ' | grep -o '\([[:digit:]]\)\([[:digit:]]\)\2\1'
grep encontrará como coincidencias cualquier número capicúa de cuatro cifras.
La otra característica interesante es la de poder elegir entre dos patrones distintos usando \| entre
los dos patrones:
echo 'ftp://asdfasf.com http://asfasdf.com' | grep -o '\(ftp\|http\)://[a-z]*\.com'
grep encontrará como coincidencias cualquier palabra que empiece con ftp o http y que continúe
con un conjunto de letras minúsculas y acabe en .com
echo 'ftp://ulises.hostalia.com/debian http://ftp.es.debian.org/debian/' | grep -o '\(ftp\|http\)://[a-z\.-\/]*'
grep encontrará como coincidencias cualquier palabra que empiece con ftp o http y que continúe
con un conjunto de letras minúsculas, puntos, y guiones.
echo 'Yes No Sí No' | grep -o '\(Sí\|Yes\)'
grep encontrará como coincidencias: "Sí" y "Yes".
echo '6hola6 9hola9 5jaja4 5haha5' | grep '\(6\|9\)[[:alpha:]]*\1'
grep encontrará como coincidencias cualquier palabra que empiece con 6 o 9 y que acabe con el
mismo número, con letras en medio.
2.8. Eligiendo el número de repeticiones \{\}
Con los metacarácteres \{\}, poniendo un número o dos entre las llaves se puede elegir el número
de veces que queremos que se repita un patrón.
echo '555 555555 555555 5555555 55 5555' | grep -o '\<5\{6\}\>'
grep encontraría las palabras formadas por exactamente seis cincos.
echo '555 555555 555555 5555555 55 5555' | grep '\<5\{3,6\}\>'
26
grep encontrará las palabras formadas por entre tres y seis cincos.
También las podemos mezclar con otros metacarácteres
echo '555 asd#lha sdf 55hi5 555aASasd55 55 5555' | grep -o '.\{4,11\}'
grep encontrará como coincidencias cualquier palabra con entre 4 y 11 carácteres, el resultado
puede parecer raro, pero la explicación es sencilla: el metacarácter "." significa cualquier carácter,
incluido el espacio, y grep tiende a buscar la palabra más grande que se adapte al patrón.
Así que para conseguir el efecto deseado:
echo '555 asd#lha sdf 55hi5 555aASasd55 55 5555' | grep –o '[[:alnum:]#]\{4,11\}'
Por si lo estaba pensando, con \<\> y el punto tampoco conseguiría el resultado que se buscaba,
ya que el punto seguiría significando cualquier carácter incluido el espacio, compruébelo usted
mismo.
echo 'http://www.esdebian.org/que-haces https://encrypted.google.com/' | grep -o
'https\{0,1\}[[:alnum:]:\/_-.]*'
Como habrá podido comprobar el metacarácter \{\} sólo afecta al elemento más cercano a él,
entonces, ¿cómo aplicarselo a un grupo?. Fácil con \(\).
echo 'http://www.esdebian.org/que-haces www.esdebian.org/que-haces' | grep -o
'\(http://\)\{0,1\}[[:alnum:]\/_-.]*'
2.9. ^ $
Los últimos metacarácteres de este tutorial son ^ y $, estos dos metacarácteres sirven para buscar
coincidencias al principio y al final de una línea respectivamente.
echo 'hola hola hola' | grep '^hola'
grep sólo coincidirá con el primer hola, debido a que es el que está al principio de la línea.
echo 'adios adios adios' | grep 'adios$'
grep sólo coincidirá con el último adios, debido a que es el que está al final de la línea.
27
echo -e "Este es el final del tutorial,\nesperamos que lo haya disfrutado y haya aprendido mucho
sobre las expresiones regulares.\nesDebian" | grep '^[[:alpha:]]*$'
TAIL
tail (que significa cola en inglés) es un programa de los sistemas tipo Unix, que muestra las últimas
líneas de uno o más archivos de texto.
tail imprimirá por defecto a la salida estándar las últimas diez líneas de sus datos de entrada. Tanto
las unidades de impresión (líneas, bloques, bytes) como su número pueden alterarse con opciones
de la línea de comandos:
-n número: imprime el número indicado de líneas.
-c número: imprime el número indicado de bytes.
Si el número indicado en las opciones va precedido por un signo +, tail imprimirá desde la enésima
unidad hasta el final del archivo. Por ejemplo, el comando
tail -c +175 archivo
Imprimirá el contenido de archivo comenzando en el byte 175.
Usando una sintaxis más vieja (que aún se usa en Sun Solaris en lugar de la opción -n), las últimas
20 líneas y los últimos 20 bytes de archivo se mostrarían, respectivamente, con los comandos:
tail -20 archivo
tail -20c archivo
Esta sintaxis, sin embargo, se considera obsoleta y no sigue el estándar POSIX 1003.1-2001. Aun
si las versiones actuales la admiten, podría no funcionar cuando se usa con otras opciones (como -
f, véase la siguiente sección).
Seguimiento de archivos
tail tiene una opción especial, -f (del inglés follow, seguir), que permite hacer seguimiento a un
archivo. En lugar de mostrar las últimas líneas y terminar, tail mostrará las últimas líneas y seguirá
leyendo del archivo; conforme se le añadan nuevas líneas, tail las imprimirá. Esta función es
particularmente útil para archivos de registro.
Para cerrar tail cuando esté haciendo seguimiento, basta interrumpirlo con Ctrl+C.
28
Monitorización de Recursos del Sistema
La mayoría del tiempo de un sysadmin (administrador de sistemas) se la pasa monitoreando.
Especialmente si estas a cargo de muchos servidores necesitas herramientas que te hagan la
tarea mas fácil; a continuación comparto con ustedes herramientas que uso diariamente que me
facilitan mi trabajo.
Monitoreo de ancho de banda
Esto es muy importante, ya que al monitorear cuanto ancho de banda consume un servidor en
tiempo real podemos determinar cuales son sus horas pico y así optimizarlo. Para monitorear esto
recomiendo el programa iptraf. Con este programa podrán monitorear todo lo que esta sucediendo
en nuestra interface de red. Les adjunto algunas imágenes:
29
Monitoreo de consumo de CPU y Memoria
Otra de las tareas de un sysadmin es monitorear el consumo de CPU y Memoria (RAM y SWAP),
linux viene con el comando “top”. A mi en lo personal no me gusta, así que uso el programa htop.
Este programa es muy completo ya que nos detalla el consumo de CPU y Memoria por proceso,
así como el consumo general de los recursos del sistema. Es mucho más amigable a comparación
del top normal. Incluso conforme se va usando el procesador o los núcleos del procesador el
programa lo indica de una manera “gráfica” tal como lo muestra la siguiente imagen que tome de
un servidor en producción:
Monitoreo de consumo de disco duro
Cada cierto tiempo es necesario que entremos a revisar cuando espacio en disco hay libre en los
servidores que manejamos. Para saber el espacio en disco duro se ejecuta el comando “df” en
linux. A mí en lo personal no me gusta, prefiero uno más “amigable” así que utilizo uno llamado
discus. Este programa es que te indica cuanto espacio esta usado y cuando espacio hay libre, así
como los porcentajes de los mismos. Aquí les adjunto una foto con la comparación del “df” con el
“discus”.
Monitoreo del I/O
Para que quede claro que es el I/O.
En computación, entrada/salida, también abreviado E/S o I/O (del original en inglés input/output),
es la colección de interfaces que usan las distintas unidades funcionales (subsistemas) de un
sistema de procesamiento de información para comunicarse unas con otras, o las señales
(información) enviadas a través de esas interfaces. Las entradas son las señales recibidas por la
unidad, mientras que las salidas son las señales enviadas por ésta.
30
En términos mas “amigables” es la entrada y salida de datos, que en realidad significa actividad del
disco duro. Entre mas sea la actividad de READ (lectura) y WRITE (escritura) mas alto va a ser el
I/O y por consiguiente mas lento se pondrá el servidor. Por eso es que para servidores que van a
servir sitios con mucho trafico, recomiendan discos duros SCSI o SAS por su alto rendimiento a
comparación de otros discos duros (como por ejemplo IDE o SATA) por consiguiente su I/O va a
ser menor y va a poder servir data mucho mas rápido.
Para monitorear el I/O yo utilizo la herramienta “iotop” (se necesita python 2.5 y un kernel 2.6.20
para que funcione) es una interfaz simple que indica que proceso esta escribiendo o leyendo en el
disco duro, tal como lo muestra la siguiente imagen:
Monitoreo de peticiones de DNS
Si administras un servidor de DNS, en alguna ocasión vas a querer saber cuantas peticiones tu
servidor de DNS tu servidor recibe. Para monitorear esto utilizo el programa dnstop con este se
puede monitorear cuantas peticiones esta teniendo tu servidor ya sea por clase de dominio .net
.org, direcciones ip, por dominio o por sub dominios.
Para ejecutarlo solo ejecutas el comando:
dnstop eth1
Tienes que especificar la interface en la cual quieres que “escuche” el programa. Presionando los
botones de 1 2 3 4 puedes ver los diferentes tipos de reportes que tiene.
Adjunto imagen del programa:
31
Monitoreo de tráfico WEB
La mayoría de nosotros estamos a cargo de un servidor que sirve paginas web, es muy importante
el monitoreo en tiempo real para saber que archivos estamos sirviendo, cuantas peticiones por
segundo estamos manejando y el trafico que estamos teniendo (en megas). El servidor web mas
usado es apache, yo utilizo la herramienta llamada “apachetop“.
Con este programa podemos monitorear que archivos servimos con mayor frecuencia, cuantos
bytes/kylobytes/megabytes servimos, cuantas peticiones por segundo, peticiones totales y un
promedio general de todo lo que sirve el apache.
Adjunto una imagen del apachetop corriendo en un servidor en producción:
Monitoreo de puertos abiertos
Otra de las tareas de un sysadmin es estar al tanto de que puertos hay abiertos en un servidor.
Como lo dice la regla, si un servicio no te sirve, quitalo del sistema. Para monitorear puertos uso la
herramienta llamada nmap.
32
Con el comando:
nmap -v 127.0.0.1
Saque un listado de puertos abiertos en el servidor. Si su servidor tiene varias direcciones IP es
importante que hagan un escaneo de puertos a todos los IP.
Adjunto imagen del resultado que muestra nmap:
GESTIÓN DE GRUPOS Y USUARIO
1.1 Gestión de Usuarios
Una vez comprendida cómo cambiar los permisos a los usuarios del sistema, es necesario
complementarlo con la gestión de dichos usuarios.
Un administrador de sistemas necesitará crear, modificar, eliminar y gestionar usuarios y
grupos de usuarios a nivel global.
En Linux existe un archivo editable que contiene TODA la información acerca de los
usuarios creados en nuestro sistema. Lógicamente, su configuración se encontrará en el
directorio de configuraciones: /etc
El archivo en cuestión se llama passwd y se localiza en /etc/passwd.
Gran parte de la seguridad de un sistema Linux, viene por el buen uso del archivo
/etc/passwd, ya que es objetivo primario para muchos ataques de crackers. (crackers !=
hackers).
En este archivo, existe una línea que contiene toda la información propia por cada usuario
existente en la máquina, con una sintáxis parecida a esta:
nombre:clave_encriptada:UID:GID:GECOS:directorio_inicial:intérprete
Ej.: alain:x:1000:1000:Alain Fernandez,,,:/home/alain:/bin/bash
33
Cada campo está separado por ‘:‘. El campo ‘nombre‘ indica el alias con el que se loguea
el usuario en el sistema. Seguidamente está la clave encriptada aunque lo que todos
encontraréis seguramente es una ‘x’.
Después nos encontramos con el UID y GID, el primero es el identificador de usuario para
el sistema y el segundo el identificador de grupo primario al que el usuario pertenece,
puesto que un usuario puede pertenecer a muchos grupos.
GECOS es un campo opcional para guardar información. Normalmente contiene el nombre
completo del usuario. GECOS significa General Electric Comprehensive Operating System.
En este campo podemos poner lo que queramos ya que el sistema no lo usa para ninguna
gestión. Se puede omitir sin poner entre los ‘:’ nada, quedando ‘::’.
Posteriormente aparece el directorio inicial es donde empezará el usuario una vez
logueado, y seguidamente el interprete de comandos usará (bash, sh, tcsh…).
Si en el campo intérprete encontramos ‘/sbin/nologin’ es un usuario que no puede
loguearse, esto tiene sentido ya que el propio sistema tiene usuarios con privilegios para
dar servicios al sistema como pueden ser ‘bin’, ‘daemon’, ‘adm’…
El usuario root siempre tiene como UID y como GID un ’0′, y cualquier usuario que lo tenga
tendrá los mismos privilegios que él. Hay que recordar que un usuario sólo puede tener un
UID, pero varios usuarios pueden tener el mismo UID.
PELIGRO: Algo totalmente desaconsejable, debido a que puede provocar agujeros de
seguridad importantes, es tener algún usuario con UID=0 distinto al root. Si esto ocurre, lo
más seguro es que hayas sido atacado.
Normalmente el sistema guarda los UID bajos (por ejemplo por debajo de 500 o por debajo
de 1000) para los usuarios del propio sistema, los que necesita para los servicios que
ofrece (por ejemplo, si tienes un servidor de ftp lo normal es tener un usuario en el sistema
que se llame ‘ftp’), y los UID altos se utilizan para los usuarios normales.
PELIGRO: Si donde debiera aparecer la clave aparece ‘::’, esto indica que no hay clave,
y por supuesto, no es nada bueno. Si aparece una ‘x’ es que las claves o la clave de ese
usuario están gestionadas en el archivo /etc/shadow ya que la mayoría de los sistemas
usan “claves en sombra”.
34
Esto es debido a que /etc/passwd debe ser visible a todos, porque si no ciertos comandos
como puede ser ‘ls’ dejarían de funcionar, y aunque la clave está encriptada no es bueno
que se encuentre a la vista por la existencia de programas de fuerza bruta que se dedican
a desencriptarlas (el famoso ‘jhon deriper‘ por ejemplo), y cualquier usuario con acceso a
nuestro sistema tendría las claves usando dichos programas.
En vez de esto se usa el fichero /etc/shadow, que sólo es visible por root.
No es aconsejable ‘jugar’ con esta información editanto y retocando directamente dichos
archivos. Para ello existen distintas herramientas que nos ayudarán a gestionar los
usuarios y grupos.
1.2 Añadiendo usuarios
Utilizaremos el comando adduser o useradd, desde nuestro interprete de comandos y
siendo administrador, root, para añadir usuarios.
Normalmente bastará con la orden adduser nombre_usuario para crear nuevos usuarios,
aunque su sintáxis completa será:
addusr [-c comentario] [-d home] [-e fecha] [-f dias] [-g grupo] [-G lista de grupos] [-m
[-k template] | -M] [-n] [-o] [-p passwd] [-r][-s shell] [-u uid] usuario
Podremos ‘ahorrarnos‘ muchas de las opciones, ya que, si no indicamos nada el ‘home’ del
usuario se creará por defecto en ‘/home/nombre_del_usuario’, con la estructura del
‘/etc/skel’.
Este, será un usuario indefinido y no se bloqueará por no usarse, tendrá la shell por
defecto (normalmente bash), se le asignará un uid automaticamente y se creará un grupo
con el mismo nombre.
Normalmente usaremos la forma sencilla:
[debian:/home/alain]# adduser pepito
Adding user `pepito’ …
Adding new group `pepito’ (1001) …
Adding new user `pepito’ (1001) with group `pepito’ …
Creating home directory `/home/pepito’ …
Copying files from `/etc/skel’ …
Enter new UNIX password:
35
Si preferimos personalizar o forzar algín campo, utilizaremos la sintáxis completa:
addusr [-c comentario] [-d home] [-e fecha] [-f dias] [-g grupo] [-G lista de grupos] [-m
[-k template] | -M] [-n] [-o] [-p passwd] [-r][-s shell] [-u uid] usuario
Donde:
[-c comentario]: Pondremos el comentario que queremos en el campo GECOS.
[-d home]: Directorio home (el de inicio) de la cuenta.
[-e fecha]: fecha en formato año-mes-día en que la cuenta caduca y se bloquea.
[-f dias]: Número de días en los que la cuenta se bloqueará si no se usa.
[-g grupo]: Nombre del grupo primario. Ojo el grupo debe ya existir.
[-G lista de grupos]: Listado de grupos al que el usuario pertenecerá.
[-m [-k template] | -M] -m: Crea el directorio home de la cuenta si es que no existe ya. Con
-k usa el directorio template para crear el directorio home o sea que copia lo de template al
home, en caso contrario se copia /etc/skel. Si en vez de -m ponemos -M el directorio no es
creado.
[-n]: Añade un grupo con el mismo nombre que el usuario
[-o]: Permite crear usuarios con uid duplicada.
[-p passwd]: Añade el password al usuario.
[-r]: Se usa para crear un usuario del sistema.
[-s shell]: Indica que shell
[-u uid]: Indicamos que uid queremos.
Para saber más…
36
[alain@debian]$ man adduser
NOTA: Podemos modificar la estructura del /home del usuario, modificando el /etc/skell
del sistema.
1.3 Modificando usuarios
Como comentamos anteriormente, existen herramientas para evitar modificar el archivo
/etc/passwd ‘a mano’. El comando usermod nos permitirá hacer estos cambios de esta
manera:
usermod [-c comentario] [-d home] [-e fecha] [-f dias] [-g grupo] [-G lista de grupos] [-
m] [-n] [-p passwd] [-s shell] [-u uid [-o] ] usuario [-L | -U] usuario
El significado de los parámetros es el mismo que en el anterior comando, así que no
necesitan explicación, salvo dos nuevos:
-L Bloquea la cuenta de
usuario.
-U La desbloquea.
Cambiaremos por ejemplo una contraseña así:
[debian:/home/alain]# usermod -p nueva_clave pepito
Y bloquearemos la cuenta de ‘pepito’ de estemodo:
[debian:/home/alain]# usermod -L pepito
Para saber más…
[alain@debian]$ oman usermod
NOTA: Un usuario puede cambiarse su propia contraseña utilizando la orden passwd. No
hace falta molestar al administrador del sistema para esto.
37
[alain@debian]$ passwd
Changing password for alain
(current) UNIX password:
1.4 Eliminando usuarios:
Llegó el momento de eliminar usuarios que ya no pintan nada ennuestro sistema. Ya es
sabido por todos que es mucho más fácil destruir que crear. En este caso bastará con
aplicar el comando deluser o userdel.
[debian:/home/alain]# deluser -R pepito
Con la opción ‘-R’ eliminará el directorio home del usuario; sin esta opción se limitará a
eliminar únicamente la cuenta de usuario, dejando el home intacto.
[alain@debian]$ man deluser
1.5 Añadiendo nuevos grupos:
Ahora toca administrar los grupos de usuarios. Cada usuario pertenece como mínimo a un
grupo, (su grupo principal de usuario), aunque podrá pertenecer a varios grupos más.
Existen ciertos grupos del sistema, tales como grupo root, grupo bin… y por lo general,
salvo raras excepciones, los usuarios nunca deben pertenecer a ninguno de esos grupos.
Para los grupos existe igualmente un archivo de configuración /etc/group, al que por
supuesto debemos proteger y cuidar como hacemos con /etc/passwd.
El fichero de shadow para los grupos es ‘/etc/gshadow‘, e igual que en los usuarios sólo
es accesible por el root.
El formato de ‘/etc/group’ es el siguiente:
nombre_grupo:clave:GID:lista de usuarios miembros
38
Aunque en el campo clave aparezca una ‘x’ al igual que pasaba con /etc/passwd, no quiere
decir que cada grupo tenga una clave. Si miramos el archivo /etc/gshadow veremos que
casi todos los campos están vacíos, es decir, no existe ninguna clave.
Para añadir un grupo utilizaremos el comando addgroup o groupadd. Al igual que
anteriormente, existirá el modo ‘rápido’ y el modo ‘personalizado’.
Modo rápido:
[debian:/home/alain]# addgroup migrupo
Adding group `migrupo’ (GID 1002) …
Hecho.
Modo personalizado:
groupadd [-g gid [-o]] [-r] [-f] [nombre del grupo]
Donde:
-g indica explícitamente el GID del grupo.
-o no obliga a que el identificador de grupo sea único, cosa totalmente desaconsejable.
-r para crear un grupo del sistema.
-f hace que groupadd no de error si el grupo ya existe.
[alain@debian]$man groupadd
1.6 Modificando grupos:
Llegará el mometo de que surja la necesidad de modificar algún grupo existente.
Utilizaremos para ello el comando modgroup:
groupmod [-g gid [-o]] [-n group_name ] [nombre-del-grupo]
Vamos a cambiar el nombre del grupo ‘tarde’ a grupo ‘noche’:
[debian:/home/alain]# groupmod -n tarde noche
groupadd noche
39
[alain@debian]$ man groupmod
1.7 Eliminando grupos:
Por último, vamos a ver como se eliminan los grupos deusuarios que ya no necesitamos.
Utilizaremos para ello el comando groupdel o delgroup:
[debian:/home/alain]# groupdel noche
Para saber más…
[alain@debian]$ man groupdel
1.8 Cómo cambiar de propietario y grupo a nuestros ficheros:
Queda ahora conocer como hacer propietario de un archivo o directorio a un usuario, o
hacer que este fichero sea propiedad de un grupo.
Para ello existen los comandos chown y chgrp.
El primero cambia de propietario a un fichero existente de esta forma:
[chown] [usuario] [archivo]
Si por ejemplo tenemos un fichero llamado ‘prueba.sh’ propiedad de ‘alain’:
[debian:/home/alain]# ls -l |grep prueba.sh
-rw-r–r– 1 alain alain 2 2008-04-10 15:41 prueba.sh
y queremos que su propietario pase a ser ‘root’, haremos:
[debian:/home/alain]# chown root prueba.sh
Vemos el resultado…
[debian:/home/alain]# ls -l |grep prueba.sh
-rw-r–r– 1 root alain 2 2008-04-10 15:41 prueba.sh
Si queremos aplicar esto a directorios, simplemente añadiremos la opción ‘-R‘ para que lo
haga de modo recursivo:
[chown] -R [usuario] [directorio]
Para saber más…
[alain@debian]$ man chown
Para cambiar de grupo a un fichero utilizaremos el comando “chgrp” de este modo:
40
[chgrp] [grupo] [archivo]
Si por ejemplo tenemos un fichero llamado ‘prueba.sh’ perteneciente al grupo ‘alain’:
[debian:/home/alain]# ls -l |grep prueba.sh
-rw-r–r– 1 root alain 2 2008-04-10 15:41 prueba.sh
y queremos que su grupo principal sea ‘root’, haremos:
[debian:/home/alain]# chgrp root prueba.sh
Vemos el resultado…
[debian:/home/alain]# ls -l |grep prueba.sh
-rw-r–r– 1 root root 2 2008-04-10 15:41 prueba.sh
Al igual que antes, añadiremos la opción ‘-R‘ para que lo haga de modo recursivo:
[chgrp] -R [grupo] [directorio]
Para saber más…
[alain@debian]$ man chgrp
PERMISOS
1.1 Política de permisos en Linux
Linux es un sistema multiusuario, por lo que necesita de una política de permisos segura y
planificada para mantener el sistema seguro.
Un administrador de sistemas Linux debe prestar mucha atención y planificar dicha política
de permisos para mantener su sistema seguro.
Podemos hacernos una primera idea de cómo se gestionan los permisos en Linux,
haciendo un ‘ls -l’ desde nuestro intérprete de comandos:
41
[alain@debian]$ ls -l
total 284
drwxr-xr-x 5 alain alain 4096 2007-11-26 17:38 2006r3
drwxr-xr-x 5 root root 4096 2007-09-17 15:48 Alain_LIVE
drwxr-xr-x 3 alain alain 4096 2007-04-02 11:38 Beryl
drwxr-xr-x 2 alain alain 4096 2007-12-14 15:05 bin
-rw-r–r– 1 alain alain 16548 2008-04-03 15:07 CELIA-DSL.odt
drwxr-xr-x 1 alain alain 4096 2008-03-27 14:03 COMOs
drwx—— 3 alain alain 4096 2008-04-07 15:02 curso-ASL
-rw-r–r– 1 alain alain 9490 2008-04-07 13:44 Curso-ASOL.odt
Como vemos, cada línea tiene un formato del estilo:
{T} {rwx} {rwx} {rwx} {N} {usuario} {grupo} {tamaño} {fecha de creación}{nombre}
1er campo T: Nos indica que tipo de archivo es:
- Si es un fichero normal
d Si es un directorio
c Especial de modo carácter (Dispositivo tty, impresora…)
p Pipe
l Enlace simbólico
2º Campo: {rwx}: Nos indica los permisos que tiene el propietario del archivo.
3º Campo {rwx}: Nos indica los permisos que tiene el grupo al que pertenece el archivo.
4º Campo {rwx}: Nos indica los permisos del resto de usuarios. (Otros)
5º Campo {N}: Es el número de archivos/directorios que contiene. Si es un fichero
aparecerá 1, si se trata de un directorio aparecerá como mínimo 2 (los directorios ‘.’ y ‘..’
más los que contenga).
6º Campo {usuario}: Indica el nombre del usuario al que pertenece el archivo o directorio.
7º Campo {grupo}: Indica el nombre del grupo al que pertenece el archivo o directorio.
8º Campo {tamaño}: Indica el tamaño.
9º Campo {fecha}: Indica la fecha de creación.
10º Campo {nombre}: Indica su nombre.
Los grupos de permisos se agrupan de 3 en 3: rwx, donde (r) significa permiso de lectura,
(w) permiso de escritura y (x) permisos de ejecución.
Por lo tanto un fichero con esta apariencia:
rwx r-x —
Significa que tendrá permisos de lectura, escritura y ejecución para el propietario, permisos
de lectura y ejecución para el grupo, y ningún permiso para el resto.
42
PERMISOS SIGNIFICADO
rwx rwx rwx Permiso para todos (Muy poco seguro, para archivos sin importancia)
rwx r– — Todos los permisos para el propietario y solo de lectura para el grupo.
r-x — — Sólo lectuta y ejecución para el propietario.
Si nos fijamos en el directorio donde comentamos que estaban los binarios (ejecutables)
comunes para todos los usuarios del sistema, directorio /bin, y pedimos un listado con ‘ls -l’
observaremos que todos los binarios tienen una sintaxis como esta:
-rwxr-xr-x 1 root root 3518 2006-09-19 14:38 znew
Todos los binarios son propiedad del root, y el resto de usuarios (nosotros) únicamente
podemos leer su contenido y ejecutarlo, algo bastante lógico y seguro, ¿no? Sería poco
serio si cualquier usuario pudiese modificar la funcionalidad de este comando.
Que pasaría si a un archivo ejecutable del directorio /bin le diésemos los siguientes
permisos:
-rwxr-x–x 1 root root 3518 2006-09-19 14:38 znew
Un usuario cualquiera (excepto root) teóricamente debería poder ejecutarlo, sin embargo,
necesita leerlo para interpretarlo (cosa que tiene prohibida), por lo tanto no se ejecutaría.
¿Qué pasaría en este otro caso?
-rwxr-xr– 1 root root 3518 2006-09-19 14:38 znew
Como usuario normal podríamos leer su contenido, pero tampoco podríamos ejecutarlo, ya
que carece de permisos de ejecución
1.2 Los permisos en decimal
1.3
Como ya hemos comentado, la operación de administrar una política de seguridad en Linux
es una tarea fundamental para un administrador de sistemas.
La única persona que puede cambiar los permisos de un archivo o directorio es su
propietario. No hace falta decir, que el root podrá cambiar los permisos de cualquier otro
usuario del sistema.
Para calcular el valor de un permiso nos basaremos en la sumas de sus valores decimales
según esta correspondencia:
r w x Permiso
43
4 2 1 Valor
Decimal
Por lo tanto los posibles valores para un permiso serán:
Permisos Valor
rwx 7
rw- 6
r-x 5
r– 4
-wx 3
-w- 2
–r 1
— 0
Lo anterior, aplicado a un fichero que agrupa los permisos en 3 grupos (propietario, grupo y
otros), resultaría así.
rwx r-x —
7 5 0
Por lo tanto,
PERMISO VALOR
rwx rwx rwx 777
rwx r-x r– 754
r-x r– – 540
Teniendo claro esto, ya podemos administrar permisos de forma sencilla utilizando el
comando chmod.
44
1.4 Cambiando permisos con chmod
Lo más habitual es utilizar el comando chmod para administrar permisos, del siguiente
modo:
[chmod] [modo] [permisos] [fichero/s]
Como modo sólo veremos el modo ‘-R’, para cambiar los permisos de un modo recursivo
dentro de los directorios.
[alain@debian]$ chmod -R 755 mi_directorio
[alain@debian]$ ls -l
[alain@debian]$
drwxr-xr-x 2 alain alain 4096 2007-07-13 13:57 mi_directorio
Otra manera de añadir o quitar permisos, será utilizando estos modos:
a Indica que se aplicará a todos.(all)
u Indica que se aplicará al usuario.(user)
g Indica que se aplicará al grupo.(group)
o Indica que se aplicará a otros.(other)
+ Indica que se añade el permiso.
- Indica que se quita el permiso.
r Indica permiso de lectura.
w Indica permiso de escritura.
x Indica permiso de ejecución.
La manera de aplicar este nuevo método será:
(A quién se aplica) +/ – (Qué permisos aplica)
Aplicando lo anterior, resultarían estas posibles combinaciones:
a+r Permisos de lectura para todos.
+r Igual que antes, si no se indica nada se supone ‘a’.
og-x Quita permiso de ejecución a todos menos al usuario.
u+rwx Da todos los permisos al usuario.
o-rwx Quita los permisos a los otros.
Aplicaremos ‘-R’ (modo recursivo) cuando se trate de directorios:
45
[alain@debian]$ chmod -R o-rx mi_directorio
[alain@debian]$ ls -l
[alain@debian]$
drwxr-x— 2 alain alain 4096 2007-07-13 13:57 mi_directorio
Con estos conceptos básicos ya podremos administrar los permisos de los usuarios de
nuestros sistemas. El comando ‘chmod’ tiene multiples opciones, recordad la existencia del
comando ‘man’ para conocer más:
[alain@debian]$ man chmod
TRABAJO CON QUOTAS
Sistemas Linux con gran cantidad de usuarios, como servidores de correo, servidores samba, etc.,
tarde o temprano tienen el problema de usuarios que almacenan demasiada información en sus
directorios de trabajo, pudiendo incluso en casos extremos llenar completamente discos duros
haciendo el sistema inservible.
Con el uso de cuotas de disco (disk quotas) es posible limitar la cantidad de espacio disponible
para cada usuario o de manera global para todos. En este manual de LinuxTotal.com.mx
conocerás a fondo como implementar y administrar cuotas de disco para control de los usuarios.
Tipos de cuota
Por Bloques (blocks): Un bloque corresponde a 1 kb y una cuota por bloques correspondería al
total de bloques que un usuario puede utilizar en el sistema. Recuerda que los archivos se guardan
en bloques de disco. Asi un archivo de 100 bytes, ocupará un un bloque de 1kb en el disco duro.
Por Inodos (inodes): Un inodo o inode en inglés (Index Node) es un número que actua como
apuntador para el sistema de archivos de Linux y le indica en que bloques específicos del disco
duro se encuentran los datos de un archivo. También el inodo en su referencia guarda información
sobre permisos, propietario, atributos, etc. Se podría ver en una analogía simple que un inodo es
como un número de serie único para cada archivo del sistema y a través de este número el sistema
recupera sus datos (bloques) y sus atributos (permisos, propietario, fechas, etc.).
En el caso de las cutoas, una cuota por inodos indicaría el total de indos a los que el usuario tiene
derecho, casi representaría el total de archivos que el usuario puede crear y digo "casi" porque los
46
usuarios podemos crear enlaces simbólicos (ln -s) sobre archivos ya existentes que no aumentan
las cantidad de inodos. Pero por simplicidad puedes verlo como un 1 inodo = 1 archivo.
Límites
Tanto las cuotas por bloques o por inodos, tienen límites de uso y son de dos tipos:
HARD: (Duro) Cuando se establece (para bloques o inodos), es el límite absoluto. El usuario no
podrá exceder este límite.
SOFT: (Suave) Este límite (para bloques o inodos) que es siempre menor al HARD, puede ser
excedido por el usuario, pero será constantemente advertido que el límite de uso para bloques o
inodos ya ha sido excedido. Podría verse como un límite de advertencia que le estará indicando al
usuario que su límite ya se excedió y tome medidas.
Cuando se usa el límite SOFT, dos situaciones pueden ocurrir. La primera es que NO se tenga
establecido un tiempo de gracia, y entonces el usuario podrá seguir usando bloques o inodos hasta
llegar al límite HARD que será su límite absoluto de uso.
La segunda situación es que SI se tenga establecido el tiempo de gracia, que puede ser en días,
horas, minutos o segundos. En este caso, el usuario podrá seguir usando bloques o inodos hasta
que termine el tiempo de gracía o llegue al límite HARD, cualquiera que ocurra primero.
El tiempo de gracias se puede establecer por usuario o globalmente y más adelante veremos como
establecerlo.
¿Donde se implementan?
Las cuotas se establecen por filesystem o sistema de archivos, es decir, debes de decidir en donde
es más conveniente instalar un sistema de cuotas, pero no hay ningún problema si se instala en
todos. Las cuotas pueden establecerse por usuario, por grupos o ambos. En el siguiente ejemplo:
#> mount
/dev/sda1 on /boot type ext3 (rw,noatime)
/dev/sda2 on / type ext3 (rw,noatime)
/dev/sda3 on /home type ext3 (rw,noatime)
none on /proc type proc (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
47
Lo anterior es un ejemplo típico de un equipo Linux con varios sistemas de archivos (/boot, / y
/home). Como se sabe en /home es donde los usuarios tienen sus directorios de trabajo (HOME),
asi que solo en este sistema de archivos crearemos cuotas, en los otros dos no tiene caso.
Configuración
Todo debe hacerse como root, y lo primero que haremos es editar el archivo "/etc/fstab" y
añadiremos "usrquota" o "grpquota", dependiendo si se desea cuotas por usuario o grupos, o
incluso ambas.
#> vi /etc/fstab
/dev/sda2 / ext3 noatime 1 1
/dev/sda1 /boot ext3 noatime 1 2
/dev/sda3 /home ext3 noatime 1 2
....
(Añadimos en la cuarta columna el tipo de cuotas que deseamos)
/dev/sda2 / ext3 noatime 1 1
/dev/sda1 /boot ext3 noatime 1 2
/dev/sda3 /home ext3 noatime,usrquota,grpquota 1 2
...
Algo similar a lo anterior deberá tener tu archivo de configuración, y como ya se indicó solo
agregamos el soporte para cuotas en el sistema de archivos que nos interese. Lo anterior por si
solo, es obvio que no hace nada, habría que reiniciar el sistema para que se apliquen los cambios
pero realmente no es necesario, lo siguiente re-monta el sistema de archivos "/home":
#> mount -o remount /home
#> mount
/dev/sda1 on /boot type ext3 (rw,noatime)
/dev/sda2 on / type ext3 (rw,noatime)
/dev/sda3 on /home type ext3 (rw,noatime,usrquota,grpquota)
none on /proc type proc (rw)
El sistema de archivos "/home" esta listo ahora para soportar cuotas de disco. El siguiente paso es
verificar con el comando quotacheck por sistemas de archivos que soporten cuotas. Este comando
crea, verifica o repara el control de cuotas en los sistemas que lo soporten, en este caso creara el
soporte:
#> quotacheck -augmv
48
quotacheck: Scanning /dev/sda3 [/home] done
quotacheck: Cannot stat old user quota file: No existe el fichero o el directorio
quotacheck: Cannot stat old group quota file: No existe el fichero o el directorio
quotacheck: Cannot stat old user quota file: No existe el fichero o el directorio
quotacheck: Cannot stat old group quota file: No existe el fichero o el directorio
quotacheck: Checked 2539 directories and 35556 files
quotacheck: Old file not found.
quotacheck: Old file not found.
Los errores que envía es precisamente porque no existía un sistema de cuotas previo, es normal
que los envíe. Cuando las cuotas esten en pleno uso, es conveniente ejecutar quotacheck
periódicamente para que verifique inconsistencias y se corrijan a tiempo. En cuanto a las opciones
estas indican lo siguiente:
a - all, es decir verifica todos los sistemas de archivos por cuotas.
u - user, verifica por soporte de cuotas para usuarios.
g - group, verifica por soporte de cuotas para grupos.
m - no-remount, evita que el sistema se remonte como de solo lectura.
v - verboso, reporta lo que hace conforme progresa, son los mensajes que salen a la
terminal.
Como ves, la opción -a en este caso no era necesario puesto que solo tenemos "/home" con
cuotas, asi que el comando anterior también pudiera ser invocado de esta manera:
#> quotacheck -ugmv /home
Pues el sistema esta listo para manipular cuotas de usuario, esto lo podemos comprobar porque en
la raíz del sistema de archivos soportado con cuotas deben existir los archivos "aquota.user" y
"aquota.group" que son binarios, no trates de modifiAlain o manipularlos:
#> cd /home
#> ls -l
total 72
-rw------- 1 root root 8192 2008-05-17 21:38 aquota.group
-rw------- 1 root root 8192 2008-05-17 21:38 aquota.user
drwx--x--x 4 user1 user1 4096 2008-05-12 16:13 user1/
drwx--x--x 4 user2 user2 4096 2008-05-12 16:13 user2/
drwx--x--x 3 user3 user3 4096 2008-05-05 12:01 user3/
49
drwx--x--x 3 user4 user4 4096 2008-05-05 12:01 user4/
(Obsérvese los dos archivos de control de cuotas, para usuarios y grupos)
Si se tuvieran más sistemas de archivos con soporte para cuotas en la raíz de cada uno estarían
estos archivos, o solo uno dependiendo lo que se pidió, usuarios, grupos o ambos. Por cierto, en
sistemas con kernel 2.2 o anterior se usaba la versión 1 de cuotas y sus archivos de control se
nombraban "quota.user" y "quota.group", del kernel 2.4 y posteriores con la versión 2 y 3, se utiliza
los mostrados anteriormente.
Ahora bien, lo anterior deja listo el sistema para el soporte de cuotas pero estás siguen sin ser
activadas se requiere activar el soporte de cuotas, para lo cual invocamos el comando quotaon:
#> quotaon -ugv /home
/dev/sda3 [/home]: group quotas turned on
/dev/sda3 [/home]: user quotas turned on
Activamos para "/home" cuotas de usuario y grupos. Cuando por alguna razón sea necesario
desactivar las cuotas, entonces utiliza la contraparte, que es el comando quotaoff:
#> quotaoff -v /home
/dev/sda3 [/home]: group quotas turned off
/dev/sda3 [/home]: user quotas turned off
Muy bien, hasta aqui ya tienes el sistema de archivos "/home" o el que hayas elegido (o todos)
para trabajar con soporte de cuotas para los usuarios y grupos, ahora veremos como aplicar estas
cuotas con los usuarios.
Aplicando la cuota a usuarios
Ahora hay que aplicar la cuota por usuario, aunque el sistema de archivos ya soporta cuotas y
están habilitadas, por defecto ningún usuario tiene establecidas cuotas. Asi que para iniciar habrá
que administrar cada usuario a través del comando edquota, que abrirá el editor de texto que se
tenga por defecto y mostrará lo siguiente:
#> edquota -u user1
Disk quotas for user user1 (uid 502):
Filesystem blocks soft hard inodes soft hard
/dev/sda3 56 0 0 14 0 0
50
Las columnas "blocks" e "inodes" son informativas, es decir nos indican la cantidad de bloques o
inodos utilizados actualmente por el usuario, y las que podemos editar son las columnas "soft" y
"hard" de cada caso. Como ya se explicó en la primera parte de este artículo, se puede indicar
libremente cualquiera de los cuatro valores, es perfectamente posible establecer valores por
bloques, por inodos o ambos, solo recuerda que el límite soft debe ser menor al hard.
Si se establece solo el hard, no habrá advertencias previas y el usuario ya no podrá guardar
archivos cuando se llegue al valor. Si se establece soft y hard, avisará cuando se rebase el límite
soft y entrará en juego el periodo de gracia. Si se acaba el tiempo de gracias o se llega al har (lo
que sea primero) ya no se podrán crear más archivos hasta que no se eliminen algunos de los que
se tengan actualmente.
Para modificar cuotas a nivel grupo, se usa el mismo comando pero con la opción -g (edquota -g
ventas).
En el ejemplo previo se modifica la cuota del usuario "user1" en el sistema de archivos "/home" que
es el que se ha usado de ejemplo en este artículo de LinuxTotal.com.mx, el comportamiento por
default es modificar cuotas para ese usuario en todos los sistemas de archivos que tengan activo el
control de cuotas (quotaon). Si se desea control de cuotas para un filesystem en específico
entonces se agrega la opción -f:
#> edquota -u user1 -f /home
(solo aplica la cuota en el sistema de archivos indicado)
Verificando el uso de las cuotas
Como usuario administrador 'root' puedes ver el uso de cuotas de cualquier usuario, ya sea
individualmente o por medio de un reporte global.
Por usuario o individualmente se usa el comando quota, estando como "root":
#> quota -u user1
Disk quotas for user user1 (uid 502):
Filesystem blocks quota limit grace files quota limit grace
/dev/sda3 56 70 100 14 0 0
Con usuarios que manejan cantidades muy grandes de cuota, es un poco dificil calcular en
términos de megas o gigas el espacio usuado y los límites de cuotas:
#> quota -u sergio
51
Disk quotas for user sergio (uid 500):
Filesystem blocks quota limit grace files quota limit grace
/dev/sda3 42578888 0 50000000 34895 0 0
Usando la opción -s se mejora el informe:
#> quota -s -u sergon
Disk quotas for user sergon (uid 500):
Filesystem blocks quota limit grace files quota limit grace
/dev/sda3 41582M 0 48829M 34905 0 0
Como usuario individual del sistema, puedes observar tus cuotas con el mismo comando quota, sin
argumentos.
Ahora bien, si se desea un reporte global de las cuotas de todos los usuarios o por grupos, siendo
"root" utiliza el comando repquota:
#> repquota /home
*** Report for user quotas on device /dev/sda3
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 184280 0 0 11 0 0
sergio -- 42579852 0 50000000 34902 0 0
user1 -- 56 70 100 14 0 0
user2 -- 52 0 0 13 0 0
user3 -- 28 0 0 7 0 0
user4 -- 28 0 0 7 0 0
Con repquota es también posible utilizar la opción -s para observar los tamaños en formato legible.
Si se usa la opción -a (all) en vez del sistema de archivos "/home", el reporte será para todos los
sistemas de archivos en el equipo que soporten cuotas. Asi mismo este reporte por defecto es por
usuarios, si se requiere que repquota reporte por grupos, añade entonces la opción -g.
52
Obsérvese en la segunda línea del reporte el tiempo de gracia (grace time), que es de 7 días tanto
para cuotas por bloque como para cuotas por archivos o inodos. Esto aplica para todos los
usuarios en global, como se aprecia en el listado que ninguno tiene establecido un tiempo de
gracia diferente al global.
Estableciendo el tiempo de gracia
A nivel global, un periodo de gracia para todos, utiliza la opción -t del comando edquota, como en
el siguiente ejemplo, recuerda que debes ser "root":
#> edquota -t
Grace period before enforcing soft limits for users:
Time units may be: days, hours, minutes, or seconds
Filesystem Block grace period Inode grace period
/dev/sda3 7days 7days
7 días es el periodo por defecto, si lo cambias a digamos 12 horas, sería "12hours". El tiempo de
gracia puede ser distinto para el límite soft por bloques o por inodos.
Por usuario específico se realiza con la opción -T del mismo comando e indicando el usuario:
#> edquota -u user1 -T
Times to enforce softlimit for user user1 (uid 502):
Time units may be: days, hours, minutes, or seconds
Filesystem block grace inode grace
/dev/sda3 unset unset
Lo único que hay que considerar es que los tiempos de gracias por usuario deben ser menores al
global. Y que este empieza a correr una vez que se ha llegado al límite soft. Cuando esto suceda,
si entras a editar de nuevo el tiempo de gracia del usuario (edquota -u user -T) se reflejara en
segundos el tiempo que le queda, pudiéndolo aumentar de nuevo si eres "root". O dejarlo en cero y
entonces el global será el que se utilice.
Fijar cuotas de manera global a todos los usuarios
En sistemas Linux con pocos usuarios, establecer las cuotas usuario por usuario no representa
ningún problema. Pero si hablamos por ejemplo de una universidad donde pudieran existir miles de
cuentas entonces si es un problema establecer cuentas individualmente. Realmente no existe una
53
manera "oficial" de establecer cuotas masivamente, sin embargo, no hay problema, usaremos un
pequeño script que te permitira realizarlo.
Establece la cuota que deseas globalmente en un solo usuario:
#> edquota -u user1
Disk quotas for user user1 (uid 502):
Filesystem blocks soft hard inodes soft hard
/dev/sda3 68 300 400 17 0 0
:wq
Veamos el reporte de cuotas con repquota:
[root@segolap ~]# repquota /home
*** Report for user quotas on device /dev/sda3
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
user1 -- 68 300 400 17 0 0
user2 -- 352 0 0 13 0 0
user3 -- 28 0 0 7 0 0
user4 -- 28 0 0 7 0 0
Solo el usuario "user1" tiene cuotas, las columnas de "grace" tendrán valores una vez que se
llegue al límite soft o suave. Usaremos entonces la opción -p (protptype) para hacer duplicados a
partir del ya establecido.
#> edquota -p user1 user2
Con lo anterior "copias" la información de límites de cuotas del "user1" al "user2", no hay límite de
cuantos usuarios puedes colocar como argumentos asi que lo siguiente es válido:
#> edquota -p user1 user2 user3 user4
Práctico para unos cuantos usuarios pero inútil si necesitamos duplicarlo en cientos de usuarios,
asi que hagamos un comando compuesto que nos extraiga los nombres de los usuarios, se puede
usar por ejemplo gawk para realizar lo anterior:
54
#> gawk -F: '$3 > 499 {print $1}' /etc/passwd
user1
user2
user3
user4
Usamos el separador ":" de campos (-F), e indicamos como acción que en el campo 3 ($3)
busquemos todos los UID mayores a 499 y que los imprima ({print $1}). Ahora solo tenemos que
usar este comando junto con edquota -p:
#> edquota -p user1 `gawk -F: '$3 > 499 {print $1}' /etc/passwd`
(Importante: nota el uso de acento grave que abarca al comando gawk, esto para que el shell lo
ejecute primero y el resultado serán los argumentos, uno o cientos de usuarios cuyo UID es mayor
a 499)
Haciendo uso de repquota de nuevo veamos que pasó:
#> repquota /home
*** Report for user quotas on device /dev/sda3
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
user1 -- 68 300 400 17 0 0
user2 -- 352 300 400 7days 13 0 0
user3 -- 28 300 400 7 0 0
user4 -- 28 300 400 7 0 0
Primero, todos los usuarios tienen las mismas cuotas que el "user1" que fue el prototipo para los
demás y segundo se observa que el "usuario" que tiene 352 bloques utilizados al pasar el límite
suave entro al periodo de gracia automáticamente que el global es de 7 días. A partir del instante
que el límite cambió de 0 a 300, comenzó el periodo de gracia. Ahora solo podrá crear más
archivos durante 7 días o cuando llegue a 400, lo primero que ocurra, claro, asumiendo que no
borre archivos primeros para recuperar espacio.
55
Avisos de cuotas excedidas (warnquota)
Cuando un usuario llega al límite suave o soft al crear o modificar un documento, algo como lo
siguiente aaprecerá:
user2> ls -l > directorio.txt
sda3: warning, user block quota exceeded.
En este instante como el "user2" no ha llegado al límite "hard" ni ha expirado el tiempo de gracia, el
sistema permite crear el archivo pero se le notifica con un warning.
Pero si lo que deseamos es notificar inmediatamente y via correo electrónico que un usuario llego
a su límite, por ejemplo, un server de correo electrónico, un usuario que ha recibido spam y esta
saturando su cuenta, puede ser notificado que su couta esta llegando al límite.
Para lo anterior usaremos el comando warnquota. Este comando simplemente invócalo desde la
línea de comandos, sin argumentos, revisará los sistemas de archivos con cuotas activadas
(quotaon) y revisará todos los usuarios buscando quien ha excedido el límite soft tanto por bloques
como por inodos, y a aquellos que lo hayan excedido les enviará un correo notifícandoles de lo
anterior.
Puedes agregar en cron una línea como la siguiente para que warnquota haga su trabajo cada 12
horas:
#> vi /etc/crontab
...
0 0,12 * * * root /usr/sbin/warnquota
...
warnquota viene con los mensajes en inglés por defecto, el archivo de configuración es
"/etc/warnquota.conf", es muy intuitivo y fácil de cambiar, personalízalo con los mensajes a español
para que sea más fácil entender a tus usuarios que han excedido sus cuotas.
EDITORES DE TEXTO
Vi
Funcionamiento general
Al invocar este editor aparece en el monitor la pantalla de edición. En ella aparece la posición
del cursor resaltada, las líneas en blanco señaladas con el carácter ~ y en la parte inferior de la
56
pantalla aparece la línea de estado, que muestra el nombre del fichero y el número de
caracteres que contiene.
Si se invoca el vi pasándole como parámetro el nombre de un fichero en la pantalla de edición
aparecerá su contenido. Cuando se invoca este editor con el nombre de un fichero que no
existe, se crea automáticamente.
Existen dos modos de operación en el vi:
Modo Edición:
Para añadir texto al fichero
Modo Comando:
Para introducir órdenes que realizan funciones específicas del vi.
Cuando se edita un fichero con el vi, los cambios no se hacen directamente sobre el fichero.
En realidad, se aplican a una copia del fichero que el vi crea en un espacio de memoria
temporal llamado buffer. La copia en disco del fichero se modifica sólo cuando se graban los
contenidos del buffer.
Esto tiene sus ventajas y sus inconvenientes. Por un lado, significa que se puede salir de la
edición de un fichero y descartar todos los cambios hechos durante una sesión, dejando la
copia de disco intacta. Por otro lado, se podría perder el contenido no grabado del buffer de
trabajo si el sistema cae.
Lo más aconsejable es grabar el trabajo frecuentemente, especialmente cuando se hacen
cambios importantes. Para grabar el fichero que se está editando sin salir del vi , basta pulsar
en modo comando la orden :w
Para terminar la sesión caben varias posibilidades, siempre en modo comando:
:q
Salir cuando no se han hecho modificaciones
:q!
Salir y descartar los cambios
:wq
Salir y guardar los cambios
57
Importante: Hay que procurar no editar un fichero con varias copias del vi al mismo tiempo,
pues de este modo no se está seguro de cual es la copia que está realmente grabada en disco.
Modo Edición:
Cuando se arranca el vi, siempre está en modo comando, por lo que antes de poder escribir
texto en el fichero se debe teclear uno de los comandos de entrada del vi , tales como
i (insert), para insertar texto en la posición actual del cursor, o a (append) para insertar texto
después de la posición actual del cursor.
Para regresar la modo comando, basta con presionar Esc. Si en un momento determinado no
se sabe en qué modo se está, simplemente pulsando Esc se asegura uno de que está en
modo comando, y se podrá continuar con el trabajo.
Modo Comando:
Cuando se abre un fichero con vi, se está en modo comando. En este modo se pueden
introducir comandos que implementan un amplio rango de funciones. Muchos de estos
comandos constan de una o dos letras y un número opcional relacionado con distintas
funciones.
Muchos comandos no requieren pulsar Return para que se ejecuten, pero todas las órdenes
que empiezan por dos puntos (:) requieren pulsar Return para que se ejecuten.
Principales comandos
Los principales comandos del vi, se encuentran clasificados en este manual según su utilidad
durante la edición de un documento.
1. Moverse por un fichero
2. Insertar texto
3. Cambiar texto
4. Deshacer cambios
5. Borrar texto
6. Copiar y mover texto
7. Comandos del ex
8. Búsqueda y reemplazo
9. Inserción de un fichero en otro
10. Edición de múltiples ficheros
58
Los comandos del vi pueden ir precedidos de un contador que indica cuantas veces se debe repetir
la operación.
Por ejemplo 3dd borra 3 líneas, 2dw borra 2 palabras, y 4x borra 4 caracteres.
También se pueden usar contadores para los comandos de moverse por la pantalla, por ejemplo
3w o 2Ctrl-F Pulsando un "." se repite la última operación realizada.
Por ejemplo, si se borra una lía y la siguiente operación es borrar una línea, basta con pulsar ".".
Nota: Muchos de los comandos delvi son case-sensitive, es decir, la misma orden tecleada en
mayúsculas o minúsculas puede tener efectos totalmente distintos.
Moverse por un fichero
Cuando arrancamos el vi , el cursor esta en la esquina superior izquierda de la pantalla. En modo
comando, existen órdenes que nos permiten moverlo por toda la pantalla.
1. De carácter en carácter
o Si el teclado esta provisto con las flechas, se pueden utilizar para mover el cursor
libremente por el texto editado hasta el momento.
o Si se usa el vi desde un terminal remoto, las flechas pueden no funcionar
correctamente, depende del emulador de terminal. En dicho caso las teclas usadas
son:
Izquierda:
h ó SpcBar
Derecha:
l ó BckSpc
Arriba:
k
Abajo:
j
2. De palabra en palabra
o Pulsando w (word) nos movemos una palabra hacia la derecha.
o Pulsando b (before) nos movemos una palabra hacia la izquierda.
3. Dentro de una línea
o Pulsando ^ nos movemos al comienzo de la línea en la que está el cursor.
o Pulsando $ nos movemos al final de la línea actual.
o Pulsando Return nos movemos al comienzo de la línea siguiente.
59
4. Dentro de una pantalla
o Pulsando H (high) nos movemos a la parte superior de la pantalla.
o Pulsando L (low) nos movemos a la parte inferior de la pantalla.
o Pulsando M (middle) nos movemos a la mitad de la pantalla
5. Av/Re Página
o Pulsando Ctrl-F (forward) se avanza una pantalla, moviéndose el cursor a la
esquina superior izquierda de la nueva pantalla.
o Pulsando Ctrl-D se avanza media pantalla.
o Pulsando Ctrl-B (scroll backward) se retrocede una pantalla.
o Pulsando Ctrl-U se retrocede media pantalla.
Insertar texto
vi proporciona muchos comandos para insertar texto, que nos hacen pasar del modo comando al
modo de edición.
1. Añadir
o Pulsando a (append) se inserta texto a la derecha del cursor.
o Pulsando A se añade texto al final de la línea en la que está el cursor.
2. Insertar
o Pulsando i (insert) se inserta texto a la izquierda del cursor.
o Pulsando I se inserta texto al principio de una línea.
3. Insertar una línea
o Pulsando o (open) se inserta una línea debajo de la posición actual del cursor
o Pulsando O se inserta una línea encima de la actual posición del cursor.
Cambiar texto
Cambiar texto implica sustituir una sección de texto por otra. vi tiene varios modos de hacer esto,
dependiendo de lo que se desee cambiar.
1. Carácter por Caracter/es:
Substituir caracteres
Para substituir el carácter bajo el cursor por uno o mas caracteres, teclear s seguido del
nuevo texto y pulsar Esc cuando se acabe.
Reemplazar un carácter
Para reemplazar el carácter bajo el cursor por otro carácter, pulsar r, seguido por un unico
carácter, pues al pulsar una tecla el vi inmediatamente regresa a modo comando
Trasposicionar caracteres
60
Esto es util para fallos tales como escribir qeu en lugar de que. Colocando el cursor sobre
la primera letra a mover y pulsando xp, se intercambian las posiciones de ambos
caracteres.
2. Palabra por palabra/s
Palabra completa
Posicionar el cursor al principio de la palabra a ser reemplazada, teclear cw seguido de la
nueva palabra. Cuando se termine de modificar se pulsará Esc
Parte de una palabra
Colocar el cursor sobre la palabra, a la derecha de la parte a cambiar, y proceder como en
el caso anterior.
3. Línea por línea/s
Línea completa
Poner el cursor en cualquier parte de la línea y teclear cc. La línea desaparece, dejando
una línea en blanco para el nuevo texto, que puede ser de cualquier longitud. Para terminar
se pulsará Esc.
Parte de una línea
Colocar el cursor a la derecha de la parte a modificar. Pulsar C, introducir la corrección y
pulsar Esc para terminar.
4. Partir/Unir líneas
Partir una línea
Mover el cursor al espacio donde se quiere partir la línea y teclear r (replace) seguido de
Return (se reemplazaria el espacio por un return sin afectar al texto)
Unir dos líneas
Colocar el cursor en la línea superior y teclear J.
Deshacer cambios
vi proporciona dos modos para deshacer los cambios hechos mientras no se ha grabado el
fichero a disco.
Deshacer el comando previo.
o Pulsando u a continuación del último comando, se deshacen los cambios
producidos por la ejecución del mismo.
Deshacer los cambios de una linea.
o Pulsando U se deshacen todos los cambios que se han hecho sobre una
línea. Este comando funciona sólo si se permanece en dicha línea.
61
Borrar texto
Caracteres
Para borrar un carácter, posicionar el cursor sobre el carácter a borrar y teclear x. El
comando x tambien borra el espacio ocupado por el carácter.
Para borrar el carácter anterior a la posicion del cursor pulsar X.
Palabras
Para borrar una palabra, posicionar el cursor al principio de la palabra y pulsar dw,
entonces se borrara la palabra y el espacio que ésta ocupaba.
Para borrar parte de una palabra, hay que colocar el cursor a la derecha de la parte a
modificar, y teclear dw.
Lineas
Para borrar una línea y el espacio que ésta ocupa, basta con pulsar dd.
Para borrar todo lo que este a la derecha del cursor, basta con pulsar D.
Para borrar todo lo que este a la izquierda del mismo basta con pulsar d0.
Fichero
Para borrar desde la línea actual hasta el final del fichero, basta con teclear dG.
Para borrar desde el principio del fichero hasta la línea actual, basta teclear d1G.
Copiar y mover texto
De la misma manera que muchos procesadores de texto permiten copiar/pegar, o cortar/pegar
líneas de texto, el vi incluye también esta posibilidad, mediante los comandos yank /put y delete
/put , respectivamente.
1. Copiar y pegar
El procedimiento para copiar una ó más líneas, es el siguiente:
o Colocarse en la primera línea a copiar.
o Escribir el número de líneas que se desea copiar.
o Teclear yy ó Y (comando yank ).
o Colocarse en la línea a donde se desean copiar
o Teclear p ó P (comando pegar )
2. Cortar y pegar
El procedimiento para mover una ó varias líneas es el siguiente:
o Colocarse en la primera línea a cortar.
o Escribir el número de líneas que se desea cortar.
o Teclear dd (comando delete ).
o Colocarse en la línea a donde se desean pegar
o Teclear p ó P (comando pegar )
3. Usar buffers con nombre
62
Para insertar repetidamente un grupo de líneas en varios lugares dentro de un documento,
se pueden copiar las líneas a un buffer con nombre. El procedimiento para dar nombre a
un buffer es el siguiente:
o Colocarse en la primera línea a copiar.
o Teclear comillas dobles ( " ) seguido de la letra con que se desea nombrar el buffer
(Ej: "a )
o A continuación escribir el número de líneas que se desea copiar o cortar.
o Teclear yy ó Y (comando yank ) ó dd (comando delete ).
o Colocarse en la línea donde se desean pegar.
o Teclear comillas dobles seguidas por la letra del buffer cuyo contenido se desea
insertar y por p ó P (comando pegar).
Aviso: Entre la ejecución de un yank ó delete y un put , sólo se pueden usar los comandos de
movimiento de cursor. Si se borrase o copiase cualquier otro texto antes de poner el nuevo texto
en su lugar, las líneas copiadas o borradas se perderían.
Si se necesita copiar o mover varios conjuntos de líneas distintos, se deben usar los buffers con
nombre, que sólo se mantienen mientras no se salga del vi, o se le asigne explícitamente un nuevo
contenido
Comandos del ex
Cuando se trata de grandes bloques de texto, los comandos del ex son más seguros que yank ,
delete y put del vi.
Éstes permiten especificar el rango de líneas a mover o copiar, así como la línea anterior al punto
donde se insertarán las líneas.
Para conocer el rango de líneas, es necesario conocer el número de cada línea:
Para visualizar los números de línea
:set nu
Para ocultar los números de línea
:set nonu
Conocidos los números de las líneas que se van a copiar, las órdenes del editor ex disponibles
son:
1. Copiar líneas
El formato básico del comando para copiar en el ex es el siguiente:
:#linea,#linea co #linea
2. Mover líneas
El formato básico del comando para mover en el ex es el siguiente:
:#linea,#linea m #linea
3. Borrar líneas
63
El formato básico del comando para borrar en el ex es el siguiente:
:#linea,#linea d
En todos los casos, los dos primeros números de línea especifican el rango de líneas a copiar ,
cortar o borrar, respectivamente, y el último corresponde a la línea anterior al punto de inserción.
Se pueden utilizar abreviaturas para especificar los rangos de líneas:
.
Denota la línea actual
$
Denota el final del fichero
Búsqueda y remplazo
vi proporciona varios modos de encontrar un string de caracteres en el texto, así como de
reemplazarlo.
Un string es simplemente uno o más caracteres en fila. Puede incluir letras, números, signos de
puntuación, caracteres especiales, espacios en blanco, tabulaciones o retornos de carro. Un string
puede ser una palabra gramatical o puede ser una parte de una palabra.
Para ir a una línea determinada de un fichero abierto se teclearía:
#lineaG (Ej. 6G)
Si no se indica un número de línea se consideraría la última del fichero.
Búsqueda
Para encontrar un string, hay que escribir una barra hacia la derecha (/) seguida por el string que
se desea buscar, y pulsar return.
El vi posiciona el cursor en la siguiente ocurrencia del string. Tecleando n se va a la siguiente
ocurrencia del string, y pulsando N a la anterior.
Si en lugar de una barra se escribiese una interrogación (?), la búsqueda sería hacia atrás, y las
direcciones de las órdenes n y N se invertirían.
Normalmente las búsquedas son case-sensitive. Si se quiere que vi ignore mayúsculas y
minúsculas durante la búsqueda, hay que teclear previamente:
:set ic
Para volver al cambio por defecto se teclearía:
64
:set noic
Ciertos caracteres especiales (/ & ! . ^ * $ \ ?) tienen un significado particular en el proceso de
búsqueda, y por lo tanto deben especificarse de un modo especial cuando están incluidos en el
string a buscar, precediéndolos por la barra hacia atrás (\).
Refinando la búsqueda
Se pueden realizar búsquedas más precisas, marcando el string con indicadores de características
tales como:
Principio de línea
Para intentar emparejar el comienzo de una línea, hay que escribir antes del string
a buscar el carácter ^
Fin de línea
Para emparejar el final de una línea, hay que terminar el string a buscar por el
carácter $
Principio de palabra
Para emparejar el principio de una palabra, hay que teclear \<
Fin de palabra
Para emparejar el final de una palabra, hay que teclear \> al final del string.
Comodines
o Para emparejar cualquier carácter, hay que teclear un punto en el string en
la posición a emparejar. (igual que ? en los nombres de ficheros de MS-
DOS)
o Para buscar caracteres alternativos en un string, se deben poner las
alternativas entre corchetes, por ejemplo:
[md]xxx encontraría los strings mxxx y dxxx
[d-m]xxx encontraría todos los strings que comiencen por cualquier
letra de la d a la m y sigan con xxx.
o Para emparejar cero ó más ocurrencias del último carácter escrito, basta
añadir un * en el string.
Reemplazo
El procedimiento para reemplazar un string está es similar al de búsqueda arriba mencionado.
Todos los caracteres especiales de emparejamiento se pueden usar también en una
búsqueda+reemplazamiento.
65
La forma básica de la orden es:
:g/string_buscado/s//string_cambiado/g
Se puede modificar el comando para parar la búsqueda y hacer que el vi pida confirmación antes
de realizar el reemplazo, mediante la orden gc (consult), respondiendo y (sí) o n (no).
Para terminar el proceso bastaría con pulsar Ctrl-C
Inserción de un fichero en otro
vi permite insertar un fichero dentro del que se está editando, mediante la orden:
:#linea r nombre_fichero
Si no se especifica un número de línea, se tomará la posición actual del cursor
Edición de múltiples ficheros
vi permite la edición de varios ficheros simultáneamente. Para ello se debe grabar el fichero
abierto (comando :w), y a continuación escribir
:n nombre_nuevo_fich.
Para cambiarse de un fichero a otro habría que teclear
:n nombrefich
Para editar una serie de ficheros caben dos posibilidades:
Dar el nombre completo de todos los ficheros a editar:
vi nombre1 nombre2 nombre3
Utilizar caracteres comodín
vi nom*
Para copiar líneas de un fichero a otro, se deben seguir los siguientes pasos:
1. Editar el primer fichero
2. Salvar las líneas que se quieran con la orden yank.
3. Sin salir del vi, editar el fichero donde se van a insertar las líneas.
:n nuevofich
4. Usar la orden put como si se tratase del mismo fichero.
Recuperación ante caídas del sistema
Si el sistema cae, el contenido del buffer donde se realizan las modificaciones se puede perder.
Se puede recuperar parte del trabajo realizado si se invoca el vi del siguiente modo:
vi -r nomfich
66
Donde nomfich es el fichero que se estaba editando en el momento en que se produjo la caída.
Cuando el sistema arranque de nuevo, enviará un mensaje indicando la recuperación del fichero.
PROGRAMACIÓN EN BASH
1. Introducción
1.1 Requisitos
Le será útil tener una cierta familiaridad con la línea de comandos de GNU/Linux y con los
conceptos básicos de la programación. Aunque esto no es una introducción a la programación,
explica (o al menos lo intenta) muchos conceptos básicos.
1.2 Usos de este documento
Este documento intenta ser útil en las siguientes situaciones
Si tiene alguna idea de programación y quiere empezar a programar algunos shell scripts.
Si tiene una idea vaga de programar en shell y quiere algún tipo de referencia.
Si quiere ver algunos scripts y comentarios para empezar a escribir los suyos propios.
Si está migrando desde DOS/Windows (o ya lo ha hecho) y quiere hacer procesos "por
lotes".
Si es un completo novato y lee todo COMO disponible.
2. Scripts muy sencillos
Este COMO tratará de darle algunos consejos sobre la programación de shell scripts, basándose
profundamente en ejemplos.
En esta sección encontrará varios scripts pequeños que esperanzadamente le ayudarán a
entender algunas técnicas.
2.1 Típico script `hola mundo'
#!/bin/bash
echo Hola Mundo
Este script tiene sólo dos líneas. La primera le indica al sistema qué programa usar para ejecutar el
fichero.
La segunda línea es la única acción realizada por este script, que imprime 'Hola Mundo' en la
terminal.
67
Si le sale algo como ./hello.sh: Comando desconocido., probablemente la primera línea,
'#!/bin/bash', está mal. Ejecute whereis bash, o vea 'encontrando el bash' para saber cómo debe
escribir esta línea.
2.2 Un script de copia de seguridad muy simple
#!/bin/bash
tar -cZf /var/my-backup.tgz /home/yo/
En este script, en vez de imprimir un mensaje en la terminal, creamos un tar-ball del directorio
home de un usuario. Esto NO pretende ser un script útil; más tarde se ofrece un script de copia de
seguridad más útil.
3. Todo sobre redirección
3.1 Teoría y referencia rápida
Existen 3 descriptores de ficheros: stdin, stdout y stderr (std=estándar).
Básicamente, usted puede:
1. redirigir stdout a un fichero
2. redirigir stderr a un fichero
3. redirigir stdout a stderr
4. redirigir stderr a stdout
5. redirigir stderr y stdout a un fichero
6. redirigir stderr y stdout a stdout
7. redirigir stderr y stdout a stderr
El número 1 'representa' a stdout, y 2 a stderr.
Una pequeña nota para ver todo esto: con el comando less puede visualizar stdout (que
permanecerá en el búfer) y stderr, que se imprimirá en la pantalla, pero será borrado si intenta leer
el búfer.
3.2 Ejemplo: stdout a un fichero
Esto hará que la salida de un programa se escriba en un fichero.
ls -l > ls-l.txt
En este caso, se creará un fichero llamado 'ls-l.txt' que contendrá lo que se vería en la pantalla si
escribiese el comando 'ls -l' y lo ejecutase.
68
3.3 Ejemplo: stderr a un fichero
Esto hará que la salida stderr de un programa se escriba en un fichero.
grep da * 2> errores-de-grep.txt
En este caso, se creará un fichero llamado 'errores-de-grep.txt' que contendrá la parte stderr de la
salida que daría el comando 'grep da *'.
3.4 Ejemplo: stdout a stderr
Esto hará que la salida stdout de un programa se escriba en el mismo descriptor de fichero que
stderr.
grep da * 1>&2
En este caso, la parte stdout del comando se envía a stderr; puede observar eso de varias
maneras.
3.5 Ejemplo: stderr a stdout
Esto hará que la salida stderr de un programa se escriba en el mismo descriptor de fichero que
stdout.
grep * 2>&1
En este caso, la parte stderr del comando se envía a stdout. Si hace una tubería con less, verá que
las líneas que normalmente 'desaparecen' (al ser escritas en stderr), ahora permanecen (porque
están en el stdout).
3.6 Ejemplo: stderr y stdout a un fichero
Esto colocará toda la salida de un programa en un fichero. A veces, esto es conveniente en las
entradas del cron, si quiere que un comando se ejecute en absoluto silencio.
rm -f $(find / -name core) &> /dev/null
Esto (pensando en la entrada del cron) eliminará todo archivo llamado `core' en cualquier
directorio. Tenga en cuenta que tiene que estar muy seguro de lo que hace un comando si le va a
eliminar la salida.
4. Tuberías
Esta sección explica de una manera muy sencilla y práctica cómo utilizar tuberías, y por qué
querría utilizarlas.
69
4.1 Qué son y por qué querrá utilizarlas
Las tuberías le permiten utilizar (muy sencillo, insisto) la salida de un programa como la entrada de
otro.
4.2 Ejemplo: una tubería sencilla con sed
Ésta es una manera muy sencilla de utilizar tuberías.
ls -l | sed -e "s/[aeio]/u/g"
En este caso, ocurre lo siguiente: primero se ejecuta el comando ls -l, y luego su salida, en vez de
imprimirse en la pantalla, se envía (entuba) al programa sed, que imprime su salida
correspondiente.
4.3 Ejemplo: una alternativa a ls -l *.txt
Probablemente ésta es una manera más difícil de hacer un ls -l *.txt, pero se muestra para ilustrar
el funcionamiento de las tuberías, no para resolver ese dilema.
ls -l | grep "\.txt$"
En este caso, la salida del programa ls -l se envía al programa grep, que imprimirá las líneas que
concuerden con la regex (expresión regular) "\.txt$".
5. Variables
Puede usar variables como en cualquier otro lenguaje de programación. No existen tipos de datos.
Una variable de bash puede contener un número, un caracter o una cadena de caracteres.
No necesita declarar una variable. Se creará sólo con asignarle un valor a su referencia.
5.1 Ejemplo: ¡Hola Mundo! utilizando variables
#!/bin/bash
CAD="¡Hola Mundo!"
echo $CAD
La segunda línea crea una variable llamada STR y le asigna la cadena "¡Hola Mundo!". Luego se
recupera el VALOR de esta variable poniéndole un '$' al principio. Por favor, tenga en cuenta
(¡inténtelo!) que si no usa el signo '$', la salida del programa será diferente, y probablemente no
sea lo que usted quería.
5.2 Ejemplo: Un script de copia de seguridad muy simple (algo mejor)
#!/bin/bash
OF=/var/mi-backup-$(date +%Y%m%d).tgz
70
tar -cZf $OF /home/yo/
Este script introduce algo nuevo. Antes que nada, debería familiarizarse con la creación y
asignación de variable de la línea 2. Fíjese en la expresión '$(date +%Y%m%d)'. Si ejecuta el script
se dará cuenta de que ejecuta el comando que hay dentro de los paréntesis, capturando su salida.
Tenga en cuenta que en este script, el fichero de salida será distinto cada día, debido al formato
pasado al comando date (+%Y%m%d). Puede cambiar esto especificando un formato diferente.
Algunos ejemplos más:
echo ls
echo $(ls)
5.3 Variables locales
Las variables locales pueden crearse utilizando la palabra clave local.
#!/bin/bash
HOLA=Hola
function hola {
local HOLA=Mundo
echo $HOLA
}
echo $HOLA
hola
echo $HOLA
Este ejemplo debería bastar para mostrarle el uso de una variable local.
6. Estructuras Condicionales
Las estructuras condicionales le permiten decidir si se realiza una acción o no; esta decisión se
toma evaluando una expresión.
6.1 Pura teoría
Los condicionales tienen muchas formas. La más básica es: if expresión then sentencia donde
'sentencia' sólo se ejecuta si 'expresión' se evalúa como verdadera. '2<1' es una expresión que se
evalúa falsa, mientras que '2>1' se evalúa verdadera.
Los condicionales tienen otras formas, como: if expresión then sentencia1 else sentencia2. Aquí
'sentencia1' se ejecuta si 'expresión' es verdadera. De otra manera se ejecuta 'sentencia2'.
71
Otra forma más de condicional es: if expresión1 then sentencia1 else if expresión2 then
sentencia2 else sentencia3. En esta forma sólo se añade "ELSE IF 'expresión2' THEN
'sentencia2'", que hace que sentencia2 se ejecute si expresión2 se evalúa verdadera. El resto es
como puede imaginarse (véanse las formas anteriores).
Unas palabras sobre la sintaxis:
La base de las construcciones 'if' es ésta:
if [expresión];
then
código si 'expresión' es verdadera.
fi
6.2 Ejemplo: Ejemplo básico de condicional if .. then
#!/bin/bash
if [ "petete" = "petete" ]; then
echo expresión evaluada como verdadera
fi
El código que se ejecutará si la expresión entre corchetes es verdadera se encuentra entre la
palabra 'then' y la palabra 'fi', que indica el final del código ejecutado condicionalmente.
6.3 Ejemplo: Ejemplo básico de condicional if .. then ... else
#!/bin/bash if [ "petete" = "petete" ]; then
echo expresión evaluada como verdadera
else
echo expresión evaluada como falsa
fi
6.4 Ejemplo: Condicionales con variables
#!/bin/bash
T1="petete"
T2="peteto"
if [ "$T1" = "$T2" ]; then
echo expresión evaluada como verdadera
else
echo expresión evaluada como falsa
fi
72
6.5 Ejemplo: comprobando si existe un fichero
#!/bin/bash
FILE=~/.basrc
if [ -f $FILE ]; then
echo el fichero $FILE existe
else
echo fichero no encontrado
fi
if [ 'test -f $FILE']
7. Los bucles for, while y until
En esta sección se encontrará con los bucles for, while y until.
El bucle for es distinto a los de otros lenguajes de programación. Básicamente, le permite iterar
sobre una serie de `palabras' contenidas dentro de una cadena.
El bucle while ejecuta un trozo de códico si la expresión de control es verdadera, y sólo se para
cuando es falsa (o se encuentra una interrupción explícita dentro del código en ejecución).
El bucle until es casi idéntico al bucle loop, excepto en que el código se ejecuta mientras la
expresión de control se evalúe como falsa.
Si sospecha que while y until son demasiado parecidos, está en lo cierto.
7.1 Por ejemplo
#!/bin/bash
for i in $( ls ); do
echo item: $i
done
En la segunda línea declaramos i como la variable que recibirá los diferentes valores contenidos en
$( ls ).
La tercera línea podría ser más larga o podría haber más líneas antes del done (4).
`done' (4) indica que el código que ha utilizado el valor de $i ha acabado e $i puede tomar el nuevo
valor.
73
Este script no tiene mucho sentido, pero una manera más útil de usar el bucle for sería hacer que
concordasen sólo ciertos ficheros en el ejemplo anterior.
7.2 for tipo-C
Fiesh sugirió añadir esta forma de bucle. Es un bucle for más parecido al for de C/perl...
#!/bin/bash
for i in `seq 1 10`;
do
echo $i
done
7.3 Ejemplo de while
#!/bin/bash
CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
echo El contador es $CONTADOR
let CONTADOR=CONTADOR+1
done
Este script 'emula' la conocida (C, Pascal, perl, etc) estructura `for'.
7.4 Ejemplo de until
#!/bin/bash
CONTADOR=20
until [ $CONTADOR -lt 10 ]; do
echo CONTADOR $CONTADOR
let CONTADOR-=1
done
8. Funciones
Como en casi todo lenguaje de programación, puede utilizar funciones para agrupar trozos de
código de una manera más lógica, o practicar el divino arte de la recursión.
Declarar una función es sólo cuestión de escribir function mi_func { mi_código }.
Llamar a la función es como llamar a otro programa, sólo hay que escribir su nombre.
74
8.1 Ejemplo de funciones
#!/bin/bash
function salir {
exit
}
function hola {
echo ¡Hola!
}
hola
salir
echo petete
Las líneas 2-4 contienen la función 'salir'. Las líneas 5-7 contienen la función 'hola'. Si no está
completamente seguro de lo que hace este script, por favor, ¡pruébelo!.
Tenga en cuenta que una función no necesita que sea declarada en un orden específico.
Cuando ejecute el script se dará cuenta de que: primero se llama a la función 'hola', luego a la
función 'quit', y el programa nunca llega a la línea 10.
8.2 Ejemplo de funciones con parámetros
#!/bin/bash
function salir {
exit
}
function e {
echo $1
}
e Hola
e Mundo
salir
echo petete
Este script es casi idéntico al anterior. La diferencia principal es la función 'e'. Esta función imprime
el primer argumento que recibe. Los argumentos, dentro de las funciones, son tratados de la
misma manera que los argumentos suministrados al script.
75
9. Interfaces de usuario
9.1 Utilizando select para hacer menús sencillos
#!/bin/bash
OPCIONES="Hola Salir"
select opt in $OPCIONES; do
if [ "$opt" = "Salir" ]; then
echo done
exit
elif [ "$opt" = "Hola" ]; then
echo Hola Mundo
else
clear
echo opción errónea
fi
done
Si ejecuta este script verá que es el sueño de un programador para hacer menús basados en texto.
Probablemente se dará cuenta de que es muy similar a la construcción 'for', sólo que en vez de
iterar para cada 'palabra' en $OPCIONES, se lo pide al usuario.
9.2 Utilizando la línea de comandos
#!/bin/bash
if [ -z "$1" ]; then
echo uso: $0 directorio
exit
fi
SRCD=$1
TGTD="/var/backups/"
OF=home-$(date +%Y%m%d).tgz
tar -cZf $TGTD$OF $SRCD
Lo que hace este script debería estar claro para usted. La expresión del primer condicional
comprueba si el programa ha recibido algún argumento ($1) y sale si no lo ha recibido,
mostrándole al usuario un pequeño mensaje de uso. El resto del script debería estar claro.
76
10. Miscelánea
10.1 Leyendo información del usuario
En muchas ocasiones, puede querer solicitar al usuario alguna información, y existen varias
maneras para hacer esto. Ésta es una de ellas:
#!/bin/bash
echo Por favor, introduzca su nombre
read NOMBRE
echo "¡Hola $NOMBRE!"
Como variante, se pueden obtener múltiples valores con read. Este ejemplo debería clarificarlo.
#!/bin/bash
echo Por favor, introduzca su nombre y primer apellido
read NO AP
echo "¡Hola $AP, $NO!"
10.2 Evaluación aritmética
Pruebe esto en la línea de comandos (o en una shell):
echo 1 + 1
Si esperaba ver '2', quedará desilusionado. ¿Qué hacer si quiere que BASH evalúe unos números?
La solución es ésta:
echo $((1+1))
Esto producirá una salida más 'lógica'. Esto se hace para evaluar una expresión aritmética.
También puede hacerlo de esta manera:
echo $[1+1]
Si necesita usar fracciones, u otras matemáticas, puede utilizar bc para evaluar expresiones
aritméticas.
Si ejecuta "echo $[3/4]" en la línea de comandos, devolverá 0, porque bash sólo utiliza enteros en
sus respuestas. Si ejecuta "echo 3/4|bc -l", devolverá 0.75.
10.3 Encontrando el bash
De un mensaje de mike (vea los agradecimientos):
Siempre usas #!/bin/bash .. a lo mejor quieres dar un ejemplo de cómo saber dónde encontrar el
bash.
77
`locate bash' es preferible, pero no todas las máquinas
tienen locate.
`find ./ -name bash' desde el directorio raíz funcionará,
normalmente.
Sitios donde poder buscar:
ls -l /bin/bash
ls -l /sbin/bash
ls -l /usr/local/bin/bash
ls -l /usr/bin/bash
ls -l /usr/sbin/bash
ls -l /usr/local/sbin/bash
(no se me ocurre ningún otro directorio... lo he encontrado
la mayoría de estos sitios en sistemas diferentes).
También puedes probar 'which bash'.
10.4 Obteniendo el valor devuelto por un programa
En bash, el valor de retorno de un programa se guarda en una variable especial llamada $?.
Esto ilustra cómo capturar el valor de retorno de un programa. Supongo que el directorio dada no
existe. (Esto también es sugerencia de Mike).
#!/bin/bash
cd /dada &> /dev/null
echo rv: $?
cd $(pwd) &> /dev/null
echo rv: $?
10.5 Capurando la salida de un comando
Este pequeño script muestra todas las tablas de todas las bases de datos (suponiendo que tenga
MySQL instalado). Considere también cambiar el comando 'mysql' para que use un nombre de
usuario y clave válidos.
#!/bin/bash
DBS=`mysql -uroot -e"show databases"`
for b in $DBS ;
do
mysql -uroot -e"show tables from $b"
done
78
11. Tablas
11.1 Operadores de comparación de cadenas
s1 = s2
s1 coincide con s2
s1 != s2
s1 no coincide con s2
s1 < s2
s1 es alfabéticamente anterior a s2, con el locale actual
s1 > s2
s1 es alfabéticamente posterior a s2, con el locale actual
-n s1
s1 no es nulo (contiene uno o más caracteres)
-z s1
s1 es nulo
11.2 Ejemplo de comparación de cadenas
Comparando dos cadenas
#!/bin/bash
S1='cadena'
S2='Cadena'
if [ $S1!=$S2 ];
then
echo "S1('$S1') no es igual a S2('$S2')"
fi
if [ $S1=$S1 ];
then
echo "S1('$S1') es igual a S1('$S1')"
fi
Cito aquí el consejo de un correo enviado por Andreas Beck, referido al uso de if [ $1 = $2 ].
Esto no es buena idea, porque si $S1 o $S2 son vacíos, aparecerá un parse error. Es mejor:
x$1=x$2 or "$1"="$2"
11.3 Operadores aritméticos
+ (adición)
- (sustracción)
* (producto)
/ (división)
% (módulo)
79
11.4 Operadores relacionales aritméticos
-lt (<)
-gt (>)
-le (<=)
-ge (>=)
-eq (==)
-ne (!=)
Los programadores de C tan sólo tienen que corresponder el operador con su paréntesis.
11.5 Comandos útiles
Esta sección ha sido reescrita por Kees (véanse agradecimientos)
Algunos de estos comandos contienen lenguajes de programación completos. Sólo se explicarán
las bases de estos comandos. Para una descripción más detallada, eche un vistazo a las páginas
man de cada uno.
sed (editor de flujo)
Sed es un editor no interactivo. En vez de alterar un fichero moviendo el cursor por la pantalla, se
utiliza una serie de instrucciones de edición de sed, y el nombre del fichero a editar. También se
puede describir a sed como un filtro. Miremos algunos ejemplos:
$sed 's/a_sustituir/sustituto/g' /tmp/petete
Sed sustituye la cadena 'a_sustituir' por la cadena 'sustituto', leyendo del fichero /tmp/petete. El
resultado se envía a stdout (normalmente la consola), pero se puede añadir '> captura' al final de la
línea de arriba para que sed envíe la salida al fichero 'capture'.
$sed 12, 18d /tmp/petete
Sed muestra todas las líneas de /tmp/petete excepto la 12 y la 18. El fichero original no queda
alterado por este comando.
awk (manipulación de bases de datos, extracción y proceso de texto)
Existen muchas implementaciones del lenguaje de programacin AWK (los intérpretes más
conocidos son gawk de GNU, y el 'nuevo awk' mawk). El principio es sencillo: AWK busca un
patrón, y por cada patrón de búsqueda que coincida, se realiza una acción.
Si tenemos un fichero /tmp/petete con las siguientes líneas:
"prueba123
80
prueba
pprruueebbaa"
y ejecutamos:
$awk '/prueba/ {print}' /tmp/petete
test123
test
El patrón que busca AWK es 'prueba' y la acción que realiza cuando encuentra una línea en
/tmp/petete con la cadena 'prueba' es `print'.
$awk '/prueba/ {i=i+1} END {print i}' /tmp/petete
Cuando se utilizan muchos patrones, se puede reemplazar el texto entre comillas por '-f
fichero.awk', y poner todos los patrones y acciones en 'fichero.awk'.
grep (impresión de líneas que coinciden con un patrón de búsqueda)
Ya hemos visto ejemplos del comando grep en los capítulos anteriores, que muestra las líneas que
concuerdan con un patrón. Pero grep puede hacer más que eso.
$grep "busca esto" /var/log/messages -c
Se ha encontrado 12 veces la cadena "busca esto" en el fichero /var/log/messages.
[vale, este ejemplo es falso, el fichero /var/log/messages está alterado :-)]
wc (cuenta líneas, palabras y bytes)
En el siguiente ejemplo, vemos que la salida no es lo que esperábamos. El fichero petete utilizado
en este ejemplo contiene el texto siguiente:
$wc --words --lines --bytes /tmp/petete
2 5 41 /tmp/petete
Wc no tiene en cuenta el orden de los parámetros. Wc siempre los imprime en un orden estándar,
que es, como se puede ver: líneas, palabras, bytes y fichero.
sort (ordena líneas de ficheros de texto)
Esta vez, el fichero petete contiene el texto siguiente:
"b
c
a"
$sort /tmp/petete
Esto es lo que muestra la salida:
81
a
b
c
Los comandos no deberían ser tan fáciles :-)
bc (un lenguaje de programación de cálculos matemáticos)
Bc acepta cálculos desde la línea de comandos (entrada desde un fichero, pero no desde una
redirección o una tubería), y también desde una interfaz de usuario. La siguiente demostración
expone algunos de los comandos. Note que ejecuto bc con el parámetro -q para evitar el mensaje
de bienvenida.
$bc -q
1 == 5
0
0.05 == 0.05
1
5 != 5
0
2 ^ 8
256
sqrt(9)
3
while (i != 9) {
i = i + 1;
print i
}
123456789
quit
tput (inicializa una terminal o consulta la base de datos de terminfo)
Una pequeña demostración de las capacidades de tput:
$tput cup 10 4
La línea de comandos aparece en (y10,x4).
$tput reset
Limpia la pantalla y la línea de comandos aparece en (y1,x1). Observe que (y0,x0) es la esquina
superior izquierda.
$tput cols
82
80
Muestra el número de caracteres que caben en la dirección x.
Es muy recomendable familiarizarse con estos programas (al menos).
12. Más scripts
12.1 Aplicando un comando a todos los ficheros de un directorio.
12.2 Ejemplo: Un script de copia de seguridad muy simple (algo mejor)
#!/bin/bash
ORIG="/home/"
DEST="/var/copias_de_seguridad/"
FICH=home-$(date +%Y%m%d).tgz
tar -cZf $DEST$FICH $ORIG
12.3 Re-nombrador de ficheros
#!/bin/sh
# renom: renombra múltiples ficheros de acuerdo con ciertas
# reglas
# escrito por Felix Hudson Enero - 2000
# primero comprueba los distintos 'modos' que tiene este
# programa
# si la primera ($1) condición coincide, se ejecuta esa parte
# del programa y acaba
# comprueba la condición de prefijo
if [ $1 = p ]; then
# ahora nos libramos de la variable de modo ($1) y ponemos $2
# de prefijo
prefijo=$2 ; shift ; shift
# una rápida comprobación para ver si se especificó algún
# fichero
# si no, hay cosas mejores que hacer que renombrar ficheros
# inexistentes!!
if [$1 = ]; then
echo "no se especificaron ficheros"
83
exit 0
fi
# este bucle for itera a lo largo de todos los ficheros que
# le hemos especificado al programa
# renombra cada uno de ellos
for fichero in $*
do
mv ${fichero} $prefijo$fichero
done
# ahora salimos del programa
exit 0
fi
# comprueba si es un renombramiento con sufijo
# el resto es casi idéntico a la parte anterior
# lea los comentarios anteriores
if [ $1 = s ]; then
sufijo=$2 ; shift ; shift
if [$1 = ]; then
echo "no se especificaron ficheros"
exit 0
fi
for fichero in $*
do
mv ${fichero} $fichero$sufijo
done
exit 0
fi
# comprueba si es una sustitución
if [ $1 = r ]; then
shift
84
# he incluído esto para no dañar ningún fichero si el
# usuario no especifica que se haga nada
# tan sólo una medida de seguridad
if [ $# -lt 3 ] ; then
echo "uso: renom r [expresión] [sustituto] ficheros... "
exit 0
fi
# elimina el resto de información
VIEJO=$1 ; NUEVO=$2 ; shift ; shift
# este bucle for itera a lo largo de todos los ficheros que
# le hemos especificado al programa
# renombra cada fichero utilizando el programa 'sed'
# es un sencillo programa desde la línea de comandos que
# analiza la entrada estándar y sustituye una expresión por
# una cadena dada
# aquí le pasamos el nombre del fichero (como entrada
# estándar)
for fichero in $*
do
nuevo=`echo ${fichero} | sed s/${VIEJO}/${NUEVO}/g`
mv ${fichero} $nuevo
done
exit 0
fi
# si se llega a esta parte es que no se le pasó nada
# apropiado al programa, por lo que le decimos al usuario
# cómo hacerlo
echo "uso:"
echo " renom p [prefijo] ficheros.."
echo " renom s [sufijo] ficheros.."
echo " renom r [expresión] [sustituto] ficheros.."
exit 0
# hecho!
85
12.4 Re-nombrador de ficheros (sencillo)
#!/bin/bash
# renombra.sh
# renombrador de ficheros básico
criterio=$1
expresion=$2
sustituto=$3
for i in $( ls *$criterio* );
do
orig=$i
dest=$(echo $i | sed -e "s/$expresion/$sustituto/")
mv $orig $dest
done
13. Cuando algo va mal (depuración)
13.1 Maneras de llamar a BASH
Una buena idea es poner esto en la primera línea:
#!/bin/bash -x
Esto producirá información interesante.
SERVICIOS BÁSICOS
Resumen
Millones de hosts se encuentran conectados a Internet. ¿Cómo se consigue mantener la pista de
todos ellos cuando pertenecen a tantos países, redes y grupos administrativos distintos? Dos
piezas básicas de infraestructura mantienen todo eso junto: el sistema de nombres de dominio
(DNS, del inglés Domain Name System), cuya función es saber quién es cada host, y el sistema de
enrutado de Internet, que se encarga de conocer cómo están conectados. Este artículo hace
referencia a la porción que supone el DNS en ese sistema.
Objetivos
Los objetivos de un servidor de nombres de dominio (DNS, del inglés Domain Name Service) son
dos:
1. Por una parte, traducir una dirección canónica en una dirección IP (del inglés, Internet
Protocol). Por ejemplo, linuxsilo.net es, a fecha de creación del artículo, 66.79.182.201.
86
2. Por otra parte, traducir una dirección IP en una o varias direcciones canónicas. Es lo que
se conoce como traducción inversa.
Haciendo un símil, el primer punto equivaldría a buscar en una agenda el número de teléfono de
una persona, dado su nombre y apellidos, mientras que el segundo sería el proceso inverso: dado
un número de teléfono averiguar a qué persona corresponde.
La correlación entre una dirección IP y un nombre de dominio no tiene porqué ser única. Esto es
debido a lo que se conocen como dominios virtuales. De hecho, es habitual que una dirección IP
equivalga a varios nombres de dominio. Por ejemplo, la dirección IP 66.79.182.201 es equivalente
a linuxsilo.net, www.linuxsilo.net, ftp.linuxsilo.net, pop3.linuxsilo.net y otros. Sin embargo, esto no
significa que la misma máquina (o host) 66.79.182.201 esté ofreciendo todos esos servicios. Esto
es posible gracias a lo que se conoce como enrutamiento (del inglés, routing) de paquetes, pero no
viene al caso del artículo.
Introducción
¿Qué es el DNS?
DNS es un sistema jerárquico con estructura de árbol. El inicio se escribe "." y se denomina raíz, al
igual que en las estructuras de datos en árbol. Bajo la raíz se hallan los dominios de más alto nivel
(TLD, del inglés, Top Level Domain), cuyos ejemplos más representativos son ORG, COM, EDU y
NET, si bien hay muchos más. Del mismo modo que un árbol, tiene una raíz y ramas que de ella
crecen. Si el lector está versado en ciencias de la computación, reconocerá el DNS como un árbol
de búsqueda y será capaz de encontrar en él los nodos, nodos hoja y otros conceptos.
Cuando se busca una máquina, la consulta se ejecuta recursivamente en la jerarquía, empezando
por la raíz. Si se desea encontrar la dirección IP de ftp.akane.linuxsilo.net., el servidor de nombres
(del inglés, nameserver) tiene que empezar a preguntar en algún sitio. Empieza mirando en su
caché. Si conoce la respuesta, pues la había buscado anteriormente y guardado en dicha caché,
contestará directamente. Si no la sabe, entonces eliminará partes del nombre, empezando por la
izquierda, comprobando si sabe algo de akane.linuxsilo.net., luego de linuxsilo.net., luego net. y,
finalmente, de ".", del cual siempre se tiene información ya que se encuentra en uno de los ficheros
de configuración en el disco duro.
A continuación preguntará al servidor "." acerca de ftp.akane.linuxsilo.net. Dicho servidor "." no
sabrá la contestación, pero ayudará a nuestro servidor en su búsqueda dándole una referencia de
dónde seguir buscando. Estas referencias llevarán a nuestro servidor hasta el servidor de nombres
que conoce la respuesta.
87
Así pues, empezando en "." encontramos los sucesivos servidores de nombres para cada nivel en
el nombre de dominio por referencia. Por supuesto, nuestro servidor de nombres guardará toda la
información obtenida a lo largo del proceso, a fin de no tener que preguntar de nuevo durante un
buen rato.
En el árbol análogo, cada "." en el nombre es un salto a otra rama. Y cada parte entre los "." son
los nombres de los nodos particulares en el árbol. Se trepa el árbol tomando el nombre que
queremos (ftp.akane.linuxsilo.net) preguntando a la raíz (".") o al servidor que sea padre desde la
raíz hacia ftp.akane.linuxsilo.net acerca de los cuales tengamos información en la caché. Una vez
se alcanzan los límites de la caché, se resuelve recursivamente preguntando a los servidores,
persiguiendo las referencias (ramas) hacia el nombre.
Otro concepto del cual no se habla tanto, pero que no es menos importante, es el dominio in-
addr.arpa, que también se encuentra anidado como los dominios "normales". in-addr.arpa nos
permite hacernos con el nombre del host cuando tenemos su dirección. Merece la pena destacar
aquí que las direcciones IP están escritas en orden inverso en el dominio in-addr.arpa. Si se tiene
la dirección de una máquina tal como 192.168.0.1, el servidor de nombres procederá del mismo
modo que con el ejemplo ftp.akane.linuxsilo.net.
Es decir, buscará los servidores arpa., luego los servidores in-addr.arpa., luego los 192.in-
addr.arpa., luego los 168.192.in-addr.arpa. y, por último, los servidores 0.168.192.in-addr.arpa. En
este último encontrará el registro buscado: 1.0.168.192.in-addr.arpa.
¿Quién necesita el DNS?
El DNS define:
1. Un espacio de nombres jerárquico para los hosts y las direcciones IP.
2. Una tabla de hosts implementada como una base de datos distribuida.
3. Un traductor (del inglés, resolver) o librería de rutinas que permite realizar consultas a esa
base de datos.
4. Enrutamiento mejorado para el correo electrónico.
5. Un mecanismo para encontrar los servicios en una red.
6. Un protocolo para intercambiar información de nombres.
Para ser auténticos ciudadanos de Internet, los sitios necesitan el DNS. Mantener un fichero local
/etc/hosts con un mapeado de todos los hosts que los usuarios puedan querer contactar no es
factible.
88
Cada sitio mantiene una o varias piezas de la base de datos distribuida que posibilita el servicio
global del sistema DNS. Su pieza de la base de datos consiste en dos o más ficheros de texto que
contienen registros para cada uno de los hosts. Cada registro es una sencilla línea consistente en
un nombre (normalmente el nombre de un host), un tipo de registro y diversos valores o datos.
El DNS es un sistema cliente/servidor. Los servidores (de nombres) cargan los datos de sus
ficheros de DNS en memoria y los usan para responder las consultas tanto de los clientes de la red
interna como de los clientes y otros servidores en la red Internet. Todos sus hosts deberían ser
clientes del DNS, pero relativamente pocos necesitan ser servidores de DNS.
Si su organización es pequeña (unos pocos hosts en una única red), puede ejecutar un servidor en
uno de sus equipos o pedirle a su ISP (del inglés, Internet Services Provider) que le proporcione
ese servicio en su nombre. Un sitio de tamaño medio con diversas subredes debería tener
múltiples servidores de DNS para reducir la latencia de las consultas y mejorar la productividad. Un
sistema muy grande puede dividir sus dominios de DNS en subdominios y usar algunos servidores
para cada subdominio.
Requerimientos y datos técnicos
En este artículo se aprenderá a instalar y configurar BIND (del inglés, Berkeley Internet Name
Domain) sobre un sistema Linux. Se darán por supuestos ciertos conocimientos mínimos de redes
TCP/IP (del inglés, Transmission Control Protocol / Internet Protocol) y de administración Linux o,
al menos, un conocimeinto básico del funcionamiento de un sistema de este tipo. Estos son los
puntos que se tratarán y el software y hardware usado.
Software:
1. Debian GNU/Linux Sarge
2. Bind 9.2.4
3. DNS Utils
4. Bind Docs
Servicios:
1. Traducción de nombres a direcciones IP.
2. Traducción inversa (de direcciones IP a nombres).
3. Listas de control de acceso.
4. Servidores secundarios.
5. Transferencia segura de zonas entre servidores primarios y secundarios (y puertos).
6. Localización de servicios (registros SRV - RFC2052, del inglés, Request For Comments).
7. Respuestas parametrizadas en función del origen de la petición (vistas).
8. Uso de la herramienta rndc.
9. Logs a medida.
89
Para este artículo se usará el FQDN (del inglés, Fully Qualified Domain Name) linuxsilo.net y los
servidores de nombres ns1.linuxsilo.net y ns2.linuxsilo.net. Un FQDN está formado por un host y
un nombre de dominio, incluyendo el dominio de más alto nivel. Por ejemplo, www.linuxsilo.net es
un FQDN. www es el host, linuxsilo es el dominio de segundo nivel y net es el dominio de más alto
nivel. Un FQDN siempre empieza con el nombre del host y continua subiendo directo al dominio de
más alto nivel, por lo que ftp.akane.linuxsilo.net es también un FQDN. akane no es un FQDN.
Instalación
De este tipo de software siempre es más que recomendable tener la última versión, pues podemos
hallar en ella importantes errores y fallos de seguridad corregidos, así como nuevas
funcionalidades que faciliten nuestra tarea como administradores de sistemas. El proceso de
instalación en una distribución Debian de Linux es tan sencillo como ejecutar (como root, por
supuesto, del mismo modo que en el resto del artículo):
yum install bind
Dependiendo de la versión de Debian, el paquete Bind9 no estará disponible (por ejemplo, en
Potato se encuentra la versión 8), por lo que deberemos actualizar a una versión más actual
(Woody o Sid en el momento de escribir este artículo) y proceder. La instalación nos deja un Bind
con una configuración básica (en /etc/bind/) y funcionando, por lo que tan sólo deberemos
configurarlo según nuestras necesidades. Empezaremos por la traducción de nombres a
direcciones IP.
El paquete Debian bind9 se instala con una configuración ya funcional para la inmensa mayoría de
los servidores terminales sin que sea necesaria la acción del usuario.
El fichero de configuración named.conf del demonio (del inglés, daemon) named (nombre en el
sistema del demonio del servidor de nombres de dominio Bind) se encuentra en /etc/bind, de modo
que todos los ficheros estáticos de configuración relacionados con Bind estén en el mismo lugar.
Se recomienda encarecidamente no modificar esta configuración, más en un sistema GNU/Debian
Linux. De todos modos, si es necesario hacerlo, posiblemente la mejor manera sea usando un
enlace simbólico a la localización que desee usarse.
Los ficheros de datos de las zonas para los servidores raíz y las zonas de traducción de
direcciones (del inglés, forward) y de traducción inversa (del inglés, reverse) para el host local (del
inglés, localhost) se encuentran también en /etc/bind. El directorio de trabajo (del inglés, working
directory) de named es /var/cache/bind. Por lo tanto, cualesquiera ficheros temporales generados
por named, como los ficheros de la base de datos de las zonas que son secundarias para el
demonio, serán escritos en el sistema de ficheros de /var, que es a donde pertenecen. Para
conseguir que esto funcione, el named.conf proporcionado con la instalación usa explícitamente
90
rutas absolutas (del inglés, fully-qualified o absolute pathnames) para referenciar los ficheros en
/etc/bind.
A diferencia de anteriores paquetes Debian de Bind, los ficheros named.conf y todos los db.* de la
instalación se consideran ficheros de configuración. Por ello, si tan sólo se requiere una
configuración "de caché" para un servidor que no ha de ser el autorizado (del inglés, authoritative)
de ningún dominio, se puede ejecutar la configuración proporcionada tal cual. Si es necesario
cambiar opciones en el named.conf, o incluso referentes al init.d, puede hacerse sin compromiso,
pues las futuras actualizaciones respetarán dichos cambios, siguiendo la política de paquetes de
Debian.
Si bien el lector es libre para idear la estructura que más le plazca para los servidores de los cuales
necesita ser el autorizado, se sugiere que todos los ficheros db para las zonas de las cuales se es
servidor primario (del inglés, master) estén en /etc/bind (quizás incluso en una estructura de
subdirectorios, dependiendo de la complejidad), y usar rutas absolutas en el fichero named.conf.
Cualesquiera zonas de las que se es servidor secundario (del inglés, secondary) deberían
configurarse en el named.conf como nombres de fichero sin ruta, de forma que los ficheros de
datos terminen creándose en /var/cache/bind. A lo largo del artículo se ilustrará este concepto para
una mejor comprensión.
Traducción de nombres a direcciones IP
El primer paso es editar el fichero /etc/bind/named.conf.options, donde cambiaremos algunos de
los valores por defecto y añadiremos todo lo necesario para que nuestro dominio sea accesible
desde el exterior.
A menos que seamos un proveedor de servicios de internet, se nos habrán proporcionado una o
más direcciones IP de servidores de nombres estables, que seguramente querremos usar como
redireccionadores (del inglés, forwarders), si bien no es imprescindible para conseguir los objetivos
básicos de este artículo. Para ello deberemos descomentar el bloque casi al principio del fichero:
// forwarders {
// 0.0.0.0;
// };
Y dejarlo en algo como esto:
forwarders {
66.79.160.3;
};
91
Donde las IPs son las correspondientes a nuestro ISP. Esta directiva le indica a nuestro servidor
que pase a otro servidor de nombres todas las peticiones para las cuales no es el autorizado o no
tiene la respuesta en caché. En el caso de no especifiAlain, se usarán los servidores raíz de DNS.
Otras opciones interesantes de Bind (dentro de la directiva options y finalizadas en punto y coma)
son:
1. pid-file "/var/run/named.pid";, que definiría la localización del fichero que contiene el PID
(del inglés, Process IDentificator) del demonio named,
2. stacksize 30M;, que determinaría un tamaño de pila de treinta megabytes,
3. datasize 20M;, que especificaría un tamaño máximo de memoria dedicado a almacenar
datos de veinte megabytes,
4. transfer-format many-servers;, que provocaría la transferencia en paralelo de varias zonas
a los servidores secundarios, acelerando el proceso,
5. allow-transfer { slaves; };, que acotaría globalmente las transferencias de zonas a los
servidores secundarios en la lista slaves (ver más abajo el uso de listas de control de
acceso),
6. y version "DNS server";, que ocultaría la versión de Bind que se está ejecutando, en aras a
una mayor seguridad del sistema.
Acto seguido se procederá a dar de alta las zonas para nuestros dominios. Si abrimos con un
editor de textos el /etc/bind/named.conf que viene por defecto con la instalación encontramos cinco
zonas:
La raíz (el punto)
localhost
127.in-addr.arpa
0.in-addr.arpa
255.in-addr.arpa
Mediante la primera damos a conocer los servidores raíz a nuestro servidor de DNS, mientras que
con las otras cuatro nos hacemos cargo de la traducción normal e inversa del localhost. A partir de
aquí, abrimos el fichero /etc/bind/named.conf.local y en él creamos la zona de nuestro dominio:
zone "linuxsilo.net" {
type master;
file "/etc/bind/db.linuxsilo.net";
allow-query { any; };
allow-transfer { slaves; };
};
92
El orden de las zonas es completamente irrelevante, pero se recomienda dejarlas en orden
alfabético para una más fácil localización en el futuro. Nótese que el nombre de la zona no termina
en "." (punto). Este es el cometido de los parámetros de cada zona:
1. type master; significa que el servidor de dominios es primario o maestro de la zona. Más
adelante, al configurar servidores secundarios, se usará type slave;.
2. file "/etc/bind/db.linuxsilo.net"; es el fichero donde especificaremos la configuración de esa
zona. Nótese que se usa una ruta absoluta, siguiendo la política de directorios de Debian.
El contenido de este fichero se especificará en breve.
3. allow-query { any; }; significa que se permiten consultas (del inglés, queries) externas a la
zona. Esto es algo útil y necesario, a menos que se quiera ser muy paranoico con la
seguridad. Simplemente se ofrece de forma técnicamente ordenada la información que es
públicamente accesible.
4. allow-transfer { slaves; }; posibilita la transferencia automática de esta configuración a los
servidores secundarios de las zonas bajo nuestro control que se especifiquen en la lista
slaves. Se profundizará más en el punto de transferencia de zonas.
Seguramente, el lector se habrá percatado ya de que se han usado dos palabras especiales, any y
slaves, que requieren una mención especial. Efectivamente, además de hacer notar la sintaxis
similar a la del lenguaje de programación C, con la que se debe ser extremamente cuidadoso, hay
dos comentarios extras que hacer:
1. any es una palabra reservada de la sintaxis de bind que significa "cualquier dirección IP",
como era lógico. Su uso es muy común y necesario. Otras palabras reservadas
importantes son none, que significa "ningún host", localhost, que significa el host local
desde cualquiera de las interfaces del sistema, y localnets, que representa a todos los
hosts de las redes para las cuales el sistema tiene una interfaz.
2. slaves, en cambio, no es ninguna palabra reservada de bind, sino que corresponde al
concepto de lista de control de acceso (ACL, del inglés, Access Control List). Estas listas
de direcciones IP nos ahorran trabajo pues, de este modo, tan sólo tenemos que
especificarlas una vez y, dado que les asginamos un identificador de grupo, podemos
referenciarlas de forma más simple y rápida. Este es el código de la ACL usada en el
ejemplo que, por supuesto, debe especificarse en algún lugar del documento antes de ser
usada:
acl "slaves" {
213.96.79.79;
};
El lector se habrá dado cuenta en seguida de las grandes ventajas de usar estas listas, bien sea
porque la lista se use en varias zonas, bien porque tengamos más de un servidor esclavo. Nótese
93
que en los identificadores de las ACL se diferencian mayúsculas y minúsculas (en inglés, case
sensitive).
A continuación se detalla el contenido del fichero de datos de la zona linuxsilo.net:
;
; BIND data file for zone linuxsilo.net
;
$TTL 604800
@ IN SOA linuxsilo.net. hostmaster.linuxsilo.net. (
2005052401 ; Serial yyyy/mm/dd/id
10800 ; Refresh (3 hours)
7200 ; Retry (2 hours)
1296000 ; Expire (15 days)
172800 ) ; Negative Cache TTL (2 days)
@ IN NS ns1.linuxsilo.net.
@ IN NS ns2.linuxsilo.net.
@ IN MX 20 mx1.linuxsilo.net.
@ IN MX 30 mx2.linuxsilo.net.
@ IN TXT "Linux Silo Dot Net"
@ IN HINFO "Intel Pentium IV" "Debian Linux"
@ IN LOC 39 34 58 N 2 38 2 E 100m 10000m 20m 100m
@ IN A 66.79.182.201
ns1 IN A 66.79.182.201
ns2 IN A 213.96.79.79
mx1 IN A 66.79.182.201
mx2 IN A 213.96.79.79
www IN A 66.79.182.201
www2 IN A 66.79.182.201
webmail IN A 66.79.182.201
ssh.tcp SRV 0 0 22 linuxsilo.net.
smtp.tcp SRV 0 0 25 mx1.linuxsilo.net.
http.tcp SRV 0 3 80 linuxsilo.net.
http.tcp SRV 0 1 80 www2.linuxsilo.net.
https.tcp SRV 1 0 443 linuxsilo.net.
pop3s.tcp SRV 0 0 995 mx1.linuxsilo.net.
94
*.tcp SRV 0 0 0 .
*.udp SRV 0 0 0 .
Se comentan acto seguido todas y cada una de las directivas y opciones de estos ficheros de
configuración (un punto y coma, ";", indica que todo lo que hay a su derecha es un comentario):
1. $TTL 604800: directiva obligatoria a partir de la versión 9 de Bind (RFC1035 y RFC2308),
indica el tiempo de vida (TTL, del inglés, Time To Live) de la información contenida en el
fichero. Es decir, el tiempo máximo de validez, tras el cual deberá refrescarse o
actualizarse (para comprobar que no haya cambiado). Es lo que se conoce como caché
positiva/negativa (del inglés, positive/negative caching), como se especifica en el
RFC2308. Por defecto se usan segundos (604800 segundos equivale a siete días
exactos), pero pueden usarse también semanas ($TTL 1w), días ($TTL 7d), horas ($TTL
168h) y minutos ($TTL 10080m). Estas abreviaturas se usan asimismo en el registro SOA,
que se explica a continuación.
Otra directiva interesante, aunque no se use en los ejemplos, es $INCLUDE <zone-file>,
que hace que named incluya otro fichero de zona en el lugar donde la directiva se usa.
Esto permite almacenar parámetros de configuración comunes a varias subzonas en un
lugar separado del fichero de la zona principal.
2. @ IN SOA linuxsilo.net. hostmaster.linuxsilo.net.: el registro SOA (del inglés, Start Of
Authority) se encuentra siempre tras las directivas y proclama información relevante sobre
la autoridad de un dominio al servidor de nombres. Es siempre el primer recurso en un
fichero de zona. El símbolo "@" (arroba) equivale a la directiva $ORIGIN (o el nombre de la
zona si dicha directiva no se ha usado - caso más frecuente) como espacio de nombres de
dominio definido por este registro. Este sería el esqueleto de este registro:
@ IN SOA <primary-name-server> <hostmaster-email> (
<serial-number>
<time-to-refresh>
<time-to-retry>
<time-to-expire>
<minimum-TTL> )
El servidor de nombres primario que es el autorizado de este dominio se usa en <primary-
name-server> y el correo electrónico de la persona a contactar acerca de este espacio de
95
nombres (del inglés, namespace) se sustituye en <hostmaster-email> (nótese que no tiene
porqué corresponder con una dirección del propio dominio).
El campo <serial-number> es un número que se incrementa cada vez que se modifica un
fichero de una zona, de forma que Bind se dé cuenta de que tiene que recargar esta zona.
Se recomienda usar la fecha de modificación en formato AAAAMMDD, donde AAAA es el
año en formato de cuatro cifras, MM es el mes en dos cifras, y DD es el día de mes en dos
cifras, seguido de un número de dos cifras, empezando por el 01. De este modo se podrán
realizar hasta cien cambios por día.
El campo <time-to-refresh> le dice a los servidores secundarios (esclavos) cuánto tiempo
deben esperar antes de preguntar a su servidor principal (maestro) si se ha hecho algún
cambio en la zona. El valor del campo <serial-number> es usado por los esclavos para
determinar si se está usando información anticuada que deba actualizarse.
El campo <time-to-retry> especifica a los servidores esclavos el intervalo de tiempo a
esperar antes de solicitar una actualización en el caso de que el servidor de nombres
principal no esté respondiendo. Si el servidor maestro no ha respondido a la petición de
actualización antes de que expire el tiempo del campo <time-to-expire>, el esclavo dejará
de actuar como servidor el autorizado de ese espacio de nombres (zona)
El campo <minimum-TTL> solicita a otros servidores de dominio que almacenen en su
caché la información de esta zona durante al menos la cantidad de tiempo en él
especificada.
Nótese que el campo <primary-name-server> termina en un punto, que es obligatorio
poner, y que representa, según lo explicado en el apartado introductorio del artículo, el
servidor de nombres raíz.
Asimismo, este punto aparecerá en todas las referencias explícitas al dominio a lo largo del
fichero. Cuando se configura un host o subdominio, por ejemplo ftp, se hace una referencia
implícita y Bind añade automáticamente el dominio, que saca de la "@" del registro SOA.
En cualquier caso, es posible usar referencias implícitas o explícitas indistintamente.
3. NS ns1.linuxsilo.net. y NS ns2.linuxsilo.net.: indican los servidores de nombre que tienen
autoridad sobre el dominio. Nótese que la arroba nos ahorra tener que escribir el nombre
del dominio completo. De hecho, el prefijo, IN también es prescindible. Esta omisión es
96
posible gracias a que Bind toma las características omitidas del registro SOA anterior, es
decir, @ IN. Desde luego, ambas formas son correctas.
4. MX 20 ns1.linuxsilo.net.: se trata de un registro MX (del inglés, Mail eXchanger) e indica
dónde mandar el correo destinado a un espacio de nombres controlado por esta zona. El
dígito que sigue a la palabra MX representa la prioridad respecto a otros registros MX para
la zona, que se especificarían en posteriores líneas (MX 30 ns2.linuxsilo.net.), siguiendo el
mismo formato pero variando dicho dígito (incrementándolo a medida que pierdan prioridad
frente a anteriores registros). Es decir, cuanto más bajo es el valor de preferencia, mayor
prioridad adquiere.
5. TXT "LinuxSilo.net DNS server": este es un registro a descriptivo, en texto plano (del
inglés, plain text), del servidor. Puede usarse libre y arbitrariamente para propósitos
diversos. Aparecerá como resultado de una consulta sobre este tipo de registro hecha al
servidor de nombres sobre esta zona.
6. HINFO "Intel Pentium IV" "Debian Linux": otro registro, también a título informativo y
totalmente opcional (del inglés, Host INFOrmation), cuyo propósito es informar sobre el
hardware y el sistema operativo, en este orden, delimitados por dobles comillas y
separados por un espacio o tabulador, de la máquina sobre la cual el servidor de nombres
se ejecuta. Tanto este tipo de registro (HINFO) como el anterior (TXT) pueden usarse en
cada uno de los subdominios (no únicamente en el dominio principal de la zona), como se
verá más abajo.
7. LOC 39 34 58 N 2 38 2 E 100m 10000m 20m 100m: registro de localización geográfica del
servidor, de nuevo opcional, que es usado por las herramientas de representación gráfica
de localizaciones de servidores, por ejemplo las de la asociación CAIDA (del inglés,
Cooperative Association for Internet Data Analysis) y otras. Puede encontrarse información
sobre este tipo de registro en el RFC1876. Las coordenadas (latitud, longitud y diámetro
del objeto) se encuentran en formato WGS-84 (del inglés, World Geodetic System, del año
1984). La localización usada en el artículo corresponde a Palma, Mallorca, Islas Baleares,
España.
El formato a seguir es el siguiente: <owner><TTL><class> LOC ( d1 [m1 [s1]] {"N"|"S"} d2
[m2 [s2]] {"E"|"W"} alt["m"] [siz["m"] [hp["m"] [vp["m"]]]] ). Donde:
97
Parámetro Significado Unidad Valores Comentario
d1 Latitud (grados)
º 0..90 Porción en grados de la latitud
m1 Latitud (minutos)
' 0..59 Porción en minutos de la latitud. Si se omite se toma por defecto 0'
s1 Latitud (segundos)
" 0..59,999 Porción en segundos de la latitud. Si se omite se toma por defecto 0"
N/S Latitud (hemisferio)
N/S Hemisferio terrestre norte/sur
d2 Longitud (grados)
º 0..180 Porción en grados de la longitud
m2 Longitud (minutos)
' 0..59 Porción en minutos de la longitud. Si se omite se toma por defecto 0'
s2 Longitud (segundos)
" 0..59,999 Porción en segundos de la longitud. Si se omite se toma por defecto 0"
E/W Longitud E/W Longitud E=este/W=oeste
alt Altitud m -100000.00 .. 42849672,95
Altitud con precisión de 0.01 m.
siz Tamaño m 0..90000000,00 Diámetro de la esfera que contiene el punto indicado. Si se omite se toma por defecto 1 m.
hp Precisión horizontal
m 0..90000000,00 Precisión horizontal en metros. Si se omite se toma por defecto 10.000 m.
vp recisión vertical
m 0..90000000,00 Precisión vertical en metros. Si se omite se toma por defecto 10 m.
8. localhost A 127.0.0.1: registro que relaciona el host local con su IP de loopback.
9. linuxsilo.net. A 66.79.182.201: registro que relaciona el nombre de dominio de segundo
nivel (el "principal" de la zona) con la IP donde está hospedado. Este es el registro más
usado, pues cualquier petición a linuxsilo.net será resuelta mediante este registro, se use
el protocolo de comunicaciones que se use (por ejemplo, http://linuxsilo.net).
10. ns1 A 66.79.182.201: a partir de aquí empieza la traducción de subdominios del dominio
para el cual somos el autorizado: los dominios de tercer nivel y sucesivos. Fíjese el lector
98
en que debe crearse un registro para cada uno, sin posibilidad de "agrupar" de ningún
modo. Asimismo, nótese que, al ser subdominios de la zona, se ha omitido el sufijo
linuxsilo.net., que se encuentra implícito debido a que no termina en "." (punto).
Es simplemente una cuestión de claridad y ahorro de espacio, pues las representaciones
en ambas zonas son - repetimos de nuevo - igualmente correctas. Otros registros similares
se citan, agrupados, a continuación:
ns2 A 213.96.79.79
TXT "LinuxSilo.net secondary nameserver"
HINFO "Intel Pentium MMX" "Debian Linux"
www A 66.79.182.201
pop3 A 66.79.182.201
smtp A 66.79.182.201
ftp A 66.79.182.201
ts A 213.96.79.79
TXT "LinuxSilo.net Team Speak server"
HINFO "Intel Pentium MMX" "Debian Linux"
Dese cuenta el lector de que se han usado dos direcciones IP distintas, lo que indicaría a
priori que, en realidad, todos estos hosts (dominios de tercer nivel) se encuentran tan sólo
en dos máquinas distintas. Pero esto no tiene porqué ser cierto, pues podría tenerse una
misma IP pública pero varias máquinas sirviendo los distintos puertos usados en estos
servicios, gracias a la acción de un router.
A propósito del concepto de alias (www, pop3, smtp y ftp son de hecho el mismo host)
existe una controvertida discusión sobre si es mejor usar el tipo de registro CNAME (del
inglés, Canonical NAME) o IN A. Muchos gurús de Bind recomiendan no usar registros
CNAME en absoluto, si bien esa discusión se escapa de los objetivos de este artículo.
En cualquier caso, es muy recomendable seguir la regla de que los registros MX, CNAME
y SOA nunca deben referenciar un registro CNAME, sino exclusivamente algo con un
registro tipo "A". Por lo tanto, no es aconsejable usar:
web CNAME www
Pero sí sería correcto:
web CNAME ns
99
También es seguro asumir que un CNAME no es un host adecuado para una dirección de
correo electrónico: [email protected], sería incorrecta dada la configuración
de arriba. La manera de evitar esto es usar registros "A" (y quizás algunos otros también,
como el registro MX) en su lugar. El autor de este artículo se decanta por el uso de IN A y
recomienda dicha práctica.
Traducción inversa
En estos momentos, los programas son ya capaces de convertir los nombres en linuxsilo.net y
balearikus-party.org a direcciones a las cuales pueden conectarse. Pero también se requiere una
zona inversa, capaz de permitir al DNS convertir una dirección en un nombre. Este nombre es
usado por muchos servidores de diferentes clases (FTP, IRC, WWW y otros) para decidir si quieren
"hablar" con el cliente o no y, si es el caso, quizás incluso cuánta prioridad se le debe asignar.
Para poder tener acceso completo a todos estos servicios en Internet es necesaria una zona
inversa.
En el fichero /etc/bind/named.conf hallamos varias zonas inversas que vienen por defecto con la
instalación, justo debajo de dos líneas de comentario como estas:
// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912
Ahí podemos encontrar la traducción de zonas inversas para localhost, 127.in-addr.arpa, 0.in-
addr.arpa y 255.in-addr.arpa, que no es necesario modificar para nada excepto en el primer caso.
Tras ellas deberemos añadir nuestra zona: 38.127.217.in-addr.arpa (recuérdese que se escriben
en orden inverso, como se explica en el apartado introductorio de este artículo):
zone "38.127.217.in-addr.arpa" {
type master;
file "/etc/bind/db.217.127.38";
};
La sintaxis es idéntica a la utilizada en las zonas de traducción de nombres explicadas en el punto
anterior, y los comentarios anteriores mantienen su validez aquí. Pasemos a ver el contenido del
fichero /etc/bind/db.217.127.38:
;
; BIND reverse data file for zone 217.127.38
;
$TTL 604800
100
@ IN SOA linuxsilo.net. hostmaster.linuxsilo.net. (
2001081501 ; Serial
10800 ; Refresh (3 hours)
7200 ; Retry (2 hours)
1296000 ; Expire (15 days)
172800 ) ; Negative Cache TTL (2 days)
@ IN NS ns1.linuxsilo.net.
NS ns2.linuxsilo.net.
156 IN PTR ns1.linuxsilo.net.
Este sería el aspecto de la zona inversa localhost, que deberemos modificar ligeramente a partir
del original:
;
; BIND data file for local loopback interface
;
$TTL 604800
@ IN SOA localhost. hostmaster.linuxsilo.net. (
2001061501 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
IN NS ns1.linuxsilo.net.
1 IN PTR localhost.ns1.linuxsilo.net.
El mapeado inverso de la dirección del host local (127.0.0.1) nunca cambia, por lo que los tiempos
entre cambios son largos. Nótese el número de serie, que codifica la fecha: el fichero fue cambiado
por última vez durante el verano del 2001, fecha en que el servidor fue creado. Nótese asimismo
que sólo el servidor maestro se lista en el dominio localhost. El valor de "@" aquí es 0.0.127.in-
addr.arpa.
De nuevo, los conceptos son los mismos (la "@" - arroba - indica el dominio de la zona
linuxsilo.net., el "." - punto - del final hace referencia al servidor de nombres raíz y el registro "SOA"
tiene exactamente la misma estructura y funcionalidad), excepto las dos últimas líneas:
1. @ IN NS ns1.linuxsilo.net. y NS ns2.linuxsilo.net.: indican a qué servidores de nombres
debe preguntarse por la traducción inversa de una dirección IP de esta zona.
101
2. 156 IN PTR ns1.linuxsilo.net.: este es el registro que se usará para devolver el nombre que
queremos que corresponda con la dirección IP que nos pertenece (cuidado al crear estos
registros, pues debe hacerse referencia exclusivamente a direcciones IP que sean de
nuestra propiedad o provocaríamos un conflicto). En este caso se indica que la dirección
156 (implícitamente se le añade el sufijo .38.127.217.in-addr.arpa, lo que indica que se
trata de "nuestra" dirección IP 66.79.182.201) equivale al host ns1.linuxsilo.net.
Es obvio que aquí "falta información", pues la dirección IP 66.79.182.201 equivale, en
realidad, a más hosts, tal y como hemos especificado en el fichero
/etc/bind/db.linuxsilo.net. Esto es cierto, pero el autor es de la opinión de que es
redundante añadir líneas del estilo:
156 IN PTR ftp.linuxsilo.net.
156 IN PTR pop3.linuxsilo.net.
156 IN PTR smtp.linuxsilo.net.
156 IN PTR www.linuxsilo.net.
[..]
Es decir, se estima más adecuado especificar un único FQDN por IP. Por supuesto, si se
poseyera un rango de direcciones IP, por ejemplo de 66.79.182.201 a 217.127.38.160,
ambos inclusive, aparecerían registros similares a los siguientes (variarían en función del
caso concreto):
156 IN PTR ns1.linuxsilo.net.
157 IN PTR ftp.linuxsilo.net.
158 IN PTR smtp.linuxsilo.net.
159 IN PTR ssh.linuxsilo.net.
160 IN PTR www.linuxsilo.net.
Para este ejemplo, se deduce que la zona linuxsilo.net. está dividida en cinco máquinas
distintas, una para cada uno de los servicios mencionados (NS, FTP, SMTP, SSH y WWW,
respectivamente).
3.
¿Por qué la traducción inversa no funciona? Hay una serie de "atenciones especiales" que prestar
en este punto que a menudo se pasan por alto al configurar un servidor de nombres de este tipo.
Se discuten a continuación dos errores comunes en las traducciones inversas:
1. La zona inversa no ha sido delegada. Cuando se solicita un rango de direcciones IP y un
nombre de dominio a un proveedor de servicios, el nombre de dominio es generalmente
102
delegado por norma. Una delegación es el servidor de nombres específico que permite ir
saltando de un servidor de nombres a otro tal y como se explica en la sección introductoria
de este artículo.
La zona inversa también debe ser delegada. Si se obtiene la red 217.127.38 con el dominio
linuxsilo.net a través de un proveedor, es preciso que dicho proveedor añada un registro
NS para nuestra zona inversa así como para nuestra zona directa. Si se sigue la cadena
desde in-addr.arpa hacia arriba hasta llegar a nuestra red, probablemente se encontrará
una fractura en la cadena, muy probablemente a la altura de nuestro proveedor de
servicios. Habiendo encontrado el eslabón roto, contacte con su proveedor de servicios y
pídales que corrijan el error.
2. Su subred no pertenece a una clase definida. Este es un concepto más avanzado, pero las
subredes sin clase (del inglés, classless subnet) son muy comunes en la actualidad y
probablemente tenga una si la suya es una empresa pequeña.
Una subred sin clase es lo que consigue que Internet siga funcionando hoy en día. Hace
algunos años se discutía mucho sobre la falta de direcciones IP. Los cerebros del IETF (del
inglés, Internet Engineering Task Force), que mantienen Internet funcionando, se
exprimieron la cabeza y hallaron la solución al problema, aunque a cierto coste. El precio
es que se obtiene menos que una subred de tipo "C" y algunas cosas pueden dejar de
funcionar.
La primera parte del problema es que su ISP debe entender la técnica utilizada. No todos
los pequeños proveedores de servicios tienen un conocimiento práctico de su
funcionamiento, por lo que quizás deba usted explicárselo y ser algo insistente (aunque
asegúrese primero que lo entiende). Entonces, ellos deberán preparar una zona inversa en
su servidor cuya correctitud puede ser examinada mediante la utilidad dig del paquete
dnsutils.
La segunda y última parte del problema es que usted debe entender la problemática y su
solución. Si no está seguro, haga aquí una pausa y busque más información sobre ello.
Sólo entonces, debería usted configurar su zona inversa para su red sin clase.
Pero hay aún otra trampa oculta en este concepto. Los servidores de nombres de dominio
antiguos no serán capaces de seguir el registro CNAME en la cadena de traducciones y
errarán en la traducción inversa de su máquina. Esto puede terminar en la asignación de
una clase de acceso incorrecta por parte de un servicio, una denegación de servicio o algo
103
a medio camino entre ambos. Si se encuentra en este caso, la única solución es que su
ISP inserte directamente su registro PTR directamente en su zona de red sin clase en lugar
de usar registros CNAME.
Algunos ISP ofrecen diversas alternativas para tratar este problema, como formularios web
que le permitirán introducir su mapa de registros de traducción inversa, etc.
Servidores secundarios
Una vez se han configurado correctamente las zonas en el servidor principal (maestro), es
necesario preparar al menos un servidor secundario (esclavo), que proporcionará robustez y
fiabilidad. Si el servidor maestro cae los usuarios aún serán capaces de obtener información del
esclavo acerca de las zonas que se representan.
El servidor esclavo debería estar lo más lejos posible del maestro, debiendo ambos compartir la
menor cantidad posible de las siguientes características: suministro eléctrico, red de área local
(LAN, del inglés, Local Area Network), ISP, ciudad y país. Si todas ellas son distintas entre el
maestro y el esclavo, entonces se tiene un servidor secundario realmente bueno.
Un servidor esclavo es simplemente un servidor de nombres que replica los ficheros de las zonas
de un maestro. Se configuran tal que así:
zone "balearikus-party.org" {
type slave;
file "sec.balearikus-party.org";
allow-query { any; };
masters { 66.79.182.201; };
};
zone "linuxsilo.net" {
type slave;
file "sec.linuxsilo.net";
allow-query { any; };
masters { 66.79.182.201; };
};
Nótese que la estructura es la misma que para el servidor primario, cambiando únicamente algunos
parámetros:
1. type slave;: indica que el servidor es esclavo para esta zona.
2. file "sec.balearikus-party.org"; y file "sec.linuxsilo.net";: como se ha explicado en la
introducción del artículo, para seguir la política de directorios de Debian, los archivos
temporales de las zonas generados automáticamente por el servidor secundario deben
104
guardarse en el directorio por defecto /var/cache/bind, por lo que tan sólo se especifican
ficheros (sin ruta, o con ruta relativa implícita, que es lo mismo). Véase el punto siguiente
para más información sobre el contenido de estos ficheros.
3. allow-query { any; };: mismo concepto que en el servidor primario.
4. masters { 66.79.182.201; };: define qué servidor es maestro para esta zona (de la cual,
recordemos, se es esclavo). Podría haberse usado una ACL aquí, de la misma manera que
se hace en el /etc/bind/named.conf del maestro, pero no se ha estimado oportuno pues
existe un único maestro para ambas zonas. De todos modos, si el lector debe administrar
una red de servidores de nombres, donde el papel de maestro y esclavo es desempeñado
a la vez por el mismo host en función de la zona, sería entonces muy conveniente crear
varias ACL, de forma que se facilite el mantenimiento y el control en la asignación de
maestro y esclavos para cada zona.
Las demás opciones de configuración se usarían de modo idéntico al del servidor maestro, siempre
y cuando las condiciones sean las mismas. Es decir, se aplican las mismas directivas (por ejemplo,
options, en la cual incluiríamos la opción forwarders) y posibilidades.
Por último, se desea destacar este apartado un aspecto que no debe pasarse por alto: las zonas
inversas, aunque especiales, también son zonas y deben transferirse del servidor primario a los
secundarios. En este momento, el que hasta ahora era servidor primario pasa a ser además
servidor secundario, pues ns2.linuxsilo.net es maestro de su zona inversa (79.96.213.in-addr.arpa),
que transferirá a ns1.linuxsilo.net, convirtiéndolo en esclavo únicamente para esa zona.
Del mismo modo, ns1.linuxsilo.net actuará como maestro de su zona inversa (38.127.217.in-
addr.arpa), que transferirá a ns2.linuxsilo.net al igual que venía ocurriendo con las zonas
balearikus-party.org y linuxsilo.net. A continuación se presentan los cambios en los ficheros de
configuración. En el named.conf de ns1.linuxsilo.net:
zone "38.127.217.in-addr.arpa" {
type master;
file "/etc/bind/db.217.127.38";
allow-transfer { slaves; };
};
zone "79.96.213.in-addr.arpa" {
type slave;
file "sec.db.213.96.79";
masters { 213.96.79.79; };
};
105
Y en el named.conf de ns2.linuxsilo.net:
zone "79.96.213.in-addr.arpa" {
type master;
file "/etc/bind/db.213.96.79";
allow-transfer { 66.79.182.201; };
};
zone "38.127.217.in-addr.arpa" {
type slave;
file "sec.db.217.127.38";
masters { 66.79.182.201; };
};
El contenido de las zonas se mantendría exactamente igual. Tras estos cambios, en el directorio
/var/cache/bind de ns1.linuxsilo.net aparecería el fichero sec.db.213.96.79 y en el mismo directorio
de ns2.linuxsilo.net aparecería el fichero sec.db.217.127.38, todo gracias a la transferencia
automática de zonas que pasa a verse a continuación.
Transferencia segura de zonas
El lector se habrá dado cuenta de que no se ha comentado nada de los ficheros sec.balearikus-
party.org y sec.linuxsilo.net especificados en las directivas zone del servidor secundario. Esto es
debido a que usaremos un procedimiento que permitirá que esos ficheros se creen de forma
automatizada a partir de los que creemos en el servidor primario, de forma que las tareas de
mantenimiento se facilitan enormemente.
Para ello, se deberán haber utilizado, como se ha hecho en el ejemplo, las opciones allow-transfer
{ slaves; }; y masters { 66.79.182.201; }; en las zonas definidas en los ficheros /etc/bind/named.conf
de los servidores primario y secundario, respectivamente. Esto permitirá que, realizados los
cambios deseados en el fichero /etc/bind/db.balearikus-party.org o /etc/bind/db.linuxsilo.net,
incluyendo el incremento del número de serie identificativo del registro SOA, y habiéndole
ordenado al servidor de nombres que recargue una, varias o todas las zonas, estos cambios se
reflejen en el secundario de forma que se generen los correspondientes ficheros
/var/cache/bind/sec.balearikus-party.org y /var/cache/bind/sec.linuxsilo.net.
Para que esta transferencia de zonas se haga de forma segura y controlada, impondremos ciertas
restricciones en el /etc/bind/named.conf y generaremos claves que nos asegurarán la privacidad en
la comunicación. Estas son las líneas que añadiremos en el /etc/bind/named.conf del servidor
primario (66.79.182.201 en el ejemplo):
106
controls {
inet 127.0.0.1 allow {
127.0.0.1;
}
keys {
"2002052101.linuxsilo.net.tsigkey.";
};
};
server 213.96.79.79 {
keys {
"2002052101.linuxsilo.net.tsigkey.";
};
};
Y estas las que añadiremos en el /etc/bind/named.conf del secundario:
controls {
inet 127.0.0.1 allow {
127.0.0.1;
}
keys {
"2002052101.linuxsilo.net.tsigkey.";
};
};
server 66.79.182.201 {
keys {
"2002052101.linuxsilo.net.tsigkey.";
};
};
Acto seguido se explica el significado de ambas directivas:
1. controls { inet 127.0.0.1 allow { 127.0.0.1; } keys { "2002052101.linuxsilo.net.tsigkey."; } };
es la directiva que ciñe el control sobre el servidor a través de la clave
2002052101.linuxsilo.net.tsigkey. únicamente al host local. Es decir, deberemos habernos
conectado (habitualmente de forma remota mediante SSH) al servidor y, desde allí,
ejecutar los comandos que controlan las acciones de Bind (normalmente mediante la
utilidad rndc, que se explicará más adelante). De aquí se deduce que, tanto la
transferencia remota de zonas como el control sobre el servidor (recarga de zonas, parada,
arranque, etc.) se realiza a través de esta clave cifrada. Además, se deduce también que
107
mediante esta restricción no será posible controlar Bind remotamente, como ya se ha
dicho. Esta es la opción por defecto y la que el autor de este artículo recomienda.
2. server 213.96.79.79 { keys { "2002052101.linuxsilo.net.tsigkey."; }; }; es una directiva que
indica al servidor cuándo debe usarse la clave. Al usar esta cláusula se obliga al servidor a
usar cierta clave cuando se comunique con una determinada dirección IP.
Para cada servidor es conveniente especificar una directiva server, especificando la
dirección IP de la otra máquina y el nombre de la clave a utilizar. En el ejemplo se usa la
misma clave para la comunicación entre servidores y para el control del servidor desde el
host local - habiendo accedido por SSH - mediante la utilidad rndc
Nótese que, si se cambia la clave, la herramienta rndc puede dejar de funcionar correctamente. Al
realizar este proceso se recomienda para el servidor (rndc stop o /etc/init.d/bind9 stop), sustituir las
claves y arrancarlo de nuevo (/etc/init.d/bind9 start). Antes de explicar cómo crear una clave de
este tipo, veamos el verdadero porqué de su necesidad y los problemas que un fallo de seguridad
podría causar.
Acerca de los puertos, Bind usa el 53 TCP para las transferencias y el 53 UDP para las consultas.
QUÉ ES UNA TSIG Y PARA QUÉ SE NECESITA
El DNS trabaja sobre un modelo pregunta-respuesta. Si un cliente necesita información del DNS,
manda una petición al servidor de DNS y éste le devuelve una respuesta. Hasta hace poco sólo
era posible basarse en la dirección IP de origen para discernir si debía o no contestarse una
consulta. Pero esto no es precisamente "ideal".
La autenticación basada únicamente en la dirección IP de origen se considera insegura. Las
transacciones firmadas (TSIG, del inglés, Transaction SIGnatures) añaden las firmas criptográficas
como método de autenticación en una conversación del DNS. Se usa una clave secreta compartida
para establecer la confianza entre las partes involucradas.
Las TSIG se usan para asegurar que la información del DNS que pretende provenir de cierto
servidor es realmente de ese servidor. Se usan principalmente para la autenticación en la
transferencia de zonas entre el servidor de nombres primario y los secundarios. Se quiere asegurar
que los servidores secundarios no serán nunca engañados para que acepten una copia de una
zona para la cual es el autorizado de un impostor que escucha en la dirección IP del servidor
primario.
108
Las transacciones firmadas se definen en el RFC2845.
En el ejemplo anterior se ha usado la clave tsigkey.linuxsilo.net.20010922 para autenticar el tráfico
del DNS entre los dos servidores, el primario (66.79.182.201) y el secundario (213.96.79.79).
CREACIÓN DE UNA CLAVE TSIG
En la instalación por defecto del paquete Debian se facilita una clave TSIG previamente generada
y totalmente funcional. Pero es, desde luego, la misma para todo aquel que se instala ese paquete.
Por lo tanto, es más que recomendable cambiarla. A continuación se muestra cómo generar una
clave particular y cómo usarla para que la transferencia de zonas se haga de forma segura.
TSIG usa una clave secreta compartida que es incorporada a una dispersiíon (del inglés, hash)
MD5 de la información a ser firmada. Bind viene con una herramienta para crear este tipo de
claves, llamada dnssec-keygen, cuyos parámetros son numerosos (ejecute dnssec-keygen --help
para ver la lista completa y man dnssec-keygen para la página del man a propósito de esta
utilidad). Estos son los pasos a seguir para crear rápidamente una clave:
1. Mediante la ejecución del comando dnssec-keygen -a HMAC-MD5 -b 512 -n HOST
2002052101.linuxsilo.net.tsigkey. se crea una clave llamada
2002052101.linuxsilo.net.tsigkey. usando el algoritmo HMAC-MD5, de 512 bits (del inglés,
BInary digiT) y tipo HOST (que es precisamente el uso para el cual va destinada).
2. De los dos ficheros generados, K2002052101.linuxsilo.net.tsigkey.+157+30191.key y
K2002052101.linuxsilo.net.tsigkey.+157+30191.private, se usará sólo el segundo. Se
aprovecha para mencionar que el formato de salida de los nombres de los ficheros
generados es Knnnn.+aaa+iiiii, donde nnnn es el nombre de la clave, aaa es la
representación numérica del algoritmo e iiiii es la marca/huella del identificador de la clave
(del inglés, footprint).
Por supuesto, los nombres de cada clave generada deben ser únicos, es decir, dos claves
no deberían compartir jamás el mismo nombre, de aquí el nombre tan inusual que se le ha
dado. La clave, propiamente dicha, es el conjunto de caracteres que se encuentra tras la
palabra Key: en la última línea del fichero con sufijo .private.
3. El siguiente paso es editar el fichero /etc/bind/rndc.key y sustituir la clave que viene por
defecto por la que acaba de ser generada. Para ello, es suficiente con cambiar el nombre
de la clave por defecto de "rndc.key" al que le hemos dado al crearla, en este caso
2002052101.linuxsilo.net.tsigkey.. Por último, hay que cambiar el valor del campo secret
por el valor de la clave generada que, como se acaba de decir más arriba, se encuentra
109
tras la palabra Key: en la última línea del fichero terminado en .private. En el caso de
ejemplo usado para el artículo, se ha generado la clave wlnQbRQM/76rol0xGkEdm [..]
MMlUFR7HpenQ==, pero el lector no debe tomar ésta como una referencia, pues variará
en cada nueva generación. Este es el contenido del fichero
K2002052101.linuxsilo.net.tsigkey.+157+30191.private:
Private-key-format: v1.2
Algorithm: 157 (HMAC_MD5)
Key: wlnQbRQM/76rol0xGkEdm [..] MMlUFR7HpenQ==
Este es el contenido del fichero /etc/bind/rndc.key que viene por defecto con la instalación
del paquete Debian:
key "rndc-key" {
algorithm hmac-md5;
secret "bsty5LYDsO8infm+n2JNsw==";
};
Y este es, finalmente, el fichero /etc/bind/rndc.key resultante del uso de la nueva clave:
key "2002052101.linuxsilo.net.tsigkey." {
algorithm hmac-md5;
secret "wlnQbRQM/76rol0xGkEdm [..] MMlUFR7HpenQ==";
};
Los dos ficheros creados al generar la clave, terminados en .key y .private, pueden ser eliminados
sin problemas. El lector, durante sus pruebas, se dará cuenta de que, si se omite el "." al final del
nombre de la clave, dnssec-keygen lo añadirá automáticamente, pudiéndose crear confusión
acerca de si el nombre que corresponde a la clave generada es con punto o sin punto al final.
Llegados a este punto, el autor recomienda usar el nombre tal y como se generó, aunque con una
simple prueba de ensayo-error (comprobar que se transfieren las zonas) se puede llegar fácilmente
a la solución correcta.
Por último, resaltar que una clave secreta es eso: secreta. Por lo tanto, es preciso que sea copiada
e instalada en ambos servidores de modo seguro. Además, se recomienda encarecidamente
cambiar los permisos de los ficheros /etc/bind/named.conf y /etc/bind/rndc.key, tanto del servidor
110
primario como del secundario, a 600 (chmod 600 /etc/bind/named.conf y chmod 600
/etc/bind/rndc.key), de manera que sean únicamente accesibles por el usuario root.
La verificación de una TSIG requiere la posibilidad de escribir un fichero temporalmente.
Asegúrese de que named tiene permisos de escritura en su directorio por defecto (cláusula
directory de la directiva options, que en Debian es, por defecto, /var/cache/bind/).
La implementación de Microsoft de las TSIG no usa el algoritmo del RFC2845 (HMAC-MD5). El
GSS-TSIG de Microsoft no cumple el estándar y, consecuentemente, no interoperará
adecuadamente con Bind.
Más información en los documentos RFC2535, RFC2845 y RFC2539
Comentarios sobre la actualización dinámica, la seguridad de las TSIG y las ACL
1. Es crítico que la clave sea guardada en secreto, lo que significa, por ejemplo, que:
a. named.conf y rndc.key no deben tener permisos de lectura para nadie que no sea
named o el usuario que ejecute rndc o nsupdate.
b. la clave no debe ser transmitida por emails, a menos que estén cifrados.
c. cualquiera a quien le dé esta clave es de confianza: por ello, désela
exclusivamente a quienes la necesiten, y nunca a personas de las que desconfíe.
d. debe considerar cambiar de clave cada cierto tiempo, después de cambios en el
personal, o si se tienen sospechas de que se pueda haber comprometido el
secreto.
2. Si ambos hosts están en la misma subred, es más difícil monitorizar (del inglés, spoofing)
la dirección IP que hacerse con una copia de la clave (por ejemplo si los routers en
contacto con el exterior filtran IPs monitorizadas), de modo que una ACL de direcciones IP
sería más efectiva.
3. Es igualmente válido especificar una ACL o una clave TSIG. Por ejemplo allow-update {key
updater; updaters; };, que significaría que tanto la TSIG como la ACL de direcciones IP son
válidas para las actualizaciones.
4. No es posible requerir a la vez una TSIG y control de acceso por IP. Los desarrolladores
de Bind no creen que esto sea útil, pues ellos se concentran en el control a nivel de usuario
más que a nivel de host de cara a las actualizaciones dinámicas (de aquí el énfasis puesto
111
en la nueva política de actualizaciones que permite a los usuarios con direcciones IP
dinámicas actualizar sus registros en el DNS).
5. Las actualizaciones dinámicas no pueden añadir o eliminar dominios, tan sólo registros de
esos dominios.
6. Un host cliente que quiera actualizar un servidor Bind únicamente necesita el binario
nsupdate y la clave apropiada. No se requieren otros binarios o librerías (del inglés,
libraries) adicionales.
7. nsupdate soporta el parámetro "-d" para tareas de depuración (del inglés, debugging).
8. nsupdate también puede usar TCP (del inglés, Transmission Control Protocol) en lugar de
UDP (del inglés, User Datagram Protocol) para las actualizaciones (parámetro "-v"), lo que
proporciona un mejor rendimiento si son muchas las actualizaciones a realizar y mayor
seguridad ya que TCP es un protocolo orientado a conexión. Además, una conexión TCP
tiene la posibilidad de ser dirigida (del inglés, piped) a través de un canal (del inglés,
tunnel) SSH (del inglés, Secure SHell)para más seguridad (encriptación y control de
acceso).
9. La política de actualizaciones es una nueva característica de Bind 9 que permite que las
actualizaciones se restrinjan a ciertos nombres específicos. Por ejemplo, para permitir que
un usuario de ADSL (del inglés, Asymmetric Digital Subscriber Line) o DHCP (del inglés,
Dynamic Host Configuration Protocol) pueda actualizar el nombre de su propio host (es
decir, aquellos a que cambian de dirección IP). Con esta política de actualizaciones, puede
configurarse una lista de claves por host y permitir a cada clave que actualice únicamente
el host o zona asociada.
Riesgos a los que expone un Bind inseguro
¿Es realmente necesario preocuparse también por el DNS? Bien, un DNS comprometido puede
exponerse a algunos riesgos interesantes:
1. Un atacante puede obtener información muy interesante si se permiten transferencias de
zonas: la lista completa de hosts y encaminadores (del inglés, routers) con sus direcciones
IP, nombres y, posiblemente, comentarios indicando su situación, etc.
2. Denegación de servicio (del inglés, Denial of service): si todos sus servidores de DNS
caen,
o Su sitio web (del inglés, website) ya no es visible (los otros websites no pueden
traducir su dirección IP).
112
o Los correos electrónicos ya no pueden ser enviados (algunos sitios en Internet con
los cuales se intercambia información a menudo habrán guardado en su caché los
registros de DNS, pero eso no durará más que unos pocos días).
o Un atacante podría inciar un falso servidor de DNS que finge ser el suyo y envía
información de DNS falsa a Internet acerca de su dominio. Es decir, pérdida de
integridad - veáse la siguiente sección.
3. Pérdida de integridad: si un atacante puede cambiar los datos del DNS o facilitar (mediante
spoofing) a otros sitios falsa información (esto se conoce como envenenamiento de DNS
(del inglés, DNS poisoning), la situación se vuelve muy peliaguda:
o Falsificar (del inglés, fake) su website, de manera que parezca el suyo, y capturar
las entradas de los usuarios que iban destinadas a su sitio, por lo que se estaría
hablando de robar cualquier cosa, desde nombres de usuario (del inglés, logins) y
contraseñas (en inglés, passwords) hasta números de tarjetas de crédito.
o Todo el correo podría ser redirigido a un servidor repetidor (del inglés, relay) que
podría copiar, cambiar o borrar correo antes de pasarlo a su sitio.
o Si su cortafuegos (del inglés, firewall) o cualquier host accesible desde Internet usa
nombres de host de DNS (del inglés, DNS hostnames) para autenticarse o para
relaciones de confianza, éstas pueden ser completamente comprometidas,
especialmente si un débil filtro de paquetes es quien protege los servidores de
Internet y la Intranet. Imagine un proxy web configurado para permitir peticiones
proxy sólo desde *.midominio.com. El atacante añade su host al dominio, por lo
que el proxy web pasa a permitir peticiones que provengan de él, permitiendo al
atacante acceso por HTTP a la Intranet. Imagine un administrador de sistemas que
usa SSH (gran invento criptográfico), pero los hosts cortafuegos tienen un .shosts
confiando en admin.midominio.com, donde admin es la estación de trabajo del
administrador. Si el atacante puede sustituir la entrada para admin.midominio.com
en el DNS, pasa a tener un acceso libre y sin necesidad de contraseña a los hosts
del cortafuegos.
El DNS se ha convertido en el objetivo favorito de los hackers, como prueban las herramientas
para realizar ataques automáticos y los gusanos que usan los fallos del DNS que aparecieron
durante el invierno de 2001.
Entonces, ¿qué medidas es necesario tomar?
Los riesgos de Bind pueden ser reducidos considerablemente con algunas medidas de prevención:
1. Aislamiento de los recursos: use un servidor dedicado y asegurado para el DNS de
Internet, no lo comparta con otros servicios y, especialmente, no permita el acceso remoto
113
de usuario. Minimizar los servicios y usuarios significa reducir la cantidad de software
ejecutándose y, por lo tanto, la probabilidad de exponerse a ataques de red. La separación
previene contra la posibilidad de que otros servicios o usuarios localicen debilidades en el
sistema y las usen para atacar a Bind.
2. Redundancia: instale un secundario en una conexión a Internet diferente (rama alejada de
su empresa, otro ISP, etc.). Si su sitio cae, al menos el resto de sitios no pensarán que
usted ha "dejado de existir", sino que tan sólo creerán que "no está disponible", por lo que,
por ejemplo, sus emails no se perderán sino que entrarán en una cola de espera
(típicamente de hasta cuatro días).
3. Use la última versión.
4. Control del acceso: restrinja la transferencia de zonas para minimizar la cantidad de
información que esté disponible en su red para los atacantes. Considere el uso de
transacciones firmadas. Considere restringir o no permitir las consultas recursivas.
5. Ejecute Bind con los mínimos privilegios: como usuario no root, con una umask muy
restrictiva (por ejemplo, 177).
6. Mayor aislación de recursos: ejecute Bind en un entorno (del inglés, jail) chroot, de modo
que sea mucho más difícil que un demonio Bind comprometido dañe el sistema operativo o
comprometa otros servicios.
7. Configure Bind para que no informe de su versión. Algunas personas no creen en esta
medida, pues es "seguridad por ocultación", pero entienda que, al menos, ayudará contra
jovencillos con scripts que rastrean la red buscando objetivos obvios. Defenderse de los
profesionales es otro asunto.
8. Detección: monitorice los logs buscando actividad inusual y cambios no autorizados en el
sistema mediante un analizador de integridad.
9. Manténgase continuamente al día de las novedades y asegúrese que se le notifica la
salida de nuevos problemas de Bind en un tiempo razonable.
114
SERVIDORES RECURSIVOS Y NO RECURSIVOS
Los servidores de nombres pueden actuar recursivamente o no permitirla. Si un servidor no
recursivo tiene la respuesta a una petición cacheada de una transacción previa o es el autorizado
del dominio al cual la consulta pertenece, entonces proporciona la respuesta apropiada. De otro
modo, en lugar de devolver una contestación real, devuelve una referencia al servidor autorizado
de otro dominio que sea más capaz de saber la respuesta. Un cliente de un servidor no recursivo
debe estar preparado para aceptar referencias y actuar en consecuencia.
Aunque los servidores no recursivos puedan parecer perezosos, tienen habitualmente un buen
motivo para deshacerse del trabajo extra. Los servidores raíz y los servidores de más alto nivel son
todos no recursivos, pero es que 10.000 consultas por segundo bien son una excusa para serlo.
Un servidor recursivo devuelve únicamente respuestas reales o mensajes de error. Se encarga de
seguir las referencias por si mismo, descargando al cliente de esa tarea.
El procedimiento básico para traducir una consulta es, esencialmente, el mismo; la única diferencia
es que el servidor de nombres se preocupa de de hacerse cargo de las referencias en lugar de
devolverlas al cliente.
LOCALIZACIÓN DE SERVICIOS
Un registro SRV especifica la localización de los servicios ofrecidos por un dominio. Por ejemplo, el
registro SRV permite consultar un dominio remoto directamente y preguntarle por el nombre de su
servidor FTP. Hasta ahora, en la mayoría de ocasiones, había que probar suerte. Para contactar el
servidor FTP de un dominio remoto, uno esperaba que el administrador de sistemas de ese
dominio hubiese seguido el estándar (el gusto mejor dicho) actual y tuviese un CNAME para ftp en
su servidor de DNS.
Los registros SRV adquieren mucha importancia en este tipo de consultas y son realmente una
mejor manera para los administradores de sistemas de trasladar servicios y controlar su uso. Sin
embargo, deben ser solicitados y analizados explícitamente por los clientes, por lo que sus efectos
se irán viendo gradualmente a medida que pase el tiempo.
Los registros SRV se parecen a registros MX generalizados con campos que permiten al
administrador local guiar y balancear la carga de las conexiones provenientes del mundo exterior.
El formato es
servicio.proto.nombre [ttl] IN SRV pri wt puerto destino
115
Donde servicio es uno de los servicios definidos en la base de datos de números asignada por la
IANA, proto puede ser tcp o udp, nombre es el dominio al cual el servicio hace referencia, pri es
una prioridad al estilo de los registros MX, wt es el peso usado para balancear la carga entre
diferentes servidores, puerto es el puerto en el cual el servicio escucha, y destino es el nombre de
host del servidor en el cual se provee ese servicio.
El registro A del destino habitualmente es devuelto de forma automática junto a la respuesta
envíada a una consulta SRV. Un valor "0" para el parámetro wt significa que no se realiza ningún
tipo especial de balanceo de carga. Un valor de "." para el destino significa que el servicio no se
ejecuta en ese sitio.
En la zona linuxsilo.net del ejemplo, adaptado del RFC2052 (donde se define SRV), se tiene lo
siguiente:
ftp.tcp SRV 0 0 21 ftp.linuxsilo.net.
ssh.tcp SRV 0 0 22 linuxsilo.net.
telnet.tcp SRV 0 0 23 linuxsilo.net.
smtp.tcp SRV 0 0 25 smtp.linuxsilo.net.
; 3/4 de las conexiones al principal, 1/4 al secundario
http.tcp SRV 0 3 80 linuxsilo.net.
http.tcp SRV 0 1 80 ns2.linuxsilo.net.
; para que funcionen tanto http://www.linuxsilo.net como http://linuxsilo.net
http.tcp.www SRV 0 3 80 linuxsilo.net.
http.tcp.www SRV 0 1 80 ns2.linuxsilo.net.
; servidor principal en el puerto 443, secundario - en caso de fallo - en otra máquina y otro puerto
https.tcp SRV 1 0 443 linuxsilo.net.
https.tcp SRV 2 0 4443 ns2.linuxsilo.net.
https.tcp.www SRV 1 0 443 linuxsilo.net.
https.tcp.www SRV 2 0 443 ns2.linuxsilo.net.
pop3s.tcp SRV 0 0 995 pop3.linuxsilo.net.
*.tcp SRV 0 0 0 .
*.udp SRV 0 0 0 .
Este ejemplo ilustra el uso tanto el parámetro wt (del inglés, weigth) para HTTP como el parámetro
de prioridad para HTTPS. Ambos servidores HTTP serán usados, dividiéndose el trabajo entre
116
ellos. El servidor secundario ns2.linuxsilo.net sólo será usado para HTTPS cuando el principal no
esté disponible. Todos los servicios no especificados están excluidos. El hecho de que el demonio
de, por ejemplo, finger no aparezca en el DNS no signifia que no se esté ejecutando, sino tan sólo
que no se podrá localizar ese servicio a través de DNS.
Microsoft usa los registros SRV estándar en Windows 2000, pero los inserta en el sistema de DNS
de una manera incompatible e indocumentada.
TIPOS DE REGISTROS DEL DNS
Tipo Nombre Función
Zona SOA Start Of Authority Define una zona representativa del DNS
NS Name Server Identifica los servidores de zona, delega subdominios
Básicos A Dirección IPv4 Traducción de nombre a dirección
AAAA Dirección IPv6 original
Actualmente obsoleto
A6 Dirección IPv6 Traducción de nombre a dirección IPv6
PTR Puntero Traducción de dirección a nombre
DNAME Redirección Redirección para las traducciones inversas IPv6
MX Mail eXchanger Controla el enrutado del correo
Seguridad KEY Clave pública Clave pública para un nombre de DNS
NXT Next Se usa junto a DNSSEC para las respuestas negativas
SIG Signature Zona autenticada/firmada
Opcionales CNAME Canonical Name Nicks o alias para un dominio
LOC Localización Localización geográfica y extensión
RP Persona responsable Especifica la persona de contacto de cada host
SRV Servicios Proporciona la localización de servicios conocidos
TXT Texto Comentarios o información sin cifrar
117
VISTAS
Las vistas (del inglés, views) son una nueva característica de Bind 9 que permite mostrar a las
máquinas internas una visión distinta de la jerarquía de nombres de DNS de la que se ve desde el
exterior (se entiende "interior" y "exterior" respecto del router que da salida a la empresa a
Internet). Por ejemplo, le permite revelar todos los hosts a los usuarios internos pero restringir la
vista externa a unos pocos servidores de confianza.
O podría ofrecer los mismos hosts en ambas vistas pero proporcionar registros adicionales (o
diferentes) a los usuarios internos.
Este tipo de configuración (llamada en ocasiones "DNS partido", del inglés "split DNS") se está
haciendo muy popular. En el pasado, se implementaba configurando servidores separados para las
versiones interna y externa de la realidad. Los clientes locales apuntaban a los servidores de
distribución que contenían la versión interna de la zona, mientras que los registros NS de la zona
padre apuntaban a servidores que corrían la versión externa.
La sentencia view de Bind 9 simplifica la configuración permitiendo tener juntos ambos conjuntos
de datos en la misma copia de named. named busca correspondencias en listas de direcciones
para adivinar qué clientes deben recibir qué datos.
La sentencia view empaqueta un lista de acceso que controla quién ve la vista, algunas opciones
que se aplican a todas las zonas en la vista y, finalmente, las propias zonas. La sintaxis es:
view "nombre-de-la-vista" {
match-clients { address_match_list; };
opcion-de-vista; ...
sentencia-de-zona; ...
};
La cláusula match-clients controla quién puede ver la vista. Las vistas son procesadas en orden
secuencial, por lo que las más restrictivas deben ir primero. Las zonas en distintas vistas pueden
tener el mismo nombre. Las vistas son una proposición de todo o nada; si las usa, todas las
sentencias zone en su fichero named.conf deben aparecer dentro del contexto de una vista.
Este es el ejemplo para los dominios linuxsilo.net y balearikus-party.org, creado a partir de la
documentación de Bind 9 que sigue el esquema de DNS partido descrito más arriba. Las dos vistas
definen ambas zonas, pero con diferentes registros.
118
acl "lan" {
192.168.0.0/24;
};
// View for all computers on local area network
view "internal" {
match-clients { lan; };
recursion yes;
// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912
// prime the server with knowledge of the root servers
zone "." {
type hint;
file "/etc/bind/db.root";
};
// Resto de zonas inversas por defecto omitidas para abreviar
zone "38.127.217.in-addr.arpa" {
type master;
file "/etc/bind/db.217.127.38";
allow-transfer { slaves; };
};
zone "79.96.213.in-addr.arpa" {
type slave;
file "sec.db.213.96.79";
masters { 213.96.79.79; };
};
zone "0.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192.168.0";
};
119
// add entries for other zones below here
zone "balearikus-party.org" {
type master;
file "/etc/bind/db.balearikus-party.org.internal";
};
zone "linuxsilo.net" {
type master;
file "/etc/bind/db.linuxsilo.net.internal";
};
};
// View for all computers outside the local area network
view "external" {
match-clients { any; };
recursion no;
// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912
// prime the server with knowledge of the root servers
zone "." {
type hint;
file "/etc/bind/db.root";
};
// Resto de zonas inversas por defecto omitidas para abreviar
zone "38.127.217.in-addr.arpa" {
type master;
file "/etc/bind/db.217.127.38";
allow-transfer { slaves; };
};
120
zone "79.96.213.in-addr.arpa" {
type slave;
file "sec.db.213.96.79";
masters { 213.96.79.79; };
};
// add entries for other zones below here
zone "balearikus-party.org" {
type master;
file "/etc/bind/db.balearikus-party.org";
allow-query { any; };
allow-transfer { slaves; };
};
zone "clan-bin.org" {
type master;
file "/etc/bind/db.clan-bin.org";
allow-query { any; };
allow-transfer { slaves; };
};
};
La red local interna es 192.168.0.0, de aquí que se use una lista de acceso que engloba a
cualquier host que sea de esa red (red 192.168.0.0, máscara 255.255.255.0, especificada como
suma de unos binarios, es decir, 24). Esta nueva situación nos lleva a precisar una nueva
definición de zona inversa, la correspondiente a la red local 0.168.192.in-addr.arpa, que se muestra
a continuación:
;
; BIND reverse data file for zone 192.168.0
;
$TTL 604800
@ IN SOA linuxsilo.net. hostmaster.linuxsilo.net. (
2001081501 ; Serial
10800 ; Refresh (3 hours)
7200 ; Retry (2 hours)
1296000 ; Expire (15 days)
121
172800 ) ; Negative Cache TTL (2 days)
@ IN NS ns1.linuxsilo.net.
1 IN PTR ns1.linuxsilo.net.
Nótese que, ahora, las zonas inversas, tanto las que se proporcionan con la instalación por defecto
para el funcionamiento básico como las definidas por el administrador, se reparten adecuadamente
entre ambas vistas. En cambio, las zonas directas son duplicadas, una ocurrencia para cada vista.
Por supuesto, los ficheros de zona apuntados contienen registros distintos, en consonancia con la
vista. Acto seguido se facilitan los registros de los ficheros de zonas directas internas (las externas
se mantienen igual, por lo que son válidas las expuestas anteriormente en este artículo).
;
; BIND data file for zone balearikus-party.org, internal view
;
$TTL 604800
@ IN SOA balearikus-party.org. hostmaster.linuxsilo.net. (
2002051001 ; Serial yyyy/mm/dd/id
10800 ; Refresh (3 hours)
7200 ; Retry (2 hours)
1296000 ; Expire (15 days)
172800 ) ; Negative Cache TTL(2 days)
balearikus-party.org. IN NS ns1.linuxsilo.net.
balearikus-party.org. IN MX 5 ns1.linuxsilo.net.
localhost IN A 127.0.0.1
balearikus-party.org. IN A 192.168.0.1
www IN A 192.168.0.1
pop3 IN A 192.168.0.1
smtp IN A 192.168.0.1
ftp IN A 192.168.0.1
;
; BIND data file for zone linuxsilo.net, internal view
;
$TTL 604800
@ IN SOA linuxsilo.net. hostmaster.linuxsilo.net. (
122
2002051001 ; Serial yyyy/mm/dd/id
10800 ; Refresh (3 hours)
7200 ; Retry (2 hours)
1296000 ; Expire (15 days)
172800 ) ; Negative Cache TTL(2 days)
NS ns1.linuxsilo.net.
MX 5 ns1.linuxsilo.net.
localhost A 127.0.0.1
linuxsilo.net. A 192.168.0.1
ns1 A 192.168.0.1
ns2 A 213.96.79.79
www A 192.168.0.1
pop3 A 192.168.0.1
smtp A 192.168.0.1
ftp A 192.168.0.1
ts A 213.96.79.79
akane A 192.168.0.1
ranma A 192.168.0.6
genma A 192.168.0.5
kasumi A 192.168.0.4
nabiki A 213.96.79.79
primetime A 192.168.0.3
LA HERRAMIENTA RNDC
El comando rndc es una útil herramienta para manipular named. La siguiente tabla muestra
algunas de las opciones que acepta. Los parámetros que provocan la creación de ficheros lo harán
en el directorio especificado como home de named en el /etc/bind/named.conf (cláusula directory,
cuyo valor por defecto es /var/cache/bind en Debian).
Comando Función
help Lista los opciones de rndc disponibles
status Muestra el estado actual del named en ejecución
123
trace Incrementa el nivel de depuración en 1
notrace Desactiva la depuración
dumpdb Vuelca la base de datos de DNS a named_dump.db
stats Vuelca estadísticas a named.stats
reload Recarga named.conf y los ficheros de zonas
reload zona Recarga sólo la zona especificada
restart Reinicia named, vaciando la caché
querylog Activa el seguimiento de las consultas entrantes
Rndc usa el puerto 953 UDP para el control remoto. Si se siguen las pautas mostradas en este
artículo, no es necesario que ese puerto sea accesible desde el exterior - configurarlo en el router -
pues el control se hará siempre desde el host local y las transferencias de zonas se realizan por el
puerto 53 TCP
PERSONALIZACIÓN DE LOS LOGS
Los logs en Bind se configuran con la sentencia logging en el named.conf. Primero se definen
canales, que son los posibles destinos de los mensajes. Luego se les dice a varias categorís de
mensajes que vayan a un canal particular.
Término Significado
canal Un lugar a donde los mensajes pueden ir: syslog, un fichero o /dev/null
categoría Una clase de mensajes que Bind puede generar; por ejemplo, mensajes sobre
actualizaciones dinámicas o mensajes acerca de respuestas a consultas
módulo El nombre del módulo de origen que genera un mensaje
lugar El nombre de un lugar syslog. DNS no tiene su propio destino, por lo que tendrán que
escogerse el estándar.
importancia Lo "malo" que es un mensaje de error; a lo que syslog se refiere como prioridad
Cuando se genera un mensaje, se le asigna una categoría, un módulo y una importancia en su
punto de origen. Después es distribuido a todos los canales asociados con esa categoría y módulo.
Cada canal tiene un filtro de importancia que define qué nivel de importancia debe tener un
124
mensaje para pasar. Los canales que llevan al syslog también son filtrados de acuerdo a las reglas
del /etc/syslog.conf.
Este es el esqueleto de una sentencia logging:
logging {
definición_de_canal;
definición_de_canal;
...
category nombre_categoría {
nombre_canal;
nombre_canal;
...
};
};
Una definición_de_canal es ligeramente diferente dependiendo de si el canal es un fichero o un
canal syslog. Se debe elegir file o syslog para cada canal; un canal no puede ser ambas cosas a la
vez.
channel "nombre_del_canal" {
file ruta [versions númvers | unlimited] [size sizespec];
syslog facility;
severity importancia;
print-category yes | no;
print-severity yes | no;
print-time yes | no;
};
En un fichero, númvers especifica cuántas versiones de copia de un fichero guardar, y sizespec
dice lo grandes que pueden llegar a ser esos ficheros (por ejemplo, 2048, 100k, 20m, 15g,
unlimited, default).
En el caso de syslog, facility especifica que nombre de lugar usar al guardar el mensaje. Puede ser
cualquiera de los estándar. En la práctica, sólo daemon y de local0 a local7 son elecciones
razonables.
El resto de sentencias en una definición de canal son opcionales. Importancia puede tomar los
valores (en orden descendente) critical, error, warning, notice, info o debug (con un nivel numérico
125
opcional, por ejemplo severity debug 3). El valor dynamic también es válido y representa el nivel de
depuración actual del servidor.
Las diversas opciones print añaden o suprimen prefijos del mensaje. El syslog incluye la fecha y
hora y el host de origen en cada mensaje guardado, pero no la importancia o la categoría. En Bind
9, el fichero de origen (módulo) que generó el mensaje también está disponible como opción print.
Adquiere sentido entonces activar print-time sólo para canales fichero, pues los registros del syslog
ponen la fecha y hora ellos solos.
A continuación se listan los cuatro canales predefinidos por defecto, que deberín ser suficiente
para la mayoría de casos:
Nombre del canal Lo que hace
default_syslog Manda importancia info al syslog con el destino daemon
default_debug Guarda en el fichero named.run, importancia puesta a dynamic
default_stderr Manda mensajes a la salida de error estándar de named, importancia info
null Se descartan todos los mensajes
La configuración de logging por defecto de Bind 9 es:
logging {
category default {
default_syslog;
default_debug;
};
};
Debería echar un vistazo a los ficheros log cuando haga grandes cambios en Bind, y quizás
incrementar el nivel de depuración. Entonces, reconfigúrelo para preservar únicamente mensajes
importantes una vez named esté estable. Algunos de los mensajes de log más comunes se listan a
continuación:
Lame server. Si recibe este mensaje acerca de una de sus zonas es que ha configurado
mal alguna cosa. El mensaje es relativamente poco importante si es sobre alguna zona en
Internet, pues significa que es problema de algún otro.
Bad referral. Este mensaje indica una descoordinacín en la comunicación entre los
servidores de nombres de una zona.
126
Not authoritative for. Un servidor esclavo no es capaz de obtener información
representativa de una zona. Quizás está apuntando al maestro equivocado o quizás el
maestro ha tenido algún problema cargando esa zona.
Rejected zone. named rechazó esa zona porque contenía errores.
No NS RRs found. El fichero de una zona no tiene registros NS tras el registro SOA. Podría
ser que no están o que no empiezan con un tabulador o un espacio en blanco. En este
último caso, los registros no se interpretan correctamente.
No default TTL set.. La mejor manera de establecer el TTL por defecto es con una cláusula
$TTL al principio del fichero de la zona. Este mensaje de error indica que el $TTL no está
presente.
No root name server for class. Su servidor está teniendo problemas para encontrar los
servidores raíz. Compruebe su fichero /etc/bind/db.root y la conexión a Internet de su
servidor.
Address already in use. El puerto en el que named quiere ejecutarse ya está siendo usado
por otro proceso, probablemente otra copia de named. Si no ve otra copia de named en
memoria, podría haberse colgado, dejando el socket de control de rndc abierto.
TAXONOMÍA DE UN SERVIDOR DE NOMBRES
Tipo de servidor Descripción
Inglés Español
authoritative autorizado Un representante oficial de una zona.
master maestro El repositorio principal de los datos de una zona; lee los datos de ficheros del disco.
slave esclavo Obtiene los datos del maestro.
stub N/A Parecido a un esclavo, pero sólo copia los datos del servidor de nombres (no los datos del equipo).
distribution distribución Un servidor que sólo es visible
(a) desde dentro de un dominio
(un "servidor oculto").
nonauthoritative(b)
no autorizado Responde una consulta a partir de su caché; desconoce si los datos son aún válidos.
caching reserva Guarda los datos de consultas previas; habitualmente no tiene zonas locales.
forwarder redireccionador Realiza consultas en nombre de muchos clientes; mantiene una caché grande.
recursive recursivo Consulta en su nombre hasta que devuelve una respuesta o un error.
127
nonrecursive no recursivo Le pasa a otro servidor si no es capaz de responder a la consulta.
a. Un servidor de distribución puede ser visible por cualquiera que conozca su dirección IP.
b. Hablando estrictamente, "no autorizado" es un atributo de la respuesta a una consulta DNS, no
de un servidor.
Tipos de sentencias usadas en el named.conf
Sentencia Descripción
include Interpola un fichero (p.e., claves de confianza accesibles sólo por named).
options Establece opciones globales de configuración del servidor de nombres y valores por
defecto.
server Especifica opciones preservidor.
key Define información de autenticación.
acl Define listas de control de acceso.
zone Define una zona de registro de recursos.
trusted-
keys Usa claves previamente configuradas.
controls Define canales utilizados para controlar el servidor de nombres con rndc.
logging Especifica categorías de logs y sus destinos.
view Define una vista de un espacio de nombres.
Ejemplo de personalización de logs
// Definimos tres canales de logs (mensajes importantes del
// syslog, depuración media y mensajes de carga de zonas)
// y luego les asignamos categorías a cada uno.
logging {
channel syslog_errors {
syslog local1;
severity error;
};
channel moderate_debug {
128
severity debug 3; // nivel 3 de depuración
file "debug.log"; // al fichero debug.log
print-time yes; // fecha actual a las entradas del log
print-category yes; // imprimir el nombre de la categoría
print-severity yes; // imprimir el nivel de gravedad
};
channel no_info_messages {
syslog local2;
severity notice;
};
category parser {
syslog_errors;
default_syslog;
};
category lame-servers { null; }; // No guardar este tipo en los logs
category load { no_info_messages; };
category default {
default_syslog;
moderate_debug;
};
};
Tabla de caracteres especiales utilizados en los registros de recursos
Caracter Significado
; Introduce un comentario
@ El nombre de dominio actual
() Permite partir una sentencia en más de una línea
* Comodín (sólo en el nombre del campo).
Tabla de mecanismos de seguridad en el named.conf
Característica Sentencias Qué especifica
allow-query options, zone Quién puede consultar la zona o servidor.
allow-transfer options, zone Quién puede solicitar transferencias de zonas.
129
allow-update zone Quién puede hacer actualizaciones dinámicas.
blackhole options Qué servidores deben ignorarse completamente.
bogus server Qué servidores no deben ser jamás consultados.
acl varios Listas de control de acceso.
Tabla de categorías de logging en Bind 9
Categoría Qué incluye
default Categorís sin una asignación explícita de canal.
general Mensajes sin clasificar.
config Análisis y procesado de ficheros de configuración.
queries/client Un mensaje corto de log por cada consulta que el servidor recibe.
dnssec Mensajes de DNSSEC.
lame-servers Servidores que se supone que sirven una zona, pero no lo están(a)
.
statistics Estadísticas agrupadas del servidor de nombres.
panic Errores fatales (duplicados en esta categoría).
update Mensajes sobre actualizaciones dinámicas.
ncache Mensajes sobre caché negativa.
xfer-in Transferencias de zonas que el servidor está recibiendo.
xfer-out Transferencias de zonas que el servidor está enviando.
db/database Mensajes sobre operaciones con bases de datos.
packet Volcados de paquetes recibidos y enviados(b)
.
notify Mensajes acerca del protocolo de notificaciones "zona modificada".
cname Mensajes del tipo "...points to a CNAME".
security Peticiones aprobadas/denegadas.
os Problemas del sistema operativo.
130
insist Comprobaciones de fallos de consistencia interna.
maintenance Sucesos periódicos de mantenimiento.
load Mensajes de carga de zonas.
response-checks Comentarios sobre paquetes de respuesta malformados o inválidos.
resolver Traducción de DNS, p.e., búsquedas recursivas para clientes.
network Operaciones de red.
a. Bien la zona padre o bien la zona hija podrían ser la culpable; es imposible determinarlo sin
investigarlo.
b. Obligatoriamente debe ser un canal simple.
CHROOT
Este apartado describe algunas precauciones extras relacionadas con la seguridad que puede
usted tomar al instalar BIND. Se explica cómo configurar BIND de manera que resida en una jaula
chroot, lo que significa que no pueda ver o acceder a ficheros fuera de su propio reducido árbol de
directorios. También se explica cómo configurarlo para que se ejecute como un usuario diferente a
root.
La idea que hay detrás de un chroot es bastante sencilla: acotar el acceso que un individuo
malicioso pueda obtener explotando vulnerabilidades de BIND. Por esa misma razón es bueno
ejecutarlo como un usuario no root (en GNU/Debian Linux a partir de la versión 9.2.4-5). Cuando
se ejecuta BIND (o cualquier otro proceso) en una jaula chroot, el proceso simplemente es incapaz
de ver cualquier otra parte del sistema de ficheros que se encuentre fuera de la jaula.
Por ejemplo, en este apartado configuraremos BIND en modo chroot en el directorio /var/lib/named.
Entonces, para BIND, el contenido de este directorio será la raíz /. Nada fuera de este directorio le
será accesible. Muy probablemente ya se ha encontrado usted ante una jaula chroot con
anterioridad, por ejemplo al acceder mediante FTP a un sistema público.
Este proceso debería considerarse un complemento de las precauciones de seguridad habituales
(ejecutar la última versión, usar listas de control de acceso, etc.), y nunca como una manera de
reemplazarlas.
131
Crear el usuario
Tal y como se menciona en la introducción, no es una buena idea ejecutar BIND como root. Por
ello, antes de empezar, se creará un usuario separado para BIND. Nótese que nunca debería
usarse un usuario genérico existente del tipo nobody para este propósito. Este proceso es
realizado automáticamente por el script de instalación del paquete Debian, pero a continuación se
resume el procedimiento manual para conseguirlo.
Es necesario añadir una línea parecida a esta en el fichero /etc/passwd:
bind:x:103:103::/var/cache/bind:/bin/false
Y una similar a la siguiente en el fichero /etc/group:
bind:x:103:
En este ejemplo no sólo vamos a ejecutar BIND como un usuario no root, sino que también lo
haremos en un entorno chroot (la instalación por defecto en Debian únicamente cubre el primer
aspecto en la actualidad).
Estas líneas crean un usuario y un grupo llamados bind para BIND. El lector debe asegurarse de
que tanto el UID (del inglés, User Identifier) como el GID (del inglés, Group Identifier) son únicos en
su sistema (ambos 103 en este ejemplo). La consola se ha dejado en /bin/false porque este
usuario jamás tendrá necesidad de hacer un login.
Estructura de directorios
Acto seguido es necesario crear una estructura de directorios para la jaula chroot en la cual se
ejecutará BIND. Puede hacerse en cualquier lugar del sistema de ficheros; aquellos más
paranoicos incluso querrán ponerlo en un volumen separado. Se usará /var/lib/named. Empiece
por crear la siguiente estructura de directorios:
/var/lib/
+--- named
+--- dev
+--- etc
+--- var
+--- run
+--- cache
+--- bind
132
+--- usr
+--- sbin
Mediante el comando mkdir podría crearse la mencionada estructura de directorios. Estos son los
comandos a ejecutar y sus parámetros:
# mkdir -p /var/lib/named
# cd /var/lib/named
# mkdir -p dev etc/bind var/run var/cache/bind usr/sbin
Copiar los ficheros necesarios
Asumiendo que usted ya ha realizado una instalación estándar de BIND 9 y que lo está usando,
tendrá, por lo tanto, un fichero named.conf y diversos ficheros de zonas. Esos ficheros deben ser
movidos (o copiados, para mayor seguridad) dentro de la jaula chroot, de modo que BIND sea
capaz de encontrarlos. named.conf y los ficheros de zonas van dentro de /var/lib/named/etc/bind.
Por ejemplo:
# cp -p /etc/bind/* /var/lib/named/etc/bind/
# cp -a /var/cache/bind/* /var/lib/named/var/cache/bind/
# cp /usr/sbin/named /var/lib/named/usr/sbin/
Además, será preciso copiar también las librerís que el ejecutable /usr/sbin/named necesita, que
pueden obtenerse ejecutando el comando ldd /usr/sbin/named. Con los siguientes comandos
crearemos los subdirectorios necesarios y copiaremos las librerís:
# cd /var/lib/named
# mkdir -p usr/lib lib
# cp /usr/lib/liblwres.so.1 usr/lib/
# cp /usr/lib/libdns.so.5 usr/lib/
# cp /usr/lib/libcrypto.so.0.9.6 usr/lib/
# cp /usr/lib/libisccfg.so.0 usr/lib/
# cp /usr/lib/libisccc.so.0 usr/lib/
# cp /usr/lib/libisc.so.4 usr/lib/
# cp /lib/libnsl.so.1 lib/
# cp /lib/libpthread.so.0 lib/
# cp /lib/libc.so.6 lib/
# cp /lib/libdl.so.2 lib/
# cp /lib/ld-linux.so.2 lib/
BIND va a necesitar escribir dentro de los subdirectorios /var/lib/named/var/cache/bind y
/var/lib/named/var/run, en el primero para guardar las zonas de las cuales esté actuando como
133
servidor esclavo y en el segundo para guardar información estadística de su ejecución. Por lo
tanto, es pertinente ejecutar las dos instrucciones siguientes:
# chown -R bind:bind /var/lib/named/var/cache/bind
# chown -R bind:bind /var/lib/named/var/run
Ficheros de sistema
Una vez que BIND esté ejecutándose en la jaula chroot, no será capaz de acceder a ficheros que
se encuentren fuera de la jaula de ningún modo. Sin embargo, necesita acceder a algunos ficheros
esenciales. Uno de los ficheros que necesita dentro de su jaula es /dev/null. Otros son /dev/zero y
/dev/random. Pueden usarse los siguientes comandos:
# mknod /var/lib/named/dev/null c 1 3
# mknod /var/lib/named/dev/random c 1 8
# mknod /var/lib/named/dev/zero c 1 5
# chmod 666 /var/lib/named/dev/{null,random,zero}
También será necesario otro fichero en el directorio /etc dentro de la jaula. Es preciso copiar
/etc/localtime ahí dentro de modo que BIND guarde los logs con fechas correctas. El siguiente
comando se resolvería el problema:
# cp /etc/localtime /var/lib/named/etc/
Logging
Normalmente, BIND guarda los logs a través de syslogd, el demonio del sistema encargado de
guardar los logs. Sin embargo, este tipo de logging se lleva a cabo enviando las entradas del log a
un socket especial, /dev/log. Debido a que se encuentra fuera de la jaula, BIND no va a poder
usarlo. Afortunadamente, hay una solución para este problema.
Todo lo que hay que hacer es añadir el parámetro -a /var/lib/named/dev/log a la línea de comandos
que lanza el syslogd. En Debian, este script se encuentra en /etc/init.d/sysklogd. Debe buscar las
líneas siguientes:
# Options for start/restart the daemons
# For remote UDP logging use SYSLOGD="-r"
#
SYSLOGD=""
Y cambiar la última de las líneas por esta:
SYSLOGD="-a /var/lib/named/dev/log"
134
Una vez reiniciado el demonio, debería ver un fichero en /var/lib/named/dev llamado log, tal que
así:
srw-rw-rw- 1 root root 0 Nov 28 14:22 log
Finalmente, remarcar que, en el caso de una actualización del paquete sysklogd, podrían perderse
los cambios realizados en dicho script por una potencial sobreescritura del fichero existente. Por lo
tanto, se recomienda tener cuidado al actualizar.
Endureciendo los permisos
Antes de nada, siéntase libre de restringir acceso en todo el directorio /var/lib/named únicamente al
usuario bind.
# chown bind:bind /var/lib/named
# chmod 700 /var/lib/named
Si desea aumentar aún más las restricciones, en los sistemas Linux puede conseguirse la
inmutabilidad de algunos de los ficheros usando la herramienta chattr en los sistemas de ficheros
ext2 y ext3.
# cd /var/lib/named
# chattr +i etc etc/localtime var
Consulte la página del man para más información: man chattr. Sería interesante poder hacer esto
mismo sobre el directorio dev pero, desgraciadamente, eso imposibilitaría que el syslogd crease el
socket dev/log. También puede elegir activar el bit de inmutabilidad en otros ficheros dentro de la
jaula, como los de las zonas primarias, en el caso de que no vayan a cambiar.
Instalación
Si se desea realizar una instalación a partir de los fuentes, se recomienda usar el paquete Debian
de fuentes bind9, disponible mediante el comando apt-get source bind9. Luego tan sólo sería
necesario ejecutar un ./configure y un make o, más fácil aún, dpkg-buildpackage, que nos hará los
dos pasos anteriores y nos dejará listos una serie de paquetes Debian que nos evitarán tener que
hacer un make install a mano.
Suponiendo que usted ya dispone de una instalación de BIND 9 en su sistema, tan sólo deberá
modificar ligeramente el script de arranque del demonio para que use estos parámetros:
-u bind, que le indica a BIND el usuario con el que debe ejecutarse.
-t /var/lib/named, que le dice a BIND que haga un chroot sobre sí mismo dentro de la jaula que
se le ha preparado.
135
-c /etc/named.conf, que le dice a BIND dónde encontrar su fichero de configuración dentro de la
jaula.
En Debian, es muy fácil cambiar el script de inicio de BIND, que encontrará en /etc/init.d/bind9,
para que acepte estas nuevas opciones. Tan sólo debe buscar estas líneas:
# for a chrooted server: "-u nobody -t /var/lib/named"
OPTS=""
Y cambiar la última línea por la siguiente:
OPTS="-u bind -t /var/lib/named -c etc/named.conf"
Cambie, por último, el ejecutable que se llama desde ese script de /usr/sbin/named a
/var/lib/named/usr/sbin/named, de manera que sea el ejecutable de dentro de la jaula el que el
script llame y no el original.
Si su versión del paquete Debian de BIND9 es la 9.2.4-5 o superior, BIND se estará ejecutando
con el usuario bind y el UID/GID 103, por lo que puede saltarse los pasos referidos a la creación
del usuario y el grupo y pasar directamente al enjaulamiento. Si la versión de su paquete es inferior
(en GNU/Debian Woody es la 9.2.4-4), entonces deberá seguir todos los pasos.
Cambios en la configuración
Deberá usted también cambiar o añadir unas pocas opciones a su named.conf a fin de mantener
ciertos directorios en orden. En particular, debería añadir (o cambiar, si ya las tiene) las siguientes
directivas en la sección de opciones:
directory "/etc/bind";
pid-file "/var/run/named.pid";
statistics-file "/var/run/named.stats";
Ya que este fichero va a ser leído por el demonio named, todas las rutas van a ser, evidentemente,
relativas a la jaula chroot. En el momento de escribir esta parte del documento, BIND 9 no soporta
muchas de las estadísticas y ficheros de volcado que las versiones previas soportaban.
Presumiblemente, versiones posteriores sí lo harán; si está ejecutando una de esas versiones,
quizás deba añadir algunas entradas adicionales para que BIND las escriba en el directorio /var/run
también.
136
Arrancando BIND
Ahora ya tan sólo queda por hacer el paso más elemental: arrancar de nuevo el demonio BIND.
Para ello, es preciso ejecutar el siguiente comando en una distribución GNU/Debian Linux:
# /etc/init.d/bind start
Introduccion a DHCP#
DHCP (Dinamic Host Control Protocol)es un protocolo de red utilizado para asignar una serie de
configuraciones TCP/IP (direccion IP, nombre,dominio al que pertenece, routeador y servidor DNS)
a los equipos de una red de área local LAN (Local Area Network).
Sin el uso de un servidor DHCP, cada dirección IP se tendria que configurar manualmente en cada
equipo y, si el equipo se mueve a otra subred, la IP del equipo seria diferente a la establecida
antes. El DHCP le permite al administrador supervisar y distribuir de forma centralizada las
direcciones IP necesarias y, automáticamente, asignar y enviar una nueva IP si el equipo es
conectado en un lugar diferente de la red.
El protocolo DHCP incluye tres métodos de asignación de direcciones IP:
Asignación manual: Asigna una dirección IP a un equipo determinado. Es mas
frecuentemente utilizado cuando se desea controlar la asignacion de direcciones IP a cada
equipo y asi evitar tambien , que se conecten equipos no identificados
Asignación automática: Asigna una dirección IP de forma permanente a un equipo. Se
suele utilizar cuando el número de equipos en la LAN no varía demasiado.
Asignación dinámica: Este metodo hace uso de la reutilizacion de direcciones IP, tecnica
mediante la cual, el servidor dhcp reinicia las tarjetas de red cada cierto intervalo de
tiempo, asignando una nueva direccion IP a los equipos.
Requerimientos para la Instalación de un DHCP
Procederemos a instalar nuestro servidor DHCP mediante la descarga de los siguientes paquetes
por lo que se recomienda que dichas descargas se hagan como root. Para ello teclearemos en
consola lo siguiente:
[localhost@localdomain ~]# yum install -y dhcp
Una vez que se halla descargado e instalado el dhcp, este creara su fichero de configuracion en la
siguiente ubicación:
/etc/dhcpd.conf
137
Configuracion del fichero dhcpd.conf
El primer paso para configurar el servidor de DHCP sera editar el fichero dhcp.conf al cual le
añadiremos la información de nuestra LAN. El archivo de configuración puede contener
tabulaciones o líneas en blanco adicionales para facilitar el formato. Las palabras clave no
distinguen entre mayúsculas y minúsculas. Las líneas que empiezan con el simbolo numeral (#) se
consideran comentarios.
Consideremos el siguiente requirimiento:
Se requiere implementar un servidor DHCP que implemente los tres métodos de asignación de
direcciones IP. El servidor DHCP contara con dos tarejtas de red, las cuales tendran asignadas las
direcciones 192.168.1.5 y 192.168.2.5, el segmento de red sobre el cual actuara el servidor DHCP
es el 192.168.1.0, la submascara de red asignada sera la 255.255.255.0, asi mismo el servidor
DHCP servira como gateway el cual tendra asignada la misma direccion IP que el DHCP
(192.168.1.5), la direccion de broadcast asiganda sera la 192.168.1.255, el rango de direcciones IP
que asinara el servidor DHCP estará entre el rango de 192.168.1.7 á 192.168.1.100.
El diagrama de la red quedara de la siguiente manera
Parametros de configuracion
ignore client-updates Parametro que ignora las direcciones IP antes asignadas
shared-network redLocal Parametro que describe las subredes que compartiran la misma red física las cuales se especifican dentro de esta declaración
subnet Segmento de subred sobre el cual actuara el dhcp
netmask Mascara de red de la subred
option routers Parametro que especifica mediante IP la ubicación del router
option subnet-mask Mascara de red de la subred
138
option broadcast-address Parametro que especifica la IP de broadcast
option domain-name "tuDominio.com"; Parametro que describe el nombre de tu dominio
option domain-name-servers Parametro que especifica mediante IP la ubicación del DNS
range Rango sobre el cual el DHCP asiganara direcciones IP
default-lease-time Parametro que indica el tiempo entre cada nueva asignacion de IP a los equipos
max-lease-time Parametro que indica el tiempo de vigencia de la direccion IP para cada equipo
host nombreDeLaMaquina Parametro que describe el nombre del equipo
option host-name "nombreDeLaMaquina.tuDominio.com"
Parametro que describe el nombre de la computadora y el nombre de dominio asociado a la misma
hardware ethernet Parametro que describe la direccion MAC asociada a la tarjeta ethernet del equipo
fixed-address Parametro que describe la direccion IP destinada a un equipo
Editaremos el fichero /etc/dhcpd.conf de tres maneras diferentes, esto con el fin de ejemplificar los
tres métodos de asignación de direcciones IP.
Asignación manual
Abriremos una terminal y con la ayuda de “vi” editaremos el fichero dhcpd.conf
[localhost@localdomain ~]#vi /etc/dhcpd.conf
Una vez abierto el fichero deberemos añadir el siguiente contenido:
#
1. DHCP Server Configuration file.
2. see /usr/share/doc/dhcp/dhcpd.conf.sample
3.
ddns-update-style interim; ignore client-updates; shared-network redLocal{
subnet 192.168.2.0 netmask 255.255.255.0{ option routers 192.168.2.5; option subnet-mask
255.255.255.0; option broadcast-address 192.168.2.255; option domain-name "redLocal.com.";
option domain-name-servers 192.168.2.5;
} host maquina1{ option host-name "maquina1.redLocal.com"; hardware ethernet
00:1b:24:e2:d7:41; fixed-address 192.168.2.10; } host maquina2{ option host-name
"maquina2.redLocal.com"; hardware ethernet 00:2c:212:ef5:a7:13; fixed-address 192.168.2.11; } }}}
Lo hecho anteriormente hace que el servidor DHCP asigne a dos equipos de la red, las direcciones
IP que fueron anexadas en el fichero dhcp.conf .
139
Asignación automatica
Abriremos una terminal y con la ayuda de “vi” editaremos el fichero dhcpd.conf
[localhost@localdomain ~]#vi /etc/dhcpd.conf
Una vez abierto el fichero deberemos añadir el siguiente contenido:
#
1. DHCP Server Configuration file.
2. see /usr/share/doc/dhcp/dhcpd.conf.sample
3.
ddns-update-style interim; ignore client-updates; shared-network factorcentos{ subnet 192.168.2.0
netmask 255.255.255.0{ option routers 192.168.2.5; option subnet-mask 255.255.255.0; option
broadcast-address 192.168.2.255; option domain-name "factorcentos.com.mx"; option domain-
name-servers 192.168.2.5; range 192.168.2.1 192.167.2.100; } }}}
Lo hecho anteriormente hace que el servidor DHCP asigne a dos equipos de la red, dos
direcciones IP aleatorias dentro del rango de 192.168.2.10 al 192.168.1.200
Asignación dinamica
Abriremos una terminal y con la ayuda de “vi” editaremos el fichero dhcpd.conf
[localhost@localdomain ~]#vi /etc/dhcpd.conf
Una vez abierto el fichero deberemos añadir el siguiente contenido:
#
1. DHCP Server Configuration file.
2. see /usr/share/doc/dhcp/dhcpd.conf.sample
140
3. ddns-update-style interim; ignore client-updates; shared-network factorcentos{ subnet
192.168.2.0 netmask 255.255.255.0{ option routers 192.168.2.5; option subnet-mask
255.255.255.0; option broadcast-address 192.168.2.255; option domain-name
"factorcentos.com.mx"; option domain-name-servers 192.168.2.5; range 192.168.2.1
192.167.2.100; default-lease-time 21600; max-lease-time 43200; } }}}
Lo hecho anteriormente hace que el servidor DHCP asigne a dos equipos de la red, dos
direcciones IP aleatorias dentro del rango de 192.168.2.10 al 192.168.1.200 las cuales seran
renovadas cada cierto tiempo asignado de nuevo direcciones IP aleatorias dentro del rango de
192.168.2.10 al 192.168.1.200.
Levantando el servicio
Al terminar de editar todos los ficheros involucrados, solo bastará iniciar el servidor DHCP, el cual
podrá inicializarse, detenerse o reinicializarse con el comando “/etc/init.d” ó de otra forma añadirlo
al arranque del sistema en un nivel o niveles de corrida en particular con el mandato chkconfig.
Para ejecutar por primera vez el servicio teclear en consola lo siguiente:
[localhost@localdomain ~]#/etc/init.d/dhcpd start
Para reiniciar el servicio:
[localhost@localdomain ~]#/etc/init.d/dhcpd restart
Para detener el servicio, utilice:
[localhost@localdomain ~]#/etc/init.d/dhcpd stop
141
DIRECTORIO CORPORATIVO (FREEIPA)
Instalación FreeIPA en un mínimo de instalación de CentOS
El objetivo es instalar FreeIPA que se utilizará como servidor de autenticación y autorización de
Zimbra y Apache.
Entorno y Parámetro
El servidor IPA será colocado dentro de una red local. En realidad, se debe colocar dentro de la red
en sí, junto con otros servidores que no son accesibles desde Internet. Basado en esto se utilizarán
los siguientes parámetros:
La dirección IP del servidor FreeIPA será 172.16.1.2/24.
El calificativo FQDN será servidor.simulnet.com. Nota que este dominio sera el utilizado
por una intranet
El REALM de Kerberos será SIMULNET.COM.
Para continuar con la instalción del servidor es importante destacar que debe existir un servidor de
DNS instalado y configurado. Ambos servicios de DNS y FreeIPA pueden convivir en el mismo
servidor.
Instalación de Software:
El primer paso es instalar el sistema operativo siendo recomendada cualquier distribución de Linux
basada en Redhat. En nuestro caso lo haremos con CentOS:
yum install ipa-server bind bind-dyndb-ldap
Este comando instalará una gran cantidad de dependencias aproximadamente unos 190
megabytes de descarga.
Configuración del Servidor:
Para comenzar el proceso de instalación y configuración debemos ejecutar el siguiente comando:
# ipa-server-install --help
Probando la instalación:
# kinit admin
Password for [email protected]:
142
El sistema les pedirá la contraseña que fue introducida anteriormente en el proceso de instalación.
Si todo sale bien pues simplemente saldrán al prompt de la consola.
Para chequear el ticket de Kerberos ejecutamos:
# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: [email protected]
Valid starting Expires Service principal
06/26/12 17:43:05 06/27/12 17:43:01 krbtgt/[email protected]
Si la salida del comando klist es semejante a esta entonces el servidor IPA está trabajando
correctamente.
SERVIDOR WEB APACHE
Arquitectura del servidor Apache
El servidor Apache es un software que esta estructurado en módulos. La configuración de cada
módulo se hace mediante la configuración de las directivas que están contenidas dentro del
módulo. Los módulos del Apache se pueden clasificar en tres categorías:
• Módulos Base: Módulo con las funciones básicas del Apache
• Módulos Multiproceso: son los responsables de la unión con los puertos de la máquina,
acepando las peticiones y enviando a los hijos a atender a las peticiones
• Módulos Adicionales: Cualquier otro módulo que le añada una funcionalidad al servidor.
Las funcionalidades más elementales se encuentran en el módulo base, siendo necesario un
módulo multiproceso para manejar las peticiones. Se han diseñado varios módulos multiproceso
para cada uno de los sistemas operativos sobre los que se ejecuta el Apache, optimizando el
rendimiento y rapidez del código.
El resto de funcionalidades del servidor se consiguen por medio de módulos adicionales que se
pueden cargar. Para añadir un conjunto de utilidades al servidor, simplemente hay que añadirle un
módulo, de forma que no es necesario volver a instalar el software.
143
Módulos Base y Módulos Multiproceso:
core: Funciones básicas del Apache que están siempre disponibles.
mpm_common: Colección de directivas que se implementan en más de un módulo multiproceso.
beos: Módulo de multiproceso optimizado para BeOS.
leader: Variable experimental de MPM.
mpm_netware: Módulo de multiproceso que implementa un servidor web optimizado para
Novell NetWare.
mpmt_os2: MPM híbrido, multiproceso y multihilo para OS/2 .
perchild: Módulo multiproceso que permite a los procesos demonio servir las peticiones que se
asignan a distintos id de usuario.
prefork: Implementa un servidor sin hilos.
threadpool: Variante experimental del módulo estándar de MPM .
mpm_winnt: Módulo multiproceso optimizado para Windows NT.
worker: Módulo multiproceso que implementa un híbrido multihilos y multiprocesos de servidor
Web.
Módulos adicionales:
mod_access: proporciona control de acceso basándose en el nombre del host del cliente, su
dirección IP u otras características de la petición del cliente.
mod_actions: este módulo se utiliza para ejecutar Scripts CGI, basándose en el tipo de medio o el
método de petición.
mod_alias: proporcionado para mapear diferentes partes del sistema de ficheros del servidor en el
árbol de documentos del servidor, y para redirección de URL's.
mod_asis: envío de ficheros que tienen sus propias cabeceras http.
mod_auth: autentificación de usuario utilizando ficheros de texto.
mod_auth_anon: permite a usuarios anónimos acceder a áreas autentificadas.
mod_auth_dbm: proporciona autentificación utilizando ficheros DBM.
mod_auth_digest: autentificación de usuario utilizando MD5.
mod_auth_ldap: permite la utilización un directorio LDAP para almacenar la base de datos de
autentificación.
mod_autoindex: muestra los contenidos de un directorio automáticamente, parecido al comando
ls de Unix.
mod_cache: Cache de contenidos indexados por URI's.
mod_cern_meta: Semántica de etiquetas meta del CERN.
mod_cgi: Ejecución de Scritps CGI.
mod_cgid: ejecución de Scripts CGI utilizando un demonio CGI externo.
mod_charset_lite: para la especificación del juego de caracteres de las traducciones.
mod_deflate: comprime el contenido antes de ser enviado al cliente.
144
mod_dir: Proporcionado para redirecciones y para servir los ficheros de listado de directorios.
mod_disk_cache: Cache para almacenar contenidos identificados por URI.
mod_echo: Un servidor simple de echo para ilustrar los módulos del protocolo.
mod_env: modificación del entorno que se envia a los scripts CGI y las páginas SSI.
mod_expires: Generación de las cabeceras http Expires, de acuerdo de los criterios
especificados por el usuario.
mod_ext_filter: pasa el cuerpo de la respuesta a través de un programa antes de enviársela
al cliente.
mod_file_cache: cachea una lista estática de ficheros en memoria.
mod_headers: personalización de las peticiones HTTP y las cabeceras de las respuestas.
mod_imap: proceso de imágenes en el lado del servidor.
mod_include: Documentos HTML generados por el servidor (Server Side Includes).
mod_info: proporciona una visión comprensiva de la configuración del servidor.
mod_isapi: Extensiones ISAPI en Apache para Windows.
mod_ldap: pool de conexiones LDAP y cacheo de resultados para la utilización de otros
módulos LDAP.
mod_log_config: registro de las peticiones hechas al servidor.
mod_logio: registro del número de bytes recibidos y enviados en cada respuesta.
mod_mem_cache: Cache de contenidos identificados por URI.
mod_mime: asocia las extensiones de peticiones de los ficheros con el comportamiento del fichero
(manejadores y filtros) y contenido (tipos mime, idioma, juego de caracteres y codificación).
mod_mime_magic: determina el tipo MIME de un fichero mirando unos pocos bytes del contenido.
mod_negotiation: se proporciona para la negociación del contenido.
mod_proxy: servidor HTTP/1.1 proxy/gateway.
mod_proxy_connect: extensión de mod_proxy para la gestión de las peticiones CONNECT.
mod_proxy_ftp: soporte FTP para mod_proxy.
mod_proxy_http: soporte HTTP para el módulo mod_proxy.
mod_rewrite: proporciona un motor de reescritura basado en reglas que rescribe las peticiones de
URL's al vuelo.
mod_setenvif: permite la configuración de las variables de entorno basándose en las
características de la petición.
mod_so: carga del código ejecutable y los módulos en al iniciar o reiniciar el servidor.
mod_speling: intenta corregir las URL mal puestas por los usuarios, ignorando las mayúsculas y
permitiendo hasta una falta.
mod_ssl: criptografía avanzada utilizando los protocolos Secure Sockets Layer y Transport
Layer Security.
mod_status: proporciona información en la actividad y rendimiento del servidor.
mod_suexec: permite a los scripts CGI ejecutarse con un nombre y grupo específico.
145
mod_unique_id: proporciona variables de entorno y un identificador único para cada petición.
mod_userdir: directorios específicos para usuarios.
mod_usertrack: registro de actividad de un usuario en el sitio.
mod_vhost_alias: Proporcionado para configurar muchos servidores virtuales dinámicamente.
El fichero httpd.conf
El fichero httpd.conf es el fichero principal de configuración del Apache, se encuentra dentro del
directorio Conf, en el directorio de instalación del Apache.
En primer lugar hay que destacar que el fichero está dividido en tres secciones, que son:
1º Parámetros globales
2º Directivas de Funcionamiento
3º Host Virtuales
En el fichero se encuentran todos los parámetros de funcionamiento del Apache. Algunos
parámetros son generales para la instalación y funcionamiento del Apache. Muchos otros de los
parámetros se pueden configurar independientes para un conjunto de directorios y/o ficheros.
En estos casos los parámetros se encuentran ubicados dentro de secciones donde se indica el
ámbito de aplicación del parámetro.
Las secciones más importantes son:
<Directory> : Los parámetros que se encuentran dentro de esta sección, sólo se aplicarán a el
directorio especificado y a sus subdirectorios.
<DirectoryMatch>: Igual que Directory, pero acepta en el nombre del directorio expresiones
regulares.
<Files>: Los parámetros de configuración proporcionan control de acceso de los ficheros por su
nombre.
<FilesMatch>: Igual que Files, pero acepta expresiones regulares en el nombre del fichero.
<Location>: Proporciona un control de acceso de los ficheros por medio de la URL
<LocationMatch>: Igual que Location, pero acepta expresiones regulares en el nombre del
fichero.
146
Algunas veces las directivas de funcionamiento de las secciones anteriores se pueden cruzar en
cuyo caso tienen el siguiente orden de preferencia:
1. <Directory> y .htaccess (.htaccess prevalece frente a <Directory>)
2. <DirectoryMatch> y <Directory>
3. <Files> y <FilesMatch>
4. <Location> y <LocationMatch>
También hay que destacar, que el fichero contiene un montón de comentarios para su correcta
utilización, las líneas comentadas aparecen con el símbolo #.
Httpd.conf: Parámetros globales
Todos los parámetros que se establecen dentro de esta sección son globales para el
funcionamiento del servidor, por lo que no admiten estar dentro de ninguna directiva.
ServerRoot: especifica la ubicación del directorio raíz donde se encuentra instalado el Apache, a
partir del cual se crea el árbol de directorios comentado anteriormente. Esta directiva no debería
cambiar a no ser que se mueva la carpeta de instalación de apache a otro directorio. Se encuentra
disponible a través del módulo Core.
PidFile: ubicación del fichero que contendrá el número de identificación del proceso cuando se
encienda el servidor. Se encuentra disponible a través de varios módulos beos, leader,
mpm_winnt, mpmt_os2, perchild, prefork, threadpool ó worker.
TimeOut: el valor se utiliza para configurar medido en segundos, tres parámetros:
1. El tiempo tal que puede tardar una petición en ser recibida entera
2. La cantidad de tiempo que espera entre recepción de paquetes TCP
3. La cantidad de tiempo entre ACK's en transmisiones TCP
Pasado este tiempo se produce un mensaje de error en el que se indica que se ha consumido el
tiempo máximo de espera. Establecer un valor muy pequeño puede dar lugar a que los usuarios
reciban este mensaje de error, y establecer un valor muy pequeño dará lugar a una sobrecarga de
la máquina. Se encuentra disponible a través del módulo Core.
KeepAlive: especifica si se utilizarán conexiones persistentes, es decir, que todas las peticiones
de un usuario se atenderán con la misma conexión. Se encuentra disponible a través del módulo
Core.
147
MaxKeepAliveRequests: número máximo de conexiones persistentes. (número máximo de
usuarios concurrentes si KeepAlive esta en ON). Para establecer este parámetro, hay que tener en
cuenta el ancho de banda de salida de nuestro servidor, por el cual deberá ser enviada toda la
información, si se establece un valor muy grande respecto al ancho de banda, el tiempo de
respuesta se verá incrementado para cada usuario. Se encuentra disponible a través del módulo
Core.
KeepAliveTimeout: tiempo que espera en segundos entre peticiones de un usuario, antes de
considerar que este ha terminado, y cerrar su conexión.
Si el valor es muy pequeño provocará que algunos usuarios no puedan visualizar la página debido
a que el número máximo de conexiones persistentes se ha superado, mientras que si se establece
un valor muy grande se estarán utilizando muchos recursos de la máquina. Se encuentra
disponible a través del módulo Core.
Listen: esta directiva permite especificar que puerto se utilizará para atender las peticiones.
Por defecto se utiliza el puerto 80 (www), también permite especificar que direcciones IP atenderá,
por defecto todas. Para atender dos direcciones IP distintas, con distintos puerto, se utilizaría:
Listen 192.168.255.5:80
Listen 192.168.255.8:8080
Se encuentra disponible a través de varios módulos beos, leader, mpm_winnt, mpmt_os2,
perchild, prefork, threadpool ó worker
LoadModule: Directiva que sirve para cargar módulos que incluyen distintas funcionalidades.
La sintaxis es:
LoadModule nombreModulo ubicacionFichero
Se encuentra disponible a través del módulo mod_so.
Httpd.conf: directivas de funcionamiento (1)
Esta es la sección principal de configuración del servidor, en ella podemos encontrar las siguientes
opciones:
ServerAdmin: especifica la dirección de correo electrónico del administrador, esta dirección
aparece en los mensajes de error, para permitir al usuario notificar un error al administrador.
148
No puede estar dentro de ninguna sección. Se encuentra disponible a través del módulo Core.
ServerName: especifica el nombre y el puerto que el servidor utiliza para identificarse,
normalmente se determina automáticamente, pero es recomendable especificarlo explícitamente
para que no haya problemas al iniciar el servidor. Si el servidor no tiene un nombre registrado en
las DNS, se recomienda poner su número IP. No puede estar dentro de ninguna sección.
La sintaxis es:
ServerName direccionIP:Puerto Ejemplo: ServerName localhost:80
DocumentRoot: la carpeta raíz que se ubica en el servidor, desde la que se servirán los
documentos. Por defecto, todas las peticiones, tendrán como raíz esta carpeta, a no ser que se
utilicen alias. Por defecto, la carpeta raíz es la carpeta Htdocs, que se encuentra en la carpeta de
instalación del Apache. No puede estar dentro de ninguna sección.
Si se cambia este directorio por otro, es muy importante que se ponga el nuevo valor, no solo en
esta línea, sino también en la sección <Directory> en la que se establecen los parámetros de
configuración de este directorio.
Esta línea empieza por " <Directory " seguido de la carpeta raíz que originalmente hay en
DocumentRoot.
Se encuentra disponible a través del módulo Core.
DirectoryIndex: especifica el fichero por defecto que buscará en cada directorio, en caso de que
no se especifique ninguno. Por defecto es index.html. Es decir, que si por ejemplo se pone en el
navegador: www.simulnet.com el servidor por defecto servirá:
www.simulnet.com/index.html
En esta directiva se pueden especificar más de un fichero, la sintaxis es la siguiente:
DirectoryIndex fichero1 fichero2 fichero3
El orden con el que se especifica el nombre de fichero determinará la prioridad a la hora de decidir
que fichero es el que se muestra.
149
La directiva se puede encontrar fuera de cualquier sección, dentro de una sección o dentro de un
fichero .htaccess.
Se encuentra disponible a través del módulo mod_dir.
AccessFileName: es el nombre del fichero de configuración que se buscará en cada una de los
directorios del servidor para conocer la configuración del mismo. Este fichero permite configurar el
comportamiento de cada uno de los directorios individualmente. Para que esta configuración
funcione, la directiva AllowOverride tiene que tener un valor que lo permita.
No puede estar dentro de ninguna sección.
El nombre de fichero que se especifica por defecto es el del fichero ".htaccess".
Como medida de seguridad, la configuración del Apache establece que no se muestre la existencia
de este fichero a ningún usuario, aunque este establecida la opción de listado de directorios. Si se
decide cambiar al nombre, habrá que redefinir la seguridad para que no se muestre el contenido
del nuevo fichero. Esto se hace en el fichero httpd.conf en una sección File como la que se
presenta a continuación en la que se establece que todos los ficheros que comiencen por .ht no se
mostrarán.
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
Se encuentra disponible a través del módulo Core.
Httpd.conf: directivas de funcionamiento (2)
TypesConfig: especifica el nombre del fichero que contiene la lista de tipos mime que conoce el
servidor, y que determinará dependiendo de las extensiones para generar las cabeceras http. No
puede estar dentro de ninguna sección.
Se encuentra disponible a través del módulo mod_mime.
DefaultType: tipo mime que se servirá por defecto en caso de no conocer la extensión del fichero
que se está sirviendo. Por defecto, se indicará que se sirve texto plano, con el valor
150
text/plain. La directiva se puede encontrar fuera de cualquier sección, dentro de una sección o
dentro de un fichero .htaccess.
Sintaxis: DefaultType tipoMime
Se encuentra disponible a través del módulo Core.
HostnameLookups: se utiliza en los ficheros de registro. Por defecto cuando se produce un
acceso, se guarda simplemente su número IP, si esta directiva se encuentra en On, el servidor
buscará la correspondencia de ese número IP con su nombre, y almacenará el nombre.
Establecer esta configuración en ON provocará que por lo menos se tenga que hacer una petición
al servidor de nombres por cada una de las peticiones de usuario, por lo que el rendimiento de la
máquina se puede ver decrementado. Esta directiva se puede encontrar dentro de una sección o
fuera de cualquier otra.
Se encuentra disponible a través del módulo Core.
ErrorLog: especifica la ubiación del fichero que contiene el registro de errores, por defecto en la
carpeta logs. Esta directiva sólo se puede encontrar fuera de cualquier sección.
Se encuentra disponible a través del módulo Core.
LogLevel: especifica el tipo de mensajes que se guardaran en el fichero de registro de errores,
dependiendo de los valores especificados, se guardarán mas o menos. Esta directiva sólo se
puede encontrar fuera de cualquier sección.
Valor de más a menos son: debug, info, notice, warn, error, crit, alert, emerg
Se encuentra disponible a través del módulo Core.
LogFormat: la directiva permite definir el formato que se utilizará para almacenar los registros. A
cada formato se le puede asignar un nombre, utilizándolo luego para crear distintos tipos de
ficheros de registro. Pueden existir varios logFormat distintos.
Sintaxis:
LogFormat "configuraciónError" nombre
151
Esta directiva se encuentra fuera de cualquier sección.
Se encuentra disponible a través del módulo mod_log_config.
CustomLog: la directiva se utiliza para especificar la ubicación y el tipo de formato que se utilizará
en un fichero de registro. Pueden existir varios ficheros de registro distintos con configuraciones
distintas. Para hacer esto, simplemente hay que poner varias líneas customlog.
Sintaxis: CustomLog fichero formato
Esta directiva se encuentra fuera de cualquier sección.
Se encuentra disponible a través del módulo mod_log_config.
ServerTokens: Esta directiva establece la información que se devuelve dentro de la cabecera http
que envía el servidor. Posibles valores de menor a mayor información son:
-Pord
-Min
-Os
-Full
Esta directiva se encuentra fuera de cualquier sección.
Se encuentra disponible a través del módulo Core.
IndexOptions: Esta directiva controla la apariencia de la página que se mostrará a un usuario
cuando se pide la lista de ficheros de un directorio.
Sintaxis:
IndexOptions [+|-]opcion [[+|-]opcion] ... (Apache 1.3.3 en adelante)
Entre las opciones que se pueden poner, destaca:
FancyIndexing: que muestra los nombres de los ficheros, con iconos etc.
Se encuentra disponible a través del módulo mod_autoindex.
152
FoldersFirst: Hace que primero se muestren los directorios. Esta opción sólo se puede
establecer en el caso de que FancyIndexing este activa.
Esta directiva se puede encontrar dentro del fichero .htaccess, dentro de una sección
<Directory> y fuera de cualquier otra.
Se encuentra disponible a través del módulo mod_autoindex.
Httpd.conf: directivas de funcionamiento (3)
AddIconByEncoding: Esta directiva permite asociar un icono a un tipo mime, de forma que
cuando la directiva fancyIndexing este activada, se mostrará al lado del fichero el icono
correspondiente.
Sintaxis:
AddIconByEncoding icon MIME-encoding…
Ejemplo:
AddIconByEncoding/icons/compressed.gif x-compress
Esta directiva se puede encontrar dentro del fichero .htaccess, dentro de una sección
<Directory> y fuera de cualquier otra.
Se encuentra disponible a través del módulo mod_autoindex.
AddIconByType: Esta directiva asocia un icono a un fichero dependiendo del un tipo mime, de
forma que cuando la directiva fancyIndexing este activada, se mostrará al lado del fichero el icono
correspondiente.
Sintaxis:
AddIconByType icon MIME-encoding…
Ejemplo:
AddIconByType /icons/text.gif text/*
La diferencia entre AddIconByType y AddIconByEncoding reside en que mientras que en la
primera se determina el tipo mime basándose en la codificación del fichero, mientras que
AddIconByType determina el tipo mime basándose en el nombre del fichero.
153
Ambas directivas se pueden encontrar dentro de el fichero .htaccess, dentro de una sección
<Directory> o fuera de cualquier otra.
Se encuentra disponible a través del módulo mod_autoindex.
AddDescription: Esta directiva permite asociar una descripción a un tipo de fichero, que se
mostrará al listar un directorio. Esta directiva se puede encontrar dentro del fichero .htaccess,
dentro de una sección <Directory> o fuera de cualquier otra.
Sintaxis:
AddDescripcion cadena, fichero
Se encuentra disponible a través del módulo mod_autoindex.
AddDefaultCharset: Esta directiva define la codificación de caracteres que se utilizará de forma
predeterminada para los documentos. Por defecto viene establecido el valor ISO 8859-1. Esta
directiva se puede encontrar dentro de cualquier sección y en los ficheros .htaccess.
Se encuentra disponible a través del módulo Core.
ErrorDocument: Esta directiva establece el la configuración del servidor para cuando se produce
un error. Se pueden establecer cuatro configuraciones distintas:
1. Sacar un texto de error
2. Redirigir a un fichero en el mismo directorio
3. Redirigir a un fichero en nuestro servidor
4. Redirigir a un fichero fuera de nuestro servidor
Hay que tener en cuenta que si el texto de error se envia a Internet Explorer, este tendrá que tener
al menos 512 Bytes, porque sino Internet Explorer mostrará su propia página de error.
Sintaxis:
ErrorDocument NúmeroError Acción
Esta directiva se puede encontrar tanto dentro del fichero .htaccess, dentro de la sección
<Directory> o fuera de cualquier otra sección.
154
Ejemplo:
ErrorDocument 404 /error404.html.
En caso de no encontrarse un fichero, se mostrará el fichero error404.html
Se encuentra disponible a través del módulo Core.
CacheRoot: establece el directorio donde se encontrarán los ficheros de la cache del Apache. Se
encuentra disponible a través del módulo mod_disk_cache
CacheSize: Tamaño de la cache en Kilobytes.
Se encuentra disponible a través del módulo mod_disk_cache
CacheGcInterval: Establece cada cuantas horas se verificará el tamaño de los ficheros de la
cache para comprobar si se corresponden con el tamaño establecido dentro de CacheSize. El valor
acepta números flotantes, por lo que se pueden establecer los intervalos en minutos. Cuanto
mayor sea el valor de esta directiva, más posibilidades existirán que se sobrepase el valor
establecido en CacheSize.
Se encuentra disponible a través del módulo mod_disk_cache
CacheMaxExpire: máximo número de horas que los ficheros permanecerán dentro de la cache.
Se encuentra disponible a través del módulo mod_cache
CacheLastModifiedFactor: Sirve para calcular la caducidad de un fichero en la cache, que será el
de la hora de la última modificación, multiplicado por este valor.
Se encuentra disponible a través del módulo mod_cache
CacheDefaultExpire: Número de horas por defecto a partir de las cuales un fichero caduca. Se
aplica en aquellos casos en los que no se puede determinar la hora de creación del fichero. Todas
las directivas de la caché, deben encontrarse fuera de cualquier sección. Esta directiva no se
puede encontrar dentro de ninguna sección.
Se encuentra disponible a través del módulo mod_cache
CREACIÓN DE DIRECTORIOS VIRTUALES EN APACHE
Esta directiva sólo se encuentra dentro del fichero de configuración httpd.conf, y se trata aparte en
este capítulo debido a su importancia.
155
Alias
Permite la definición de directorios virtuales, un directorio virtual es un directorio que se encuentra
en un directorio distinto del que se mapea en la URL. El directorio virtual no se tiene porqué
encontrar dentro de árbol de directorios que se crea a partir de DocumentRoot, sino que se puede
encontrar en cualquier otra ubicación, incluso se podría encontrar en otro servidor distinto.
Por ejemplo, cuando se escribe www.desarrolloweb.com/manual/php la carpeta php no se tiene
que encontrar necesariamente dentro de la carpeta manual, que a su vez esta dentro de la carpeta
raíz Desarrolloweb, sino que puede estar en una ubicación distinta, y fuera del árbol de
subdirectorios de la directiva DocumentRoot
Sintaxis:
Alias nombreFicticio ubicacionReal
Ejemplo:
Alias /manual/php "c:\php"
- el directorio php no se encuentra dentro del directorio manual dentro de la carpeta documentRoot,
sino en la carpeta c:\php.
Por defecto vienen creados dos redirecciones con Alias.
- Icons: para establecer la carpeta donde se encuentran los iconos que utilizará el Apache para
mostrar el contenido de los directorios, y
- Manual: que apunta a la carpeta donde está instalado el manual del Apache en caso de que se
hubiera elegido la opción durante la instalación.
AliasMatch
La utilidad de esta directiva es idéntica a la de la directiva Alias, la única diferencia es que mientras
Alias utiliza expresiones estándar regulares para especificar la URL que se va mapear.
Sintaxis:
AliasMatch Expresión regular ubicación
Seguridad en Apache I
Cuando un servidor apache recibe una petición de una página web, antes de devolver el resultado,
lleva a cabo varias acciones para verificar que la petición esta autorizada. Las distintas acciones
que lleva a cabo para verificar la validez de la aplicación, se pueden agrupar en tres tipos:
Autentificación, Autorización y Control de Acceso.
156
La autentificación es el proceso por el cual se verifica la identidad de una persona. De una forma
simple, este proceso se puede llevar a cabo mediante un nombre de usuario y una contraseña,
pero se pueden llegar a utilizar otros métodos para validar la identidad de una persona, como
mediante el uso de certificados, tarjetas etc…
En apache la autentificación puede estar gestionada por distintos módulos, dependiendo de la
forma de implementación. Si decide llevarla a cabo gestionando ficheros con listas de usuarios y
contraseñas (encriptadas), deberá utilizar el módulo mod_auth. Sin embargo, si decide llevarla a
cabo mediante base de datos, deberá utilizar los módulos mod_auth_dbm.
La autorización es el proceso por el cual se verifica que un usuario con una identidad conocida,
tiene acceso al recurso solicitado. Para llevar a cabo esta acción, se suelen utilizar listas de
permisos en las cuales se enumeran cada una de las acciones que puede realizar un usuario, o las
que no puede hacer. Normalmente, para simplificar la gestión de estos ficheros, los usuarios se
suelen unir en grupos proporcionando los permisos al grupo.
En apache la autorización a recursos es gestionada o bien mediante la directiva <directory> en el
fichero principal de configuración, o bien mediante la configuración de la carpeta a través de
ficheros .htaccess.
El control de acceso es el proceso por el cual se verifica que la máquina desde la que se ha hecho
la petición, tiene acceso al recurso. Los controles de acceso se utilizan para limitar y controlar las
máquinas que tienen acceso a un recurso independientemente del usuario que accede, ya que
estos controles se llevan a cabo antes de que se realice el proceso de autentificación.
En apache, el control de acceso se puede llevar a cabo mediante las directivas <directory><files>y
<location>, o a través del fichero de configuración .htaccess para controlar una carpeta especifica.
En todo caso y para poder llevar a cabo la configuración de las tres características aquí
enumeradas, autentificación, autorización y control de acceso, es necesario tener la directiva
AllowOverride con el valor AuthConfig, para así permitir el uso de las distintas directivas de
autentificación.
Autentificación y autorización de usuarios en Apache. Mod_auth
Para configurar el servidor apache para que sea capaz de autentificar a los usuarios y verificar la
autorización del mismo al recurso solicitado, es necesario realizar las siguientes acciones:
1. Crear un fichero con usuarios
2. Crear un fichero con grupos (si es necesario)
157
3. Definir las directivas en el fichero de configuración o mediante un fichero .htaccess
En los ficheros de usuarios de apache, en cada línea se especifica un usuario, escribiendo el
nombre de usuario separado de dos puntos, seguido de la contraseña encriptada con MD5. En los
ficheros de grupos de apache, en cada línea se especifica un grupo escribiendo el nombre del
grupo seguido de dos puntos, y a continuación separado por espacios, los nombres de los
usuarios.
Es recomendable que tanto los ficheros de usuarios como los de grupos, se encuentren
almacenados fuera de los directorios publicados, para que de esta forma nadie pueda
descargarlos. Asimismo, solo el usuario root debería estar autorizado a escribir en él, mientras que
solo el usuario que ejecuta el servicio web, debería estar autorizado para leerlo.
El fichero de grupos se puede crear manualmente, pero el fichero con los usuarios es
recomendable crearlo mediante la utilidad htpasswd, que se encuentra en la carpeta con los
binarios de apache.
Para crear un fichero de usuario se utilizará la siguiente sintaxis:
htpasswd -c ruta/passwords usuario
El flag -c se utiliza para crear un fichero nuevo, por lo que sólo se deberá poner la primera vez que
se crea el fichero, sino lo borrará.
Los módulos que intervienen en la autentificación y autorización son los de core y mod_auth.
Las directivas de mod_auth necesarias para configurar la autenticación y autorización son las
siguientes:
• AuthUserFile: siver para especificar la ruta donde se almacenará el fichero de usuarios.
• AuthGroupFile: sirve para especificar la ruta donde se almacenará el fichero de grupos. Las
directivas de core necesarias para complementar la configuración del módulo son:
• AuthType: selecciona el tipo de autentificación de usuarios que se utilizará para autentificar a un
usuario. Puede variar por directorio. Los valores posibles son Basic y Digest. Con Basic, la
transferencia de las claves se hará sin cifrar, y con digest se harán cifradas.
• AuthName: especifica un nombre del dominio para el cual se solicita el acceso, este nombre
figurará en la pantalla donde se pide la clave, y a su vez servirá para que el cliente identifique la
contraseña que debe utilizar al enviar una petición a un área determinada.
158
• Require: selecciona los usuarios que pueden acceder a un área determinada, los usuarios se
pueden determinar a través de nombres o grupos.
Proteger carpetas mediante usuarios en Apache
1. Crear un fichero de claves fuera de la parte pública:
-htpasswd -c /ruta/passwords Alain
Al hacerlo, pedirá que se introduzca la clave, y esta será codificada, escribiendo el fichero.
2. Crear un nuevo fichero, en la misma ubicación que "ruta", que se llamará "groups" en la que se
almacenarán los grupos, por ahora uno, para ello escribir la siguiente línea y guardar el fichero:
usuariosAutenticados: Alain
De esta forma, debería tener un fichero que se llame passwords, y que contenga una línea con los
datos del usuario Alain, y un fichero, con nombre groups, que contiene una línea definiendo un
grupo llamado usuariosAutenticados, del que sólo el usuario Alain forma parte.
3. Crear un fichero con el nombre .htaccess en la carpeta que se quiere proteger, y escribir las
siguientes líneas y guardar el fichero:
AuthType Basic
AuthName "ServidorPruebasAlain"
AuthUserFile /ruta/passwords
AuthGroupFile /ruta/groups
Require group usuariosAutenticados
La explicación del contenido del fichero es la siguiente:
• Con "AuthType Basic" se estará protegiendo la carpeta con autentificación básica, es decir que la
clave que el usuario introduzca, se transmitirá sin cifrar por la web.
• Con "AuthName "ServidorPruebasAlain" se asociará esta carpeta con el dominio
"ServidorPruebasAlain", nombre con el que lo identificará el cliente.
• Con "AuthUserFile /ruta/passwords" y "AuthGroupFile /ruta/groups" Se definirá la ubicación tanto
de los ficheros de usuarios como los ficheros de grupos y se almacenarán en la carpeta /ruta, con
nombres passwords y groups respectivamente.
• Con "Require group usuariosAutenticados" se autorizará el acceso al contenido de esta carpeta a
todos los usuarios que forman parte del grupo de "usuariosAutenticados", por lo que en la práctica
se autorizará el acceso al contenido al usuario Alain.
159
En vez de realizar las autorizaciones a grupos completos, se puede autorizar a un usuario
determinado cambiando la última línea por "Require user Alain", de esta forma sólo se autorizará al
usuario Alain.
Se puede permitir el acceso a todos los usuarios identificados mediante la introducción de la
siguiente directiva "Require valid-user". El hecho de que esta directiva este incluida en el fichero,
hace que las demás no tengan efecto.
Autentificación y autorización de usuarios con Mysql y Apache. mod_auth_mysql
En capítulos anteriores hemos explicado como controlar la autentificación y la autorización de
usuarios con el mod_auth. Este módulo tiene como característica el que almacena los nombres de
usuario, las contraseñas y los grupos en ficheros de texto que deben ser escritos y gestionados por
el administrador del sistema. Esta solución es obviamente poco escalable, ya que en cuanto el
número de usuarios y de grupos es elevado, el gestionarlos y controlarlos puede ser un problema.
Por este motivo existe el mod_auth_mysql, este módulo permite gestionar la autentificación y
autorización, almacenando los usuarios y los grupos en tablas de Mysql, de forma que incluso se
pueden gestionar mediante un panel de control escrito en php.
Para utilizar el módulo es necesario disponer de al menos una tabla donde se almacenen los
usuarios y otra donde se almacenen los grupos. Para ello se puede crear una tabla usuarios con
los campos, nombre y password, y otra tabla llamada grupos con los campos grupo, usuario,
almacenando una entrada por cada usuario que tenga un grupo.
La configuración es la siguiente:
En primer lugar será necesario establecer el servidor, el usuario y la contraseña de la conexión con
la base de datos, esto se hará escribiendo la siguiente línea en el fichero httpd.conf, y
reemplazando los valores por los correctos:
Auth_MySQL_Info <host> <user> <password>
Para configurar el módulo será necesario establecer los valores de las siguientes directivas del
módulo:
Auth_MySQL_DB: nombre de la base de datos
Auth_MySQL_Password_Table: nombre de la base de datos que contiene los nombres de
usuario y las contraseñas.
Auth_MySQL_Username_Field: nombre del campo de la tabla que contiene al usuario.
Auth_MySQL_Password_Field: nombre del campo de la tabla que contiene la contraseña del
usuario.
160
Auth_MySQL_Group_Table: nombre de la tabla que contiene los usuarios y los grupos a los
que pertenecen.
Auth_MySQL_Group_Field: nombre del campo de la tabla que contiene el nombre del grupo
Auth_MySQL_Empty_Passwords on/off para determinar si se aceptan usuarios con contraseñas
vacias.
Auth_MySQL_Encryption_Types para especificar el tipo de encriptación que se utilizará para
almacenar la clave del usuario dentro de la base de datos.
Auth_MySQL_Non_Persistent on/off para especificar si se desean utilizar conexiones persistentes.
Además será necesario establecer las siguientes directivas de core para su correcto
funcionamiento:
AuthName: con el nombre del dominio
AuthType: establecido a Basic
Una vez puesto en marcha, el funcionamiento es análogo al módulo mod_auth.
Control de acceso en Apache. Mod_access
Las directivas que proporciona este módulo se pueden utilizar dentro de los elementos, y del
fichero de configuración httpd.conf, o bien dentro de ficheros .htaccess ubicados dentro de las
carpetas.
Las directivas con las que cuenta el módulo para permitir o denegar el acceso son:
• Allow: controla los servidores que tendrán acceso al contenido, por ejemplo:
Allow from simulnet.com Permite el acceso desde simulnet.com
Allow from 192.168.0.1 Permite el acceso desde 192.168.0.1
Allow from 192.168 Permite el acceso desde todas las direcciones Ip que comienzan por 192.168
Allow from all Permitir todas
• Deny: controla los servidores a los que se denegará el acceso, por ejemplo:
Deny from simulnet.com Deniega el acceso desde desarrolloweb.com
Deny from 192.168.0.1 Deniega el acceso desde 192.168.0.1
Deny from 192.168 Deniega el acceso desde todas las direcciones Ip que comienzan por 192.168
Deny from all Denegar todas
• Order: determina el orden en el que se leerán los permisos, por ejemplo para leer primero los
permitidos y luego los no permitidos se pondrá "Allow,Deny" en este caso si un servidor esta en la
lista de permitidos, y en la de denegados, el acceso al mismo será denegado, ya que la entrada
dentro de la opción Deny sobrescribirá la de la entrada Allow.
161
Hay que tener en cuenta que el uso de order junto con Allow from all ó Deny from all, permite
especificar configuraciones como, permitir desde una máquina x y denegar del resto, de una forma
muy sencilla.
Adicionalmente, mediante la directiva SetEnvIf del módulo mod_setenvif, se pueden establecer
variables de entorno que determinen el funcionamiento de Allow o Deny de la misma forma que se
utilizan números IP ó nombres de máquinas. Por ejemplo, utilizando
Allow from env=entrada permitirá el acceso a todas las peticiones que tengan definida la variable
de entorno "entrada".
Controlar acceso dependiendo del navegador con Apache
Mediante el uso conjunto de las directivas Allow, Deny, Order y SetEnvIf se puede restringir el
acceso a un sitio dependiendo del tipo de navegador. Para realizarlo simplemente basta con crear
una variable de entorno dependiendo del tipo del navegador, y permitir el acceso a las peticiones
que cuenten con esta variable de entorno denegándoselo al resto.
Para ello la configuración necesaria es la siguiente:
SetEnvId User-Agent googlebot entrar
Order Deny, Allow
Deny from all
Allow from env=entrar
En la primera línea se especifica que se creará una variable de entorno llamada entrar cuando el
navegador sea el motor de indexación de google.
En la segunda línea se especifica el orden en el que se utilizará la lista de servidores, primero los
denegados y luego los permitidos.
En la cuarta línea se especifica que se deniega el acceso a cualquier petición
En la quinta línea se especifica que se permite el acceso a las peticiones que tienen definida la
variable de entorno entrar.
En el caso de que entre el motor de indexación de google, primero se leerá la línea en que se
deniegan todas las peticiones, para a continuación leer la línea en la línea en la que se permite el
acceso desde las peticiones que tienen definida la variable entrar, como el navegador que lo hace
es el googlebot, esta variable estará definida y entrará.
162
En el caso en que la petición sea realizada por cualquier otro navegador, primero se leerá la línea
en la que se deniegan las peticiones, y como no satisface la línea en que lo permite, no entrará
20 trucos de seguridad para Apache
Del mismo modo debes tener en cuenta que algunas de estas recomendaciones pueden disminuir
el rendimiento de tu servidor dependiendo de tu configuración y de las especificaciones del
sistema.
Primero, cerciorate de tener instalado los últimos parches de seguridad
No tiene sentido poner una cerradura mas resistente a tu puerta si dejas la ventana abierta.Del
mismo modo si no tenemos los ultimos parches de seguridad instalado no tendría sentido continuar
con la optimización de seguridad.
Restringir acceso por IP
Si tienes un recurso al que deba solamente tener acceso alguna red, o IP en concreto puedes
configurarlo en Apache. Por ejemplo si deseas restringir el acceso a tu Intranet para permitir
solamente la red 176.16:
Order Deny,Allow
Deny from all
Allow from 176.16.0.0/16
o por IP:
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Oculta la versión y otra información delicada
Por defecto muchas instalaciones de Apache muestran el número de versión que está
funcionando, el sistema operativo y un informe de módulos de Apache están instalados en el
servidor. Los usuario maliciosos pueden utilizar esta información para atacar tu servidor. Hay dos
directivas que necesitas agregar, o corregir en tu archivo de httpd.conf:
ServerSignature Off
ServerTokens Prod
El ServerSignature aparece en la parte inferior de las páginas generadas por apache tales
como los famosos errores 404.
163
La directiva ServerTokens se utiliza para determinarse lo que pondrá Apache en la cabecera de la
respuesta HTTP del servidor.
Apache debe funcionar bajo su propia cuenta y grupo de usuario
Algunas versiones de Apache corren bajo el usuario nobody, esto compromete mucho su
seguridad por lo tanto haz lo siguiente:
User apache
Group apache
Utiliza el mod_security
El mod_security es un módulo estupendo de Apache escrito por Ivan Ristic, el autor de Apache
Security de O'Reilly.
Esta es una lista de cosas que puedes hacer con mod_security:
• Filtración simple
• Filtración basada en expresiónes regular
• Validación de codificación de la URL
• Validación de codificación Unicode
• Auditing
• Prevención del ataque NULL Byte
• Límitar la memoria de subida
• Enmascarar la identidad del servidor
• Y más
Deshabilitar cualquier módulo innecesario
Apache viene por defecto instalado con un serie de módulos.Debes echarle un vistazo a la
documentación de Apache y ver para que sirve cada uno de ellos, y de esta manera te darás
cuenta de que hay algunos que no son útiles en tu servidor.
Busca en httpd.conf las lineas que contengan LoadModule. Para deshabilitar el módulo debes
agregar un # al principio de la línea, para que de esta forma pase a ser un comentario. Para buscar
los módulos prueba con:
grep LoadModule httpd.conf
Aquí están algunos módulos que se instalan por defecto pero a menudo no son necesarios:
mod_imap, mod_include, mod_info, mod_userdir, mod_status, mod_cgi, mod_autoindex.
164
Asegurarte de que los archivos a los que se accede son los deseados
No deseamos que se pueda acceder a los directorios que no tengan permisos para ello,
supongamos que el directorio raiz para nuestras webs es /web, la configuración óptima deberá ser
la siguiente:
Order Deny,Allow
Deny from all
Options None
AllowOverride None
Order Allow,Deny
Allow from all
Desactiva las opciones para explorar directorios
Esto lo puedes hacer con las opciones de directiva dentro de la etiqueta directorio tiene dos
posibles valores none o indexes.
Options -Indexes
Desactiva los includes del lado servidor
Esto también se hace con las opciones de directiva dentro de la etiqueta directorio tiene dos
posibles valores none o include.
Options -Includes
Desactiva la ejecución de CGI
Si no necesitas la ejecución de CGI por algún motivo en concreto desacrivalos se hace con las
opciones de directiva dentro de la etiqueta directorio tiene dos posibles valores none o ExecCGI.
Options -ExecCGI
No permitir que apache siga enlaces simbólicos
De nuevo se configura con las opciones de directiva dentro de la etiqueta directorio tiene dos
posibles valores none o FollowSymLinks.
Options -FollowSymLinks
165
Desactivar todas las opciones
Si deseas desactivar el uso de todas las opciones simplemente:
Options None
Si solamente deseas desactivar algunas en concreto, separalas con un espacio en las opciones de
directiva:
Options -ExecCGI -FollowSymLinks -Indexes
Desactivar la ayuda para los archivos .htaccess
Esto esta ya hecho pero con la directiva AllowOverride. Cámbialo a none.
AllowOverride None
Otra opción interesante sería bloquear la descarga de todos los archivos que comienzen con .ht
por ejemplo, se haría de la siguiente manera:
AccessFileName .httpdoverride
Order allow,deny
Deny from all
Satisfy All
Disminuye el valor máximo de tiempo de espera
Por el defecto el tiempo de espera es de 300 segundos. Puedes disminuirlo por seguridad para
prevenir ataques de esta manera:
Timeout 45
Limitar el tamaño maximo de peticiones
Apache tiene varias directivas que permiten que limites el tamaño de una petición, esto puede ser
muy útil.
Una buena manera de comenzar es con la directiva LimitRequestBody. Esta directiva esta fijada a
ilimitado por defecto. Si estás permitiendo uploads de archivos que no sean mayores a 1MB,
podrías fijar este ajuste a algo parecido a esto:
LimitRequestBody 1048576
Si no estás permitiendo uploads de archivos puedes fijarlo incluso a un tamaño más pequeño.
166
Algunas otras directivas a mirar son LimitRequestFields, LimitRequestFieldSize y
LimitRequestLine.
Conclusión
Espero que estas recomendaciones os hayan sido útiles y recuerda que el uso que le tienes
que dar depende en gran medida de los recursos que necesitas y de las caracteristicas de tu
servidor, antes de hacer cualquier cambio si no estas seguro documéntate y utiliza este artículo
unicamente como una referencía que te lleve a la solución más idonea.
PROXY PARA NAVEGACIÓN
Introducción
Un servidor proxy-cache tiene básicamente dos funciones, como proxy actúa como intermediario
en una transacción Web, el acepta la petición del cliente, la procesa y luego reenvía la solicitud al
servidor original, como servidor de cache almacena el contenido de las solicitudes de los clientes
para su posible uso de nuevo, cuando existe otra solicitud del mismo contenido el servidor
devuelve el contenido del cache, sin tener que contacta al servidor de nuevo.
Un servidor proxy-cache puede ser utilizado por las siguientes razones:
● Usar menos ancho de banda de la conexión a Internet.
● Reducir el tiempo de carga de las paginas Web.
● Proteger los equipos de la red interna.
● Prever que los usuarios acceden a sitios prohibidos.
● Generar estadísticas del trafico de la red y por usuario.
● Asegurar que solo usuarios autorizados pueden conectarse a Internet.
Squid
Squid es un programa de software libre que implementa un servidor proxy y un demonio para
caché de páginas web, publicado bajo licencia GPL. Tiene una amplia variedad de utilidades,
desde acelerar un Servidor Web, guardando en caché peticiones repetidas a DNS y otras
búsquedas para un grupo de usuarios que comparte recursos de la red, hasta caché de web,
además de añadir seguridad filtrando el tráfico. Está especialmente diseñado para ejecutarse bajo
entornos tipo Unix.
Características de Squid
Squid proporciona un servicio de Proxy que soporta peticiones HTTP, HTTPS y FTP a equipos que
necesitan acceder a Internet y a su vez provee la funcionalidad de caché especializado en el cual
167
almacena de forma local las páginas consultadas recientemente por los usuarios. De esta forma,
incrementa la rapidez de acceso a los servidores de información Web y FTP que se encuentra
fuera de la red interna.
Proxy para SSL
Squid también es compatible con SSL (Secure Socket Layer) con lo que también acelera las
transacciones cifradas, y es capaz de ser configurado con amplios controles de acceso sobre las
peticiones de usuarios.
Jerarquías de caché
Squid puede formar parte de una jerarquía de caches. Diversos proxys trabajan conjuntamente
sirviendo las peticiones de las páginas. Un navegador solicita siempre las páginas a un sólo proxy,
si este no tiene la página en la caché hace peticiones a sus hermanos, que si tampoco las tienen
las hacen a su/s padre/s. Estas peticiones se pueden hacer mediante dos protocolos: HTTP e
ICMP.
ICP, HTCP, CARP, caché digests
Squid sigue los protocolos ICP, HTCP, CARP y caché digests que tienen como objetivo permitir a
un proxy "preguntarle" a otros proxys caché si poseen almacenado un recurso determinado.
Caché transparente
Squid puede ser configurado para ser usado como proxy transparente de manera que las
conexiones son enrutadas dentro del proxy sin configuración por parte del cliente, y habitualmente
sin que el propio cliente conozca de su existencia. De modo predefinido Squid utiliza el puerto 3128
para atender peticiones, sin embargo se puede especificar que lo haga en cualquier otro puerto
disponible o bien que lo haga en varios puertos disponibles a la vez.
WCCP
A partir de la versión 2.3 Squid implementa WCCP (Web Cache Control Protocol). Permite
interceptar y redirigir el trafico que recibe un router hacia uno o más proxys caché, haciendo control
de la conectividad de los mismos. Además permite que uno de los proxys caché designado pueda
determinar como distribuir el tráfico redirigido a lo largo de todo el arreglo de proxys caché.
Control de acceso
Ofrece la posibilidad de establecer reglas de control de acceso. Esto permite establecer políticas
de acceso en forma centralizada, simplificando la administración de una red.
168
Aceleración de servidores HTTP
Cuando un usuario hace petición hacia un objeto en Internet, este es almacenado en el caché, si
otro usuario hace petición hacia el mismo objeto, y este no ha sufrido modificación alguna desde
que lo accedió el usuario anterior, Squid mostrará el que ya se encuentra en el caché en lugar de
volver a descargarlo desde Internet. Esta función permite navegar rápidamente cuando los objetos
ya están en el caché y además optimiza enormemente la utilización del ancho de banda.
SNMP
Squid permite activar el protocolo SNMP, este proporciona un método simple de administración de
red, que permite supervisar, analizar y comunicar información de estado entre una gran variedad
de máquinas, pudiendo detectar problemas y proporcionar mensajes de estados.
Caché de resolución DNS
Squid está compuesto también por el programa dnsserver, que se encarga de la búsqueda de
nombres de dominio. Cuando Squid se ejecuta, produce un número configurable de procesos
dnsserver, y cada uno de ellos realiza su propia búsqueda en DNS. De este modo, se reduce la
cantidad de tiempo que la caché debe esperar a estas búsquedas DNS.
Proxy-Cache en Squid
El proxy caché es una manera de guardar los objetos solicitados de Internet (por ejemplo, datos
como páginas web) disponibles vía protocolos HTTP, FTP y en un sistema más cercano al lugar
donde se piden. Los navegadores web pueden usar la caché local Squid como un servidor proxy
HTTP, reduciendo el tiempo de acceso así como el consumo de ancho de banda. Esto es muchas
veces útil para los proveedores de servicios de Internet para incrementar la velocidad de sus
consumidores y para las redes de área local que comparten la conexión a Internet.
Debido a que también es un proxy (es decir, se comporta como un cliente en lugar del cliente real),
puede proporcionar un cierto grado de anonimato y seguridad. Sin embargo, también puede
introducir problemas significativos de privacidad ya que puede registrar mucha información,
incluyendo las URL solicitadas junto con otra información adicional como la fecha de la petición,
versión del navegador y del sistema operativo.
Un programa cliente (por ejemplo, un navegador) o bien tiene que especificar explícitamente el
servidor proxy que quiere utilizar (típico para consumidores de ISP) o bien podría estar usando un
proxy sin ninguna configuración extra. A este hecho se le denomina caché transparente, en el cual
todas las peticiones HTTP son interceptadas por squid y todas las respuestas guardadas en caché.
Esto último es típico en redes corporativas dentro de una red de acceso local y normalmente
incluye los problemas de privacidad mencionados previamente.
169
Squid tiene algunas características que pueden facilitar establecer conexiones anónimas.
Características tales como eliminar o modificar campos determinados de la cabecera de peticiones
HTTP de los clientes. Esta política de eliminación y alteración de cabeceras se establece en la
configuración de Squid. El usuario que solicita páginas a través de una red que utiliza Squid de
forma transparente, normalmente no es consciente de este proceso o del registro de información
relacionada con el proceso.
Requerimientos de Hardware y Sistemas Operativos
Los requerimientos de Hardware de Squid son generalmente modestos, el parámetro mas
importante a ser tomado en cuanta en una instalación de squid es la memoria. El no poseer
memoria suficiente causa una drástica degradación en el rendimiento de los sistemas. Otro
aspecto importante es el espacio en disco, mas espacio significa mayor cantidad de objetos en
cache y menores búsquedas en Internet. Una interfaz de discos mas rápida es siempre
recomendada, por ejemplo siempre prefiera a discos SCSI a discos ata o sata.
El procesamiento no es una variable critica en el rendimiento de squid, aunque CPU mas rápidos
siempre son preferidos. Como squid utiliza una pequeña cantidad de memoria por cada respuesta
de cache existe una relación entre el espacio de la memoria y el cache de disco, como regla
general se puede utilizar que se necesitan 32 MB de memoria RAM por cada GB de cache de
disco, por lo cual un sistema con 1 GB de memoria puede almacenar 32 GB de cache sin afectar
su rendimiento.
Squid puede ser instalado en sistemas Linux, Unix, y Windows.
Instalación de Squid en Centos
Para instalar en servidor Squid en Debian GNU/Linux se debe ejecutar desde una consola como
usuario root :
#yum install squid
Configuración de Squid
El archivo de configuración general de squid se llama squid.conf y se encuentra ubicado en
/etc/squid/squid.conf.
La configuración de Squid es similar a la de los archivos Unix, cada línea de configuración
comienza con una directiva seguida de un valor o valores, squid ignora las lineas en blanco o las
que comienzan con el símbolo numeral “#”.
170
Ejemplos de Configuración en squid
cache_log /squid/var/cache.log
# define the localhost ACL
acl Localhost src 127.0.0.1/32
connect_timeout 2 minutes
log_fqdn on
Algunas Directivas poseen un solo valor, por lo cual lineas repetidas harán que se tomen
solamente la ultima, en el siguiente ejemplo la segunda linea es la que es tomada como valor del
servidor:
connect timeout 2 minutes
connect timeout 1 hour
Controles de Acceso (ACL)
Los controles de acceso son la parte mas importante en la configuración del servidor squid, estas
se utilizan para dar acceso a los usuarios y también para negarlo. Las ACL pueden usarse para
restringir o prevenir acceso a ciertos sitios o contenidos. Utilizan la siguiente sintaxis:
acl nombre_acl tipo_acl descripción ...
acl nombre_acl tipo_acl "archivo_de_descripciones" ...
Cuando usamos un "archivo_de_descripciones", cada descripción se corresponde con una línea
del archivo.
Tipos de ACL
src
Especifica una dirección origen de una conexión en formato IP/máscara. Por ejemplo, utilizaremos
una acl de tipo src para especificar la red local:
acl red_local src 192.168.1.0/24
También podemos especificar rangos de direcciones mediante una acl de tipo src:
acl jefes src 192.168.1.10-192.168.1.25/32
dst
Especifica una dirección destino de una conexión en formato IP/máscara.
171
acl google dst 216.239.0.0/24
También podemos especificar hosts concretos mediante una acl de tipo dst:
acl google dst 216.239.59.104/32 216.239.39.104/32 216.239.57.104/32
Las definiciones son idénticas a las acl de tipo src salvo que se aplican al destino de las
conexiones, no al origen.
srcdomain y dstdomain
Estos tipos de acl especifican un nombre de dominio. En el caso de srcdomain es el dominio origen
y se determina por resolución DNS inversa de la IP de la máquina, es decir, tendremos que tener
bien configurado el DNS de la red local.
En el caso de dstdomain el nombre del dominio se comprueba con el dominio que se haya
especificado en la petición de página web.
Por ejemplo:
acl google_com dstdomain google.com
srcdom_regex y dstdom_regex
Especifican una expresión regular que verifican los dominio origen o destino. La expresión regular
hace distinción entre mayúsculas y minúsculas salvo que incluyamos la opción "-i" que evita dicha
distinción.
Ejemplo:
acl google_todos dstdom_regex -i google\..*
Observamos como al incluir "-i" estamos indicando que no haga distinción entre mayúsculas y
minúsculas.
time
Este tipo de acl permite especificar una franja horaria concreta dentro de una semana.
La sintaxis es la siguiente:
acl nombre_acl_horaria time [días-abrev] [h1:m1-h2:m2]
Donde la abreviatura del día es:
172
S - Sunday (domingo)
M - Monday (lunes)
T - Tuesday (martes)
W - Wednesday (miércoles)
H - Thursday (jueves)
F - Friday (viernes)
A - Saturday (sábado)
Además la primera hora especificada debe ser menor que la segunda, es decir:
h1:m1 tiene que ser menor que h2:m2
Ejemplo
acl horario_laboral time M T W H F 8:00-17:00
Estaríamos especificando un horario de 8 a 17 y de lunes a viernes.
url_regex
Permite especificar expresiones regulares para comprobar una url completa, desde el http:// inicial.
Por ejemplo, vamos a establecer una acl que se verifique con todos los servidores cuyo nombre
sea adserver:
url_regex serv_publicidad ^http://adserver.*
En otro ejemplo podemos ver una acl que verifique las peticiones de archivos
mp3:
url_regex archivos_mp3 -i mp3$
referer_regex
Define una acl que se comprueba con el enlace que se ha pulsado para acceder a una
determinada página. Cada petición de una página web incluye la dirección donde se ha pulsado
para acceder. Si escribimos la dirección en el navegador entonces estaremos haciendo una
petición directa.
Por ejemplo vamos a establecer una acl para todas las páginas a las que hayamos accedido
pulsando en una ventana de búsqueda de google:
173
acl pincha_google referer_regex http://www.google.*
req_mime
Las acl de tipo req_mime se utilizan para comprobar el tipo de petición mime que realiza un cliente,
y se puede utilizar para detectar ciertas descargas de archivos o ciertas peticiones en túneles
HTTP.
Esta acl sólo comprueba las peticiones que realiza el cliente, no comprueba la respuesta del
servidor. Esto es importante para tener claro qué estamos haciendo y qué no.
Ejemplo
acl subida req_mime_type -i ^multipart/form-data$
acl javascript req_mime_type -i ^application/x-javascript$
acl estilos req_mime_type -i ^text/css$
acl audiompeg req_mime_type -i ^audio/mpeg$
rep_mime_type
Este tipo de acl se utiliza para verificar el tipo de respuesta recibida por el proxy. Este tipo de acl,
analiza una respuesta del servidor por lo que sólo le afectas las reglas de respuesta como
http_reply_access y no las reglas http_access que se aplican a las peticiones.
Ejemplo:
acl javascript rep_mime_type -i ^application/x-javascript$
acl ejecutables rep_mime_type -i ^application/octet-stream$
acl audiompeg rep_mime_type -i ^audio/mpeg$
EJERCICIOS CON ACL
Ejercicio 1
Crear un archivo de configuración para denegar el acceso a todos los equipos a la dirección
www.google.com
acl all src 0.0.0.0/0.0.0.0
acl no_permitido1 dstdomain www.google.com
acl localhost src 127.0.0.1
http_access deny no_permitido1 !localhost
174
En este ejemplo construimos la acl llamada localhost que representa el servidor proxy (dirección
loopback). Observe que en http_access se ha puesto !localhost para denegar el acceso a todos los
equipos de la red menos al equipo local. De esta manera el equipo en el que está instalado squid
puede acceder a la página www.google.com
Ejercicio 2
Crear un archivo de configuración que deniegue el acceso a las direcciones www.google.com y
www.hotmail.com.
acl all src 0.0.0.0/0.0.0.0
acl localhost localhost src 127.0.0.1
acl no_permitido1 dstdomain www.google.com www.hotmail.com
http_access deny no_permitido1 !localhost
En este caso el archivo de configuración es similar al caso anterior. Tan sólo hay que poner
www.hotmail.com después de www.google.com en la acl no_permitido1.
Ejercicio 3
Crear un archivo llamado no_permitidos, en la ruta /etc/squid que contenga las direcciones de los
tres siguientes dominios:
http://www.google.com
http://www.yahoo.com/
http://www.hotmail.com/
A continuación crea un archivo de configuración squid.conf que deniegue las conexiones a las
direcciones que se encuentran en el archivo no_permitidos.
acl all src 0.0.0.0/0.0.0.0
acl localhost src 127.0.0.1
acl no_permitido1 url_regex “/etc/squid/no_permitidos”
http_access deny no_permitido1 !localhost
Ejercicio 4
Se dispone de una red local con dirección 192.168.1.0 y máscara 255.255.255.0. Crear un archivo
de configuración squid.conf que permita el acceso a Squid a todos los equipos de la red y no lo
permita a los restantes.
175
acl all src 0.0.0.0/0.0.0.0
acl todalared src 192.168.1.0/255.255.255.0
acl localhost src 127.0.0.1
http_access allow todalared
http_access deny all !localhost
Ejercicio 5
Se dispone de una red de área local con dirección 192.168.1.0 y máscara 255.255.255.0. Se desea
permitir el acceso a Squid a los equipos con las IP que están comprendidas en el rango
192.168.1.1 y 192.168.1.10 (ambas incluidas). Crea en el directorio /etc/squid3/ un archivo llamado
ip_permitidas que tenga estas direcciones (cada dirección en una línea diferente). Con esta
configuración para Squid se permite el acceso a Squid a todas estas direcciones y denegar el
acceso a las restantes.
acl all src 0.0.0.0/0.0.0.0
acl red_local src “/etc/squid3/ip_permitidas”
acl localhost src 127.0.0.1
http_access allow red_local
http_access deny all !localhost
Ejercicio 6
Impide la conexión a Internet a todos los equipos en horario de 18:00 a 21:00 horas.
acl all src 0.0.0.0/0.0.0.0
acl localhost src 127.0.0.1
acl horario time 18:00-21:00
http_access deny horario !localhost
Ejercicio 7
Niega las conexiones a todos los equipos en horario de 18:00 a 21:00 horas, pero sólo los lunes,
martes y miércoles.
acl all src 0.0.0.0/0.0.0.0
acl horario time MTW 18:00-21:00
http_access deny horario !localhost
Ejercicio 8
Deniega el acceso a Squid al equipo con IP 192.168.1.5. Permite el resto de accesos a Squid.
176
acl all src 0.0.0.0/0.0.0.0
acl equipo5 src 192.168.1.5
http_access deny equipo5
Ejercicio 9
Deniega el acceso a Squid al equipo con IP 192.168.1.5 en horario de 18:00 a 21:00 horas.
Permite el resto de accesos a Squid.
acl all src 0.0.0.0/0.0.0.0
acl equipo5 src 192.168.1.5
acl horario 18:00-21:00
http_access deny equipo5 horario
Ejercicio10
Niega el acceso a Squid al equipo con IP 192.168.1.5 en horario de 18:00 a 21:00 horas. Para el
resto de equipos permitir el acceso sólo en horario de 10:00 a 14:00 horas. Se supone que los
equipos pertenecen a la red 192.168.1.0 con máscara 255.255.255.0.
acl all src 0.0.0.0/0.0.0.0
acl red_local src 192.168.1.0/255.255.255.0.
acl equipo5 src 192.168.1.5
acl horario1 18:00-21:00
acl horario2 10:00-14:00
http_access deny equipo5 horario1
http_access allow red_local horario2
http_access allow equipo5
Ejercicio 11
En el archivo /etc/squid3/permitidos se tiene una lista de todas las direcciones IP de la red local. El
equipo10 tiene la dirección IP 192.168.1.10. Se permite el acceso a Internet al equipo10 de lunes a
miércoles de 9:00 a 14:00 horas. También se permite el acceso a los equipos de la red local de
lunes a miércoles. Se prohibe el acceso en el resto de casos.
acl all src 0.0.0.0/0.0.0.0
acl localhost src 127.0.0.1
acl redlocal src “/etc/squid/permitidos”
acl equipo10 src 192.168.1.10
acl horario time MTWHF 9:00-14:00
177
acl horario2 time MTW
http_access allow equipo10 horario
http_access allow redlocal horario2
http_access allow localhost
http_access deny all
Ejercicio 12
Restringe el acceso a todo el contenido con extensión .mp3 a los equipos de la red.
acl all src 0.0.0.0/0.0.0.0
acl redlocal src 192.168.1.0/255.255.255.0
acl musica urlpath_regex \.mp3
http_access allow redlocal !musica
http_access deny all
AUTENTICACIÓN EN SQUID
Es muy útil el poder establecer un sistema de autenticación para poder acceder hacia Internet,
pues esto permite controlar quienes si y quienes no accederán a Internet sin importar desde que
máquina de la red local lo hagan. Será de modo tal que tendremos un doble control, primero por
dirección IP y segundo por nombre de usuario y clave de acceso.
ELIGIENDO EL MÓDULO DE AUTENTICACIÓN
Se consideraran dos opciones de autenticación una a través de texto simple con claves de acceso
creadas con htpasswd o bien a través de un servidor LDAP, lo cual constituye una solución más
robusta.
AUTENTICACIÓN SIMPLE
Squid puede utilizar el módulo ncsa_auth, de la NCSA (National Center for Supercomputing
Applications), y que ya viene incluido como parte del paquete principal de Squid en la mayoría de
las distribuciones actuales. Este módulo provee una autenticación muy sencilla a través de un
archivo de texto simple cuyas claves de acceso fueron creadas con htpasswd.
178
Creación del archivo de claves de acceso
Se requerirá la creación previa de un archivo que contendrá los nombres de usuarios y sus
correspondientes claves de acceso (cifradas). El archivo puede localizarse en cualquier lugar del
sistema, con la única condición que sea asequible para el usuario squid.
Debe procederse a crear un archivo /etc/squid3/claves:
#touch /etc/squid/claves
Salvo que vaya a utilizarse un guión a través del servidor web para administrar las claves de
acceso, como medida de seguridad, este archivo debe hacerse para que solo el usuario squid
pueda leerlo o escribirlo:
#chmod 600 /etc/squid/claves
#chown squid:squid /etc/squid/claves
A continuación deberemos dar de alta las cuentas que sean necesarias, utilizando el mandato
htpasswd -mismo que viene incluido en el paquete de apache. Ejemplo:
#htpasswd /etc/squid/claves areyes
Lo anterior solicitará teclear una nueva clave de acceso para el usuario joseperez y confirmar
tecleando ésta de nuevo. Repita con el resto de las cuentas que requiera dar de alta. Todas las
cuentas que se den de alta de este modo son independientes a las ya existentes en el sistema. Al
dar de alta una cuenta o cambiar una clave de acceso lo estará haciendo EXCLUSIVAMENTE para
el acceso al servidor Proxy. Las cuentas son independientes a las que se tengan existentes en el
sistema como serían shell, correo y Samba.
Parámetros en /etc/squid/squid.conf
Lo siguiente será especificar que programa de autenticación se utilizará.
Localice la sección que corresponde a la etiqueta auth_param basic program.
Por defecto no está especificado programa alguno. Considerando que ncsa_auth se localiza en
/usr/lib/squid3/ncsa_auth, procederemos a añadir el siguiente parámetro:
auth_param basic program /usr/lib/squid/ncsa_auth /etc/squid/claves
179
/usr/lib/squid3/ncsa_auth corresponde a la localización de el programa para autenticar y
/etc/squid/claves al archivo que contiene las cuentas y sus claves de acceso.
Autenticación a través del módulo LDAP
Considerando que se ha configurado exitosamente OpenLDAP como servidor de autenticación,
solo basta definir el directorio y el servidor LDAP a utilizar.
La sintaxis utilizada para squid_ldap_auth es la siguiente:
#squid_ldap_auth -b "Directorio-o-DN-a-utilizar" servidor-ldap-autilizar
Ejemplo:
#squid_ldap_auth -b "cn=people,dc=su-dominio,dc=com" 127.0.0.1
Parámetros en /etc/squid/squid.conf
Se debe editar el archivo /etc/squid/squid.conf y se especificar el programa de autenticación se
utilizará. Localice la sección que corresponde a la etiqueta auth_param basic program. Por defecto
no está especificado programa alguno. Considerando que squid_ldap_auth se localiza en
/usr/lib/squid3/ncsa_auth, procederemos a añadir el siguiente parámetro:
auth_param basic program /usr/lib/squid/squid_ldap_auth -b
"cn=people,dc=su-dominio,dc=com" 127.0.0.1
Lo anterior conecta al directorio dc=su-red-local,dc=com en el servidor
LDAP en 127.0.0.1.
Listas y reglas de control de acceso
El siguiente paso corresponde a la definición de una Lista de Control de Acceso. Especificaremos
una denominada passwd la cual se configurará para utilizar obligatoriamente la autenticación para
poder acceder a Squid. Debe localizarse la sección de Listas de Control de Acceso y añadirse la
siguiente línea:
acl password proxy_auth REQUIRED
Habiendo hecho lo anterior, deberemos tener en la sección de Listas de Control de Acceso algo
similar a lo siguiente:
Listas de Control de Accesos: autenticación.
180
#
# Recommended minimum configuration:
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl redlocal src 192.168.1.0/255.255.255.0
acl password proxy_auth REQUIRED
Procedemos entonces a modificar la regla de control de accesos que ya teníamos para permitir el
acceso a Internet. Donde antes teníamos lo siguiente:
http_access allow redlocal
Le añadimos passwd, la definición de la Lista de Control de Acceso que requiere utilizar clave de
acceso, a nuestra regla actual, de modo que quede como mostramos a continuación:
http_access allow redlocal password
Habiendo hecho lo anterior, la zona de reglas de control de acceso debería quedar de este modo:
Reglas de control de acceso: Acceso por clave de acceso.
#
# INSERT YOUR OWN RULE(S) HERE TO allow ACCESS FROM YOUR
CLIENTS
#
http_access allow localhost
http_access allow redlocal password
http_access deny all
SERVIDOR DE CORREO ZIMBRA
¿Que es Zimbra?
La Suite de Colaboración Zimbra es un programa colaborativo creado por Zimbra Inc., fue
adquirida por Yahoo! Inc. en Septiembre de 2007 y posteriormente adquirida por VMWare,
haciendo un acuerdo de mantener sus estándares de Software Abierto. Posee tanto el componente
de servidor como su respectivo cliente.
181
Existen varias versiones de Zimbra disponibles: una versión soportada por la comunidad de
Software Abierto (Open Source), y otras con parte del código cerrado y soportado comercialmente
que contiene algunas mejoras.
Al igual que el programa de correo electrónico Exchange, de Microsoft, Zimbra permite a los
empleados de oficina enviar, recibir, guardar y buscar los miles de mensajes procesados cada día.
El Servidor ZCS hace uso de proyectos Open Source existentes como ser: Postfix, MySQL,
OpenLDAP. Expone una interfaz de programación de aplicaciones (API) SOAP para toda su
funcionalidad y actúa tanto como un servidor IMAP y POP3.
El Cliente Web ZCS es una interfaz de colaboración y administración completa creada empleando
el Toolkit Zimbra Ajax. Soporta correos electrónicos y calendarios a través de una impresionante
interfaz web Ajax, que provee tips de sus objetos, ítems arrastrables, y menús que se expanden al
hacer clic derecho. También incluye capacidades de búsqueda avanzada y permite relacionar
fechas.
El calendario compartido en grupo también esta incluido.
ZCS es compatible con clientes propietarios tales como Microsoft Outlook, Novell Evolution y
Apple Mail. También provee soporte de sincronización nativo para muchos dispositivos móviles
(Nokia E-Series, Android, BlackBerry, Windows Mobile,etc).
Instalación
A la hora de la instalación el elemento más importante a tener en cuenta es que Zimbra se instala
bajo la carpeta /opt si el almacenamiento de buzones e indexado se mantiene por defecto entonces
esta carpeta o partición asignada, debería ser la que más espacio dedicado tenga.
Requerimientos
Los requerimientos de Zimbra Collaboration Suite son, en comparación con otros productos
similares, bastante bajos. Para entornos de evaluación (hasta50 cuentas) la siguiente configuración
debería ser suficiente:
-CPU Intel/AMD de 32bits a 1.5 GHz o superior.
-1 GB de RAM.
-10 GB de espacio libre en disco para el software y los logs.
-Espacio adicional para el almacenamiento del correo y las bases de datos (depende del número
de cuentas y de la cuota de disco asignada a cada una)
182
Primero que todo nos vamos para nano /etc/hosts allí colocaremos la ip de nuestro servidor, el
nombre del equipo, junto con el dominio y el host.
-Luego editaremos el archivo /etc/sysconfig/network donde colocaremos el nombre del servidor
más el dominio.
-Antes de instalar Zimbra debemos detener el servicio de Postfix y evitar que arranque de nuevo,
para eso ejecutamos los comandos:
service postfix stop
chkconfig postfix off
-Instalación de Dependencias:
nc (Netcat)
sudo
libidn
gmp
NPTL
libstdc++ (32 bits)
sysstat
sqlite
-Cuando se ejecuta el script de instalación, este verifica que los paquetes de Zimbra a ser
instalados estén disponibles:
Zimbra Core: Instala las librerías, utilitarios y herramientas de monitoreo.
Zimbra LDAP: Instala OpenLDAP el cual provee una solución opensource de servicio de
directorio.
Zimbra Store: Instala el servidor de buzones, incluyendo Jetty, el contenedor de Servlets
para el servidor de Zimbra.
Zimbra MTA: Instala el Postfix, Clamav, SpamAssasin y Amavis.
Zimbra SNMP: Instala el paquete SNMP para monitoreo.
Zimbra Logger: Instala las herramientas para syslog y reportes estadísticos.
Zimbra Spell: Instala el motor Aspell para revisión ortográfica.
Zimbra Apache: Es instalado automáticamente cuando Zimbra Spell es instalado.
La configuración del servidor de Zimbra se realiza a través de los menús presentados por el script
de instalación. Este script muestra los valores de la configuración por defecto. El menú muestra
además el nombre lógico del servidor y el dominio de correo. Estos valores pueden ser cambiados
183
según se desee. Para instalaciones de servidor simple, la clave del administrador debe ser definida
que será la utilizada posteriormente para acceder a la consola administrativa.
-Ahora nos vamos a registrar como usuario Zimbra ya que vamos a ver si los
servicios están corriendo en buen estado.
su zimbra
-Y ejecutamos el comando zmcontrol status para poder ver los servicios.
zmcontrol status
Aquí nos sale el estado de cada uno de los servicios los cuales deben estar todos en Running.
A partir de aquí seleccionamos un navegador web y apuntamos hacia la dirección:
https://nombreserver:7071
Y listo ya tenemos instalado nuestro servidor de correo Zimbra.
Configurando la Autenticación de Zimbra con FreeIPA:
Antes de hacer la configuración externa es importante destacar que una que vez que se establece
que la autenticación de Zimbra es externa, el admin creado en el proceso de instalación queda
inutilizado y esto podría traernos problemas, para resolver esto debemos hacer lo siguiente:
# su -l zimbra
$ zmprov modifydomain simulnet.com zimbraAuthFallbackToLocal TRUE
$
-Prerequisitos
Lo primero es crear una cuenta en el directorio de FreeIPA que servirá de enlace (bind) a la hora
de autenticar.
Configuración
Paso 1:
Entrar en la consola administrativa de Zimbra: https://correo.simulnet.com:7071
184
Paso 2:
Una vez logueado con el usuario administrador, en la izquierda seleccionamos el dominio que
vamos a configurar, y finalmente hacemos click en: Configure Authentication.
Paso 3:
Seleccionar "External LDAP"
Escribimos el nombre del servidor de FreeIPA (servidor.simulnet.com)
En LDAP Filter, poner "(&(objectClass=inetOrgPerson)(objectClass=posixAccount)(uid=%u))" sin
las comillas
En LDAP Search Base, poner: "cn=users,cn=accounts,dc=example,dc=com" sin las comillas
Y finalmente click en Next.
185
Paso 4:
Marcamos el checkbox "Use DN/Password to bind to external server:" y poner el usuario que
creamos como prerequisito.
Click Next
Paso 5:
186
En este paso tenemos la posibilidad de verificar que la configuración realizada es correcta y est’a
funcionando.
Paso 6:
Si todo ha salido como debería, saldrá un mensaje en verde indicando que el proceso de
autenticación se ha completado satisfactoriamente.
Click next y finalmente click finish.
187
VIRTUALIZACIÓN
Mucha gente e pregunta como tener su propio Cloud, a ser posible opensource y que sea sencillo
de instalar. Una respuesta a esta pregunta es Openstack, aunque tenemos muchas otras opciones,
hoy vamos a desplegar Openstack con la ayuda de stackops, una distribución Baremetal basada
en Ubuntu 10.04 que nos ayuda a instalar Openstack de manera más sencilla e intuitiva que
hacerlo a mano. Destacar que la instalación que vamos ha hacer es un entorno SingleNode, el más
sencillo y no lo recomiendo para un entorno final, sólo para familiarizarnos e ir poco a poco
probando a aumentar la complejidad.
¿QUÉ ES OPENSTACK?
OpenStack es un proyecto de código abierto procedentes de Rackspace y la NASA, con el objetivo
de establecer normas más abiertas de la industria. OpenStack incluye un un proyecto de Compute
y Storage. StackOps es un súcedaneo de OpenStack, es un asistente que nos ayudará a
desplegar OpenStack en tan sólo unos minutos. Soluciones comerciales, con soporte también está
disponible.
Cosas a considerar para elegir una son el tipo de almacenamiento (por ejemplo, NFS o iSCSI SAN,
el almacenamiento local, almacenamiento distribuido), el hipervisor de apoyo, multi-alquiler, alta
188
disponibilidad, API, auto-servicio de panel de control, integración de la facturación, la medición de
recursos, automatización, aislamiento de la red, concesión de licencias, la apertura a la
personalización, soporte comercial, asistencia para la integración, etc.
Preparación del Servidor
Vamos a preparar el servidor con las siguientes caracteristicas obtenidas en la página oficial de
Stackops, para un entorno SingleNode:
Server Minimum
Configuration Recommended Configuration
Controller/Network/Volume/Compute
Node
64 bits x86
2GB of RAM*
1 x 30GB of SATA
disk
1 x 1Gb NIC
2 x 64 bits x86
32GB of RAM **
2 x 32GB of SAS/SATA/SSD –
Raid 1.
2 x 2TB of SATA – Raid 1. ***
2 x 1Gb NIC
* 2GB de RAM sólo permite 1 instancia m1.small o 3 m1.tiny sin hacer swapping de memoria. Sólo
para entornos de prueba.
** 32GB of RAM necesita 2 Quad-core CPU con Hyperthreading: 16 instancias de tipo m1.small por
servidor. Una regla apróximada es 2 x m1.small instancias por Core y 4GB de RAM por Core.
*** Como regla general, 2 TB de almacenamiento en el nodo Volumen reservados por nodo
añadido
-Después de instalado el Nodo de Stackops abrimos nuestro navegador preferido e introduciremos
http://IP:8888 que anteriormente escribimos, o si no la recordamos en la pantalla del Ubuntu nos
mostrará la IP para gestionarlo, muy al estilo Baremetal de muchos appliance. Esta web interna
nos llevará a installer.stackops.org, deberemos crear una cuenta para entrar, es grátis. Es
important crearla, ya que seguramente después de este curso en SingleNode, querremos hacer un
DualNode, MultiNode y quizás un Advanced.
Como podemos observar, el asistente nos muestra una topologia de como pueden ser los entornos
soportados por el Asistente de stackops, tenemos desde el más básico, hasta configuraciones
completamente estructuradas por servicio. Seleccionaremos en nuestro caso SingleNode y
pulsaremos Start Deployment.
-La primera pantalla del asistente nos mostrará que nuestro Hypervisor no soporta KVM, solo
QEMU, esto pasa por estar virtualizando el Ubuntu, instalandolo en una máquina fisica no
189
tendriamos este problema. También he marcado el disco de 2TB que le otorgamos antes, sólo a
modo información para que no se olvide.
-El siguiente paso nos mostrará algunos parámetros de nuestro sistema, DNS, hostname, CPU,
etc. Pulsaremos en Next.
190
-Este es el paso de Networking, cómo es un entorno sencillo, una tarjeta de red para todo es lo
óptimo, recordemos que en un entorno distribuido, Management y Public no estarán en la misma
tarjeta ni en el mismo rango de red. Pulsaremos Continue si estamos de acuerdo.
-El siguiente paso es el de Global Settings, viene marcado la interfaz web Horizon, aunque
experimental funciona de lujo. Si pulsamos en Advanced Mode, veremos lo siguiente.
-En la sección de volume podremos utilizar el disco de 2TB que antes pusimos, seleccionaremos
/dev/sdb que es nuestro disco secundario. Podemos ver la parte avanzada también.
191
-Llego la hora de Compute, no podremos cambiar la parte de QEMU por la razón que explicamos
más arriba. Podemos ver la sección avanzada si queremos.
-Pasado este paso vamos revisando los valores por defecto que establece el instalador y si no
estamos de acuerdo con alguno simplmente lo modificamos.
Configurando el servidor
Empezamos por abrir un cliente SSH de nuestra elección donde introducimos la IP con la cual
configuramos nuestro servidor virtual. Por defecto, las credenciales para root es de password
stackops. Debermos cambiarla llegados a este punto.
Lo primero que haremos será ver como podemos comprobar el estado básico de nuestra
plataforma. Con el comando nova-manage podemos hacer muchas cosas.
192
Para ello debemos movernos al directorio: /var/lib/nova/bin y ejecutamos: ./nova-
manage service list
Con este comando comprobaremos que nuestros servicios básicos para el funcionamiento del
Cloud están funcionando.
El usuario por defecto de la Distribución de Stackops usa Keystone para administrar los usuarios y
los tenants de la plataforma. Hay creados dos usuarios por defecto: ‘admin’ con la contraseña
‘password’ y ‘admin:password’. Stackops no recomienda el usuario admin para trabajar como
usuario Cloud. Recomiendan el usuario ‘demo’ con password ‘password’ y ‘demo:password’ para
las credenciales de EC2.
Si quiere administrar el proyecto con la API de EC2 u Openstack v1.1, necesitas ejecutar un script
que se encuentra en /var/lib/stackops/setenv.sh
Este script creará todo lo necesario para las variables de entorno. Puedes modificar el script con un
vi para cada usuario:
Para ejecutar dicho escript debemos hacer lo siguiente:
-controller:/var/lib/nova/bin# cd /var/lib/stackops/
-controller:/var/lib/stackops# source setenv.sh
-controller:/var/lib/stackops# env | grep 'NOVA' && env | grep 'EC2' && env | grep
'OS_' && env | grep 'AUTH_TOKEN'
ATENCIÓN, hay un Bug reconocido, para solucionarlo y no tener más errores en el futuro por favor
ejecutar esta linea también:
1. root@nova-controller:/var/lib/stackops# export OS_AUTH_STRATEGY=keystone
Virtual Images, Llego el momento de la verdad, descargar una imagen para poder después irnos a
la interfaz web y poder desplegar instancias con esta imagen. Para ello en el directorio
/var/lib/stackops ejecutamos ./pubXXXXX.sh donde este último nombre corresponde al tipo de
imagen que podemos agregar a nuestra cloud.
Una vez descargada y añadida automáticamente al repositorio de imágenes pasaremos al entorno
WEB.
La Interfaz Web, Horizon
Para ello introducimos en un navegador web la misma IP con la que hemos configurado el sistema
pero esta vez sin puerto, y un elegante formulario nos solicitará las credenciales que comentamos
anteriormente (admin o demo).
193
En la pantalla podemos ver dos pestañas básicas, User Dashboard y System Panel que nos
muestra un resumen de nuestros recursos, Instancias levantadas, etc. Cuanto más compute y
volume tengamos, más recursos nos mostrará esta ventana.
La parte de servicios es un resumen en tiempo real de los servicios, asi como su estado, si
tuvieramos un entorno distribuido, nos gustará que esta ventana todo aparezca en verde.
En la parte de Images, podemos ver las imágenes que tenemos y borrarlas, en caso de que no
fueran necesarias. En nuestro caso las dejamos como están.
En la parte de Tenants y Users podemos crear un Tenant como proyecto al que asignar diferentes
recursos, vCPU, vRAM, instancias, IP, etc, y luego añadir usuarios a ese Tenant o proyecto.
Creando una instancia
Lo primero que tenemos que hacer es crearnos un certificado para administrar la Instancia, en
Dashboard iremos a Keypairs y generaremos un certificado, tan sencillo como poner un nombre y
pulsar en Add Keypair.
Nos solicitará si queremos guardarlo, y pulsaremos Aceptar, debemos recordar donde lo
guardamos.
Iremos a la sección Images de Dashboard y pulsaremos Launch, elegiremos un nombre para la
instancia y un tamaño para ella, yo he seleccionado m1.small y de keypair nuestro certificado.
Ya ha empezado el despliegue de nuestra instancia, si pulsamos refresh, en unos segundos
veremos lo de la imagen de la derecha.
Si pulsamos VNC Console en el menú de la derecha podremos ver nuestra instancia a nivel de
VNC, lo cual es siempre agradecido en caso de perder el .pem o para algunas gestiones básicas.
Conectando a la Instancia
Firewall Rules, lo primero que tenemos que hacer es editar por SSH las reglas de firewall en este
caso default, también se puede por interfaz gráfico, pero he preferido el entorno de consola en esta
siuación.
Para ello ejecutamos:
root@nova-controller:/var/lib/stackops# euca-authorize default -P tcp -p 22 -s 0.0.0.0/0
root@nova-controller:/var/lib/stackops# euca-authorize default -P icmp -t -1:-1
Bien, para conectar a la instancia, no vamos a poder hacerlo con la IP actual 10.0.0.2 porque no es
una IP de nuestro rango, tenemos que crear una IP pública.
194
Pulsaremos Allocate IP para obtener una IP del rango que pusimos en el asistente, cuando ya la
tengamos, imagen a la derecha, pulsaremos Associate to instance para asociarla a nuestra
instancia ya creada.
Seleccionaremos la Instancia a la que queremos conectar la IP y pulsamos Associate IP, después
podremos ver el resumen de como ha quedado nuestra IP pública y contra que instancia está
conectada.
Si volvemos al menú Instances veremos que también vemos la IP “pública” asociada a nuestra
Instancia.
Si ejecutamos un ping ya tenemos conectividad.
Ahora necesitaremos un cliente SSH de su preferencia con este cliente necesitamos utilizar el key
que exportamos anteriormente y si todo sale bien estaremos conectados a nuestra instancia.
Si volvemos a la pantalla de System Panel podemos ver un resumen de los recursos que nos
quedan asi como las instancias subidas.
Conclusiones
Openstack no es el futuro es el presente. Cualquier empresa de Hosting que se precie
está adoptando el modelo de negocio Cloud privada, Cloud Hibrida, y Pública. Openstack
representa ya una cuota de mercado bastante grande y seguirá creciendo con el paso de
los meses.
Stackops es una distribución para hacernos el despliegue de Openstack más llevadero.
Para cualquier consulta, soporte, o instalación más avanzada, por favor, dirigir los correos
a http://www.stackops.com/contact-us/
Más información en http://openstack.org/ y en video en OpenStack Y
Monitoreo y Gestión
Nagios
Nagviz
Para el uso de Nagios y Nagviz vamos a utilizar una Distro basada en Centos 5 llamada FAN (Fully
Automated Nagios)
195
Requerimientos:
Requerimientos Mínimos
4 GB de Disco Duro libre
1 GB de RAM.
1 CPU de un core
Requerimientos Recomendados
20 GB o más de espacio libre en disco esencialmente para /var. Necesarios para el
servidor de base de datos MySQL y los archivos rrd.
CPU de dos cores o Hiperhilado por cada CPU virtualizado.
2 GB of RAM.
Virtualización
FAN puede ser instalado en VMware ESX 3.5 or vSphere 4.1, pero no es recomendado para
grandes sitios (1000 hosts y 5000 servicios por ejemplo).
Instalación
La instalación de FAN es semejante a una instalación estándar de CentOS. Es rápida e intuitiva.
FAN puede ser instalado en modo Standalone o modo distribuido en dependencia de las
exigencias.
Durante el proceso de instalación se necesita configurar algunos parámetros como son:
Idioma
Tipo de Teclado
Particionamiento
Zona Horaria
Contraseña de root
Primera Conexión
Para poder accede a la nueva plataforma debemos asegurarnos que la configuración de la red es
correcta.
Todas las herramientas de monitoreo están instaladas y configuradas. Desde una computadora
con un navegador web de su preferencia abra la siguiente dirección: http://nombre_o_ip_server
El nombre de usuario y la contraseña por defecto de todos los aplicativos instalados es:
nagiosadmin/nagiosadmin
196
Configurando el Monitoreo Distribuido
Esta característica está disponible desde la versión 2.1. Una arquitectura distribuida se basa en:
1 Servidor Central de Monitoreo.
1 Servidor de Base de Datos
Y varios agentes de monitoreo.
El servidor central consolida todos los datos recogidos de monitoreo y ofrece una interfaz de
usuario la cual ofrece la posibilidad de monitorear y gestionar el servidor central y los agentes de
monitoreo.
Los agentes de monitoreo envían los datos recogidos al servidor de base de datos. Este tipo de
configuración permite la distribución de los chequeos realizados en cualquier tipo de entorno.
Se requiere la instalación mínima de 2 servidores FAN:
fan-database
fan-central, también puede ser considerado como un agente de monitoreo.
Pero se recomienda instalar 3 servidores FAN:
fan-database
fan-central
fan-poller
GLPI (GESTIONNAIRE LIBRE DE PARC INFORMATIQUÉ)
GLPI es una solución de software abierto (Open Source) para la gestión del inventario informático y
de soporte técnico (Help Desk). Es una aplicación Web que ataca los principales problemas de
197
gestión del inventario informático: La administración de los recursos de hardware, software,
usuarios, suministros e incidencias.
Las principales funcionalidades de la aplicación son:
Gestión de recursos informáticos
Gestión de licencias de software
Gestión de consumibles
Base de conocimientos
Gestión de reservas
Soporte Técnico
Automatización de inventario
El uso de este programa tiene sus ventajas:
Reducción de costos
Optimización de recursos
Rigurosa gestión de licencias
Alta calidad
Usabilidad satisfactoria
Seguridad
La aplicación está totalmente escrita en PHP y requiere de un servidor Apache con soporte para
PHP4 como mínimo, aunque se recomienda PHP5, así como una base de datos de MySQL 4.1.2.
Requisitos:
Apache.
PHP 4 o superior
MySQL 4.1.2 o superior
Instalación
Descargar el fichero de instalación desde la siguiente dirección:
http://www.glpi-project.org/
Descomprimir el fichero descargado en la carpeta raíz del directorio virtual de nuestro servidor
WEB, se nos creara una carpeta llamada glpi, si queremos, la podemos renombrar, acceder a la
instalación mediante un navegador WEB en la siguiente dirección:
http://localhost/glpi
198
Aquí se nos mostrará la pantalla de instalación, en la que se nos solicita el idioma que queremos
usar en nuestro sistema.
Se continúa con el asistente de Instalación hasta finalizarlo.
En la última ventana del sistente se nos indica que la instalación ha finalizado, y que se han creado
4 usuarios con los distintos niveles de acceso a la aplicación, solo nos queda pulsar el botón
Utilizar GLPI, para entrar en la aplicación.
Los usuarios creados por defectos son:
glpi/glpi para la cuenta de Administrador.
tech/tech para la cuenta de Técnico.
normal/normal para la cuenta Normal.
post-only/post-only para la cuenta postonly
Configuración inicial de la aplicación
Una vez en la ventana de acceso a GLPI, se nos solicitará un usuario y contraseña para poder
acceder, utilizaremos el usuario creado con mayores privilegios para administrar y configurar
nuestra aplicación, así que usamos el usuario glpi.
Una vez dentro podemos ver los diferentes menús que tiene la aplicación, los cuales los iremos
revisando uno a uno. Una de las primeras tareas que debemos hacer es editar el usuario glpi y
modificarlo, o crear uno nuevo con privilegios de Super-Admin y deshabilitar o borrar el usuario
glpi, En nuestro caso vamos a editar el usuario glpi, y modificarlo, Para ello nos vamos al menú
Administración y luego a Usuarios, entonces pulsamos sobre el usuario glpi.
Aquí editamos los datos del usuario glpi y ponemos los que creamos convenientes., de esta
manera el usuario del Super-Admin será administrador en lugar de glpi, así mismo, también le
cambiaremos la contraseña, y editaremos sus datos, como son su dirección de correo electrónico y
su numero de teléfono.
Una vez hechos los cambios pulsamos el botón Actualizar para que se graben.
Ya modificado o creado a nuestro Super-Admin, nos desconectaremos y volveremos a iniciar con
los datos del nuevo Super-Admin, en este caso iniciaremos con el usuario administrador.
Seguidamente hacemos lo mismo con el usuario tech, ya que tiene los mismos privilegios. Esto lo
hacemos para que no se nos vaya a colar alguien en nuestra aplicación y nos cambie la
contraseña del Super-Admin, y borre al usuario tech, ya que de esa manera ya no podríamos
199
acceder con dichos permisos a la aplicación, ni crear un nuevo usuario con esos privilegios. Por lo
que solo nos quedaría volver a instalar la aplicación.
Para borrar el usuario tech, vamos al menú Administración y luego a Usuarios, aquí marcamos
la casilla a la izquierda del(os) usuario(s).
Customización de la Interfaz:
Nuestro siguiente paso será customizar el aspecto grafico de la aplicación, para lo que editaremos
los siguientes ficheros ubicados en la carpeta /glpi/pcis ubicada en la raíz de nuestro servidor Web:
favicon.ico
fd_logo.png
haut_install.png
login_glpi.png
logo-glpi-login.png
CONFIGURACION
General:
Para acceder a la configuración general del sistema, vamos al menú Configuración y luego a
General. Aquí tenemos varias pestañas, cada una de ellas con parámetros de configuración,
iremos configurándolas de una en una según los parámetros que se adecuan a nuestras
necesidades.
Configuración general
Nivel de loggin: Aquí se configura que es lo que se guarda en el fichero de loggin.
Tiempo de conservación de los logs, en días (0=infinito): Aquí se configura el tiempo
que deben conservarse los logs, con 30 es suficiente.
Huso horario: Aquí se configura el huso horario de nuestra ubicación geográfica.
Logs en ficheros (SQL, mail, cron...): Aquí se configura si se desea tener también Logs
de otros servicios, en nuestro caso diremos que NO.
Inventario
Umbral de alarma predeterminado para los cartuchos y consumibles: Cuándo los
consumibles bajan por debajo del umbral indicado, se nos avisará, este valor depende de
la rapidez con la que se consumen los mismos, en este caso ponemos 2.
Campos automáticos (marcados con *): Por Entidad
200
Fecha de inicio de ejercicio fiscal (día y mes): configuramos la fecha de inicio del
ejercicio fiscal, por defecto está el 31-01-2005.
Soporte
Asignar automáticamente las incidencias al responsable técnico: No
Conservar las incidencias al purgar un elemento del inventario: No
Programas visibles en Helpdesk por defecto: Si
Registrar las modificaciones de incidencias añadiendo el seguimiento: Si
Asunto predeterminado de los documentos relacionados con las incidencias: --
Alertas por email
Alertas sobre contratos (Valor predeterminado): --
Alertas sobre datos financieros (Valor predeterminado): --
Comprobar la presencia de actualizaciones
Comprobar la presencia de actualizaciones: Nunca
Dirección del Proxy: Si hay Proxy, configurarlo aquí si no hay dejar en blanco.
Puerto del Proxy: Si hay Proxy, configurarlo aquí si no hay dejar en blanco.
Usuario del Proxy: Si hay Proxy, configurarlo aquí si no hay dejar en blanco.
Contraseña del Proxy: Si hay Proxy, configurarlo aquí si no hay dejar en blanco.
Configuración de la presentación
Número de decimales para los importes: Aquí configuramos el número de decimales
para los importes monetarios, por defecto pone el 2.
Cantidad máxima de caracteres para cada elemento de la lista:
Cantidad de elementos a mostrar por página:
Intervalo para los horarios:
Límite de horarios para la planificación:
Visualiza apellido y nombre:
Personalización
Texto en la página de inicio: Aquí se configura el mensaje que se puede poner en la
ventana de inicio de sesión.
Enlace a la Ayuda del CAU: En esta casilla se puede poner un enlace a una página WEB
de ayuda para los usuarios.
Enlace a la Ayuda Central: En esta casilla se puede poner un enlace a una página WEB
de ayuda para los Usuarios con perfiles de técnico y administrativos.
201
AJAX
Utilizar Ajax:
Comodín Ajax:
No utilizar Ajax si el número de elementos es inferior a (0=nunca):
Autocompletar campos de texto con Ajax:
Ajax - Cantidad máxima de elementos mostrados:
Personalización
Configuración de la presentación
Formato de fechas: En este desplegable se puede elegir el formato de fecha que
queremos utilizar.
Mostrar los ID GLPI:
Desplegar lista:
Utilizar para pestañas Siguiente/Anterior: Aquí se configura si se quieren utilizar las
pestañas para navegar por los elementos cuando esto son visualizados como ficha, es
decir avanzar, retroceder, inicio y final.
Cantidad de elementos a mostrar por página: Aquí se configura la cantidad máximas
por defecto de elementos que se pueden visualizar en pantalla.
Formato de Número: Aquí se configura el formato para la presentación de valores
numéricos.
Cantidad máxima de caracteres para las listas desplegables: Aquí se configura el
número máximo de caracteres que pueden haber en una lista desplegable, la cantidad por
defecto es suficiente, ya que una cantidad mayor mostraría listas demasiado anchas.
Cantidad de eventos de log que se mostrarán: Aquí se configuran el número de eventos
que queremos que se vean en el apartado de Logs.
Idioma predeterminado: Aquí se puede elegir el idioma para la interfaz de la aplicación.
Soporte
Mostrar las incidencias nuevas al entrar en el sistema: Aquí se configura que cuando
un miembro de soporte inicia su sesión, en la ventana de bienvenida se le muestran las
nuevas incidencias que le han sido asignadas y las que aún están sin asignar.
Seguimiento privado por defecto: Esta casilla es para establecer si el seguimiento de las
incidencias son privados o públicos, por defecto esta en NO, o sea seguimiento público.
Colores de las prioridades: Aquí se puede establecer el color identificativos para cada
prioridad de una incidencia, y así según el color el técnico de soporte puede ver que tan
urgente es una incidencia.
Mostrar primero las incidencias más recientes: Aquí se indica que las incidencias que
se muestran primero sean las más recientes.
202
Restringir la gestión manual de los elementos
Restringir la gestión de monitores:
Restringir la gestión de teléfonos:
Restringir la gestión de periféricos:
Restringir la gestión de impresoras:
Modo OCSNG
Activar el modo OCSNG:
Identificación
Inserción automática de usuarios a partir de fuentes externas de autenticación:
Preguntas frecuentes
Autorizar la consulta anónima de las Preguntas Frecuentes:
CAU (Centro de Atención a Usuarios)
Permitir las aperturas de incidencias anónimas (helpdesk.html) :
El contenido de la incidencia es obligatorio:
Gateway de correo: tamaño máximo de cada fichero adjunto (0 : sin límite):
Título de incidencia obligatorio:
La categoría de la incidencia es obligatoria:
OPENNMS
Preparando el servidor
OpenNMS es una aplicación que permite la administración y el monitoreo de una red. Este
software permite hacer de manera muy automatizada, informes y gráficas del uso de los recursos
tanto de la infraestructura de red como de los equipos clientes. Este software da una ventaja ya
que se administra vía WEB lo cual hace de su uso algo mas óptimo y eficiente.
Características.
automatizado de la red.
Requerimientos.
203
Instalación repositorio openNMS
Se descargo el repositorio de openNMS el cual tiene los paquetes requeridos para instalar todas
las dependencias necesarias.
La instalación se realiza con “yum” es preferible a rpm, ya que este resuelve los paquetes y
dependencias que hagan falta a la hora de instalar el paquete.
Instalación y configuración de Postgresql
Se instalo Postgresql server y el cliente con yum install.
Se inicia el servicio y las bases de datos del Postgresql.
Para poderse conectar a las bases de datos, se configuran los permisos de Postgresql.
En la ruta /var/lib/pgsql/data/pg_hba.conf y el archivo debe quedar así.
Nota: se reinicia el servicio del Postgresql.
204
Instalación Java Development Kit
Se descarga el archivo RPM.
Instalación.
Instalación openNMS
Anteriormente se instalaron los repositorios de openNMS siendo así como solo ejecutar un
comando el repositorio de openNMS resolverá todos los paquetes que necesite para completar su
instalación.
Descargara aproximadamente 500 MB
Configuración de java
Con este comando se le indica al OpenNMS que tome los archivos que necesita del java.
Actualización de la base de datos de OpenNMS
Con el siguiente comando se instalan las bases de datos que utiliza el openNMS con las opciones:
-d: para actualizar la base de datos
-i: para insertar cualquier dato por defecto que pertenezca a la base de datos
-s: para crear o actualizar los procedimientos almacenados que openNMS utiliza para ciertos tipos
de acceso a Datos
205
Instalación IPLIKE
IPLIKE es un programa compatible con Postgresql que proporciona una aplicación para la
búsqueda eficiente y completa de direcciones IP. OpenNMS trae por defecto una versión de
IPLIKE pero es recomendable instalar la Nueva versión que tiene un mejor rendimiento.
Agregando una nueva regla al firewall
Lo que debemos hacer es agregar una regla para que el firewall permita el tráfico de datos por el
puerto 8980 que es de openNMS en el archivo /etc/sysconfig/iptables de la siguiente manera:
Luego de editar el archivo reiniciamos el firewall con el comando service iptables restart.
Iniciamos los servicios
service opennms start : para iniciar el servicio openNMS
ERRORES
Si en la instalacion de IPLIKE no nos sale OK en la instalación de base de datos, podemos
ejecutarlo manualmente con el comando.
206
/usr/sbin/install_iplike.sh -h
Interfaz web
Esta es la presentacion de nuestro openNMS funcionando, entramos a él copiando en la barra de
direcciones nuestra IP donde se aloja el servicio openNMS el puerto (8980) ejemplo:
192.168.10.60:8089/opennms y entramos con el usuario y contraseña que por defecto es admin,
admin.
OSSIM
Open Source Security Information Management por sus siglas (OSSIM) es una colección de
herramientas bajo la licencia GPL, diseñadas para ayudar a los administradores de red en la
seguridad de las computadoras, detección de intrusos y prevención.
Descripción
El objetivo del proyecto ofrecer una herramienta que ayude a la administracion de eventos de
seguridad mediante un motor de correlacion y una colección detallada de herramientas open
source las cuales sirven al administrador para tener una vista de todos los aspectos relativos a la
seguridad en su infraestructura.
OSSIM a su vez provee una fuerte motor de correlación, con detallados niveles, bajos, medianos y
altos de interfaces de visualización, como también reportes y herramientas de manejo de
incidentes.
207
La habilidad de actuar como un sistema de prevención de intrusos basado en información
correlativa de cualquier fuente, resulta en una útil herramienta de seguridad. Toda esta información
puede ser filtrada por red o sensor con el objetivo de proveer únicamente la información requerida
por un usuario específico, permitiendo una buena granularidad en un ambiente de seguridad multi
usuario.
Componentes
Ossim está compuesto por los siguientes elementos de software:
• Arpwatch, utilizado para detección de anomalías en direcciones MAC.
• P0f, utilizado para la identificación pasiva de OS.
• Pads, utilizado para detectar anomalías en servicios.
• Openvas, utilizado para la evaluación y correlación cruzada (Sistema de detección de intrusos vs
Escaner de Vulnerablidad)
• Snort, utilizado como sistema de detección de intrusos (IDS) como también para la correlación
cruzada con Nessus.
• Spade, es un motor de detección de anomalías en paquetes. Utilizado para obtener conocimiento
de ataques sin firma.
• Tcptrack, utilizado para conocer la información de las sesiones, lo cual puede conceder
información útil relativa a los ataques.
• Ntop, el mismo construye una impresionante base de datos con la información de la red, para la
detección de anomalías en el comportamiento.
• Nagios, utilizado para monitorear la disponibilidad de los hosts y servicios.
• nfSen, visor de flujos de red para la detección de anomalías de red
• Osiris, es un sistema de detección de intrusos basado en host (HIDS).
• Snare, colecciona los logs de sistemas Windows.
• OSSEC, es un sistema de detección de intrusos basado en hosts
• OSSIM también incluye herramientas desarrolladas específicamente para él, siendo el más
importante un motor de correlación con soporte de directivas lógicas e integridad de logs con
plugins.
Top Related