Tunning - Seguridad Lógica en FreeBSD

Autor: David Barbero
Fecha: 29 de Enero de 2003
Fecha Revisión: 10 de Septiembre de 2003


Introducción

Este artículo es una referencia para poner a punto la seguridad de un sistema FreeBSD.

Seguridad en el sistema de Ficheros

El sistema de ficheros que monta FreeBSD es UFS 4.2BSD compatible con todos los BSD. Dentro de el UFS de Freebsd hay dos tipos:

El primero es UFS, lo usa las ramas anteriores a 4.x (4.x incluida) y tiene la seguridad de siempre sin mejoras y soporta quotas.

El Segundo es UFS2, se usa apartir de la rama 5,x y tiene mejoras significativas en seguridad. Sus más significativas son Mandatory Access Control (MAC), File System Access Control List, snapshots y quotas.

No comentare más sobre los tipos de sistemas de ficheros, pero si haré unas recomendaciones para mejorar la seguridad desde el sistema de ficheros.

Hay que considerar que el usuario root debemos usarlo SOLO y EXCLUSIVAMENTE para fines de administración, por lo cual usaremos los usuarios normales. Teniendo esto en cuenta, es de lógica que separemos la partición /home de su posicion original (/usr/home). Con esto también evitamos en parte de fragmentación ya que nuestra partición /usr no tendrá que ser tan grande.

Tambien pondremos los flags NOSUID y NODEV a las particiones /tmp y /usr/home, asi nos aseguraremos que nadie podra usar programas potencialmente peligrosos en esas particiones.

NOSUID No permite la Ejecución de programas con el bit suid, es decir, que se ejecutan como root y son potencialmente peligrosos para el sistema.

NODEV no permite la creación de dispositivos de sistema en esa partición librandonos así de la posible instalación de programas potencialmente peligrosos para el sistema.

Para Configurar esto es necesario mofificar el fichero /etc/fstab e incluir NODUID y NODEV en la sección Options quedando de una forma parecida a esto:

# Device                Mountpoint      FStype  Options                      Dump    Pass#
/dev/ad0s1b             none            swap    sw                           0       0
/dev/ad0s1a             /               ufs     rw                           1       1
/dev/ad0s1e             /tmp            ufs     rw,noatime,nosuid,nodev      2       2
/dev/ad0s1g             /usr            ufs     rw,noatime                   2       2
/dev/ad0s1h             /usr/home       ufs     rw,noatime,nosuid,nodev      2       2
/dev/ad0s1f             /var            ufs     rw,noatime                   2       2
/dev/ad2s1h             /data           ufs     rw,noatime                   2       2
/dev/acd0c              /cdrom          cd9660  ro,noauto                    0       0
/dev/acd1c              /cdrom1         cd9660  ro,noauto                    0       0
proc                    /proc           procfs  rw                           0       0

Una vez montado el sistema de ficheros si ejecutamos la orden mount veremos que efectivamente están las opciones que queriamos:

hellen#mount
/dev/ad0s1a on / (ufs, local)
/dev/ad0s1e on /tmp (ufs, local, noatime, nosuid, nodev, soft-updates)
/dev/ad0s1g on /usr (ufs, local, noatime, soft-updates)
/dev/ad0s1h on /usr/home (ufs, local, noatime, nosuid, nodev, soft-updates)
/dev/ad0s1f on /var (ufs, local, noatime, soft-updates)
/dev/ad2s1h on /data (ufs, local, noatime, soft-updates)
procfs on /proc (procfs, local)

Para más información consultar fstab(5), fsck(8), mount(8), umount(8)

Seguridad en las contraseñas

Empezaremos aplicando una buena política de contraseñas, para lo cual debemos pensar cual será el máximo tiempo que un usuario estará con la misma contraseñ y de cuantos caracteres será como mínimo.

