Securización de un sistema Ubuntu (GNU/Linux) Últimamente he escrito varios posts sobre estándares y aspectos más estratégicos de negocio e IT, como por ejemplo: ● BS 25999-1: Gestión de la Continuidad del Negocio ● Cobit, estándar para el buen gobierno de los Sistemas de Información ● ITIL y ISO 20000, marcos de trabajo para servicios IT ● Metodologías de desarrollo ● Estructurar las organizaciones en procesos ● PMBOK, Project Management / Gestión de proyectos ● PRINCE2 como complemento a PMBOK para la gestión de proyectos (project management) ● Metodologías ágiles de gestión de proyectos (Scrum, DSDM, Extreme Programming – XP…) ● Scrum, gestión ágil de proyectos / agile project management ● Getting Things Done (GTD), organízate con eficacia de David Allen Es habitual escuchar críticas a este tipo de enfoque más estratégico, aludiendo al hecho de que se habla y teoriza mucho pero no se concreta nada. En este nuevo artículo, en el que ha colaborado Raúl Gómez (experto en seguridad técnica), se plasman de forma técnica muchas de las ideas de buena gestión estratégica IT o de negocio. Vamos a ver cómo podemos montar un servidor con Ubuntu Linux que cumpla mínimamente con las buenas prácticas de seguridad: ● Efectuar una configuración segura ● Establecer una política de contraseñas ● Utilizar herramientas para la gestión de usuarios ● Proteger los servicios de red ● Garantizar la trazabilidad ● Proporcionar herramientas de monitorización en tiempo real e histórica para facilitar proyecciones de futuras necesidades ● Establecer política de copias de seguridad ● Efectuar tests de stress del sistema Y es que en definitiva el software libre, por más libre y abierto que sea, no tiene porque ser seguro a no ser que se establezca una configuración adecuada y alineada con las políticas/normativas/ procedimientos de la organización. Contenido 1. Configuración mínima 2. Securización del sistema base Kernel: parámetros de seguridad Limitando los recursos del sistema Memoria, número de procesos y sesiones concurrentes Espacio en disco 3. Interacción básica con el sistema Shells Shell Bash Locales: configuración del idioma Mensajes legales e informativos: Issue & motd Usuarios privilegiados: sudo Sistema de archivos Esquema de los permisos de ficheros/directorios Permisos por defecto: UMASK Permisos especiales: SUID y SGID Directorios con permisos de escritura global Archivos sin propietarios Detección de modificaciones de ficheros: Tripwire 4. Política de contraseñas Política global Contraseñas de un solo uso: OTP (One time password)
58
Embed
Securización de un sistema Ubuntu (GNU/Linux)beta.redes-linux.com/.../seguridad/securizacion_ubuntu.pdfSecurización de un sistema Ubuntu (GNU/Linux) Últimamente he escrito varios
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Securización de un sistema Ubuntu (GNU/Linux)
Últimamente he escrito varios posts sobre estándares y aspectos más estratégicos de negocio e IT, como por ejemplo:
● BS 25999-1: Gestión de la Continuidad del Negocio● Cobit, estándar para el buen gobierno de los Sistemas de Información● ITIL y ISO 20000, marcos de trabajo para servicios IT● Metodologías de desarrollo● Estructurar las organizaciones en procesos● PMBOK, Project Management / Gestión de proyectos● PRINCE2 como complemento a PMBOK para la gestión de proyectos (project management)● Metodologías ágiles de gestión de proyectos (Scrum, DSDM, Extreme Programming – XP…)● Scrum, gestión ágil de proyectos / agile project management● Getting Things Done (GTD), organízate con eficacia de David Allen
Es habitual escuchar críticas a este tipo de enfoque más estratégico, aludiendo al hecho de que se habla y teoriza mucho pero no se concreta nada. En este nuevo artículo, en el que ha colaborado Raúl Gómez (experto en seguridad técnica), se plasman de forma técnica muchas de las ideas de buena gestión estratégica IT o de negocio.Vamos a ver cómo podemos montar un servidor con Ubuntu Linux que cumpla mínimamente con las buenas prácticas de seguridad:
● Efectuar una configuración segura● Establecer una política de contraseñas● Utilizar herramientas para la gestión de usuarios● Proteger los servicios de red● Garantizar la trazabilidad● Proporcionar herramientas de monitorización en tiempo real e histórica para facilitar
proyecciones de futuras necesidades● Establecer política de copias de seguridad● Efectuar tests de stress del sistema
Y es que en definitiva el software libre, por más libre y abierto que sea, no tiene porque ser seguro a no ser que se establezca una configuración adecuada y alineada con las políticas/normativas/procedimientos de la organización.
Contenido1. Configuración mínima2. Securización del sistema base Kernel: parámetros de seguridad Limitando los recursos del sistema Memoria, número de procesos y sesiones concurrentes Espacio en disco3. Interacción básica con el sistema Shells Shell Bash Locales: configuración del idioma Mensajes legales e informativos: Issue & motd Usuarios privilegiados: sudo Sistema de archivos Esquema de los permisos de ficheros/directorios Permisos por defecto: UMASK Permisos especiales: SUID y SGID Directorios con permisos de escritura global Archivos sin propietarios Detección de modificaciones de ficheros: Tripwire4. Política de contraseñas Política global Contraseñas de un solo uso: OTP (One time password)
Gestión del acceso5. Gestión de usuarios Creación de usuarios Gestion de cuentas6. Servicios básicos del sistema Activación en arranque Servicio de correo: Postfix Servicio web: Apache PHP Apache básico Módulos de Apache Servir por localhost las aplicaciones más criticas Base de datos MySQL Acceso remoto: SSH7. Trazabilidad Fecha y hora del sistema Logs de usuario con Bash Rotación y conservación de logs Análisis de logs de Apache mediante Awstats Envio por correo de los eventos más significativos con logcheck8. Monitorización del sistema Actualización automática de la lista de paquetes del sistema Monitorizar desde la consola Espacio en disco CPU Ancho de banda / Bandwidth Ancho de banda / Bandwidth Memoria RAM / Swap Monitorización en tiempo real: Nagios Ancho de banda consumido con Bandwidthd SNMP Soporte ‘Devices I/O’ en net-snmp Monitorización historica: Cacti Script Device I/O para cacti9. Seguridad Cortafuegos / Firewall Monitorización de firewall con fwlogwatch Detección de intrusos / IDS: Snort Rootkits Control del ancho de banda10. Copias de seguridad Utilidades rsnapshot Información de estado dpkg y mysql Tars semanales Reportes11. Tests de stress Sistema Conexiones HTTP con httperf Conexiones HTTP con Apache Benchmarking tool12. Issue tracking
1. Configuración mínimaRecomiendo echar un vistazo a la Guía de referencia rápida para la personalización de Ubuntu Edgy (6.10) GNU/Linux, aunque la versión de Ubuntu es bastante antigua, la mayoría de secciones aún son válidas. En el caso de los servidores, resultan especialmente interesante las siguientes secciones:
● Editor de textos de consola Vim● (Des)Compresores
● Compartir directorios/ficheros● Antivirus● Hacking● Conexión SSH sin password● Otros● Otro artículo: Mutt como cliente de correo de consola
2. Securización del sistema base
Kernel: parámetros de seguridadEl kernel de Linux dispone de diversos parámetros que nos permiten configurar su actuación frente al tráfico de red. Al iniciar el sistema se establecen los valores de los parámetros indicados en ‘/etc/sysctl.conf’. No obstante, también es posible modificarlos mediante el comando ‘sysctl’.Los parámetros más importantes a tener en cuenta son:- Activar la protección contra IP spoofing:
sysctl -w net.ipv4.conf.default.rp_filter=1
sysctl -w net.ipv4.conf.all.rp_filter=1
- Activar TCP SYN Cookie Protection para minimizar la posibilidad de ataques de denegación de servicio por ataques de paquetes SYN. No obstante, actualmente ya no se recomienda esta opción dado que las capacidades de los sistemas han aumentado considerablemente y activarlo nos hace perder otras características de TCP (ver recomendación de Andi Kleen, autor de las SynCookies):
sysctl -w net.ipv4.tcp_syncookies=1
- Desactivar el reenvío de paquetes IP (solo es necesario cuando queremos que la máquina actue como una pasarela mediante NAT):
- Activar la protección contra mensajes de error mal construidos:sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1
- Desactivar ICMP Redirect Acceptance, mediante los cuales un atacante podría indicar al sistema una ruta mejor para llegar a otras redes (habitualmente utilizado por routers). Únicamente los permitiremos si proceden de nuestro gateway:
sysctl -w net/ipv4/conf/all/accept_redirects=0
sysctl -w net/ipv4/conf/all/send_redirects=0
sysctl -w net/ipv4/conf/all/secure_redirects=1
- Desactivar IP Sourcing routing mediante el cual un atacante podría especificar la ruta a seguir para ir desde una IP origen a una destino:
- Ignorar ICMP Requests PINGs, personalmente prefiero dejarlo a 0 y controlar desde donde y hacia donde permito los pings mediante iptables (firewall). En cualquier caso, si queremos desactivar completamente que el sistema responda a pings:
sysctl -w net.ipv4.icmp_echo_ignore_all=1
Para consultar los valores actuales:sysctl net.ipv4.conf.default.rp_filter
Para establecer los nuevos valores de forma permanente para sucesivos reinicios es necesario modificar /etc/sysctl.conf.
Limitando los recursos del sistemaSe considera una buena práctica limitar los recursos del sistema utilizados por los usuarios, de forma que minimicemos las probabilidades de que se efectúen ataques de denegación de servicio contra todo el sistema.
Memoria, número de procesos y sesiones concurrentesPara limitar la memoria, el número de procesos y las sesiones concurrentes que puede tener cada usuario debemos editar ‘/etc/security/limits.conf’. A modo de ejemplo:
# Prevents anyone from dumping core files.
* hard core 0
# This will prevent anyone (except root) from having more than 150 processes, and a
warning will be given at 100 processes.
* soft nproc 100
* hard nproc 150
# This will prevent anyone in the 'users' group from having more than 150 processes,
and a warning will be given at 100 processes.
@users soft nproc 100
@users hard nproc 150
@users - maxlogins 4
# Address space limit: 2GB
* hard as 2097152
# Maximum data size: 128MB
* hard data 131072
# Maximum locked-in-memory address space: 128MB
* hard memlock 131072
# Maximum resident set size: 1GB
* hard rss 1013352
En este caso estamos limitando cada usuario (excepto root) a un máximo de:● 150 procesos para todos los usuarios● 100 procesos para los usuarios del grupo ‘users’● 2GB de RAM● 4 logins concurrentes
Una vez configurado, podemos realizar una sencilla prueba para verificar que el sistema no nos permite crear más de 100 procesos:
$ for i in `seq 500`; do sleep 5 & done
Espacio en discoPara habilitar las limitaciones de espacio debemos tener montada las particiones afectadas con los parámetros ‘usrjquota’ y ‘grpjquota’ en ‘/etc/fstab’ (journalling quotas). Por ejemplo:
Por otra parte, el servicio de quotas (/etc/init.d/quota) debe estar activo. Podemos comprobarlo mediante la aplicación ‘sysv-rc-conf’ (consultar sección de Servicios de esta guía).Podemos activar inmediatamente las quotas mediante:
touch /aquota.user /aquota.group
chmod 600 /aquota.*
mount -o remount /
quotacheck -avugm
quotaon -avug
Si encontramos algun tipo de problema con quotacheck (p.ej. puede ser que entre en conflicto con gvfs), podemos probar a reiniciar el sistema.A continuación, para modificar las quotas de un grupo de usuario determinado:
EDITOR="vi" edquota -g users
Tendremos que cambiar los números correspondientes, por ejemplo:Disk quotas for group users (gid 100):
Filesystem blocks soft hard inodes
soft hard
/dev/sda6 23808 1048576 1572864 37 0
0
/dev/sda7 10312844 47185920 52428800 8780 0
0
En este caso, el sistema realizará un aviso por mail local a los 45GB (45*1024*1024), mientras que el límite real se encuentra en los 50GB (50*1024*1024) para el grupo ‘users’ y el dispositivo sda7 (p.ej. /home/). En el caso de sda6 (p.ej. raíz /), el limite blando es 1GB (1*1024*1024) y el duro 1.5 GB (1.5*1024*1024).Los ficheros que contabilizan dentro de la quota de grupo son aquellos que tienen como propietario el mismo grupo. Es decir, un usuario que pertenece al grupo A y B puede crear archivos asignándolos a uno u a otro hasta agotar ambas quotas. Por este motivo, establecer los límites por usuario permite un mayor control:
EDITOR="vi" edquota -u usuario
Es también interesante limitar todos aquellos grupos que corren servicios como apache2.Podemos ver un resumen de todas las quotas aplicadas:
# repquota -s -a
*** Informe para user quotas en dispositivo /dev/mapper/isw_beahgicji_Volume07
Período de gracia de bloque: 7días; período de gracia de Inode: 7días
Límites de bloque límites de archivo
Usuario usado blando duro gracia usado bland duro gracia
Cabe destacar que el periodo de gracia (grace limit) es el tiempo que transcurre antes de que el usuario es obligado a cumplir el “soft limit”. Para modificarlo:
# edquota -t
Período de gracia antes de imponer límites blandos para users:
La unidad de tiempo puede ser: días, horas, minutos, o segundos
Sistema de archivos Período de gracia de bloque Período de gracia de inode
/dev/mapper/isw_beahgicji_Volume06 7días 7días
/dev/mapper/isw_beahgicji_Volume07 7días 7días
Finalmente, en caso de agotar la cuota, el usuario recibirá el siguiente mensaje:$ cp /usr/bin/dpkg .
cp: writing `./dpkg': Disk quota exceeded
3. Interacción básica con el sistema
ShellsLa shell es la aplicación mediante la cual los usuarios pueden interactuar con el sistema. Es recomendable habilitar únicamente las shells que nos interesen editando ‘/etc/shells’:
# /etc/shells: valid login shells
#/bin/csh
/bin/sh
#/usr/bin/es
#/usr/bin/ksh
#/bin/ksh
#/usr/bin/rc
#/usr/bin/tcsh
#/bin/tcsh
#/usr/bin/esh
#/usr/bin/screen
#/bin/dash
/bin/bash
#/bin/rbash
Únicamente las shells no comentadas seran permitidas, siempre y cuando añadamos al principio de ‘/etc/pam.d/common-auth’:
# This will not allow a user to change their shell unless
# their current one is listed in /etc/shells. This keeps
# accounts with special shells from changing them.
auth required pam_shells.so
Shell BashEs interesante configurar la shell Bash para permitir el auto-completado inteligente de comandos (presionando [tab]) editando ‘/etc/bash.bashrc’ y descomentado:
# enable bash completion in interactive shells
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
En ese mismo fichero, es recomendable añadir los siguiente alias:alias mv='mv -i'
alias cp='cp -i'
alias rm='rm -i'
alias ln='ln -i'
export EDITOR='vim'
export TMOUT=3600
Esto evitará borrados involuntarios de ficheros dado que cada vez que modifiquemos un fichero mediante mv, cp, rm o ln se pedirá confirmación.Por otra parte, la variable TMOUT provocará automáticamente un logout de la terminal si no se ejecuta nada durante los segundos especificados (si se está visualizando un programa interactivo como top, no se produce timeout). De esta forma reduciremos las probabilidades de que un usuario se deje su sesión abierta y accesible por otra persona que tenga acceso físico a su ordenador.Cabe destacar que si se ejecuta screen después de establecer la variable TMOUT, se hereda y se produce logout primero de las ventanas de screen y despues de la sesión que ejecutó screen.
Locales: configuración del idiomaPara que el sistema muestre los mensajes en un idioma determinado (p.ej. Castellano):
apt-get install language-pack-es language-pack-en
Y a continuación editamos ‘/etc/environment’ y ‘/etc/default/locale’:#LANG="en_GB.utf8"
LANG="es_ES.UTF-8"
LANGUAGE="es_ES:en_EN"
#LANGUAGE="en_GB:en:es_ES:es"
Mensajes legales e informativos: Issue & motdSe recomienda establecer un mensaje legal que notifique a los usuarios que el acceso al sistema es exclusivo para aquéllos que han sido autorizados. Para ello se debe editar los ficheros ‘/etc/issue’ y ‘/etc/issue.net’, por ejemplo:
Cabe destacar que si queremos que el banner se muestre a los usuarios que se conecten mediante SSH (ver sección de Servicios de esta guía), debemos editar ‘/etc/ssh/sshd_config’ y descomentar:
Banner /etc/issue.net
Por otra parte, una configuración segura implica proporcionar la mínima información sobre el sistema al usuario en cuanto a las características del mismo (p.ej. distribución, kernel, etc). Para minimizar ese aspecto podemos poner en blanco el mensaje de bienvenida (o incluir el mensaje genérico que nos interese):
echo > /etc/motd
echo > /etc/motd.tail
Si lo dejamos en blanco, debemos asegurarnos que el script de inicio ‘/etc/init.d/bootmisc.sh’ no lo reconstruye. Para ello lo editamos y comentamos las siguientes lineas:
Y por otra parte, editamos ‘/etc/cron.d/update-motd’ y comentamos:#*/10 * * * * root [ -x /usr/sbin/update-motd ] && /usr/sbin/update-motd 2>/dev/
null
Usuarios privilegiados: sudo
Con el objetivo de garantizar la máxima trazabilidad, se requiere que el usuario root no sea utilizado directamente. Para ello podemos configurar el sistema para que el grupo de usuarios que nos interese puedan adquirir privilegios de root editando ‘/etc/group’ y añadiendo:
admin:x:114:miusuario
Ademas debemos tener en '/etc/sudoers' la siguiente línea:
# Members of the admin group may gain root privileges %admin ALL=(ALL) ALL
Para editar sudoers siempre debemos utilizar el comando ‘visudo’. Con esta configuración, el usuario o usuarios del grupo seleccionado (‘admin’ en este caso) podrán acceder al sistema normalmente y una vez dentro ejecutar ‘sudo comando’ o ‘sudo -s’ para adquirir privilegios de root.Cabe destacar que Ubuntu suele venir configurada así por defecto.
Sistema de archivos
Esquema de los permisos de ficheros/directorios
Permisos por defecto: UMASKEs posible establecer los permisos con los que se crean los nuevos ficheros/directorios, para ello tendremos que editar varios ficheros. El primero es ‘/etc/login.defs’:
UMASK 022
El segundo ‘/etc/profile’:umask 022
Y finalmente, editamos ‘/etc/pam.d/common-session’ y añadimos al final:session optional pam_umask.so umask=0022
Son necesarios tantos cambios porque en función de como nos conectemos a la máquina (físicamente, remotamente por ssh, X Window, etc.) se utilizaran unos scripts u otros.En cuanto a la mascara, nos podría interesar establecer umask como 027 para que todos los ficheros/directorios creados no tengan permisos de acceso para otros usuarios que no sean los del grupo del propietario.Ejemplo de funcionamiento de umask:
$ umask 000
$ touch file1
$ ls -l file1
-rw-rw-rw- 1 oracle oinstall 0 Dec 26 19:24 file1
$ umask 002
$ touch file2
$ ls -l file2
-rw-rw-r-- 1 oracle oinstall 0 Dec 26 19:24 file2
$ umask 022
$ touch file3
$ ls -l file3
-rw-r--r-- 1 oracle oinstall 0 Dec 26 19:25 file3
Permisos especiales: SUID y SGIDCuando el bit SUID (set user ID) o SGID (set group ID) está activo en un ejecutable, esto implica que ese archivo se ejecutará con los permisos del propietario o grupo propietario respectivamente. Por ejemplo:
Ping tiene activado el bit SUID y su propietario es root, por tanto cuando sea ejecutado
por un usuario, el programa adquirirá los privilegios de root. En ocasiones se requiere este comportamiento, pero en otras puede ser innecesario y únicamente contribuye a debilitar la seguridad del sistema (p.ej. se descubre una vulnerabilidad/overflow en ping que permite al usuario obtener una shell, esta shell seria con permisos de root).Para identificar todos los ficheros SUID o GUID podemos utilizar:
En ocasiones estos son necesarios, como por ejemplo ‘/tmp’. Pero en otras puede suponer un peligro para el sistema. Está en nuestras manos decidir cuales dejar con dichos permisos.A modo de ejemplo, con el usuario user01 creamos un directorio con permisos de escritura universales:
En el ejemplo anterior, como el directorio tiene permisos de escritura para todo el mundo, el usuario user02 podría borrar/modificar el archivo ‘hola’ a pesar de que este pertenece a user01 y sus permisos sean -rw-r–r–. Por ejemplo, con el usuario user02 ejecutamos el borrado:
$ rm hola
rm: ¿borrar el archivo regular vacío «hola» protegido contra escritura? (s/n) y
Por otra parte, los directorios con permisos de escritura global que tienen el Sticky bit activado como ‘/tmp’:
Este comportamiento no tiene lugar, los ficheros creados únicamente pueden ser modificados por sus propietarios o por el propietario del directorio. Por ejemplo, con el usuario user02:
$ rm hola
rm: ¿borrar el archivo regular vacío «hola» protegido contra escritura? (s/n) y
rm: no se puede borrar «hola»: Operación no permitida
Consecuentemente, del listado de directorios con permisos globales de escritura, los que tienen el
bit Sticky activado son casos especiales que debemos tener en cuenta.Para activar/desactivar el bit sticky en un directorio:
chmod +t directorio/
chmod -t directorio/
Archivos sin propietariosPara identificar archivos sin propietarios:
find / -path /proc -prune -o -nouser -o -nogroup
Si en el futuro se crease un usuario con el mismo ID, este adquiriría permisos automáticamente sobre estos ficheros y podría suponer un problema de seguridad.
Detección de modificaciones de ficheros: TripwirePodríamos utilizar tripwire para detectar modificaciones en ficheros del sistema. Tripwire construye una BBDD con los MD5 de los ficheros:
apt-get install tripwire
4. Política de contraseñas
Política globalTodas las contraseñas deben ser cifradas y por tanto, contenidas en /etc/shadow. Para validar que passwd no contiene passwords:
$ grep -v ':x:' /etc/passwd
En ‘/etc/passwd’ todos los usuarios deben tener el campo password una x.Se recomienda forzar a los usuarios a cambiar sus contraseñas de forma periódica (p.ej. 60 días) y que no puedan ser cambiadas más de una vez en un día (p.ej. en caso de que tengamos configurado el sistema para mantener un histórico de contraseñas irrepetibles, el usuario no podrá cambiar su contraseña N veces en el mismo día hasta volver a tener la misma). Para ello editamos ‘/etc/login.defs’ y establecemos:
# Maximum number of days a password is valid.
PASS_MAX_DAYS 60
# Minimum number of days before a user can change the password since the last change.
PASS_MIN_DAYS 1
#Number of days when the password change reminder starts.
PASS_WARN_AGE 15
Adicionalmente, si un usuario no cambia su contraseña 2 semanas después de haberse caducado, se recomienda bloquear la cuenta. De esta forma el sistema desactivará las cuentas de usuario que no estén siendo utilizadas y minimizaremos el riesgo de accesos indebidos. Debemos editar ‘/etc/default/useradd’:
# Number of days after password expiration that account is disabled.
INACTIVE=14
Por otra parte, es recomendable que el sistema lleve un control de contraseñas históricas para evitar que el usuario reutilice los últimos N passwords. Además, es interesante que el sistema también valide la robustez de las nuevas contraseñas. Con este objetivo, debemos instalarcracklib:
apt-get install libpam-cracklib
update-cracklib
A continuación editamos ‘/etc/pam.d/common-password’ y lo dejamos así:password required pam_cracklib.so retry=3 minlen=8 difok=1 lcredit=0 ucredit=1
● Longitud mínima de 8 caracteres, no obstante puede ser inferior si se utilizan caracteres que valen más: Mayúsculas, minúsculas, dígitos, etc…
● Al menos 1 caracteres deben ser diferentes al password anterior.● Según el manual, el parámetro ‘obscure’ provoca que se realicen las siguientes validaciones:
Palindrome: Verifies that the new password is not a palindrome of (i.e., the reverse of) the previous one.
Case Change Only: Verifies that the new password isn´t the same as the old one with a change of case.
Similar: Verifies that the new password isn´t too much like the previous one Simple: Is the new password too simple? This is based on the length of the password
and the number of different types of characters (alpha, numeric, etc.) used. Rotated: Is the new password a rotated version of the old password? (E.g., “billy”
and “illyb”)● Por su parte, cracklib realiza estas otras comprobaciones:
Que los cambios de passwords no se simplemente invertir la palabra o cambiar mayúsculas por minúsculas.
Comprobaciones contra un diccionario interno, construido a partir de datos que hay en los ficheros del sistema (update-cracklib)
● Finalmente ‘remember=12′ hace que el sistema recuerde las últimas 12 contraseñas y no deja que el usuario las repita. Para que funcione correctamente vamos a necesitar ejecutar también:
● touch /etc/security/opasswd
chown root:root /etc/security/opasswd
chmod 600 /etc/security/opasswd
Existen alternativas a cracklib como por ejemplo libpam-passwdqc, el cual es más configurable aunque hoy por hoy menos popular.Finalmente, validamos el estado actual de algún usuario del sistema:
# chage -l miusuario
Last password change : Aug 05, 2008
Password expires : Oct 04, 2008
Password inactive : never
Account expires : never
Minimum number of days between password change : 1
Maximum number of days between password change : 60
Number of days of warning before password expires : 15
Cabe destacar que para usuarios ya creados podemos modificar sus opciones mediante chage (ver man).
Contraseñas de un solo uso: OTP (One time password)Podemos configurar el sistema para que en el momento del acceso, si introducimos incorrectamente o en blanco nuestro password, el sistema nos ofrezca la alternativa de logearnos con un password de un solo uso. Esto puede ser de gran utilidad si nos conectamos a la máquina desde un ordenador que no podemos confiar (p.ej. un cibercafé).Para esto necesitamos instalar opie:
apt-get install opie-server
A continuación, como usuario establecemos una contraseña y el programa nos proporciona un challenge:
opiepasswd -c -f
ID marble OTP key is 499 vp5957
CAB TILE YOU NINA BRED ELLA
Podemos obtener un listado de los 10 futuros password de un solo uso que vamos a poder usar mediante el comando siguiente:
No obstante, resulta interesante utilizar algún programa escrito en J2ME para móviles como vejotp, con el cual podremos generar el password de un solo uso que necesitemos indicando el challenge correspondiente que nos indique el servidor al conectarnos.Por último, falta configurar el sistema para que acepte estas contraseñas. Editamos ‘/etc/pam.d/common-auth’:
auth sufficient pam_unix.so nullok_secure
auth sufficient pam_opie.so
auth required pam_deny.so
#auth requisite pam_unix.so nullok_secure
#auth optional pam_smbpass.so migrate missingok
Y en el caso de que usemos SSH, editamos ‘/etc/ssh/sshd_config’:ChallengeResponseAuthentication yes
Existen alternativas a OPIE como por ejemplo libpam-otpw, el cual utiliza la típica tarjeta de coordenadas en lugar de passwords de un solo uso.
Gestión del accesoDespués de 3 intentos fallidos de un usuario, es recomendable bloquear su cuenta para los siguientes 30 segundos por ejemplo (durante los cuales será denegado su acceso aunque ponga correctamente sus credenciales). A partir de ese punto, cada nuevo intento fallido representará otros 30 segundos de bloqueo. Si el usuario indica su contraseña correcta pasado ese tiempo, el contador de intentos fallidos se resetea a 0.Para ello utilizaremos ‘pam_tally’ editando ‘/etc/pam.d/common-auth’:
# 3 auth attempts, after that user will be locked for 30 seconds for each new failed
El parámetro ‘per_user’ hará que tally valide si se ha establecido algún valor individual (diferente de 0) al usuario mediante faillog. Por ejemplo, para limita el número de reintentos fallidos y establecer el tiempo de bloqueo para un usuario concreto:
faillog --maximum 5 --lock-time 120 -u miusuario
Otro ejemplo, no permitir que un usuario se bloquee aunque sobrepase los valores por defecto de intentos fallidos de autenticación:
faillog --maximum -1 -u miusuario
Para ver el estado de los usuarios podemos utilizar:pam_tally
pam_tally --user misusuario
faillog -a
faillog -u miusuario
Para desbloquear:pam_tally --user miusuario --reset
Es importante eliminar todos los parámetros ‘nullok’ o ‘nullok_secure’ del modulo pam_unix.o dado que permiten passwords en blanco (tanto en common-password como en common-auth).Ver más en opciones (bloqueos permanentes, etc.) en el siguiente manual.
5. Gestión de usuarios
Creación de usuariosPara crear un usuario y asignarle un password:
Estos comando crean su directorio de usuario con el skeleton básico (-m), crea un grupo con el mismo nombre que el usuario y será su grupo primario (-n) y además pertenecerá al grupo admin. Por otra parte, también se especifica la política de contraseñas específica.Para establecer contraseñas aleatorios podemos ayudarnos del siguiente programa:
apt-get install makepasswd
makepasswd --chars=8
Gestión de cuentasTomando como ejemplo un usuario que dispone de la siguiente entrada en ‘/etc/shadow’:
● Desactiva un usuario (sin posibilidad de recuperar el password):● passwd -d usuario
● Se asigna un hash en blanco y en el octavo campo añade un 1 (cuenta caducada el 2 de Enero de 1970):
● usuario::14111:0:99999:7::1:
● Activar un usuario que ha sido desactivado: eliminar la expiración y asignar una nueva contraseña
● chage -E -1 aurora
passwd aurora
● Estado:● passwd -S usuario
chage -l usuario
● Si no queremos que root pueda logearse directamente al sistema y que el acceso a la cuenta de administración se realice mediante sudo. Aparte de configurar correctamente sudo, debemos bloquear y desactivar el usuario root:
· days since Jan 1, 1970 that password was last changed
· days before password may be changed
· days after which password must be changed
· days before password is to expire that user is warned
· days after password expires that account is disabled
· days since Jan 1, 1970 that account is disabled
Otras funcionalidades útiles:● Listar usuarios no bloqueados:● egrep -v '.*:*|:!' /etc/shadow | awk -F: '{print $1}'
● Listar archivos de un usuario concreto (nos puede servir para identificar usuarios que no disponen de información en el sistema):
● find / -path /proc -prune -o -user usuario -ls
● Comprobamos que el fichero de grupos es correcto:● # grpck -r
'www-data' is a member of the 'adm' group in /etc/group but not in /etc/
gshadow
'miusuario' is a member of the 'users' group in /etc/group but not in /etc/
gshadow
no matching group file entry in /etc/gshadow
add group 'admin' in /etc/gshadow ?No
group marble: no user 0
delete member '0'? No
no matching group file entry in /etc/gshadow
add group 'marble' in /etc/gshadow ?No
'miusuario' is a member of the 'adm' group in /etc/gshadow but not in /etc/
group
grpck: no changes
6. Servicios básicos del sistema
Activación en arranquePara la activación/desactivación de los servicios que queremos en arranque podemos utilizar la herramienta de consola ‘sysv-rc-conf’:
apt-get install sysv-rc-conf
Ejecutando ‘sysv-rc-conf’ podremos marcar los servicios/scripts/demonios que queremos arrancar al iniciar el sistema. La aplicación aplica los cambios de forma instantanea al situarnos sobre alguna de las X y pulsar ‘espacio’. Para salir pulsamos la ‘q’.Si queremos saber en que runlevel arranca el sistema por defecto:
$ grep ':initdefault' /etc/inittab
id:2:initdefault:
En caso de que no exista el fichero, es porque probablemente tengamos el sistema de arranque Upstart, el runlevel por defecto suele ser el 2 (es posible verificarlo en ‘/etc/event.d/rc-default’).Suele ser recomendable desactivar la posibilidad de reiniciar el ordenador mediante CTRL+ALT+SUPR para evitar reinicios involuntarios (p.ej. la señora de la limpieza).En caso de que utilicemos el tradicional sistema de arranque de Unix/Linux (System V init), bastará con comentar (/etc/inittab):
# What to do when CTRL-ALT-DEL is pressed.
#ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
Y aplicar los cambios:# init q
O si como mecanismo de arranque usamos Upstart (como es el caso de Ubuntu), editamos ‘/etc/
event.d/control-alt-delete’ y comentamos:#exec /sbin/shutdown -r now "Control-Alt-Delete pressed"
Servicio de correo: PostfixEl sistema requerirá un servicio de correo aunque únicamente sea para uso local, dado que varias tareas automáticas reportaran su estado mediante correo.En caso de que nuestro sistema venga configurado con sendmail, es recomendable desinstalarlo e instalar algún otro sistema más robusto como postfix (historicamente sendmail ha tenido muchos fallos de seguridad):
Para una configuración básica y segura, primero definiremos que usuario del sistema recibirá los correos destinados a root (p.ej. muchas tareas automáticas del sistema envían correo a root). Editamos ‘/etc/aliases’ y añadimos:
root: miusuario
Y ejecutamos:newaliases
A continuación, securizaremos la instalación de postfix de forma que muestre la información mínima necesaria. Editamos ‘/etc/postfix/main.cf’:
# Rewrite "user" to "user@$myorigin" with locally submitted mail
# Or "user" to "user@$remote_header_rewrite_domain" with remote connection
# only if $remote_header_rewrite_domain is not empty (by default it is empty)
#
# By default: myorigin = $mydomain = /etc/mailname
append_at_myorigin = yes
Asi ocultamos la versión y obligamos a que todo mail enviado por los procesos automáticos del sistema tengan como dominio el especificado en ‘/etc/mailname’ (si se envian a usuario@localhost se reescribira como usuario@dominio).Editamos ‘/etc/mailname’ para establecer el dominio que queremos, por ejemplo:
un.ejemplo.com
Si no vamos a utilizar Postfix como un servicio de correo remoto y únicamente lo queremos usar de forma local, editamos ‘/etc/postfix/master.cf’ para asegurarnos que únicamente se aceptan conexiones localhost:
127.0.0.1:smtp inet n - - - - smtpd
Con esto ya tenemos postfix preparado:/etc/init.d/postfix restart
Finalmente, si nos interesa que el correo local que reciba un usuario sea reenviado a otra dirección, en el directorio personal del usuario creamos ‘.procmailrc’:
max_execution_time = 30 ; Maximum execution time of each script, in seconds
max_input_time = 60 ; Maximum amount of time each script may spend parsing request
data ;max_input_nesting_level = 64 ; Maximum input variable nesting level
memory_limit = 16M ; Maximum amount of memory a script may consume (16MB)
Apache básicoVeamos como mejorar la configuración de apache. Por un lado editamos ‘/etc/apache2/apache2.conf’ y cambiamos los siguientes parámetros para que Apache no muestre información innecesaria:
#ServerTokens Full
ServerTokens Prod
#ServerSignature On
ServerSignature Off
También debemos aseguramos que no se cambian estos parámetros en los sites activos (‘/etc/apache2/sites-enabled/*).En general los comando HTTP TRACE y TRACK no son utilizados para servir páginas y por tanto, podemos desactivarlos para evitar que un usuario malintencionado los utilice para intentar atacar. Para cada uno de los sites-enabled, lo editamos y añadimos dentro del VirtualHost:
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
Activamos el modulo ‘rewrite’ y reiniciamos el servicio:a2enmod rewrite
/etc/init.d/apache2 restart
A continuación podemos validar que realmente ha surgido efecto el bloqueo de los comandos TRACE y TRACK:
$ telnet 127.0.0.1 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
TRACE / HTTP/1.0
A: b
C: d
Host: foo
HTTP/1.1 403 Forbidden
Date: Tue, 05 Aug 2008 17:09:34 GMT
Server: Apache
Content-Length: 255
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.</p>
<hr>
<address>Apache Server at foo Port 80</address>
</body></html>
Connection closed by foreign host.
Otra medida de seguridad consiste en desactivar el uso de FollowSymLinks para no permitir que un usuario pueda crear enlaces simbólicos hacia directorios que no deseamos que estén expuestos. Para ello, en las opciones de los sites-enabled debemos indicar:
Options None
Finalmente, es conveniente que le indiquemos a Apache exactamente en que IPs queremos que escuche. De esta forma podemos limitarlo por ejemplo únicamente para uso local. Para ello editamos ‘/etc/apache2/ports.conf’ y cambiamos Listen 80 por Listen ip_maquina:80.Otro aspecto importante es proteger el servicio de ataques de denegación de servicio (DoS). En el fichero ‘/etc/apache2/apache2.conf’ podemos realizar algunos cambios:
● Si establecemos un timeout bajo, minimizamos el impacto de los ataques pero puede que algunos CGIs que requieran más tiempo dejen de funcionar (p.ej. 300 segundos):
● Timeout 300
● Si tenemos activado el HTTP KeepAlive, definir un timeout bajo minimiza el impacto de ataques (p.ej. 15 segundos):
● KeepAliveTimeout 15
MaxKeepAliveRequests 100
● Habitualmente, aunque apache2-mpm-worker, se utiliza apache2-mpm-prefork como versión de apache por defecto dado que esta es compatible con PHP. Prefork puede ser customizado, pero estos son los valores recomendados por defecto:
● <IfModule mpm_prefork_module>
# Number of child server processes created on startup
StartServers 5
# Sets the desired minimum number of idle child server processes
MinSpareServers 5
# Sets the desired maximum number of idle child server processes
MaxSpareServers 10
# Sets the limit on the number of simultaneous requests that can be
supported;
MaxClients 150
# Sets the limit on the number of requests that an individual child server
process will handle
MaxRequestsPerChild 0
</IfModule>
● De todos ellos, los únicos parámetros con los que se suele jugar son MaxClient y MaxRquestPerChild. Con este último, indicar un valor diferente de cero nos permitiría limitar la memoria utilizada por procesos que tienen memory leakages.
● Limitar el tamaño del BODY de las peticiones puede ser muy útil por ejemplo para evitar que los usuarios suban ficheros excesivamente grandes (p.ej. 500 KB = 1024*500 bytes):
● LimitRequestBody 512000
● Limitamos el número de campos que puede tener una petición en el HEADER (de media suelen tener 20) y su tamaño (7KB = 8190 bytes)
● LimitRequestFields 50
LimitRequestFieldSize 8190
LimitRequestLine 8190
Módulos de ApacheApache se encuentra programado con funciones residentes en módulos independientes al core de la aplicación, eso nos permite activar únicamente aquellas características que vamos a utilizar para minimizar riesgos. Desactivación de módulos:
a2dismod alias
a2dismod auth_basic
a2dismod authn_file
a2dismod authz_default
a2dismod authz_groupfile
a2dismod authz_host
a2dismod authz_user
a2dismod autoindex
a2dismod cgi
a2dismod dir
a2dismod env
a2dismod mime
a2dismod negotiation
a2dismod php5
a2dismod rewrite
a2dismod setenvif
a2dismod ssl
a2dismod status
Activación de modulos mínimos:# Default page (e.g. index.html)
a2enmod dir
a2enmod mime
# Language preference
a2enmod negotiation
a2enmod php5
a2enmod rewrite
# Workarounds for certain browser bugs
a2enmod setenvif
# Allows access rules based on hosts (allow from...)
a2enmod authz_host
Servir por localhost las aplicaciones más criticasFinalmente, si vamos a utilizar Apache como servidor web remoto pero queremos también instalar aplicaciones de gestión como phpmyadmin, cacti, nagios, etc… Es recomendable que estas se encuentren en una instancia del servidor que solo sea accesible desde local para los usuarios de la máquina, pero no para el resto del mundo. Es decir, vamos a evitar que cualquier persona pueda acceder libremente por ejemplo a ‘http://www.midominio.com/phpmyadmin’, pero si vamos a permitir que un usuario con cuenta en el sistema pueda acceder mediante SSH realizando Port Forwarding:
Con el anterior comando, ssh abrirá el puerto 8080 en la máquina del cliente y redireccionará todo lo que le llegue al puerto 80 de la interfaz localhost del servidor. Por tanto, el cliente (una vez se ha autenticado con su usuario por SSH) podrá acceder a phpmyadmin mediante ‘http://localhost:8080/phpmyadmin’. Adicionalmente, todo el tráfico viajará cifrado sin necesidad de configurar el SSL de Apache.Con este objetivo, vamos a crear ‘/etc/apache2/sites-available/localhost’:
Cuando instalamos phpmyadmin (u otras aplicaciones web similares) mediante el sistema de paquetes de Ubuntu, se generan ficheros de configuración en ‘/etc/apache2/conf.d/’ para que apache pueda encontrar la aplicación web (p.ej. mediante alias). Esto nos resta control y por defecto hace que la web sea accesible remotamente. Para minimizar riesgos, comentamos la línea de ‘/etc/apache2/apache2.conf’ que carga estas configuraciones estándar:
# Include generic snippets of statements
#Include /etc/apache2/conf.d/
Y en contrapartida, tendremos que copiar/enlazar todo aquello que queramos que sea accesible únicamente por localhost en el directorio ‘/var/www/localhost’.
Base de datos MySQLSecurizamos la instalación básica ejecutando ‘mysql_secure_installation’. Según el manual, este comando permite:
● You can set a password for root accounts.● You can remove root accounts that are accessible from outside the local host.● You can remove anonymous-user accounts.● You can remove the test database, which by default can be accessed by anonymous users.
Se recomienda aplicar las 4 acciones. Por otra parte, en la configuración de ‘/etc/mysql/my.cnf’:# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# log = /var/log/mysql/mysql.log
#
# Error logging goes to syslog. This is a Debian improvement
#
# Here you can see queries with especially long duration
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
Logeamos las queries que tardan más de 2 segundos en ejecutarse.
/etc/init.d/mysql restart
Finalmente, para crear un usuario con su propia base de datos:CREATE USER 'miusuario'@'localhost' IDENTIFIED BY 'YB9gYu6I';
GRANT USAGE ON *.* TO 'miusuario'@'localhost' IDENTIFIED BY 'YB9gYu6I' WITH
GRANT ALL PRIVILEGES ON miusuario.* TO 'miusuario'@'localhost';
FLUSH PRIVILEGES;
Acceso remoto: SSHPara la securización de SSH, vamos a hacer que únicamente un grupo de usuario pueda conectarse. Creamos el grupo ‘sshlogin’ y añadimos usuarios al mismo:
sudo groupadd sshlogin
sudo adduser miusuario sshlogin
Importante: Si utilizamos FreeNX o NX (artículo sobre FreeNX) para el acceso remoto al escritorio, también tendremos que añadir al grupo ‘sshlogin’ el usuario ‘nx’.Editamos ‘/etc/ssh/sshd_config’ para impedir que root pueda acceder directamente y no se forwardeen las X:
PermitRootLogin no
X11Forwarding no
AllowGroups sshlogin
Reiniciamos el servicio:sudo /etc/init.d/ssh restart
En caso de que desde nuestra máquina tengamos que acceder a diversos servicios SSH y no queremos tener que recordar las diferentes contraseñas, podemos generar una pareja de claves RSA (pública y privada) en la máquina cliente (se recomienda que asignar password para proteger la clave privada):
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
Con ssh-keygen hemos creado una clave privada ‘~/.ssh/id_rsa’ que no debemos compartir con nadie y una clave pública ‘~/.ssh/id_rsa.pub’ que hay que copiar en el directorio ‘~/.ssh/authorized_keys’ de los servidores a los que queramos conectar con SSH:
Y desde cada servidor:$ cat id_rsa.pub >> .ssh/authorized_keys
$ rm id_rsa.pub
Podemos poner determinadas condiciones bajo las cuales se utilizaran estas claves, por ejemplo:from="81.11.105.10",command="/bin/ls",no-port-forwarding,no-X11-forwarding,no-
Al inicio de la clave hemos especificado:● from=”81.11.105.10″: únicamente puede ser utilizada desde un cliente con esa IP.● command=”/bin/ls”: únicamente se permitirá la ejecución de ese fichero.● no-port-forwarding: no permite redirigir puertos.● no-X11-forwarding: no permite la redirección gráfica de programas (X Window)● no-agent-forwarding: no permite redirigir peticiones entre servidores a agentes ssh de
autenticación.● no-pty: el cliente no obtendrá una terminal con shell, solo podra ejecutar comando (p.ej. ‘ssh
usuario@servidor /bin/ls’)A partir de este momento, cada vez que queramos conectarnos a uno de estos servidores SSH, ssh nos preguntará por la contraseña que le hemos puesto a nuestra clave privada y por tanto, solo hace falta recordar 1 contraseña. No obstante, aun podemos simplificar más la gestión:
● En la generación de las claves RSA no asignamos contraseña y por tanto esta no será requerida para conectarnos a los servidores por SSH (en caso de que ya la hayamos asignado, podemos cambiarla mediante ‘ssh-keygen -p’). Este punto tiene el inconveniente de que en caso de que alguien se haga con el fichero que contiene la clave privada, tendrá acceso completo a los servidores configurados.
● Uso de keychain (ssh-agent) para que únicamente tengamos que teclear la contraseña que protege la clave privada una vez.
Veamos como configurar el segundo punto:$ sudo apt-get install keychain
Editamos el fichero ‘~/.bashrc’ y añadimos al final:## SSH Agent
# Do not execute if I am root (sudo -s)
if [ "$(id -u)" != "0" ]; then
keychain id_rsa --nocolor --quiet
. ~/.keychain/`uname -n`-sh
fi
Salimos del sistema y volvemos a entrar para que sean efectivos los cambios de bashrc. La primera vez que se ejecute ‘keychain’ nos preguntará la contraseña que protege a la clave privada:
Mientras permanezca la máquina en marcha podremos acceder a los servidores mediante SSH sin que nos solicite de nuevo la contraseña.En el siguiente enlace podéis encontrar una descripción detallada de cómo funciona SSH.
7. Trazabilidad
Fecha y hora del sistemaPara que los logs resulten de utilidad y tengamos una buena trazabilidad de todo lo que ocurre en el sistema, es necesario que la máquina disponga de la fecha/hora correcta. Para ello podemos configurar la sincronización automática con otros servidores de Internet via NTP:
apt-get install ntpdate
Creamos ‘/etc/cron.daily/ntpdate’:#! /bin/bash
/usr/sbin/ntpdate -u ntp.ubuntu.com
Y damos permisos de ejecución:chmod 755 /etc/cron.daily/ntpdate
Por defecto el sistema utilizará los servidores de Ubuntu (ntp.ubuntu.com) para la sincronización.En caso de que fuese necesario, también conviene asegurarnos que el sistema tiene configurada la
Logs de usuario con BashEn ‘/etc/profile’ podemos añadir las siguientes variables de entorno (personalmente únicamente añado la que permite tener histórico con timestamp, visualizable con el comando history de cada usuario):
########
## declare -r: Variables de entorno que no pueden ser modificadas
## readonly -p: Lista variables que no pueden ser modificadas
# Nombre del archivo de historial (default '~/.bash_history')
export HISTFILE='~/.bash_history'
#declare -r HISTFILE='~/.bash_history'
# nº máximo de comandos que puede contener el archivo (default 500).
export HISTFILESIZE='500'
# nº de comandos por los que podrá navegar el usuario con las teclas de cursor
(default 500)
export HISTSIZE='500'
# Ignorar comandos duplicados y espacios en blanco delante (default blank)
export HISTCONTROL=ignorespace:ignoredups
# Save history with timestamp (default blank)
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
# No guardar en el historial los siguientes comandos (por defecto en blanco)
export HISTIGNORE=”:ls:cd ..:cd /:”
Esto mismo también lo podemos establecer en ‘/etc/bash.bashrc’ si queremos que no solo afecte a las login shells.
Rotación y conservación de logsEn el sistema debemos tener instalado anacron o cron, si tenemos ambos simultaneamente (aunque uno de los dos demonios esté parado) no se ejecutaran las tareas de /etc/cron.daily, weekly, etc.. (debido a como viene por defecto /etc/crontab). En nuestro caso, al ser un servidor y estar siempre en marcha usaremos cron:
apt-get purge anacron
apt-get install cron
La política de gestión de logs será:● Rotación mensual● Mantenimiento de las últimas 24 copias (2 años de log)● Incorporar la fecha de creación al nombre del fichero
Preparamos las tareas de rotacion de log a ejecutar por cron de forma mensual:chmod 644 /etc/cron.daily/sysklogd
chmod 644 /etc/cron.weekly/sysklogd
cp /etc/cron.weekly/sysklogd /etc/cron.monthly/
chmod 755 /etc/cron.monthly/sysklogd
Editamos ‘/etc/cron.monthly/sysklogd’ y modificamos la linea que llama a save_log para incluir en la rotación todos los ficheros log gestionados por syslogd:
De esta forma, syslogd cumplirá con la política de gestión de logs que hemos definido.Mediante ‘syslogd-listfiles –all’ podemos ver todos los ficheros que serán rotados, por ejemplo:
/var/log/mail.warn
/var/log/uucp.log
/var/log/user.log
/var/log/daemon.log
/var/log/messages
/var/log/debug
/var/log/auth.log
/var/log/mail.err
/var/log/syslog
/var/log/mail.log
/var/log/mail.info
/var/log/kern.log
/var/log/lpr.log
El resto de logs que no son generados por syslogd, los gestionaremos a través de logrotate.Editamos /etc/logrotate.conf y establecemos la política general de logs:
# rotate log monthly
monthly
# keep 24 months of backlog
rotate 24
# uncomment this if you want your log files compressed
compress
# Postpone compression of the previous log file to the next rotation cycle
delaycompress
# create new (empty) log files after rotating old ones
create
# uncomment this if you want your log files compressed
compress
# Postpone compression of the previous log file to the next rotation cycle
delaycompress
# Archive old versions of log files adding a daily extension like YYYYMMDD instead of
simply adding a number.
dateext
# Rotate the log file even if it is empty
ifempty
# packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own wtmp, or btmp -- we'll rotate them here
/var/log/wtmp {
missingok
# monthly
create 0664 root utmp
# rotate 1 }
/var/log/btmp {
missingok
# monthly
create 0664 root utmp
# rotate 1 }
En ‘/etc/logrotate.d’ tenemos ficheros con los logs a rotar y en algunos casos, con políticas concretas diferentes a la global. Para nos aseguramos que no haya políticas diferentes a la global para logs específicos podemos ejecutar:
find /etc/logrotate.d/ -type f -exec sed -i 's/daily/#daily/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/weekly/#weekly/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/monthly/#monthly/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/rotate/#rotate/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/post#rotate/postrotate/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/pre#rotate/prerotate/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/notifempty/#notifempty/g' {} ;
find /etc/logrotate.d/ -type f -exec sed -i 's/size/#size/g' {} ;
Cabe destacar que es necesario revisar la configuración existente en ‘/etc/logrotate.d’ por si faltase realizar alguna modificación extra (p.ej. logs extra de apache como ‘/var/log/apache2/localhost/*.log’).Del resto de logs del sistema que queramos rotar y no estén ya incluidos, tendremos que crear un fichero nuevo en ‘/etc/logrotate.d’ indicándolo (en general, todo paquete de Ubuntu ya viene preparado para que sus logs sean gestionados automáticamente por syslogd o logrotate). Es importante tener en cuenta que no debemos rotar:
● Binarios como /var/log/faillog o /var/log/lastlog● Logs de nagios dado que romperíamos el historial interno. Mejor que lo gestione la propia
aplicación directamente.● Logs generados directamente por syslogd (como hemos visto antes). Visualizar con syslogd-
listfiles –all
Análisis de logs de Apache mediante AwstatsCon awstats podremos ver las visitas, tráfico y otros aspectos relacionados con cada uno de los dominios virtuales que tengamos configurados en Apache. Para su instalación presuponemos que ya tenemos configurado Apache y que awstats va ser accesible únicamente de forma local:
Creamos el fichero ‘/etc/apache2/conf.d/awstats.conf’ con el siguiente contenido:ScriptAlias /cgi-bin/awstats.pl /usr/lib/cgi-bin/awstats.pl
Reiniciamos apache:/etc/init.d/apache2 restart
Y accedemos a la web mediante ‘http://localhost:8080/cgi-bin/awstats.pl?config=localhost’.Para que se actualice periódicamente el análisis de Awstats, editamos /etc/cron.d/awstats (cada noche):
Envío por correo de los eventos más significativos con logcheckCon logcheck podremos resumir los eventos del sistema registrados en los logs y enviarlos a nuestro correo de forma diaria:
apt-get install logcheck logcheck-database
Editamos ‘/etc/logcheck/logcheck.logfiles’:# Estos 2 ficheros incluyen todos los mensajes enviados a syslog ()/etc/syslog.conf)
/var/log/syslog
/var/log/auth.log
# Apache
/var/log/apache2/error.log
/var/log/apache2/localhost/error.log
# MySQL
#/var/log/mysql/mysql.log # En debian, si descomentas la linea de log de /etc/mysql/
my.cnf, el log va por syslog
#/var/log/mysql/mysql-slow.log
La tarea cron que se encarga de la ejecución diaria es ‘/etc/cron.d/logcheck’.Por otra parte, la configuración de logcheck se encuentra en ‘/etc/logcheck/logcheck.conf’:
# Controls the address mail goes to:
# *NOTE* the script does not set a default value for this variable!
Una vez configurado, podemos probar su funcionamiento ejecutando:sudo -u logcheck logcheck
Logcheck incorpora por defecto toda una serie de reglas para la selección o el descarte de las lineas del log a enviar en el resumen. Es posible que nos interese refinar estas reglas, haciendo que sean descartadas cadenas que no nos aporten nada. Por ejemplo, veamos como ignorar las lineas generadas por el firewall o nagios (ver secciones correspondientes), dado que esa información ya la analizamos con otras herramientas.Creamos ‘/etc/logcheck/ignore.d.server/000-custom’ y añadimos:
^w{3} [ :0-9]{11} [._[:alnum:]-]+ nagios2: CURRENT SERVICE STATE:
^w{3} [ :0-9]{11} [._[:alnum:]-]+ nagios2: CURRENT HOST STATE:
^w{3} [ :0-9]{11} [._[:alnum:]-]+ nagios2: Warning: A system time change of [0-9]+
seconds (backwards in time) has been detected. Compensating...
Si queremos incluir más reglas, podemos validarlas contra el log que nos interese:sed -e 's/[[:space:]]*$//' /var/log/ulog/syslogemu.log | egrep '^w{3} [ :0-9]{11}
[._[:alnum:]-]+ kernel: [FW:[ ._[:alnum:]-]+]'
sed -e 's/[[:space:]]*$//' /var/log/syslog | egrep '^w{3} [ :0-9]{11} [._[:alnum:]-]+
nagios2: CURRENT SERVICE STATE:'
sed -e 's/[[:space:]]*$//' /var/log/syslog | egrep '^w{3} [ :0-9]{11} [._[:alnum:]-]+
nagios2: CURRENT HOST STATE:'
sed -e 's/[[:space:]]*$//' /var/log/syslog | egrep '^w{3} [ :0-9]{11} [._[:alnum:]-]+
nagios2: Warning: A system time change of [0-9]+ seconds (backwards in time) has been
detected. Compensating...'
Si la regla funciona, aparecerán los mensajes que queremos eliminar.
8. Monitorización del sistema
Actualización automática de la lista de paquetes del sistemaPara comprobar que nuestro sistema se encuentra actualizado, primero necesitamos que se actualice la lista de paquetes automáticamente. Creamos ‘/etc/apt/apt.conf.d/10periodic’:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
De esta forma se actualizará el listado de paquetes (apt-get update) cada día mediante el fichero ‘/etc/cron.daily/apt’.Si hemos instalado nagios (ver Sección correspondiente), este nos informará de cuando hay paquetes pendientes de ser actualizados.
Aviso de actualizaciones pendientesCon apticron podremos hacer que el sistema nos envíe un correo cada vez que se disponga de paquetes pendientes de ser actualizados (p.ej. parches de seguridad):
apt-get install apticron
Para su uso necesitamos tener configurado un servidor de correo (SMTP), podemos configurar un postfix (ver sección anterior de servicios) o utilizar ssmtp para conectar contra un servidor de correo ya configurado.En el segundo caso, instalamos mediante ‘apt-get install ssmtp’ y editamos ‘/etc/ssmtp/ssmtp.conf’:
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=miusuario
# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
mailhub=servidor.correo.com:25
# Where will the mail seem to come from?
#rewriteDomain=nonsense.non
# The full hostname
hostname=el.dominio.de.esta.maquina.com
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=NO
En el fichero anterior indicamos a quien redirigimos los correos de root, el servidor de correo que utilizaremos y el dominio con el que saldrán los correos de la máquina actual.Tanto si ya tenemos un servidor postfix configurado como si hemos optado por SSMTP, debemos probar que el comando 'mail' nos permite enviar correos:
Una vez validado, podemos continuar con la configuración de apticron editando ‘/etc/apticron/apticron.conf’ y estableciendo el correo al que queremos recibir las alertas:
Esto es todo. Cron ejecutará diariamente el script ‘/etc/cron.daily/apticron’, el cual comprobará las actualizaciones pendientes y enviará un correo en caso de que sea necesario.Cabe destacar que para que funcione, el sistema debe estar configurado para que actualice automáticamente el listado de paquetes (ver sección anterior).
Monitorizar desde la consola
Espacio en discoPara la monitorización del espacio en disco podemo usar los comandos:
df -h
du -ms
El primero muestra el estado de todas las particiones, el segundo presenta los megas que ocupa el directorio actual.Puede que nos interese ordenar los directorios en función de su tamaño, para ello podemos descargar un script específico:
cd /usr/local/bin
wget http://www.pixelbeat.org/scripts/dutop
chmod 755 /usr/local/bin/dutop
Que al ejecutar facilita la siguiente información:# dutop
27% 183.8M ./Fotos
26% 180.5M ./Fotos.zip
19% 135.0M ./Documentos
5% 37.4M ./Trabajo
5% 35.6M ./Musica
CPULa monitorización de la CPU (más otros parámetros) podemos llevarla a cabo mediante ‘top’ o ‘htop’:
apt-get install htop
Ancho de banda / BandwidthAplicaciones recomendadas:
apt-get install bwm-ng
Y también:apt-get install jnettop
Para este último debemos crear el fichero ‘~/.jnettop’:#interface "eth0"
# Show IP and Ports per separate
local_aggregation none
# I don't care about remote port
remote_aggregation port
# Do not generate more traffic resolving every IP
resolve off
Al ejecutar jnettop podemos interactuar con la aplicación para cambiar los parámetros establecidos. Por ejemplo:
● ‘l’: cambia la agregación local● ‘r’: cambia la agregación remota
Conexiones de redConexiones de la máquina:
# netstat -atunp
Si la máquina se encuentra haciendo NAT en una red, podemos ver también las conexiones “NATeadas”:
# apt-get install netstat-nat
# netstat-nat -N
Si hemos configurado el firewall con iptables (ver sección correspondiente), podremos ver las conexiones controladas por el módulo CONNTRACK:
# apt-get install iptstate
# iptstate
Memoria RAM / SwapPara obtener un listado de los procesos del sistema ordenados por la memoria consumida:
ps -A --sort=-rsz -o pid,vsz,rssize,pmem,comm
Cada parámetro indica:● pid: Process ID● vsz: Virtual Memory Size (includes RAM & Swap)● rssize: Resident Memory Size (only RAM)● pmem: Ratio of the process’s resident set size to the physical memory on the machine
Para ver la memoria total utilizada tenemos dos opciones:# vmstat -S M
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 34 6 12 134 0 0 348 60 556 521 10 1 75 14
# free -m
total used free shared buffers cached
Mem: 502 494 8 0 12 132
-/+ buffers/cache: 349 153
Swap: 972 34 938
Cada columna significa:● Cache: Bloques de información leídos del disco duro● Buffer: Memoria temporal utilizada por el kernel (p.ej. comunicaciones con dispositivos, envio/
recepción de información por red, etc.)● Swap: Cuando la memoria RAM escasea, el kernel transfiere partes de la memoria RAM a
la memoria SWAP, la cual realmente se encuentra en el disco duro y por tanto es mucho más lenta (pero nos permite cargar más aplicaciones de las que podriamos con nuestra RAM actual).
Cuando se requiere más memoria, el kernel debe decidir si reducir la cache/buffers o enviar bloques de memoria a la Swap. Esta decisión se encuentra parametrizada mediante el valor swappines:
cat /proc/sys/vm/swappiness
Habitualmente su valor es de 60, pero puede situarse entre 0 (poco probable que se realice swap) y 100 (máxima prioridad a realizar swap). Según las aplicaciones de nuestro sistema quizás nos interese cambiarlo, p.ej. en un desktop, cuando se ejecutan procesos cron que consumen mucho
disco duro (por ejemplo slocate), la cache crecerá y puede que se envíen aplicaciones a la swap (swap-in) y el usuario notará una ralentización notable del sistema en el momento que quiera acceder a ellas (swap-out). Para cambiar el parámetro:
# echo "10" > /proc/sys/vm/swappiness
# cat /proc/sys/vm/swappiness
Este cambio se perderá en el siguiente reinicio, para que sea permanente editamos /etc/sysctl.conf y añadimos la linea:
vm.swappiness=10
‘ps_mem’ es un script (python) que imprime el total de memoria RAM sumarizada por proceso padre (p.ej. si apache realiza varios forks, al mostrar la información los unificará):
cd /usr/local/bin
wget http://www.pixelbeat.org/scripts/ps_mem.py
chmod 755 /usr/local/bin/ps_mem.py
Resultado de ejemplo:# ps_mem.py |less
Warning: Shared memory is slightly over-estimated by this system
for each program, so totals are not reported.
Private + Shared = RAM used Program
68.0 KiB + 320.0 KiB = 388.0 KiB klogd
116.0 KiB + 288.0 KiB = 404.0 KiB atd
80.0 KiB + 416.0 KiB = 496.0 KiB mysqld_safe
88.0 KiB + 416.0 KiB = 504.0 KiB dd
68.0 KiB + 436.0 KiB = 504.0 KiB logger
152.0 KiB + 520.0 KiB = 672.0 KiB syslogd
96.0 KiB + 584.0 KiB = 680.0 KiB init
152.0 KiB + 720.0 KiB = 872.0 KiB less
208.0 KiB + 740.0 KiB = 948.0 KiB cron
308.0 KiB + 1.3 MiB = 1.6 MiB pickup
332.0 KiB + 1.3 MiB = 1.7 MiB master
352.0 KiB + 1.4 MiB = 1.7 MiB qmgr
1.2 MiB + 856.0 KiB = 2.0 MiB screen (2)
780.0 KiB + 2.3 MiB = 3.0 MiB sshd (3)
1.2 MiB + 1.9 MiB = 3.1 MiB mutt
1.8 MiB + 2.3 MiB = 4.1 MiB snmpd
840.0 KiB + 7.0 MiB = 7.8 MiB apache2 (6)
9.0 MiB + 1.4 MiB = 10.4 MiB bash (6)
15.4 MiB + 5.1 MiB = 20.6 MiB mysqld
Monitorización en tiempo real: NagiosCon Nagios podemos monitorizar diversos sistemas en tiempo real, generando alertas cuando se incumpla alguno de los parámetros especificados. También vale la pena considerar la opción de utilizar Monit en su lugar.
En estos ficheros de configuración especificaremos los servidores y servicios que queremos monitorizar. Para una guía más detallada consultar el wiki de Ubuntu sobre Nagios para así configurar Nagios según nuestras necesidades..Hay que tener en cuenta que si alguno de los servicios a comprobar es una mysql, debemos asegurarnos que nagios tiene su propio usuario con acceso:
mysql -u root -p
CREATE USER 'nagios'@'localhost';
FLUSH PRIVILEGES;
Nagios depende de apache, dado que su interfaz principal es via web. Para ello apache va a requerir algunos módulos extra:
a2enmod auth_basic
a2enmod authn_file
a2enmod authz_default
a2enmod authz_groupfile
a2enmod authz_host
a2enmod authz_user
a2enmod cgi
a2enmod alias
/etc/init.d/apache2 restart
Una vez configurado, la puesta en marcha:# /etc/init.d/nagios2 stop
# /etc/init.d/nagios2 start
Cabe destacar que los plugins de nagios se encuentran en ‘/usr/lib/nagios/plugins’, y puede que nos interese tener soporte SNMP (ver sección SNMP):
apt-get install nagios-snmp-plugins
Ancho de banda consumido con BandwidthdBandwidthd dibuja gráficas y tablas HTML con el tráfico generado, así podemos controlar lo que sucede en el servidor:
apt-get install bandwidthd
cd /var/www
ln -s /var/lib/bandwidthd/htdocs/ bandwidthd
Configuración en /etc/bandwidthd/bandwidthd.conf:subnet 0.0.0.0/0
Cabe destacar que bandwithd consume bastante memoria RAM (200 MB aprox. de media) y quizás con otras herramientas como Cacti ya tenemos información suficiente sobre el ancho de banda.
SNMPSNMP es un protocolo que permite monitorizar servidores y dispositivos de red de forma remota. Nos puede resultar útil activarlo en nuestra máquina de forma local para que sea utilizado en conjunto con Nagios y/o Cacti.
La configuración anterior hace que SNMP sea accesible en modo lectura para cualquier usuario, además monitorizará el disco principal “/” y los procesos apache2 y mysqld.Reiniciamos el servicio:
/etc/init.d/snmpd restart
Si queremos lanzar consultas SNMP desde la terminal:snmpwalk -v 1 -c public localhost interface|less
Para una explicación más detallada vale la pena leer el siguiente tutorial: Monitoring Server Performance.
Soporte ‘Devices I/O’ en net-snmpEn Ubuntu, net-snmp no viene compilado con soporte para proporcionar información de I/O de los dispositivos del sistema (disco duro). Tenemos la opción de recompilar activando la funcionalidad,
o delegar esta tarea a un script que consultará /proc/diskstats. Optamos por la segunda por su sencillez:Editamos/etc/snmp/snmpd.conf y añadimos al final:
Damos permisos de ejecución y reiniciamos SNMP:chmod 755 /usr/local/bin/snmp-diskio-collector
/etc/init.d/snmpd restart
Para probar que funciona correctamente:snmpwalk -m ALL -v1 -c public localhost diskIOTable
Monitorización historica: CactiCacti es una herramienta que almacena un histórico del estado de diferentes aspecto del sistema local (p.ej. CPU, Memoria, ancho de banda, etc.) o remoto via SNMP. Vale la pena considerar también muni como alternativa.Cacti requerirá Apache y SNMP para funcionar (ver secciones correspondientes).
apt-get install cacti
ln -s /usr/bin/php5 /usr/bin/php
Una vez instalado, podemos acceder vía web por defecto en ‘http://localhost/cacti’ (aunque puede variar depende de como configuremos apache).A través de la web, crearemos un “dispositivo SNMP” que realmente será nuestro sistema y añadiremos unas gráficas estándar:
● Crear dispositivo “ucd/net SNMP Host” apuntando a localhost.● Añadir graph templates:● 1) ucd/net – CPU Usage● 2) ucd/net – Load Average● 3) ucd/net – Memory Usage● 4) Unix – Logged in Users● 5) Unix – Ping Latency● 6) Unix – Processes● Añadir data queries:● 1) SNMP – Get Mounted Partitions● 2) SNMP – Get Processor Information● 3) SNMP – Interface Statistics● 4) ucd/net – Get Monitored Partitions● Añadir gráficas desde “New graphs”● Desde “Graph Management”, seleccionar las nuevas gráficas y añadirlas al al árbol (Place on a
Tree)Más información en la web de cacti.
Script Device I/O para cactiSi hemos activado el soporte I/O para dispositivos (disco duro) en el servicio SNMP, podemos hacer que cacti monitorice también esa información.Lo mejor es seguir las instrucciones del foro de cacti, pero a grandes rasgos los pasos a seguir son los siguientes:
Desde un PC cliente, descargamos el mismo fichero e importamos via web los ficheros:● ‘net-snmp_devIO-BytesRW_graphTMPL.xml’:● Cacti has imported the following items:
Pulsamos Create.A continuación, asociamos las siguientes fuentes seleccionando del desplegable la fuente que concuerde según la descripción y marcando el checkout de la derecha:
Data Source: Bytes_Read
Data Source: Bytes_Written
Volvemos a añadir una nueva gráfica al Data Query:Name: Device I/O - Reads/Writes
Graph template: ucd/net Device I/O - Reads/Writes
Asociamos las siguientes fuentes:Data Source: Device_Reads
Data Source: Device_Writes
Finalmente al Host template “ucd/net SNMP Host” asociamos la Data Query “ucd/net – Get Device I/O “. A partir de aquí, todos los nuevos hosts que se asignen la plantilla “ucd/net SNMP Host”, podran crear gráficas de lectura/escritura al disco duro.
9. Seguridad
Cortafuegos / FirewallAntes de configurar el cortafuegos, vamos a preparar el sistema ULOG que nos permitirá registrar eventos procedentes de iptables:
apt-get install ulogd ulogd-mysql
Por defecto ULOG viene configurado para que el fichero de log sea ‘/var/log/ulog/syslogemu.log’. No obstante, ULOG también nos permite almacenar la información en una MySQL. Para activarlo descomentamos de ‘/etc/ulogd.conf’:
plugin="/usr/lib/ulogd/ulogd_MYSQL.so"
Y, en el mismo fichero, configuramos el acceso a la MySQL:
[MYSQL]
table="ulog"
pass="secret"
user="ulog"
db="ulog"
host="localhost"
Finalmente, en la MySQL creamos el usuario y la BBDD con su correspondiente estructura:CREATE USER 'ulog'@'localhost' IDENTIFIED BY 'secret';
GRANT USAGE ON * . * TO 'ulog'@'localhost' IDENTIFIED BY 'secret' WITH
GRANT ALL PRIVILEGES ON `ulog` . * TO 'ulog'@'localhost';
FLUSH PRIVILEGES;
USE ulog;
source /usr/share/doc/ulogd-mysql/mysql.table;
Para conocer las bases de “iptables” podemos ver este otro artículo con más explicaciones sobre iptables, veamos un ejemplo más avanzado que en general establece las siguientes reglas:
● Por defecto denegamos todo el tráfico.● Limitamos los rangos de IP reservados para redes privadas (excepto si estamos en una de
ellas)● Bloqueamos ataques de SYN/RST flood.● Bloqueamos paquetes malformados.● Mantenemos una lista negra temporal de IPs que han intentado realizar un ataque de fuerza
bruta: han intentado realizar más de 2 conexiones en 20 segundos al puerto de SSH. Las IPs se mantienen en la lista negra durante 10 minutos.
● Dejamos el puerto SSH de entrada abierto.● De salida permitimos:
DNS SMTP + IMAP SSL SSH HTTP/HTTPS NTP de Ubuntu
● Respecto al protocolo ICMP, permitimos: Echo request hacia Internet Echo reply desde Internet Destination Unrecheable desde Internet Time exceed desde Internet
● Registramos el tráfico que no ha sido aceptado por las reglas anteriores (no obstante limitamos el número de registros por segundo para no desbordar el sistema):
Entrada Salida Redirecciones: en nuestro ejemplo no aplica.
Podemos guardar el script en ‘/usr/local/bin/firewall’:#!/bin/bash
#
# Copyright (C) 2008 http://www.marblestation.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
Creamos el script ‘/usr/local/bin/firewall-off’:#!/bin/bash
######### CONFIGURABLE #########
IPTABLES="/sbin/iptables";
####### FIN CONFIGURABLE #######
# Reset
$IPTABLES -Z
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t nat -X
$IPTABLES -t mangle -F
$IPTABLES -t mangle -X
# Politica general
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
Es importante que establezcamos unos permisos seguros a los scripts:# chmod 750 /usr/local/firewall
# chmod 750 /usr/local/firewall-off
# chown root:root /usr/local/firewall
# chown root:root /usr/local/firewall-off
A partir de estos ejemplos, probablemente será necesario adaptarlos a nuestras necesidades. Cuando cubra nuestros requerimientos, podemos hacer que se ejecute automáticamente al iniciar el sistema si lo añadimos al fichero ‘/etc/rc.local’ (antes del exit 0).
Monitorización de firewall con fwlogwatchfwlogwatch permite enviar resumenes diarios por correo o generar output en HTML sobre el estado del firewall:
# apt-get install fwlogwatch
# dpkg-reconfigure fwlogwatch
Depues del reconfigure, /etc/default/fwlogwatch quedara parecido a lo siguiente:START_DAEMON='true'
PARAMS='-A '
MODE=''
EMAIL='root@localhost'
CRON_EMAIL='root@localhost'
CRON_PARAMS='-l 1h -t -p -d -n -N -O Sapata'
# 1 day: -l 1d
# show time: -t
# show protocol: -p
# differenciate destination port: -d
# reverse dns: -n
# service (not only port): -N
# sort by destination IP (ascending), protocol (asc) and time (asc): -O Sapata
Editamos /etc/fwlogwatch/fwlogwatch.config para indicarle el log:input = /var/log/ulog/syslogemu.log
# Use 'alert_threshold' to define how many connections must happen (within
# the 'forget' time range) to activate an alert/response.
# Command line option: -a [count]
#
alert_threshold = 10
Editamos /etc/group:adm:x:4:logcheck,www-data
Para el reporte HTML, presuponemos que tenemos configurado Apache. Copiamos el CGI correspondiente:
Editamos /usr/lib/cgi-bin/fwlogsummary.cgi:# 1 day info
RECENT="-l 1d"
WEBDIR="/var/www/localhost/fwlogwatch" ...
MESSAGES="/var/log/ulog/syslogemu.log" ...
#if [ -z $1 ]
#then
MESSAGES="/var/log/ulog/syslogemu.log"
#else
# MESSAGES="$1"
#fi
Esta última parte la comento pq no me parece seguro permitir abrir un fichero del sistema indicado por parámetro.Suponiendo que en /var/www/localhost tenemos un host virtual:
Creamos el fichero /etc/apache2/conf.d/fwlogwatch.conf con el siguiente contenido:ScriptAlias /cgi-bin/fwlogsummary.cgi /usr/lib/cgi-bin/fwlogsummary.cgi
Reiniciamos apache:/etc/init.d/apache2 restart
Y accedemos a la versión web via http://localhost/cgi-bin/fwlogsummary.cgi.En caso de que queramos recibir alertas por correo en tiempo real, activaremos el demonio en el fichero /etc/default/fwlogwatch mediante START_DAEMON=’true’ y iniciaremos el servicio:
/etc/init.d/fwlogwatch restart
Detección de intrusos / IDS: SnortPodríamos instalar Snort como sistema de detección de intrusos (IDS) de nuestra red:
apt-get install snort
También disponemos de Acidbase que utiliza snort para facilitar el análisis y detección de intrusiones mediante una interfaz web:
apt-get install snort-mysql acidbase
RootkitsValidamos que el sistema no dispone de ningún rootkit instalado:
apt-get install chkrootkit rkhunter
sudo rkhunter --update
sudo rkhunter --check
sudo chkrootkit
Las desinstalo pq no me interesa que se ejecuten periodicamente:apt-get purge chkrootkit rkhunter
Control del ancho de bandaEs recomendable establecer políticas para controlar el tráfico que recibimos y enviamos, o incluso dar más prioridad a determinados paquetes (p.ej. conexiones SSH). Para ello tenemos más información en otros tutoriales como Enrutamiento avanzado y control de tráfico en Linux.Añado varios scripts de ejemplo que pueden ser de utilidad que establecen los siguientes parámetros utilizando Hierarchy Token Bucket (HTB):
● Limita la velocidad de bajada a 95 megabits● Se crea una clase raiz “1:1″ que limita la subida a 95 Megabits (para evitar la saturación del
enlace) y de la cual cuelgan 3 colas de diferentes prioridades: “1:10″ Cola de prioridad alta (ideal para tráfico interactivo como SSH). “1:20″ Cola de prioridad media (por defecto) “1:30″ Cola de prioridad baja que limita la velocidad de subida al 70% de los 95
Megabits (perfecto para hosts o servicios que no queremos que nos saturen la conexión)
Entre las 3 colas el sistema cogerá más paquetes de aquellas que tienen mayor prioridad, y dentro de las colas se utiliza un reparto uniforme entre las diferentes conexiones para que una no se haga con todo el caudal (Stochastic Fairness Queueing – SFQ).Una vez establecidas las colas, por defecto todo el tráfico va a la cola “1:20″ y podemos marcar mediante iptables aquellas que queremos que vayan a una cola diferente. Por ejemplo:
$IPTABLES -t mangle -I OUTPUT -p tcp --sport 22 -s $LAN_IP1 -m mark --mark 0 -j MARK -
-set-mark 10
En el ejemplo anterior, todo el tráfico que surjan del puerto 22 (servicio SSH) es etiquetado con la marca “10″ que hará que el paquete vaya a la cola “1:10″ (la más prioritaria).Veamos el script completo ‘/usr/local/bin/traffic-control’:
#!/bin/bash
## http://www.docum.org/docum.org/monitor/
## http://crysol.inf-cr.uclm.es/node/692
# In megabits
DOWNLINK=95
UPLINK=95
DEV=eth0
LAN_IP1="71.11.5.10"
IPTABLES="/sbin/iptables";
#LIMIT_IP1="192.168.22.3"
# Clean existing down/up-link qdiscs
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null
###### uplink
#### QDISC
# Hierarchy Token Bucket which (HBT) pointing by default to class 1:20 (HBT is the
10. Copias de seguridadCon rsnapshot podremos hacer copias de seguridad automáticas y periódicas, optimizando al máximo el espacio ocupado mediante el uso de enlaces simbólicos:
apt-get install rsnapshot
Para configurar las copias editamos /etc/rsnapshot.conf para indicar donde se guardaran los scripts:
snapshot_root /var/cache/rsnapshot/
Además, en este mismo fichero vamos a establecer nuestra política de backups: Se almacenaran las últimas 6 horas, los últimos 7 días, las últimas 4 semanas y los últimos 6 meses. Por otra parte, también indicaremos que directorios queremos copiar y que scripts ejecutar:
En este ejemplo estamos haciendo backup tanto de directorios locales (p.ej. /etc) como remotos del servidor ‘webserver’.Es importante que los parámetros de este fichero de configuración se encuentren separados por tabulaciones y no por espacios, de lo contrario rsnapshot no podrá procesarlo correctamente. Comprobamos que el archivo de configuración sea correcto:
# rsnapshot configtest
Syntax OK
Simula la creación de un snapshot:# rsnapshot -t hourly
El snapshot más reciente siempre se encontrará en el número más bajo, en el caso de los snapshots realizados cada hora: /var/cache/rsnapshot/hourly.0/Es recomendable evitar que slocate indexe el backup, editamos /etc/updatedb.conf:
Utilidades rsnapshotA la hora de hacer backup, además de especificar directorios concretos podemos hacer que se ejecuten scripts (p.ej. que realicen volcados de las BBDD) para que también se efectue una copia de su resultado (en el fichero de configuración de ejemplo anterior, se puede observar como hay varios scripts especificados).
Información de estadoA modo de ejemplo, podemos crear un script a medida /usr/local/bin/backup_info.sh que genere varios ficheros con el estado de la máquina en el momento de realizar la copia:
Editamos ‘/root/.my.cnf’ para establecer el password de root y así poder realizar volcados sin necesidad de interaccionar con la máquina:
[client]
user = root
password = secret
host = localhost
Ejecutamos:chmod 600 /root/.my.cnf
En el fichero de configuración especificaremos los scripts a ejecutar y el destino de su resultado:backup_script /usr/local/bin/backup_dpkg.sh localhost/dpkg/
Backups remotosSi queremos hacer backup de directorios remotos o incluso ejecutar scripts remotos (p.ej. volcado mysql), en el servidor donde tenemos rsnapshot debemos generar una clave SSH con ssh-keygen (ver sección correspondiente) para el usuario root (/root/.ssh/).En la máquina a la que queremos conectarnos para hacer las copias, crearemos un usuario bloqueado:
Además, permitiremos que el usuario ejecute ‘rsync’ como root mediante ‘sudo’ sin necesidad de contraseña. Para ello ejecutamos ‘visudo’ y añadimos al final:
rsnapshot ALL=NOPASSWD: /usr/bin/rsync
Para que rsnapshot funcione se conecte remotamente sin intervención, necesitamos copiar la clave pública a ‘/home/rsnapshot/.ssh/authorized_keys’ y conviene establecer todas las limitaciones posibles (ver sección SSH):
En este ejemplo, el usuario solo podrá ser utilizado desde una IP concreta, siempre que tenga la clave privada y únicamente podrá ejecutar el script ‘/home/rsnapshot/.ssh/validate-ssh.sh’:
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
*&*)
echo "Rejected" ;;
*(*)
echo "Rejected" ;;
*{*)
echo "Rejected" ;;
*;*)
echo "Rejected" ;;
*< *)
echo "Rejected" ;;
*`*)
echo "Rejected" ;;
rsync --server*)
# the calling user HAST TO BE in the sudoers list for executing rsync!
sudo $SSH_ORIGINAL_COMMAND ;;
mysqldump *)
$SSH_ORIGINAL_COMMAND ;;
/home/rsnapshot/.ssh/backup_mysql_all.sh)
/home/rsnapshot/.ssh/backup_mysql_all.sh ;;
*)
echo "Rejected $SSH_ORIGINAL_COMMAND" ;;
esac
Este script permitirá al usuario ejecutar únicamente 'rsync' (con permisos de root mediante 'sudo'), 'mysqldump' y el script '/home/rsnapshot/.ssh/backup_mysql_all.sh':
El script anterior realiza un volcado de todas las BBDD de MySQL utilizando un usuario/password determinado. Dado que contiene información sensible, el script debe tener permisos restrictivos:
chown -R rsnapshot:rsnapshot /home/rshapshot
chmod 700 /home/rshapshot/.ssh/*.sh
Con esto ya tenemos preparado todo el montaje. Rsnapshot podrá conectarse al servidor (ver fichero de configuración de ejemplo anterior, donde se definían copias del servidor ‘webserver’) sin contraseña y hacer backups de directorios y MySQL. Adicionalmente, hemos establecido controles adicionales para minimizar la posibilidad de que un atacante pueda intentar aprovecharse de la configuración (cifrado SSH, autenticación por clave asimétrica limitada a una IP y a unos comandos concretos).
Tars semanalesDe forma semanal, haremos que se cree un tar con la última copia para poder enviarlo cómodamente a otro ordenador:
rsnapreport.pl | mail -s"[rsnapshot] Weekly report" marble@localhost
11. Tests de stress
SistemaPara poner a prueba la resistencia del sistema, podemos utilizar la herramienta ‘stress’ para consumir memoria RAM, CPU o disco duro de forma masiva y forzada:
apt-get install stress
Opciones:-t, --timeout N timeout after N seconds
-c, --cpu N spawn N workers spinning on sqrt()
-i, --io N spawn N workers spinning on sync()
-m, --vm N spawn N workers spinning on malloc()/free()
--vm-bytes B malloc B bytes per vm worker (default is 256MB)
--vm-hang N sleep N secs before free (default is none, 0 is inf)
--vm-keep redirty memory instead of freeing and reallocating
-d, --hdd N spawn N workers spinning on write()/unlink()
--hdd-bytes B write B bytes per hdd worker (default is 1GB)
--hdd-noclean do not unlink files created by hdd workers
Ejemplo de consumo de memoria y CPU:$ stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --vm-keep --timeout 10s
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
Session rate [sess/s]: min 0.00 avg 0.33 max 1.00 stddev 0.39 (10/10)
Session: avg 5.00 connections/session
Session lifetime [s]: 20.9
Session failtime [s]: 0.0
Session length histogram: 0 0 0 0 0 10
Conexiones HTTP con Apache Benchmarking toolOtra herramienta para testear la capacidad de un servicio web:
apt-get install apache2-utils
Por ejemplo, enviar 1000 request mediante 5 procesos concurrentes:$ ab -n 1000 -c 5 http://localhost/
Benchmarking localhost (be patient)
Server Software: Apache
Server Hostname: localhost
Server Port: 80
Document Path: /
Document Length: 612 bytes
Concurrency Level: 5
Time taken for tests: 0.382452 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 852852 bytes
HTML transferred: 612612 bytes
Requests per second: 2614.71 [#/sec] (mean)
Time per request: 1.912 [ms] (mean)
Time per request: 0.382 [ms] (mean, across all concurrent requests)
Transfer rate: 2175.44 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 0 1 8.6 0 98
Waiting: 0 0 0.3 0 1
Total: 0 1 8.6 0 98
Percentage of the requests served within a certain time (ms)
50% 0
66% 1
75% 1
80% 1
90% 1
95% 1
98% 1
99% 74
100% 98 (longest request)
Resulta interesante hacer la prueba con URLs que hagan diferentes tipos de procesado:● Páginas estáticas● Páginas dinámicas PHP● CGIs
Si consultamos el manual (man ab), es posible indicar a ab que utilice cookies (-C cookie-name=value) o HTTP authentication (-P proxy-auth-username:password).Otro ejemplo para realizar conexiones con HTTP KeepAlive, se abriran 10 conexiones y durante 30 segundos se utilizaran para enviar peticiones al servidor:
# ab -kc 10 -t 30 http://localhost/
Benchmarking localhost (be patient)
Server Software: Apache
Server Hostname: localhost
Server Port: 80
Document Path: /
Document Length: 612 bytes
Concurrency Level: 10
Time taken for tests: 5.824757 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 49511
Total transferred: 44432403 bytes
HTML transferred: 30603060 bytes
Requests per second: 8584.05 [#/sec] (mean)
Time per request: 1.165 [ms] (mean)
Time per request: 0.116 [ms] (mean, across all concurrent requests)
Transfer rate: 7449.41 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 0 0 2.6 0 127
Waiting: 0 0 2.6 0 127
Total: 0 0 2.6 0 127
Percentage of the requests served within a certain time (ms)
50% 0
66% 1
75% 1
80% 1
90% 2
95% 2
98% 4
99% 4
100% 127 (longest request)
12. Issue trackingLa gestión de incidencias o las solicitudes de alta/baja/modificación del sistema puede ser efectuada mediante trac.