14 jul 2012

Securizando CentOS, SL y Fedora ante extraños, bruteforce y mas || hardening CentOS SL Fedora

Bueno, vamos a ver como bloquear cuentas de usuario, incluso el root, ante intentos fallidos de login, tanto en tty, consolas y GDM.



En CentOS 6.x, SL6.x y Fedora, no se usa mas pam_tally, sino pam_tally2

Lo que haremos, es editar /etc/pam.d/system-auth y colocar estas lineas

auth        required  pam_tally2.so deny=2 onerr=fail even_deny_root unlock_time=600 root_unlock_time=3600

Quedandonos algo asi:



#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required  pam_env.so
auth        required  pam_tally2.so deny=2 onerr=fail even_deny_root unlock_time=600 root_unlock_time=3600

En la seccion account, quedará algo asi, por si no lo tenian colocado:


account     required  pam_unix.so
account     required  pam_tally2.so


Ahora, voy a explicar que es cada sentencia:

deny=2: Dice que tras 2 intentos fallidos actuará
onerr=fail: Dice que tras el evento fallido
even_deny_root: Hace que la regla tambien se aplique al root
unlock_time=600: Desbloquea la cuenta de forma automatica tras 600 segundos, para usuarios no root
root_unlock_time=3600: Desbloquea la cuenta de root, tras 3600 segundos.

De esta forma, tenemos un bloqueo de 10 minutos para los usuarios, y de 1 hora para el root.
Para ver los fail login de un usuario, hacemos:

pam_tally2 -u usuario

Para resetear y desbloquearlo, hacemos:

pam_tally2 -r -u usuario

Siempre teniendo en cuenta que esto se hace como root, asi que si el root esta bloqueado, no podremos hacerlo.

El log que utiliza pam_tally2 se ubica en /var/log/tallylog, que contiene algo de codigo maquina  y algo legible, en caso de tener un servidor seguro, es recomendable, indicarle a pam_tally2 que destine el log en otro lado, por ejemplo, si tengo una PC en LAN, que es "segura", en la linea podria agregar:

file=/path/to/counter

Donde el path, podria ser un NFS, mejor un SSHFS, previamente montado.

Podemos añadir la sentencia audit, para que el log vaya quedando en /var/log/audit/audit.log

Donde podemos ver tras un intento fallido, haciendo tail -f /var/log/audit/audit.log

type=USER_AUTH msg=audit(1341519610.654:239): pid=0 uid=0 auid=500 ses=1 msg='op=PAM:authentication acct="synflag" exe="/bin/su" hostname=? addr=? terminal=pts/2 res=failed'

La ventaja, es que tambien registrará intentos fallidos con nombres de usuario no existentes.
Por ultimo, para ver la bitacora, pueden mirar /var/log/secure, donde luego de unas pruebas, en mi caso, veo:

Jul  5 16:50:46 hostname su: pam_unix(su-l:auth): authentication failure; logname=synflag uid=500 euid=0 tty=pts/0 ruser=synflag rhost=  user=synflag
Jul  5 16:50:55 hostname su: pam_tally2(su-l:auth): user synflag (500) tally 4, deny 2
Jul  5 16:51:09 hostname su: pam_tally2(su-l:auth): user synflag (500) tally 5, deny 2
Jul  5 16:51:37 hostname su: pam_tally2(su-l:auth): user synflag (500) tally 7, deny 2

Aun nos quedan 3 archivos, sigamos:

Editaremos /etc/pam.d/password-auth

Donde añadiremos una linea, por debajo de 'auth required pam_env.so' que será asi:

auth required pam_tally2.so deny=2 onerr=fail even_deny_root unlock_time=600 root_unlock_time=3600En la seccion account, añadimos:

account required pam_tally2.so en la primera linea de la seccion

Luego, editamos /etc/pam.d/gdm-passwords

En la seccion 'auth' veremos una linea que dice 'auth substack password-auth'
Ahí, cambiamos substack, por include

En la seccion 'account', donde vemos 'account substack password-auth', lo cambiamos quedando asi:

account include password-auth

En la seccion password, donde vemos 'password substack password-auth', lo cambiamos, quedando asi:

password include password-auth

Y por ultimo, en la seccion 'session', donde vemos 'session substack password-auth', lo cambiamos, quedandonos asi:

session include password-auth

Ahora, toca editar '/usr/share/polkit-1/actions/org.freedesktop.consolekit.policy'

Abrimos con nano o lo que usen, y donde vean yes, voy a dar un ejemplo:

<action id="org.freedesktop.consolekit.system.stop">
    <description>Stop the system</description>
    <message>System policy prevents stopping the system</message>
    <defaults>
      <allow_inactive>no</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
  </action>

Donde dice 'yes', lo cambian por 'auth_admin_keep', en todos los campos del archivo donde diga yes.

Luego, editan /etc/gdm/custom.conf y en la seccion [security], colocan debajo DisallowTCP=true y luego, van a: Sistema -> Administracion -> Autenticacion y tildan esto, les dejo una imagen:


Tildan donde dice, habilitar el control de acceso local, que no hace mas que leer el archivo que nombra abajo, el que acaban de editar.

Con estas ultimas cosas, si entienden ingles van a saber lo que indica el polkit, sino, basicamente, prevenimos apagones y logout sin permiso de root.
Con el ultimo, desactivamos las conexiones TCP, a nuestro X11, o sea, nuestra grafica, si no comparten escritorio por SSH, o de algun otro modo, no se preocupen. El puerto por defecto de GDM es el 6000.
Luego de todo esto, a TODOS los archivos que editaron, les hacen, como root:

chattr +i /etc/pam.d/archivo, por ejemplo, para que nada ni nade los altere, excepto el root, haciendo chattr -i

Vamos a seguir con /etc/security/access.conf

En este archivo, vamos a definir, que el root, asi como los usuarios del grupo wheel, solo pueden acceder al sistema, desde las tty, pts (las terminales de las X), y los host que nosotros especifiquemos.

Por lo tanto, root, mi usuarios, pueden acceder a mi PC de forma local, desde remoto, ya sea SSH incluso PERMITIENDO el acceso root, o cualquier otro metodo de login remoto, sera denegado, por no provenir desde mi 127.0.0.1 y mi IP local, 192.168.x.x. Para evitar el spoof, un metodo por el cual pueden simular que tienen mi IP, tambien tocaremos /etc/sysctl.conf

Empecemos, esta es una muestra de como dejar /etc/security/access.conf

# Login access control table.
#
# Comment line must start with "#", no space at front.
# Order of lines is important.
#
# When someone logs in, the table is scanned for the first entry that
# matches the (user, host) combination, or, in case of non-networked
# logins, the first entry that matches the (user, tty) combination.  The
# permissions field of that table entry determines whether the login will
# be accepted or refused.
#
# Format of the login access control table is three fields separated by a
# ":" character:
#
# [Note, if you supply a 'fieldsep=|' argument to the pam_access.so
# module, you can change the field separation character to be
# '|'. This is useful for configurations where you are trying to use
# pam_access with X applications that provide PAM_TTY values that are
# the display variable like "host:0".]
#
# permission : users : origins
#
# The first field should be a "+" (access granted) or "-" (access denied)
# character.
#
# The second field should be a list of one or more login names, group
# names, or ALL (always matches). A pattern of the form user@host is
# matched when the login name matches the "user" part, and when the
# "host" part matches the local machine name.
#
# The third field should be a list of one or more tty names (for
# non-networked logins), host names, domain names (begin with "."), host
# addresses, internet network numbers (end with "."), ALL (always
# matches), NONE (matches no tty on non-networked logins) or
# LOCAL (matches any string that does not contain a "." character).
#
# You can use @netgroupname in host or user patterns; this even works
# for @usergroup@@hostgroup patterns.
#
# The EXCEPT operator makes it possible to write very compact rules.
#
# The group file is searched only when a name does not match that of the
# logged-in user. Both the user's primary group is matched, as well as
# groups in which users are explicitly listed.
# To avoid problems with accounts, which have the same name as a group,
# you can use brackets around group names '(group)' to differentiate.
# In this case, you should also set the "nodefgroup" option.
#
# TTY NAMES: Must be in the form returned by ttyname(3) less the initial
# "/dev" (e.g. tty1 or vc/1)
#
##############################################################################
#
# Disallow non-root logins on tty1
#
#-:ALL EXCEPT root:tty1
#
# Disallow console logins to all but a few accounts.
#
-:ALL EXCEPT wheel shutdown sync:LOCAL
#
# Same, but make sure that really the group wheel and not the user
# wheel is used (use nodefgroup argument, too):
#
-:ALL EXCEPT (wheel) shutdown sync:LOCAL
#
# Disallow non-local logins to privileged accounts (group wheel).
#
-:wheel:ALL EXCEPT LOCAL .win.tue.nl
#
# Some accounts are not allowed to login from anywhere:
#
#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL
#
# All other accounts are allowed to login from anywhere.
#
##############################################################################
# All lines from here up to the end are building a more complex example.
##############################################################################
#
# User "root" should be allowed to get access via cron .. tty5 tty6.
+ : root : cron crond tty2 tty3 tty4 tty5 pts/X polkit-1
                    # En pts/X, colocan las cantidad que suelen usar de consolas desde grafica con acceso       root, como ser pts/0 pts/1 pts/2 pts/3 y asi, en ese formato, sin comas ni nada. Si desean permitir el acceso root a las X, no lo recomiendo, añaden :0