Yo he decidido usar un mínimo de 8 caracteres para las contraseñas y un máximo de 30 días por contraseña. Tambien he decidido cambiar el sistema de cifrado de las contraseñas, que por defecto es md5, por uno más seguro, Blowfish.

Para configurar estas opciones necesitamos que editar el archivo /etc/login.conf

 hellen# vi /etc/login.conf 

Para cambiar el cifrado tenemos que buscar la línea

 default:\
        :passwd_format=md5:\

Una vez modificada quedaría de la siguiente forma:

default:\
        :passwd_format=blf:\

Con este cambio ya tendriamos configurado el sistema de cifrado usando Blowfish.

Ahora vamos a cambiar la longitud mínima de caracteres para cada contraseña y hacer que cada usuario cambie su contraseña cada 30 días, Para ello pondremos lo siguiente al final de el apartado default:\

  	:umask=022:\
  	:minpasswordlen=8:\
  	:passwordtime=30d:\

Con esto lo que estamos haciendo es obligar a que la contraseña tenga un mínimo de 8 caracteres y que sea obligarorio cambiarla antes de 30 días. Esto influye en todos los usuarios del sistema, pero nosotros queremos que el usuario root tenga un minimo de 11 caracteres, por lo cual nos vamos a la sección root:\ y hacemos que quede de la siguiente forma:

root:\
	:ignorenologin:\
	:minpasswordlen=11:\
	:tc=default:

Con esto hemos forzado que la contraseña de root tenga un mínimo de 11 caracteres.

Una vez realizados estos cambios, tenemos que decirle al sistema que rehaga la base de datos del sistema de contraseñas, esto lo hacemos con la orden cap_mkdb de la siguiente manera:

 hellen# cap_mkdb /etc/login.conf

Una vez ejecutado el comando para actualizar el sistema de contraseñas solo nos quedaría cambiar la contraseña para que el sistema la cifre con Blowfish, procedemos a ello:

login: sico
Password:

passwd
Changing local password for sico.
Old password:
New password:
Please enter a password at least 8 characters in length.
New password:
Retype new password:
passwd: updating the database...
passwd: done

Ya hemos visto que funciona correctamente, ahora solo nos queda con el usuario root, precedemos a ello:

su
Password:

passwd root
Changing local password for root.
New password:
Please enter a password at least 11 characters in length.
New password:
Retype new password:
passwd: updating the database...
passwd: done

Un último cambio más, nos queda modificar un archivo para que cuando demos de alta un nuevo usuario en el sistema la contraseņa se cibre con Blowfish, este achivo es /etc/auth.conf y en el hay que buscar la línea

# crypt_default =       md5 des

y sustituirla por:

crypt_default =      blf

Seguridad en el servidor ssh

El Servidor SSH se instala por defecto con una configuración no demasiado propicia para la seguridad, hay que decir que es buena, pero se puede mejorar.

Lo primero que tenemos que hacer es configurar el servidor SSH para que solo acepte conexiones por el protocolo 2 que es bastante más seguro que el protocolo 1, para lo cual modificaremos el archivo /etc/ssh/sshd_config

 hellen#vi /etc/ssh/sshd_config 

En el cual buscamos las siguiente línas:

#Port 22
#Protocol 1 2
#ListenAddress 0.0.0.0
#Banner /some/path

Y las sustituimos por:

Port 22
Protocol 2
ListenAddress 192.168.10.1
Banner /etc/ssh/banner

La explicación de estos cambios son muy sencillos:

Port nos indica el puerto por el cual los clientes se van a conectar.

Protocol nos indica el protocolo que vamos a usar, nosotros elegimos el protocolo 2 por que es mucho más seguro.

ListenAddress indica la ip de la tarjeta de red por la que queremos que escuche, 192.168.10.1 es un ejemplo que habría que sustituir por la vuestra IP.

Banner que realmente no es una opción de seguridad, pero si lo es de advertencia, cuando el cliente se conecta al servidor, este pondra el banner antes de poder loguearse en nuestro FreeBSD.

Como seguramente /etc/ssh/banner no exista lo tendremos que crear, este es el contenido que tengo yo:

hellen# cat /etc/ssh/banner
************************************************************************

This is a private system!!! All connection attempts are logged and 
monitored. All unauthorized connection attempts will be investigated and 
handed over to the proper authorities.

************************************************************************
hellen# 

Una vez que ya teneis el banner ya tenemos casi configurado el servidor ssh, solo nos faltaría decidir que usuarios pueden conectar por SSH a nuestra máquina. Dentro de esta situación tenemos dos posibilidades, Filtrar por la IP del cliente, o filtrar por Usuario, La primera Opción muchas veces no es posible ya que tenemos que tener un firewall instalado en la máquina y ademas de esto, muchos clientes utilizan conexiones por rtb (Modem Analógico en Línea analógica) en las cuales no disponen de IP fija y cada conexión tienen una diferente, asi que vamos a filtrar por Usuarios.

La opción para filtrar por usuarios es muy fácil, es AllowUsers y tambien hay que ponerla dentro de /etc/ssh/sshd_config

Una vez decididos que usuarios van a poder conectar, vamos a configurarlo

hellen# echo AllowUsers sico@192.168.10.2 syvic toni >> /etc/ssh/sshd_config
hellen# cat /etc/ssh/sshd_config
Port 22
Protocol 2
ListenAddress 192.168.10.1
...
...
# override default of no subsystems
Subsystem       sftp    /usr/libexec/sftp-server

AllowUsers      sico@192.168.10.2 syvic toni
hellen# 

Como veis he añadido a tres usuarios, el primero a sico que ademas le he dicho desde que IP puede conectar, es decir, sico podria conectar desde 192.168.10.2 y despues he puesto a los usuarios syvic y toni que pueden conectar desde cualquier lugar.

Seguridad en Consola

La seguridad en Consola es bastante importante puesto que álguien podría arrancar nuestra máquina en modo mono-usuario y trastear en ella con privilegios de root, o simplemente podriamos dejar una consola con una sesión iniciada, ausentarnos y álguien podría usar nuestra sesión para hacer algo que a nadie nos gustase.

Primero vamos a configurar el sistema para que si arranca en modo mono-usuario nos pida las contraseña de root para poder usar la máaquina. Para ello tenemos que editar el archivo /etc/ttys y localizar la línea que pone:

console none                            unknown off secure

Esta línea tenemos que modificarla dejandola de la siguiente manera.

console none                            unknown off insecure

De esta manera nadie que no posea la contraseña de root podra iniciar sesión si arranca la máquina en modo mono-usuario.

Una vez que tenemos el modo mono-usuario vamos a explicar como bloquear una consola por si nos tenemos que ausentar de la máquina y no podemos cerrar la sesión.

Para bloquear la sesión disponemos de una orden del propio sistema, esta orden se llama lock y bloquea la consola en la que estemos trabajando, por defecto la bloquea durante 15 minutos, pero podemos indicarle que este más tiempo ejecutando lock -n, otra peculiaridad que tiene esta orden es que te pide que pongas una contraseña que no tiene nada que ver con la del sistema, pero si prefieres usar la contraseña sistema puedes ejecutar el comando lock -p

hellen# lock
Key:
Again:
lock: /dev/ttyp0 root timeout in 15 minutes
time now is Thu Jan  30 03:00:34 CET 2003
Key:

Aunque yo personalmente prefiero usar vlock que aunque no se encuentra en la base del sistema está en los ports y su uso es muy fácil.

hellen# cd /usr/ports/security/vlock && make install clean

Una vez instalado su funcionamiento es muy fácil, simplemente se ejecuta vlock y tenemos bloqueada la consola en la que nos encontremos, tambien se puede usar vlock -a y bloqueariamos todas las consolas.

hellen# vlock -a
The entire console display is now completely locked.
You will not be able to switch to another virtual console.
Please enter the password to unlock.
root's password:

Esto es todo en la sección sobre Consolas.

Cerrando Puertos

Lo primero que tenemos que saber es que cuando instalamos el sistema por defecto solemos arrancar servicios que realmente no usamos, por lo cual vamos a ir localizando y cerrando estos servicios que mas de una vez pueden comprometer nuestro sistema.

Vamos a empezar usando la orden sockstat -4 el cual nos va a decir que puertos tenemos abiertos.

hellen# sockstat -4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
root     sshd       873    3 tcp4   *:22                  *:*                  
root     inetd       92    4 tcp4   *:21                  *:*                  
root     syslogd     77    4 udp4   *:514                 *:*                  
root	 X_SERV	    234	   4 tcp4   *:6000		  *:*
root	 sendmail    92    4 tcp4   *:25		  *:*
root	 submission 245    4 tcp4   *:587		  *:*

hellen#

Como veis hay ciertos puertos que están abiertos y que realmente no voy a usar nunca, es el caso del 587 (Submission), el 25 (SMTP) puesto que yo no tengo en esta máquina un servidor de correo, el 6000 tampoco lo vamos a usar puesto que sirve para conexiones remotas a un servidor X-window, el 21 que es el puerto del ftp tampoco voy a usarlos, asi que vamos a ir cerrando puertos y asegurando el sistema.

Lo que vamos a cerrar primero es el puerto 6000 ya que nosotros no vamos a servir entorno grafico a nadie, para esto necesitamos editar el archivo /usr/X11R6/bin/startx Y lo calizar la linea

serverargs=""

Modificarla hasta que quede de la siguiente forma:

serverargs="-nolisten tcp"

Con esto ya tenemos un puerto menos abierto, ahora vamos a cerrar el 587 (Submission), este puerto no se necesita para mandar ni recibir correo, pero pertenece al sendmail, para cerrarlo necesitamos editar el archivo /etc/mail/sendmail.cf y buscar la línea

O DaemonPortOptions=Port=587, Name=MSA, M=E

Es ta línea hay que comentarla para que sendmail no la cargue por defecto.

#O DaemonPortOptions=Port=587, Name=MSA, M=E

Ahora vamos a cerrar el puerto 25 ya que por norma general los correos nos los descargamos desde otro servidor y no los recibe directamente mi máquina, por lo cual voy a hacer que no arranque sendmail.

Para esto necesitamos editar el archivo /etc/rc.conf y añadir la siguiente línea dependiendo de la versión de nuestro FreeBSD.

Si tenemos una versión de FreeBSD inferior a una 4.6-RELEASE:

sendmail_enable="NO"

Si es superior o Igual a 4.6-RELEASE:

sendmail_enable="NONE"

En mi ejemplo no ha salido el puerto 111 (sunrpc) pero es muy habitual que este puerto salga, para eliminar este puerto tenemos que seguir editando /etc/rc.conf y poner dentro

nfs_server_enable="NO"
nfs_client_enable="NO"
portmap_enable="NO"

otro puerto de los que tenemos abierto es el 514 que pertenece al syslogd y esta a la espera de poder brindar la oportunidad de logear remotamente, como realmente lo que nos interesa es que registre lo que ocurre en nuestra máquina, vamos a poner lo siguiente en /etc/rc.conf

syslogd_enable="YES"
syslogd_flags="-ss"

Luego por último teniamos abierto el puerto 21 que corresponde al servidor ftp, el cual en esta máquina no me va a servir de nada, por lo cual lo voy a cerrar, como se ve en la salida de sockstat -4 estaba ejecutandose desde el inetd, asi que vamos a cortar el inetd para que no arranque el ftp y otros servicios que no nos interesan, para ello ponemos lo siguiente en /etc/rc.conf

inetd_enable="NO"

Ahora despues de esto solo nos queda pasar el sistema a monopuesto y volverlo a multipuesto para que recargue las variables modificadas, otra solución es reiniciar la máquina, yo prefiero pasar a monopusuario:

shutdown now

Una vez que ya hemos pasado a multiusuario ejecutamos sockstat -4 y comprobamos que esta a nuestro gusto.

hellen# sockstat -4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
root     sshd       873    3 tcp4   *:22                  *:* 

hellen#

Otra sección acabada ;o)

Seguridad con los usuarios

Una vez llegado a este punto lo siguiente que haremos es activar el acconuting para tener un cierto control sobre los usuarios, para hacer esto tenemos que editar el archivo /etc/rc.conf y añadirle la siguiente línea:

accounting_enable="YES"

Para ver las opciones que tiene la opción de accouting te aconsejo ver el manual de sa y de lastcomm

hellen# man sa
hellen# man lastcomm

En el sistema existe un usuario llamado toor que tiene privilegios de root, este usuario nunca se usa, por lo cual vamos a eliminarlo para dejar el sistema lo más limpio posible.

hellen# vipw
# $FreeBSD: src/etc/master.passwd,v 1.25.2.6 2002/06/30 17:57:17 des Exp $
#
root:$2a$04$i/o8gD2EdrL8BVw2VXumpuXxXxXxXxXxu0xijdQPPewnWDM2bjr2m:0:0::0:0:Charlie &:/root:/bin/csh
toor:*:0:0::0:0:Bourne-again Superuser:/root:
daemon:*:1:1::0:0:Owner of many system processes:/root:/sbin/nologin

Como vemos el usuario toor existe, lo borramos, y ya que estamos vamos tambien a cambiar el nombre del root que por defecto está puesto en Charlie &, para ello dejamos la configuración de la siguiente manera:

# $FreeBSD: src/etc/master.passwd,v 1.25.2.6 2002/06/30 17:57:17 des Exp $
#
root:$2a$04$i/o8gD2EdrL8BVw2VXumpuXxXxXxXxXxdQPPewnWDM2bjr2m:0:0::0:0:Sico:/root:/bin/csh
daemon:*:1:1::0:0:Owner of many system processes:/root:/sbin/nologin

Yo en el nombre de root he puesto sico, pero lo podeis sustituir por vuestro nombre o lo que querais.

Ahora vamos a decidir que usuarios pueden hacerse root usando la orden su, estos usuarios para poder usar dicha orden deben estar dentro del grupo wheel, si no lo están no podran hacerse root.

hellen# vi /etc/group
# $FreeBSD: src/etc/group,v 1.19.2.3 2002/06/30 17:57:17 des Exp $
#
wheel:*:0:root
daemon:*:1:daemon

Como vemos ahora mismo solo está root dentro del grupo, si intentamos hacernos root desde un usuario nos dirá lo siguiente:

%su
su: you are not in the correct group (wheel) to su root.
%

Para permitir que nos deje hacernos root debemos dejar la línea de la siguiente manera:

# $FreeBSD: src/etc/group,v 1.19.2.3 2002/06/30 17:57:17 des Exp $
#
wheel:*:0:root,sico
daemon:*:1:daemon

Yo he decidido que el usuario sico se va a poder hacerse root, guardamos los cambios y comprobamos que funciona:

hellen:~> su -
Password:
hellen#

Una ultima opción para controlar que ningún usuario mal intencionado pueda dejar algun programa en los directorios temporales es aconsejable poner en /etc/rc.conf la siguiente línea:

clear_tmp_enable="YES"

Bueno, Pues esto es todo, aun se podrian introducir un par de cosas más para mejorar la seguridad, pero las dejare para la futura actualización de este documento.

Espero que os sea de ayuda. Salud!


"No lo intentes, hazlo o no lo hagas, pero no lo intentes"