Securización de un sistema Ubuntu...

58
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)

Transcript of Securización de un sistema Ubuntu...

Page 1: 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

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)

Page 2: 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

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

Page 3: 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

● 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):

sysctl -w net.ipv4.ip_forward=0

sysctl -w net.ipv6.ip_forward=0

- Ignorar Broadcasts Request:sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1

- 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:

sysctl -w net.ipv4.conf.all.accept_source_route=0

- Logear paquetes: Spoofed Packets, Source Routed Packets, Redirect Packetssysctl -w net.ipv4.conf.all.log_martians=1

- 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

sysctl net.ipv4.conf.all.rp_filter

sysctl net.ipv4.tcp_syncookies

sysctl net.ipv4.ip_forward

sysctl net.ipv6.ip_forward

Page 4: 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

sysctl net.ipv4.icmp_echo_ignore_broadcasts

sysctl net.ipv4.icmp_ignore_bogus_error_responses

sysctl net.ipv4.conf.all.accept_redirects

sysctl net.ipv4.conf.all.send_redirects

sysctl net.ipv4.conf.all.accept_source_route

sysctl net.ipv4.conf.all.log_martians

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:

/dev/sda4 / ext4 defaults,errors=remount-

ro,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0 1 1

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:

Page 5: 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

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

----------------------------------------------------------------------

root -- 63404 0 0 18960 0 0

usuario1 -- 457G 0 0 303k 0 0

usuario2 +- 10072M 5120M 5120M 6días 8780 0 0

ftp -- 4 0 0 1 0 0

freevo -- 44 0 0 18 0 0

mythtv -- 48 0 0 15 0 0

couchdb -- 132 0 0 33 0 0

Un usuario puede consultar el estado de su cuota:$ quota -s

Disk quotas for user usuario (uid 1000):

Filesystem blocks quota limit grace files quota limit grace

/dev/vzfs 24 26 28 6 0 0

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

Page 6: 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

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.

Page 7: 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

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:

***************************************************************************

NOTICE TO USERS

This computer system is for authorized use only. Use of this system

constitutes consent to security monitoring and testing. All activity is

logged with your host name and IP address.

Any or all uses of this system and all files on this system may be

intercepted, monitored, recorded, copied, audited, inspected, and disclosed

to law enforcement personnel, as well as authorized officials of other

agencies, both domestic and foreign.

Unauthorized or improper use of this system may result in administrative

disciplinary action and civil and criminal penalties. By continuing to use

this system you indicate your awareness of and consent to these terms and

conditions of use. LOG OFF IMMEDIATELY if you do not agree to the conditions

stated in this warning.

*****************************************************************************

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:

# Update motd

#uname -snrvm > /var/run/motd

[ -f /etc/motd.tail ] && cat /etc/motd.tail >> /var/run/motd

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

Page 8: 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

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:

# ls -la /bin/ping

-rwsr-xr-x 1 root root 30856 2007-12-10 18:33 /bin/ping

Ping tiene activado el bit SUID y su propietario es root, por tanto cuando sea ejecutado

Page 9: 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

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:

find / -path /proc -prune -o -type f -perm +6000 -ls

Solo SUID:find / -path /proc -prune -o -type f -perm +2000 -ls

Solo GUID:find / -path /proc -prune -o -type f -perm +4000 -ls

Una vez identificados, podemos proceder a seleccionar cuales queremos dejar con el bit SUID o SGID activado.Para activar/desactivar SUID:

chmod u+s fichero

chmod u-s fichero

Y para activar/desactivar SGID:chmod g+s fichero

chmod g-s fichero

Directorios con permisos de escritura globalPara identificar directorios con permisos de escritura global ejecutaremos:

find / -path /proc -prune -o -perm -2 ! -type l -ls

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:

$ mkdir test

$ chmod 777 test

$ sudo chown -R root:root test

$ cd test

$ touch hola

$ ls -la

total 8

drwxrwxrwx 2 root root 4096 2008-08-22 13:56 .

drwxr-x--- 126 root root 4096 2008-08-22 13:55 ..

-rw-r--r-- 1 user01 group1 0 2008-08-22 13:56 hola

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’:

$ ls -lad /tmp/

drwxrwxrwt 13 root root 49152 2008-08-22 13:54 /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

Page 10: 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

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

dcredit=1 ocredit=2

password requisite pam_unix.so use_authtok obscure md5 remember=12

En este ejemplo hemos hecho que:● El usuario tiene que repetir 3 veces la nueva contraseña para realizar el cambio.

Page 11: 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

● 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:

$ opiekey -n 10 499 vp5957

490: WARD PIE ROSE SKY SKI SHAY

491: I MITE VET AN IQ DENY

Page 12: 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

492: BED BIEN TWIN WACK GELD SENT

493: NECK MASH FLIT RICE GALE BY

494: FLUB GET NOB MOOD TUM CITE

495: WOO SNOB THEY SARA JILT GUSH

496: VALE HOWE GAIT EEL HUED ODE

497: I WON FOOL TOAD FEE HOFF

498: FULL SOWN EGAN RICH WEAN HUGE

499: CAB TILE YOU NINA BRED ELLA

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

attempt

auth required pam_tally.so onerr=succeed deny=3 unlock_time=30 per_user

auth sufficient pam_unix.so

auth sufficient pam_opie.so

auth required pam_deny.so

# Reset user lock if auth suceeds

account required pam_tally.so onerr=succeed

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

faillog -u miusuario -r

Page 13: 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

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:

useradd -d /home/miusuario -m -G admin,users -K

PASS_MAX_DAYS=60,PASS_MIN_DAYS=1,PASS_WARN_AGE=15,UMASK=0022 -s /bin/bash miusuario

passwd miusuario

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’:

usuario:$1$ZyihUAz0$RqBWU1OINGOsUILv3g2Kh/:14111:0:99999:7:::

Veamos diversas acciones de utilidad….● Expira la contraseña de un usuario para obligarle a cambiarla:● passwd -e usuario

● Establece el 3er campo de /etc/shadow a 0:● usuario:$1$ZyihUAz0$RqBWU1OINGOsUILv3g2Kh/:0:0:99999:7:::

● Bloquea o desbloquea (recuperando password anterior) un usuario:● passwd -l usuario

● Añade una exclamación delante del hash de la contraseña en /etc/shadow y en el octavo campo añade un 1 (cuenta caducada el 2 de Enero de 1970):

● usuario:!$1$ZyihUAz0$RqBWU1OINGOsUILv3g2Kh/:14111:0:99999:7::1:

● Para deshacer los cambios:● passwd -u usuario

● 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:

● passwd -l -d root

● Quedando algo parecido a:● root:!:13449:0:99999:7::1:

En resumen, campos del /etc/shadow:[username]:[password]:[date]:PASS_MIN_DAYS:PASS_MAX_DAYS:PASS_WARN_AGE:INACTIVE:EXPIRE

:

Page 14: 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

Según el manual: · login name

· encrypted password

· 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/

Page 15: 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

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):

apt-get purge sendmail sendmail-base sendmail-bin sendmail-cf sendmail-doc

apt-get install procmail

apt-get install postfix

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’:

#smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)

smtpd_banner = Welcome

biff = no

# 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’:

:0 c

/var/mail/miusuario

# Copia del correo personal a gmail :0 [email protected]

Para realizar configuraciones más complejas de Postfix podemos consultar esta otra guía.

Servicio web: Apache

Page 16: 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

Una vez instalado apache (habitualmente con soporte PHP), podemos proceder a realizar una securización de su configuración.

PHPEn primer lugar, nos aseguramos que PHP no informe de su presencia editando ‘/etc/php5/apache2/php.ini’ y modificando:

; Misc ; ; Decides whether PHP may expose the fact that it is installed on the

server ; (e.g. by adding its signature to the Web server header). It is no security ;

threat in any way, but it makes it possible to determine whether you use PHP ; on your

server or not.

expose_php = On

por:expose_php = Off

Por otra parte, también se recomienda establecer límites a los recursos que puede utilizar una web PHP:

;;;;;;;;;;;;;;;;;;; ; Resource Limits ; ;;;;;;;;;;;;;;;;;;;

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

Page 17: 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

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

Page 18: 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

● 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:

ssh -L 8080:localhost:80 miusuario@IP_DEL_SERVIDOR

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’:

NameVirtualHost 127.0.0.1:80

Page 19: 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

<VirtualHost 127.0.0.1:80>

ServerAdmin [email protected]

ServerName localhost

ServerAlias localhost.localdomain

DocumentRoot /var/www/localhost

<Directory /var/www/localhost>

AllowOverride All

Options FollowSymLinks

Order allow,deny

allow from all

</Directory>

# Possible values include: debug, info, notice, warn, error, crit,

# alert, emerg.

LogLevel warn

ErrorLog /var/log/apache2/localhost/error.log

CustomLog /var/log/apache2/localhost/access.log combined

ServerSignature Off

Include /etc/apache2/conf.d/

</VirtualHost>

Activamos el site:mkdir /var/www/localhost

mkdir /var/log/apache2/localhost

a2ensite localhost

/etc/init.d/apache2 restart

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.

Page 20: 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

/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

MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0

MAX_USER_CONNECTIONS 0 ;

CREATE DATABASE IF NOT EXISTS miusuario;

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.

The key fingerprint is:

18:0f:fe:29:b2:17:c2:a0:8d:6e:11:80:de:01:21:be user@localhost

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:

scp ~/.ssh/id_rsa.pub usuario@servidor:/home/user/

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-

agent-forwarding,no-pty ssh-rsa AAAABdZjH4WE5y5EH/

O9nHoplj8sZz0iIb1XPU5e5ZTxd7tWhMf9p391yAfM6ybjabmFXZZuFm9q/

Page 21: 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

AjD53qjX+q7YhQUXC0I5JhFU0CAHxKuvuguogWio39x36Ag/zgJ5IJXcrCNsuoDw== [email protected]

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:

Enter passphrase for /home/user/.ssh/id_rsa:

Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)

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

Page 22: 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

zona horaria que nos interese (p.ej. Europa/Madrid):# date

Wed Aug 6 07:14:36 EDT 2008

# cd /etc

# mv timezone timezone.old

# echo "Europe/Madrid" > timezone

# mv localtime localtime.old

# ln -s /usr/share/zoneinfo/Europe/Madrid localtime

# date

Wed Aug 6 13:16:08 CEST 2008

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

Page 23: 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

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:

logs=$(syslogd-listfiles --weekly)

por:logs=$(syslogd-listfiles --all)

También modificaremos:savelog -g adm -m 640 -u ${USER} -c 4 $LOG >/dev/null

por: # Rotate monthly (script placed at /etc/cron.monthly/)

# Keep 24 copies: -c 24

# Clean older copies than 24: -C

# Add date instead of .0 .1: -d

# Create a new file owned by adm and syslog with permission 640

savelog -g adm -m 640 -u ${USER} -c 24 -d -C $LOG >/dev/null

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

Page 24: 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

# 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:

apt-get install awstats

mkdir /var/lib/awstats/localhost

chown www-data:www-data /var/lib/awstats/localhost

Creamos ‘/etc/awstats/awstats.localhost.conf’ apuntando al log que queramos analizar:LogFile="/var/log/apache2/localhost/access.log"

LogFormat=1

DNSLookup=1

DirData="/var/lib/awstats/localhost"

DirCgi="/cgi-bin"

DirIcons="/icon"

SiteDomain="localhost"

AllowToUpdateStatsFromBrowser=1

Page 25: 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

AllowFullYearView=3

Copiamos iconos básicos:cp -r /usr/share/awstats/icon /var/www/localhost/

Actualizamos output HTML:/usr/lib/cgi-bin/awstats.pl -config=localhost -update

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):

0 1 * * * www-data /usr/lib/cgi-bin/awstats.pl -config=localhost -update >/dev/null

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!

# Should be set to an offsite "[email protected]"

SENDMAILTO="miusuario"

# Send the results as attachment or not.

# 0=not as attachment; 1=as attachment

# Default ist 0

MAILASATTACH=1

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:]-]+ kernel: [FW:[ ._[:alnum:]-]+]

^w{3} [ :0-9]{11} [._[:alnum:]-]+ nagios2: CURRENT SERVICE STATE:

Page 26: 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

^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

Page 27: 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

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:

echo "Prueba" | mail -s "Prueba" [email protected]

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:

EMAIL="[email protected]"

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

Page 28: 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

# 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

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----

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

Page 29: 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

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.

# apt-get install nagios2 nagios-images nagios-plugins

Configuramos un usuario para nagios:# sudo htpasswd -c /etc/nagios2/htpasswd.users nagiosadmin

New password:

Re-type new password:

Adding password for user nagiosadmin

Preparamos el sistema:# chown nagios:nagios /var/log/nagios2/

# chown -R nagios:www-data /var/cache/nagios2/

# cd /bin/

# ln -s /usr/bin/mail mail

Page 30: 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

Creamos nuestra configuración específica:mkdir /etc/nagios2/mysite

cd /etc/nagios2/mysite

cp

cp ../conf.d/contacts_nagios2.cfg contacts.cfg

cp ../conf.d/timeperiods_nagios2.cfg timeperiods.cfg

cp ../conf.d/localhost_nagios2.cfg localhost.cfg

cp ../conf.d/generic-service_nagios2.cfg generic-service.cfg

cp ../conf.d/generic-host_nagios2.cfg generic-host.cfg

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.

# apt-get install snmpd snmp

Page 31: 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

Nos aseguramos que solo sea accesible por localhost /etc/default/snmpd y desactivamos los módulos smux, ipv6 :

# snmpd options (use syslog, close stdin/out/err).

# Log by Syslog only: warning messages, errors, alerts and critical.

# ingore: notice info and debug

SNMPDOPTS='-Ls 01234 -Lf /dev/null -A -u snmp -I -smux,ipv6 -p /var/run/snmpd.pid

127.0.0.1'

En la configuración ‘/etc/snmp/snmpd.conf’ indicamos::## sec.name source community

## ======== ====== =========

#com2sec local localhost public

#com2sec network_1 172.16.1.0/24 public

#com2sec network_2 192.168.2.0/24 public

## Access.group.name sec.model sec.name

## ================= ========= ========

#group MyROGroup_1 v1 local

#group MyROGroup_1 v1 network_1

#group MyROGroup_2 v2c network_2

## MIB.view.name incl/excl MIB.subtree mask

## ============== ========= =========== ====

#view all-mibs included .1 80

## MIB

## group.name context sec.model sec.level prefix read write notif

## ========== ======= ========= ========= ====== ==== ===== =====

#access MyROGroup_1 "" v1 noauth exact all-mibs none none

#access MyROGroup_2 "" v2c noauth exact all-mibs none none

#

rocommunity public

syslocation NewYork

syscontact admin@localhost

#ignoredisk /dev/rdsk/c0t2d0

disk /

#disk /usr

#disk /var

proc apache2

proc mysqld

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

snmpwalk -v 1 -c public localhost system|less

snmpget -v 1 -c const1payted localhost ifPhysAddress.2

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,

Page 32: 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

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:

pass .1.3.6.1.4.1.2021.13.15 /usr/local/bin/snmp-diskio-collector

Creamos el script /usr/local/bin/snmp-diskio-collector:#!/bin/sh

# by Jamie Wilkinson jamie @anchor.net.au

# this code is in the public domain

# based on passtest from the net-snmp distribution examples

# WARNING there is shitloads of IO required to get this information

debug_flag=0

debug () {

if [ $debug_flag -eq 1 ]; then

echo $* >> /tmp/snmp-diskio-collector-debug.log

fi }

PLACE=".1.3.6.1.4.1.2021.13.15"

REQ="$2"

debug

debug "new run"

debug "args $*"

if [ "$1" = "-s" ]; then

exit 0

fi

# the 'tail' of the oid, everything after $PLACE

oidtail=`echo $REQ | sed "s/^$PLACE//"`

debug "oidtail=$oidtail"

# number of devices we can export

devcount=`wc -l /proc/diskstats | cut -f1 -d' '`

debug "devcount=$devcount"

item=`echo $oidtail | cut -f4 -d.`

index=`echo $oidtail | cut -f5 -d.`

debug "oidtail=$oidtail, item=$item, index=$index"

if [ "$1" = "-n" ]; then

if [ -z "$item" ]; then

item=1

index=1

elif [ -z "$index" ]; then

index=1

else

index=`expr $index + 1`

if [ "$index" -gt "$devcount" ]; then

index=1

item=`expr $item + 1`

if [ "$item" -gt 6 ]; then

# break out of the loop

exit 0;

fi

fi

fi

RET=$PLACE.1.1.$item.$index

else

case "$REQ" in

$PLACE) exit 0;;

Page 33: 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

*) RET=$REQ ;;

esac

fi

debug "after -n, item=$item, index=$index"

debug "RET is now $RET"

echo "$RET"

debug "oidtail=$oidtail, item=$item, index=$index"

# awk uses this variable in the environment below

export index

# see linux kernel Documentation/iostats.txt for format

if [ -n "$index" ]; then

case "$item" in

1)

# diskIOIndex

debug "result: diskIOIndex $index"

echo "integer"

echo $index

exit 0

;;

2)

# diskIODevice

debug "result: diskIODevice $index"

echo "string"

awk 'FNR == ENVIRON["index"] { print $3 }' /proc/diskstats

exit 0

;;

3)

# diskIONRead

debug "result: diskIONRead $index"

echo "counter"

awk 'FNR == ENVIRON["index"] { print $6 }' /proc/diskstats

exit 0

;;

4)

# diskIONWritten

debug "result: diskIONWritten $index"

echo "counter"

awk 'FNR == ENVIRON["index"] { print $10 }' /proc/diskstats

exit 0

;;

5)

# diskIOReads

debug "result: diskIOReads $index"

echo "counter"

awk 'FNR == ENVIRON["index"] { print $4 }' /proc/diskstats

exit 0

;;

6)

# diskIOWrites

debug "result: diskIOWrites $index"

echo "counter"

awk 'FNR == ENVIRON["index"] { print $8 }' /proc/diskstats

exit 0

;;

*) exit 0; #echo "string"; echo "debug... $RET $REQ"; exit 0 ;;

esac

else

exit 0

Page 34: 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

fi

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:

# cd /usr/share/cacti/resource/snmp_queries/

# wget http://forums.cacti.net/download.php?id=2635

# mv download.php?id=2635 Cacti_Net-SNMP_DevIO_v2.zip

# unzip Cacti_Net-SNMP_DevIO_v2.zip

# rm -f *TMPL.xml Cacti_Net-SNMP_DevIO_v2.zip

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:

GPRINT Preset

[success] Normal [update]

Data Input Method

[success] Get SNMP Data (Indexed) [update]

Page 35: 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

Data Template

[success] ucd/net - Device I/O [new]

Graph Template

[success] ucd/net - Device I/O - Bytes Read/Written [new]

Page 36: 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

● ‘net-snmp_devIO-ReadsWrites_graphTMPL.xml’● Cacti has imported the following items:

GPRINT Preset

[success] Exact Numbers [update]

Data Input Method

[success] Get SNMP Data (Indexed) [update]

Data Template

[success] ucd/net - Device I/O [update]

Graph Template

[success] ucd/net - Device I/O - Reads/Writes [new]

● ‘net-snmp_devIO-LoadAVG_graphTMPL’: solo es compatible con sistemas BSD. No lo cargamos en Linux.

Creamos el Data Query mediante “Data Queries – Add”:Name: ucd/net - Get Device I/O

Description:

XML Path: <path_cacti>/resource/snmp_queries/net-snmp_devio.xml

Data Input Method: Get SNMP Data (indexed)

Pulsamos “Create”.Ahora es el momento de añadir las gráficas asociadas. En el recuadro associate graph, pulsamos sobre Add y rellenamos el formulario:

Name: Device I/O - Bytes Read/Written

Graph template: ucd/net Device I/O - Bytes Read/Written

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:

Page 37: 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

[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

MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0

MAX_USER_CONNECTIONS 0 ;

CREATE DATABASE IF NOT EXISTS `ulog` ;

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

# (at your option) any later version.

#

Page 38: 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 program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

# GNU General Public License for more details.

#

# You should have received a copy of the GNU General Public License

# along with this program; if not, write to the Free Software

# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#

######### CONFIGURABLE #########

IPTABLES="/sbin/iptables";

ECHO="/bin/echo";

#LAN_INTERFACE_GETIP="eth0:0"

LAN_INTERFACE="eth0"

LOOPBACK_INTERFACE="lo"

#LAN_IP1="71.11.10.19"

LAN_IP1=`ifconfig $LAN_INTERFACE|grep inet|grep -v inet6|cut -d " " -f 12|cut -d ":" -

f 2`

LAN_IP2=""

LAN_IP3=""

DNS_IP="213.186.33.99" # NS1 NS2 of ISP

#BROADCAST_IP1=71.11.10.255"

BROADCAST_IP1=`ifconfig $LAN_INTERFACE|grep inet|grep -v inet6|cut -d " " -f 14|cut -

d ":" -f 2`

#LAN_NET=$LAN_IP/`ifconfig $LAN_INTERFACE|grep inet|grep -v inet6|cut -d " " -f 16|cut

-d ":" -f 2`

BANNED_IPs=""

NTP_UBUNTU="91.189.94.4"

####### FIN CONFIGURABLE #######

##

# Required kernel modules: nf_conntrack, nf_nat, nf_nat_ftp, nf_conntrack_ftp

#

# * Non-standard ports:

# modprobe ip_conntrack_ftp ports=21,2121

# modprobe ip_nat_ftp ports=21,2121

#

# Current tracked connections:

# cat /proc/net/ip_conntrack | wc -l

#

# Max allowed tracked connections:

# sysctl -a net.ipv4.netfilter.ip_conntrack_max

#

# Possible modifications to /etc/sysctl.conf:

#

## Time limit to consider a connection active: 432000 seconds (432000 / (60*60*24) = 8

days)

# net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 28800

#

## Max tracked connections (65536 connections * 350 bytes per connection) / (1024 *

1024) = 21,87 MBytes

# net.ipv4.netfilter.ip_conntrack_max = 65536

#

## Time limit to close a connection (60 seconds)

# net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60

Page 39: 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

#

# Reload sysctl: sysctl -p

##

# Reset tablas de filtrado

$IPTABLES -t filter -Z

$IPTABLES -t filter -F

$IPTABLES -t filter -X

# Reset tablas de nuevas conexiones

$IPTABLES -t nat -Z

$IPTABLES -t nat -F

$IPTABLES -t nat -X

# Reset tablas de modificación de paquetes

$IPTABLES -t mangle -Z

$IPTABLES -t mangle -F

$IPTABLES -t mangle -X

echo "[start] Default policy"

# Politica general de tráfico entrante/saliente y redirigido

$IPTABLES -t filter -P INPUT DROP

$IPTABLES -t filter -P OUTPUT DROP

$IPTABLES -t filter -P FORWARD DROP

# Politica de las cadenas extendidas (donde se pueden realizar alteraciones de

paquetes)

$IPTABLES -t mangle -P INPUT ACCEPT

$IPTABLES -t mangle -P OUTPUT ACCEPT

$IPTABLES -t mangle -P PREROUTING ACCEPT

$IPTABLES -t mangle -P POSTROUTING ACCEPT

# Paquetes que crean nuevas conexiones y deben ser alterados por NAT

$IPTABLES -t nat -P OUTPUT ACCEPT

$IPTABLES -t nat -P PREROUTING ACCEPT

$IPTABLES -t nat -P POSTROUTING ACCEPT

echo "[end] Default policy"

echo "[start] Local users control"

#--uid-owner {USERNAME} : Matches if the packet was created by a process with the

given effective USERNAME.

#--gid-owner {groupid}: Matches if the packet was created by a process with the given

effective group id.

#--pid-owner {processed}: Matches if the packet was created by a process with the

given process id.

# Allow any TCP connection originated by myuser

#$IPTABLES -A OUTPUT -o $LAN_INTERFACE -p tcp --sport 1024:65535 --dport 1:65535 -m

state --state NEW,ESTABLISHED -m owner --uid-owner myuser -j ACCEPT

#$IPTABLES -A INPUT -i $LAN_INTERFACE -p tcp --sport 1:65535 --dport 1024:65535 -m

state --state RELATED,ESTABLISHED -j ACCEPT

echo "[end] Local users control"

echo "[start] Loopback"

# Permitir trafico a la interfaz loopback

$IPTABLES -A INPUT -i $LOOPBACK_INTERFACE -s 127.0.0.1 -j ACCEPT

$IPTABLES -A OUTPUT -o $LOOPBACK_INTERFACE -d 127.0.0.1 -j ACCEPT

# Permitir trafico a la interfaz loopback con IPs internas

SPACE=" "

INTERNAL_IPs=$LAN_IP1$SPACE$LAN_IP2$SPACE$LAN_IP3

for internal_ip in $INTERNAL_IPs

Page 40: 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

do

$IPTABLES -A INPUT -i $LOOPBACK_INTERFACE -s $internal_ip -j ACCEPT

$IPTABLES -A OUTPUT -o $LOOPBACK_INTERFACE -d $internal_ip -j ACCEPT

done

echo "[end] Loopback"

echo "[start] Banned IPs"

##################### IPs Baneadas

for banned_ip in $BANNED_IPs

do

$IPTABLES -A INPUT -s $banned_ip -j DROP

$IPTABLES -A OUTPUT -s $banned_ip -j DROP

$IPTABLES -A FORWARD -s $banned_ip -j DROP

done

##################### Fin IPs Baneadas

echo "[end] Banned IPs"

echo "[start] Reserved IPs blocks"

##################### Prevent spoofing

# New chain

$IPTABLES -N reserved_blocks

$IPTABLES -F reserved_blocks

# Redirect all traffic to new chain

$IPTABLES -A INPUT -j reserved_blocks

$IPTABLES -A OUTPUT -j reserved_blocks

### [start] private networks

# 10.0.0.0/8 Private network RFC 1918

$IPTABLES -A reserved_blocks -s 10.0.0.0/8 -j DROP

$IPTABLES -A reserved_blocks -d 10.0.0.0/8 -j DROP

# 172.16.0.0/12 Private network RFC 1918

$IPTABLES -A reserved_blocks -s 172.16.0.0/12 -j DROP

$IPTABLES -A reserved_blocks -d 172.16.0.0/12 -j DROP

# 169.254.0.0/16 Link-Local RFC 3927

$IPTABLES -A reserved_blocks -s 169.254.0.0/16 -j DROP

$IPTABLES -A reserved_blocks -d 169.254.0.0/16 -j DROP

# 192.168.0.0/16 Private network RFC 1918

# !! Limited to LAN_INTERFACE, because in other interface we have 192.168.0.0 networks

#$IPTABLES -A reserved_blocks -i $LAN_INTERFACE -s 192.168.0.0/16 -j DROP

#$IPTABLES -A reserved_blocks -o $LAN_INTERFACE -d 192.168.0.0/16 -j DROP

### [end] private networks

### [start] Other reserved blocks

# 0.0.0.0/8 Current network (only valid as source address) RFC 1700

$IPTABLES -A reserved_blocks -s 0.0.0.0/8 -j DROP

$IPTABLES -A reserved_blocks -d 0.0.0.0/8 -j DROP

# 14.0.0.0/8 Public data networks (per 2008-02-10, available for use[1]) RFC 1700

# Addresses within this block are assigned to users and should be treated as such

# Do not drop

# 127.0.0.0/8 Loopback RFC 3330

$IPTABLES -A reserved_blocks -s 127.0.0.0/8 -j DROP

$IPTABLES -A reserved_blocks -d 127.0.0.0/8 -j DROP

# 128.0.0.0/16 Reserved (IANA) RFC 3330

# Addresses in this block are subject to future allocation to a Regional Internet

# Registry for assignment in the normal manner.

## Do not drop

Page 41: 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

# 191.255.0.0/16 Reserved (IANA) RFC 3330

# Addresses in this block are subject to future allocation to a Regional Internet

# Registry for assignment in the normal manner.

## Do not drop

# 192.0.2.0/24 Documentation and example code RFC 3330 (Test-Net [RFC3330])

$IPTABLES -A reserved_blocks -s 192.0.2.0/24 -j DROP

$IPTABLES -A reserved_blocks -d 192.0.2.0/24 -j DROP

# 192.88.99.0/24 IPv6 to IPv4 relay RFC 3068

$IPTABLES -A reserved_blocks -s 192.88.99.0/24 -j DROP

$IPTABLES -A reserved_blocks -d 192.88.99.0/24 -j DROP

# 198.18.0.0/15 Network benchmark tests RFC 2544

$IPTABLES -A reserved_blocks -s 198.18.0.0/15 -j DROP

$IPTABLES -A reserved_blocks -d 198.18.0.0/15 -j DROP

# 223.255.255.0/24 Reserved (IANA) RFC 3330

$IPTABLES -A reserved_blocks -s 223.255.255.0/24 -j DROP

$IPTABLES -A reserved_blocks -d 223.255.255.0/24 -j DROP

# 224.0.0.0/3 includes:

# - Reserved for Multicast (former Class D network) RFC 3171 (224.0.0.0/4): From 224/

8 to 239/8

# - Reserved for Future use (former Class E network) RFC 1700 (240.0.0.0/4): From

240/8 to 255/8

# - Broadcast: 255.255.255.255

$IPTABLES -A reserved_blocks -s 224.0.0.0/3 -j DROP

$IPTABLES -A reserved_blocks -d 224.0.0.0/3 -j DROP

### [end] Other reserved blocks

##################### Fin Direcciones privadas

echo "[end] Reserved IPs blocks"

echo "[start] Attack protection"

##################### Ataques

echo "* SYN/RST flood"

# Stop flood

# New chain

$IPTABLES -N flood

$IPTABLES -F flood

# Redirect all eth0 traffic to new chain

$IPTABLES -A INPUT -i $LAN_INTERFACE -p tcp --syn -j flood

$IPTABLES -A OUTPUT -o $LAN_INTERFACE -p tcp --syn -j flood

$IPTABLES -A FORWARD -i $LAN_INTERFACE -p tcp --syn -j flood

# Chain rules

# Drop excessive RST packets to avoid TCP reset attacks, by given the

# next real data packet in the sequence a better chance to arrive first.

$IPTABLES -A flood -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-

burst 2 -j ACCEPT

# Protect against SYN floods by rate limiting the number of new

# connections from any host to 5 per second.

$IPTABLES -A flood -m state --state NEW -p tcp -m tcp --syn -m recent --name synflood -

-set

$IPTABLES -A flood -m state --state NEW -p tcp -m tcp --syn -m recent --name synflood -

-update --seconds 1 --hitcount 5 -m limit --limit 30/s --limit-burst 3 -j ULOG --ulog-

nlgroup 1 --ulog-prefix "[FW:SYN Packets flood] "

Page 42: 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

$IPTABLES -A flood -m state --state NEW -p tcp -m tcp --syn -m recent --name synflood -

-update --seconds 1 --hitcount 5 -j DROP

echo "* Malformed packets"

# Create new chain

$IPTABLES -N malformed_packets

$IPTABLES -F malformed_packets

# Redirect all traffic to new chain

$IPTABLES -A INPUT -j malformed_packets

$IPTABLES -A OUTPUT -j malformed_packets

$IPTABLES -A FORWARD -j malformed_packets

# Log & Drop all incoming fragments

$IPTABLES -A malformed_packets -f -m limit --limit 30/s --limit-burst 3 -j ULOG --ulog-

nlgroup 1 --ulog-prefix "[FW:Fragments Packets] "

$IPTABLES -A malformed_packets -f -j DROP

# Log & Drop new connections with SYN flag not set

#$IPTABLES -A malformed_packets -p tcp ! --syn -m state --state NEW -m limit --limit

30/s --limit-burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:New without SYN] "

$IPTABLES -A malformed_packets -p tcp ! --syn -m state --state NEW -j DROP

# Log & Drop all incoming malformed NULL packets (Block null scans)

$IPTABLES -A malformed_packets -p tcp --tcp-flags ALL NONE -m limit --limit 30/s --

limit-burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:NULL Packets] "

$IPTABLES -A malformed_packets -p tcp --tcp-flags ALL NONE -j DROP # NULL packets

# Drop all incoming malformed XMAS packets (Block xmas scans)

$IPTABLES -A malformed_packets -p tcp --tcp-flags ALL ALL -m limit --limit 30/s --

limit-burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:XMAS Packets] "

$IPTABLES -A malformed_packets -p tcp --tcp-flags ALL ALL -j DROP #XMAS

# Drop all incoming malformed FIN packets (Block FIN scans)

$IPTABLES -A malformed_packets -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 30/s --

limit-burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:Fin Packets Scan] "

$IPTABLES -A malformed_packets -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet

scans

# Drop bogus TCP packets

$IPTABLES -A malformed_packets -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -m limit --

limit 30/s --limit-burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:Bogus Packets] "

$IPTABLES -A malformed_packets -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

$IPTABLES -A malformed_packets -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -m limit --

limit 30/s --limit-burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:Bogus Packets] "

$IPTABLES -A malformed_packets -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP

# Log & Drop all incoming invalid packets

#$IPTABLES -A malformed_packets -m state --state INVALID -m limit --limit 30/s --limit-

burst 3 -j ULOG --ulog-nlgroup 1 --ulog-prefix "[FW:Invalid Packets] "

$IPTABLES -A malformed_packets -m state --state INVALID -j DROP

echo " - Bruce force attack prevention"

##### [start] Prevent Brute force attack

$IPTABLES -N brute_force

$IPTABLES -N brute_force_blacklist

$IPTABLES -A brute_force_blacklist -m limit --limit 30/s --limit-burst 3 -j ULOG --

ulog-nlgroup 1 --ulog-prefix "[FW:Bruteforce] "

$IPTABLES -A brute_force_blacklist -m recent --name brute_force_blacklist --set

$IPTABLES -A brute_force_blacklist -j DROP

# Incoming connections from blacklisted hosts are dropped for 10 minutes (every droped

Page 43: 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

connection, restarts the 10 minutes period).

$IPTABLES -A brute_force -m recent --update --name brute_force_blacklist --seconds

600 --hitcount 1 -j DROP

# These rules are just for counting of incoming connections.

$IPTABLES -A brute_force -m recent --set --name counting1

$IPTABLES -A brute_force -m recent --set --name counting2

$IPTABLES -A brute_force -m recent --set --name counting3

$IPTABLES -A brute_force -m recent --set --name counting4

# A host is blacklisted if it exceeds:

# - 2 connection attempts in 20 seconds

# - 14 in 200 seconds

# - 79 in 2000 seconds

# - 399 attempts in 20000 seconds.

$IPTABLES -A brute_force -m recent --update --name counting1 --seconds 20 --

hitcount 3 -j brute_force_blacklist

$IPTABLES -A brute_force -m recent --update --name counting2 --seconds 200 --

hitcount 15 -j brute_force_blacklist

$IPTABLES -A brute_force -m recent --update --name counting3 --seconds 2000 --

hitcount 80 -j brute_force_blacklist

$IPTABLES -A brute_force -m recent --update --name counting4 --seconds 20000 --

hitcount 400 -j brute_force_blacklist

$IPTABLES -A brute_force -j ACCEPT

# Control SSH service: only new conections

BRUTEFORCE_EXCEPTION_IP="132.106.3.12"

#$IPTABLES -A INPUT -p TCP -s ! $BRUTEFORCE_EXCEPTION_IP --dport 22 -m state --state

NEW -j brute_force

$IPTABLES -A INPUT -p TCP --dport 22 -m state --state NEW -j brute_force

##### [end] Prevent Brute force attack

##################### Fin Ataques

echo "[end] Attack protection"

echo "[start] Internet < -> Host"

echo "* Incoming traffic"

##################### Puertos de entrada abiertos

echo " - SSH"

# Aceptamos SSH

$IPTABLES -A INPUT -i $LAN_INTERFACE -p tcp -s 0/0 --sport 1024:65535 -d $LAN_IP1 --

dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A OUTPUT -o $LAN_INTERFACE -p tcp -s $LAN_IP1 --sport 22 -m state --state

RELATED,ESTABLISHED -j ACCEPT

##################### Fin Puertos de entrada abiertos

echo "* Outgoing traffic"

##################### Puertos de salida abiertos

echo " - DNS"

# Outgoing DNS

# udp first

for dns_server_ip in $DNS_IP

do

$IPTABLES -A OUTPUT -p udp -s $LAN_IP1 --sport 1024:65535 -d $dns_server_ip --dport

53 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p udp -s $dns_server_ip --sport 53 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

# tcp next

$IPTABLES -A OUTPUT -p tcp -s $LAN_IP1 --sport 1024:65535 -d $dns_server_ip --dport

53 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p tcp -s $dns_server_ip --sport 53 -d $LAN_IP1 -m state --state

Page 44: 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

RELATED,ESTABLISHED -j ACCEPT

done

echo " - SMTP"

#outgoing SMTP

$IPTABLES -A OUTPUT -p tcp -s $LAN_IP1 --sport 1024:65535 -d 0/0 --dport 25 -m state --

state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p tcp -s 0/0 --sport 25 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

echo " - IMAP SSL"

#outgoing IMAP SSL

$IPTABLES -A OUTPUT -p tcp -s $LAN_IP1 --sport 1024:65535 -d 0/0 --dport 993 -m state -

-state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p tcp -s 0/0 --sport 993 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

echo " - SSH"

#outgoing SSH

$IPTABLES -A OUTPUT -p tcp -s $LAN_IP1 --sport 1024:65535 -d 0/0 --dport 22 -m state -

-state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p tcp -s 0/0 --sport 22 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

echo " - HTTP & HTTPS"

#outgoing http and https

# for apt-get and other stuff

$IPTABLES -A OUTPUT -p tcp -s $LAN_IP1 --sport 1024:65535 -d 0/0 --dport 80 -m state -

-state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p tcp -s 0/0 --sport 80 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

$IPTABLES -A OUTPUT -p tcp -s $LAN_IP1 --sport 1024:65535 -d 0/0 --dport 443 -m state

--state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p tcp -s 0/0 --sport 443 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

echo " - NTP"

#outgoing NTP to ubuntu servers

$IPTABLES -A OUTPUT -p udp -s $LAN_IP1 --sport 1024:65535 -d $NTP_UBUNTU --dport 123 -

m state --state NEW,ESTABLISHED -j ACCEPT

$IPTABLES -A INPUT -p udp -s $NTP_UBUNTU --sport 123 -d $LAN_IP1 -m state --state

RELATED,ESTABLISHED -j ACCEPT

##################### Fin Puertos de salida abiertos

echo "* ICMP"

##################### ICMP

### Drop icmp, but only after letting certain types through.

# Echo Reply

#$IPTABLES -A INPUT -p icmp --icmp-type 0 -j ACCEPT

# Destination Unreachable

#$IPTABLES -A INPUT -p icmp --icmp-type 3 -j ACCEPT

# Tiempo Excedido

#$IPTABLES -A INPUT -p icmp --icmp-type 11 -j ACCEPT

# Echo Request

#$IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 30/second -j ACCEPT

## Allow outgoing ping

# Echo Request to Internet

$IPTABLES -A OUTPUT -o $LAN_INTERFACE -p icmp --icmp-type 8 -d 0/0 -s $LAN_IP1 -m

limit --limit 30/second -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Echo Reply from Internet

$IPTABLES -A INPUT -i $LAN_INTERFACE -p icmp --icmp-type 0 -d $LAN_IP1 -s 0/0 -m state

Page 45: 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

--state ESTABLISHED,RELATED -j ACCEPT

# Destination Unreachable from Internet

$IPTABLES -A INPUT -i $LAN_INTERFACE -p icmp --icmp-type 3 -d $LAN_IP1 -s 0/0 -m state

--state ESTABLISHED,RELATED -j ACCEPT

# Time Exceeded from Internet

$IPTABLES -A INPUT -i $LAN_INTERFACE -p icmp --icmp-type 11 -d $LAN_IP1 -s 0/0 -m

state --state ESTABLISHED,RELATED -j ACCEPT

# Allow ping between internal IPs

SPACE=" "

INTERNAL_IPs=$LAN_IP1$SPACE$LAN_IP2$SPACE$LAN_IP3

for internal_ip1 in $INTERNAL_IPs

do

for internal_ip2 in $INTERNAL_IPs

do

# Receive Echo Reply

$IPTABLES -A INPUT -p icmp --icmp-type 0 -d $internal_ip1 -s $internal_ip2 -m

state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Receive Echo Request

$IPTABLES -A INPUT -p icmp --icmp-type 8 -d $internal_ip1 -s $internal_ip2 -m

state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Send Echo Request

$IPTABLES -A OUTPUT -p icmp --icmp-type 8 -d $internal_ip1 -s $internal_ip2 -m

limit --limit 30/second -m state --state ESTABLISHED,RELATED -j ACCEPT

# Receive Echo Reply

$IPTABLES -A OUTPUT -p icmp --icmp-type 0 -d $internal_ip1 -s $internal_ip2 -m

limit --limit 30/second -m state --state ESTABLISHED,RELATED -j ACCEPT

done

done

##################### Fin ICMP

# Use "-m state" (ip_conntrack module) in order to allow legitim traffic:

#

# - NEW: A packet which creates a new connection.

# - ESTABLISHED: A packet which belongs to an existing connection (i.e., a reply

packet, or outgoing packet on a

# connection which has seen replies).

# - RELATED: A packet which is related to, but not part of, an existing connection,

such as an ICMP error, or (with

# the FTP module inserted), a packet establishing an ftp data connection.

# - INVALID: A packet which could not be identified for some reason: this includes

running out of memory and ICMP

# errors which don't correspond to any known connection. Generally these packets

should be dropped.

### Log

echo "[start] Logging"

echo "* Logging exceptions"

## [start] Do not log

# netbios UDP

$IPTABLES -A INPUT -p udp -d $BROADCAST_IP1 --dport 137:138 -j DROP

## [end] Do not log

echo "* Logging rules"

# Limit: The first 3 packets that match this rule will be logged. After this, it will

be 30 seconds until one of the

# burst will be regained; if no packets hit the rule for 90 seconds, the burst will be

Page 46: 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

fully recharged.

$IPTABLES -A INPUT -m limit --limit 30/s --limit-burst 3 -j ULOG --ulog-nlgroup 1 --

ulog-prefix "[FW:INPUT Drop] "

$IPTABLES -A OUTPUT -m limit --limit 30/s --limit-burst 3 -j ULOG --ulog-nlgroup 1 --

ulog-prefix "[FW:OUTPUT Drop] "

$IPTABLES -A FORWARD -m limit --limit 30/s --limit-burst 3 -j ULOG --ulog-nlgroup 1 --

ulog-prefix "[FW:FORWARD Drop] "

echo "[end] Logging"

# Disable firewall in 30 seconds...

# ...so we can test it

#SAFETY=`sleep 30;/usr/local/bin/firewall-off` &

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

Page 47: 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

# 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:

cp /usr/share/doc/fwlogwatch/examples/fwlogsummary.cgi /usr/lib/cgi-bin/

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:

mkdir /var/www/localhost/fwlogwatch

chown -R www-data:www-data /var/www/localhost/fwlogwatch/

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

Page 48: 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

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

most easy one)

tc qdisc add dev $DEV root handle 1: htb default 20

#### Classes

# Root class that shape everything at $UPLINK speed preventing huge queues which

destroy latency

tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}mbit burst 6k

Page 49: 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

# High priority class (1:10)

tc class add dev $DEV parent 1:1 classid 1:10 htb rate ${UPLINK}mbit burst 6k prio 1

# Medium priority class (1:20)

tc class add dev $DEV parent 1:1 classid 1:20 htb rate ${UPLINK}mbit burst 6k prio 2

# Low priority class (1:20) with speed reduced to 70%

tc class add dev $DEV parent 1:1 classid 1:30 htb rate $[7*$UPLINK/10]mbit burst 6k

prio 3

#### Queueing

# Stochastic Fairness Queueing: avoid that one connection consumes all the bandwidth

tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10

tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10

tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10

#### Marking

### Mark traffic with 10 (highest), 20 or 30 (lowest)

$IPTABLES -F -t mangle

# Prioritize local SSH

$IPTABLES -t mangle -I OUTPUT -p tcp --sport 22 -s $LAN_IP1 -m mark --mark 0 -j MARK -

-set-mark 10

# Limit host

#$IPTABLES -t mangle -I FORWARD -s $LIMIT_IP1 -m mark --mark 0 -j MARK --set-mark 30

#### Classify

# Traffic with MARK 10 to the highest prioritized class (1:10)

tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10

tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20

tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 30 fw flowid 1:30

# By default, the rest ends up in 1:20

########## downlink

# Slow downloads down to somewhat less than the real speed to prevent queuing the ISP.

#

# Attach ingress policer:

tc qdisc add dev $DEV handle ffff: ingress

# Filter *everything* to it (0.0.0.0/0), drop everything that's coming in too fast:

tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src

0.0.0.0/0 police rate ${DOWNLINK}mbit burst 10k drop flowid :1

Por otra parte, podemos tener un script para listar las colas ‘/usr/local/bin/traffic-control-list’:#!/bin/bash

tc -s qdisc ls dev eth0

Y finalmente, para desactivar las colas ‘/usr/local/bin/traffic-control-list-off’:#!/bin/bash

DEV=eth0

TC=/sbin/tc

# clean existing down- and uplink qdiscs, hide errors

$TC qdisc del dev $DEV root 2> /dev/null > /dev/null

$TC qdisc del dev $DEV ingress 2> /dev/null > /dev/null

Para ver en tiempo real el efecto de las colas establecidas, es recomendable utilizar el script ‘monitor_tc_top.pl‘ de la siguiente web:

# cd /usr/local/bin/

# wget -c http://www.docum.org/docum.org/monitor/download/monitor_tc_top.pl

# chmod 755 monitor_tc_top.pl

# monitor_tc_top.pl

Ejemplo:

Page 50: 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

20:37:11 up 18 days, 7:30, 2 users, load average: 0.18, 0.05, 0.01

Interval Cumulated Total

Dev Classid Tokens Ctokens Rate Speed Send Send

-------------------------------------------------------------------------

eth0 1:1 485 4033 2.42KB 624.32KB/s 6.91MB 8.47MB

eth0 1:10 485 4033 6.67KB 1.37KB/s 18.52KB 23.42KB

eth0 1:20 500 4048 18.41KB 558B/s 2.39KB 87.90KB

eth0 1:30 4 3388 2.39KB 622.40KB/s 6.89MB 8.36MB

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:

...

#rsync_short_args -a

rsync_long_args --delete --numeric-ids --relative --delete-excluded --stats --

timeout=10

...

#########################################

# BACKUP INTERVALS #

# Must be unique and in ascending order #

# i.e. hourly, daily, weekly, etc. #

#########################################

## Tendremos backup de las últimas 6 horas, los últimos 7 días, las últimas 4 semanas

y los últimos 6 meses:

interval hourly 6

interval daily 7

interval weekly 4

interval monthly 6

...

# Excluimos algunos ficheros para hacer más pequeños los backups

exclude access.log

exclude access.log.*

exclude access_log

exclude error.log

exclude error.log.*

exclude .bash_history

...

###############################

### BACKUP POINTS / SCRIPTS ###

###############################

# LOCALHOST

backup /etc/ localhost/

backup /home/ localhost

backup /var/www/ localhost

backup /usr/local/ localhost

backup /var/lib/awstats/ localhost

Page 51: 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

backup /var/lib/bandwidthd/ localhost

backup /var/lib/cacti/ localhost

backup /var/cache/nagios2/ localhost

backup /var/lib/nagios2/ localho

backup_script /usr/local/bin/backup_dpkg.sh localhost/dpkg/

backup_script /usr/local/bin/backup_mysql.sh localhost/mysql/

backup_script /usr/local/bin/backup_info.sh localhost/info/

backup rsnapshot@webserver:/etc/ webserver/ ssh_args=-p 22

backup rsnapshot@webserver:/usr/local/ webserver/ ssh_args=-p 22

backup rsnapshot@webserver:/var/www/ webserver/ ssh_args=-p 22

backup_script /usr/bin/ssh -i /root/.ssh/id_rsa rsnapshot@webserver /home/

rsnapshot/.ssh/backup_mysql_all.sh > db.sql webserver/mysql/all/

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:

FINDOPTIONS='-ignore_readdir_race'

export FINDOPTIONS

PRUNEFS="NFS nfs nfs4 afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts

ftpfs devfs mfs shfs sysfs cifs lustre_lite tmpfs usbfs udf"

export PRUNEFS

PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/spool /media /var/cache/rsnapshot /var/cache/

rsnapshot-tar"

export PRUNEPATHS

NETPATHS=""

export NETPATHS

LOCALUSER="nobody"

export LOCALUSER

NICE=10

export NICE

IONICE_CLASS=2

export IONICE_CLASS

IONICE_PRIORITY=7

export IONICE_PRIORITY

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:

#!/bin/bash

# Date

/bin/date -R > date.out

# Host name and kernel

/bin/uname -a > uname.out

Page 52: 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

# Interfaces

/sbin/ifconfig -a > ifconfig.out

# Disk space

/bin/df -h > df.out

# Processes

/bin/ps aux > ps.out

# Open ports & conections

/bin/netstat -atunp > netstat.out

/usr/bin/lsof -i > lsof-i.out

# Processes with lots of files open

/usr/bin/lsof +c 15 | awk '{printf("%15s (%s)n", $1, $2)}' | sort | uniq -c | sort -

rn | head > losf-processes-with-lots-of-open-files.out

# Mounted filesystems

/bin/mount > mount.out

# Connected users

/usr/bin/who > who.out

# Firewall rules

/sbin/iptables -L > iptables.out

# Daemons & init scripts

/usr/sbin/sysv-rc-conf --list > sysv-rc-conf.out

# Files with special permissions

#/usr/bin/find / -path /proc -prune -o -perm -2 ! -type l -ls > find-world-

writable.out

#/usr/bin/find / -path /proc -prune -o -nouser -o -nogroup > find-files-without-

owner.out

#/usr/bin/find / -path /proc -prune -o -type f -perm +6000 -ls > find-suid-guid.out

dpkg y mysqlScripts que copian el listado de paquetes instalados en Ubuntu y un volcado de la MySQL:

cp /usr/share/doc/rsnapshot/examples/utils/backup_dpkg.sh /usr/local/bin/

cp /usr/share/doc/rsnapshot/examples/utils/backup_mysql.sh /usr/local/bin/

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/

backup_script /usr/local/bin/backup_mysql.sh localhost/mysql/

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:

useradd -d /home/rsnapshot -m -K PASS_MAX_DAYS=-

1,PASS_MIN_DAYS=0,PASS_WARN_AGE=0,UMASK=0022 -s /bin/bash rsnapshot

passwd -l rsnapshot

mkdir -p /home/rsnapshot/.ssh

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

Page 53: 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

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):

from="71.21.5.19",command="/home/rsnapshot/.ssh/validate-ssh.sh",no-port-

forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa

AAUTQEbt7GOcR4jZ2bTgzxpgABIwAAAQEAwAQKRBv+ABDyOgvHfAxSVcWOEzhieC7rwrBjquLJw0W+U9vD7Qgm

ffmuKDZksI7bAAB3NzaC1yc2EAAAdbHBOGg/zgXcrCNsuJ5IJoDw== [email protected]

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':

#!/bin/bash

/usr/bin/mysqldump --all-databases --add-drop-table --password=secret -u miusuario

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:

cp /usr/share/doc/rsnapshot/examples/utils/rsnaptar /usr/local/bin/

mkdir /var/cache/rsnapshot-tar/

Editamos /usr/local/bin/rsnaptar para especificar el lugar donde guardaremos los tar, comentamos

Page 54: 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

GPG y añadimos info al mail que se genera automaticamente.# DIRECTORIES

TAR_DIR="/var/cache/rsnapshot-tar"

SNAPSHOT_DIR="/var/cache/rsnapshot/daily.0/" ...

#GPG="/usr/bin/gpg" ...

${CAT} << EOF | ${SENDMAIL}

To: ${TO_EMAIL}

Subject: [rsnapshot] Tar backup job complete - ${HOSTNAME}

Now is the time to backup the latest files from rsnapshot on ${HOSTNAME}

Tar files created on ${TAR_DIR}/${DATE}/

EOF

Editamos ‘/etc/cron.d/rsnapshot’ para que se ejecute cada semana:# Weekly

# At 5:00 every monday

0 5 * * 1 root /usr/local/bin/rsnaptar marble@localhost

ReportesSi queremos recibir un reporte del backup cada cierto tiempo como medida para saber que se están efectuando:

cp /usr/share/doc/rsnapshot/examples/utils/rsnapreport.pl.gz /usr/local/bin/

gzip -d /usr/local/bin/rsnapreport.pl.gz

chmod 755 /usr/local/bin/rsnapreport.pl

Establecemos en /etc/rsnapshot.conf el nivel de verbose a 3 y añadimos –stats al comando rsync_long_args:

# Verbose level, 1 through 5.

# 1 Quiet Print fatal errors only

# 2 Default Print errors and warnings only

# 3 Verbose Show equivalent shell commands being executed

# 4 Extra Verbose Show extra verbose information

# 5 Debug mode Everything

#

verbose 3

...

# Default rsync args. All rsync commands have at least these options set.

#

#rsync_short_args -a

rsync_long_args --delete --numeric-ids --relative --delete-excluded --stats --

timeout=10

# this script prints a pretty report from rsnapshot output

# in the rsnapshot.conf you must set

# verbose >= 3

# and add --stats to rsync_long_args

# then setup crontab 'rsnapshot daily 2>&1 | rsnapreport.pl | mail -s"SUBJECT"

[email protected]

# don't forget the 2>&1 or your errors will be lost to stderr

Editamos /etc/cron.d/rsnapshot para hacer que el reporte se genere una vez a la semana:# 4 times per day

0 */4 * * * root /usr/bin/rsnapshot hourly > /dev/null

# At 3:30 every day

30 3 * * * root /usr/bin/rsnapshot daily > /dev/null

# At 3:00 every monday

0 3 * * 1 root /usr/bin/rsnapshot weekly > /dev/null

# At 2:30 every 1st of month

30 2 1 * * root /usr/bin/rsnapshot monthly > /dev/null

Page 55: 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

# Run rsnapshot once a week as it were hourly but with rsnapreport (send report by

mail)

# I use it only to validate that backups are being done.

# When we execute rsnapshot daily/weekly/... rsync is not called, only a move is done

and rsnapreport can not generate a report with that info.

# At 1:00 every monday

0 1 * * 1 root /usr/bin/rsnapshot hourly 2>&1 | /usr/local/bin/

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

stress: info: [13247] dispatching hogs: 8 cpu, 4 io, 2 vm, 0 hdd

stress: info: [13247] successful run completed in 10s

Únicamente consumo de memoria:stress --vm 2 --vm-bytes 128M --vm-keep --timeout 10s

Conexiones HTTP con httperfPodemos realizar pruebas contra un servicio web para ver su capacidad de respuesta:

apt-get install httperf

Por ejemplo, crear 100 conexiones con un ratio de 10 por segundo:httperf --hog --server www --num-conn 100 --rate 10 --timeout 5

Crear 10 sesiones a un ratio de 1 por segundo, cada sesion consisten en 5 llamadas espaciadas por 2 segundos:

httperf --hog --server=www --wsess=10,5,2 --rate 1 --timeout 5

Ejemplo de ejecución:$ httperf --hog --server=localhost --port 3000 --wsess=10,5,2 --rate 1 --timeout 5

httperf --hog --timeout=5 --client=0/1 --server=localhost --port=3000 --uri=/ --rate=1

--send-buffer=4096 --recv-buffer=16384 --wsess=10,5,2.000

Maximum connect burst length: 1

Total: connections 50 requests 90 replies 50 test-duration 30.088 s

Connection rate: 1.7 conn/s (601.8 ms/conn, < =11 concurrent connections)

Connection time [ms]: min 308.3 avg 4186.5 max 6065.9 median 4252.5 stddev 1489.6

Page 56: 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

Connection time [ms]: connect 0.1

Connection length [replies/conn]: 1.000

Request rate: 3.0 req/s (334.3 ms/req)

Request size [B]: 86.0

Reply rate [replies/s]: min 1.2 avg 1.6 max 1.8 stddev 0.2 (6 samples)

Reply time [ms]: response 2530.6 transfer 52.8

Reply size [B]: header 414.0 content 12642.0 footer 0.0 (total 13056.0)

Reply status: 1xx=0 2xx=0 3xx=0 4xx=0 5xx=50

CPU time [s]: user 2.70 system 12.57 (user 9.0% system 41.8% total 50.8%)

Net I/O: 21.4 KB/s (0.2*10^6 bps)

Errors: total 40 client-timo 0 socket-timo 0 connrefused 0 connreset 40

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

Page 57: 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

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.

Page 58: 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