#
# User "root" should be allowed to get access from hosts with ip addresses.
+ : root : 192.168..x.x 192.168.x.x // Aqui, colocan su IP y alguna mas que tenga permisos en su lan  //
+ : root : 127.0.0.1
#
# User "root" should get access from network 192.168.201.
# This term will be evaluated by string matching.
# comment: It might be better to use network/netmask instead.
#          The same is 192.168.201.0/24 or 192.168.201.0/255.255.255.0
+ : root : 127.0.0.1
+ : root : 192.168..x.x // Colocan la IP de su LAN, la local, no una mascara, dado que asi, otro de la LAN, puede ser una oficina, tambien tendria acceso //
#
# User "root" should be able to have access from domain.
# Uses string matching also.
# + : root : localhost
#
# User "root" should be denied to get access from all other sources.
- : root : ALL
#
# User "foo" and members of netgroup "nis_group" should be
# allowed to get access from all sources.
# This will only work if netgroup service is available.
#+ : @nis_group foo : ALL
#
# User "john" should get access from ipv4 net/mask
#+ : john : 127.0.0.0/24
#
# User "john" should get access from ipv4 as ipv6 net/mask
#+ : john : ::ffff:127.0.0.0/127
#
# User "john" should get access from ipv6 host address
#+ : john : 2001:4ca0:0:101::1
#
# User "john" should get access from ipv6 host address (same as above)
#+ : john : 2001:4ca0:0:101:0:0:0:1
#
# User "john" should get access from ipv6 net/mask
#+ : john : 2001:4ca0:0:101::/64
#
# All other users should be denied to get access from all sources.
#- : ALL : ALL
En /etc/sysctl.conf añaden esta linea, si es que ya no estan:


net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1

Ahora, aseguremos /etc/sysconfig/init

# nano /etc/sysconfig/init

Tanto en CentOS como SL viene por defecto este valor al final de todo:

SINGLE=/sbin/sushell

Cambienlo por sulogin, eso quiere decir que en single user mode, es decir, runlevel 1, como viene por defecto, el pass de root no se pide, se entrega shell, ahora pedirá el password.


Pueden probar, de iniciar el demonio sshd, permitir el acceso root, y pedir a una persona X de su LAN, que intente acceder, le dira que el password es incorrecto, lo mismo con su usuario. Esto aplica a usuario root y los usuarios del grupo wheel.

Ahora, vamos a establecer los limites, en caso de una fork bomb en bash o .c o .pl, limitamos la cantidad de procesos por usuario a 1024, haciendo:

nano /etc/security/limits.conf

Colocan al final de todo, esta linea

*          soft    nproc     1024

Por ultimo, como dije antes, lo ideal seria que en la instalacion, seleccionen encriptar su /home, por si guardan documentos importantes, pr0n casero o personal, etc.

Ahora, ponemos password a GRUB, para que no puedan obtener una shell con el inicio del GRUB.



1.- tipean en un terminal grub-crypt
2.- Se abrira un prompt, les pedira un password 2 veces, y luego les mostrará un hash, correspondiente al password, en md5.
3.- Editan /boot/grub/menu.lst
4.- Colocan debajo de timeout, en la seccion principal, password --sha512 hash, donde hash, es el hash que les arrojo en el punto 2


Quedando algo asi

#boot=/dev/sda
default=0
timeout=1
password --encrypted
 asdljasdl//jldasljdasd/ (mas largo aun, dado que es sha512)

Ahora, me diran, que gano con TODO esto?, resumiendo

1.- Bloquean cuenta root y no root, tras intento fallido de autenticacion mas de 3 veces y queda logueado
2.- Bloquea intentos de logueo desde la grafica, o sea, el GDM de gnome
3.- Evitan que reinicien o apaguen el equipo sin el pass de root, muy util si dejan una notebook prendida en, no se, la casa de un amigo, un trabajo, para el logour, usen crtl+alt+l bloqueando la pantalla.
4.- Va a requerir contraseña de usuario cada vez que intenten acceder al deposito de claves de gnome, por ejemplo, si abren Chrome y tenian contraseñas guardadas, no los va a dejar acceder a ningun sitio donde tengan contraseñas alojadas, sin antes ingresar el password, esto lo pide por sesion, no cada vez, asi que una vez desbloqueada la sesion no lo pide nuevamente, lo mismo sucede con los demas depositos de claves
5.- Deniegan cualquier peticion de red a su X.org
6.- Evitan cualquier modificacion de los archivos que acabamos de configurar, a menos que sea el root y use el comando chattr -i antes que nada.
7.- Usuarios privilegiados, ustedes y el root, solo podran acceder a la PC de forma local y nadie podra acceder de forma remota, a menos que especifiquen la IP del mismo.
8.- Detener una bomba fork evitando que el sistema colapse
9.- Evitar que inicien tu PC, ejecuten una shell de GRUB y obtengan root, pudiendo borrar todo o cambiar todos los password del sistema

Bueno, parece un poco paranoico esto no?, pero bueno, si miran la seguridad de sistemas como BSD, OSX y otros, veran que esto viene por defecto, a muchos les molesta, pero les aseguro que mejor prevenir que curar.

Como ultima nota y la remarco, si tienen documentos importantes en su /home, es recomendable que al instalar CentOS, SL o Fedora, cifren desde el instalador, la particion, la opcion esta en Anaconda, el instalador de RHEL.


Para mas informacion, man, lean los manpages de todo, y Google!

Saludos!

No hay comentarios: