Tag administración de sistemas

list open files (lsof)

lsof es una utilísima orden que nos muestra la información relacionada con los descriptores de archivo de nuestro sistema. Por ejemplo, cuando queremos desmontar un sistema de archivo y la respuesta es “Error: sistema ocupado”, con ‘lsof +D /punto_de_montaje‘ podemos saber todos los procesos (la primera columna de la fila, o filas, que obtenemos como respuesta) que están utilizando dicho sistema de archivos (y actuar en consecuencia).

¿Qué más podemos saber con él? Pues conocer/obtener el listado de:

Leer más


Otra protección más con iptables y módulo recent

Al hilo de esta entrada, si lo que queremos es controlar, incluso, un posible escaneo de puertos desde una IP, y no solo peticiones abusivas a uno de nuestros servicios que es de lo que trataba la entrada anterior, tenemos:

iptables -I INPUT  --m state --state NEW -m recent  --set
iptables -I INPUT  --m state --state NEW -m recent  --update --seconds 60 --hitcount 5 -j DROP

Con la ejecución de estas 2 órdenes, cualquier intento de realizar más de 5 conexiones (destinados a cualquiera de nuestros puertos) desde una misma IP, producirá un bloqueo de las conexiones desde esta IP durante 60 segundos.

Este es un mecanismo fácil, rápido y eficiente de control de las peticiones que recibimos en nuestros servidores y más ligero que opciones como la comentada aquí, ya que detectamos y protegemos con el módulo recent de iptables, en un nivel más bajo y que apenas introduce carga al sistema.

Como ya comenté, lo podemos hacer también en routers, solo que afecta a otras tablas/cadenas (filter/FORWARD, nat/PREROUTING,…) y opciones a considerar.

¡Espero que os sea útil!

 Referencias

  1. man iptables

Más sobre fortificación de SSH

En cuanto ponemos un servicio SSH accesible desde cualquier parte de Internet, los ataques de fuerza bruta y demás se suceden casi al instante (es una licencia, evidentemente, hay un tiempo de “descubrimiento”). Nos llegan desde todo el globo terráqueo por lo que, hablando de protección y suponiendo que nunca accederá un usuario desde determinados continentes o países, aplicar la Geolocalización IP para deshabilitar conexiones se convierte en una opción muy interesante. Aún reconociendo la importancia de realizar buenos filtros y de implementar mecanismos de autenticación multifactor, en esta entrada nos vamos a centrar solo en las opciones de SSH básicas para su protección. He tomado como base, la clase que impartía en Administración de Servicios de Internet dedicada a SSH y su fortalecimiento.

Las opciones con las que vamos a intentar mejorar y adaptar la configuración de nuestro servicio a nuestra política de seguridad y a nuestras necesidades, las encontraremos en el fichero /etc/ssh/sshd_config.

Empecemos….

Leer más


Fortificando el acceso con SSH: 2FA con Google Authenticator

Como comentaba al final de la entrada anterior, quien disponga de un hosting propio al que se conecte con sesiones de trabajo también debería estar interesado en fortificar este acceso utilizando un mecanismo 2FA en el servicio SSHGoogle Authenticator es una buena opción, entre otros argumentos, nos centraliza en la misma herramienta el acceso a múltiples servicios: los de Google, Redes Sociales,…

Para el caso que nos ocupa, debemos, para CentOS:

  • Instalar en el servidor el software necesario para la autenticación.
yum install pam-devel make gcc-c++ wget 
wget http://google-authenticator.googlecode.com/files/libpam-google-authenticator-1.0-source.tar.bz2
tar xvf libpam-google-authenticator-1.0-source.tar.bz2 && cd libpam-google-authenticator-1.0
make
sudo make install
  • Este sistema está basado en el tiempo y, por tanto, debemos asegurarnos que la fecha y hora de nuestros sistemas estén sincronizadas. Es un paso MUY IMPORTANTE y, si no lo hacemos, NO FUNCIONARÁ. Para ello, debemos instalar el servidor ntp y configurarlo para que se sincronice con algún servicio accesible desde nuestra red:
yum install ntp
En el fichero /etc/ntp.conf añadimos la información de nuestro servidor de tiempos: server servidor_ntp
service ntpd start
  • Ejecutamos google-authenticator con el usuario que queremos proteger (no tienen que ser todos) Nos generará un enlace al sitio de Google donde encontraremos el código QR con el que debemos, en nuestro móvil y con la app Google Authenticator, crear una cuenta para nuestro acceso SSH igual que comentamos en la entrada anterior para WordPress. Además, nos proporcionará los códigos de un solo uso que debemos usar cuando no tengamos disponible dicha app.
  • Además de la ejecución, deberemos responder a 4 preguntas: mejor ‘Y’ a todas ;).
    • Con la primera, le estamos indicando que queremos que los tokens estén basados en el tiempo y que actualice el fichero HOME/.google_authenticator que es donde almacenará información importante como el enlace y los código mencionados en el punto anterior.
    • En la segunda nos pregunta si queremos deshabilitar el uso del mismo token por diferentes usuarios
    • En la tercera nos indica el tiempo por defecto (30″) para compensar posibles diferencias temporales entre cliente y servidor
    • Y en la última, limita el número de intentos a 3 cada 30″ para evitar ataques de fuerza bruta
  • En el siguiente paso, debemos configurar el módulo PAM del servicio SSH. En el fichero /etc/pam.d/sshd debemos añadir
auth   required  pam_google_authenticator nullok secret=/home/${USER}/.google_authenticator

nullok permite que los usuarios para los que no tengamos configurado el segundo factor de autenticación, puedan entrar al sistema sin solicitarles el código. Con secret le indicamos dónde está el fichero con la información de autenticación.

  • En el fichero /etc/ssh/sshd_config debemos activar (escribir  YES) la opción ChallengeResponseAuthentication.
  • También debemos asegurarnos, en el mismo fichero, que esté UsePAM yes y PubKeyAuthentication no
  • Y finalmente, reiniciar el servicio ejecutando:
service sshd restart

Existen más opciones que nos pueden interesar para afinar el sistema 2FA. Por ejemplo una idea es que cuando accedamos desde determinados sitios (nuestra red local), no nos solicite el segundo factor. Esto se consigue con la instalación (si no está ya) del módulo pam_access y configurando las PAM:

auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/access-local.conf
auth       required     pam_google_authenticator.so nullok secret=/home/${USER}/.google_authenticator

Además, en el fichero /etc/security/access-local.conf debemos escribir algo parecido a esto (donde 10.0.0.0/24 es la red local):

# only allow from local IP range
+: ALL :10.0.0.0/24
+: ALL : LOCAL
-: ALL : ALL

Si queremos que el 2FA NO se aplique a los usuarios de un grupo determinado:

auth [success=1 default=ignore] pam_succeed_if.so user ingroup sudo
auth       required     pam_google_authenticator.so nullok secret=/home/${USER}/.google_authenticator

Si quisiéramos que se aplicara solo a ese grupo, basta con sustituir “user ingroup” por “user notingroup

La información de esta entrada sirve también para proteger otros servicios de sesión de usuario como login, su, sudo, lightdm

¡Espero que os sea útil!

Referencias

  1. https://code.google.com/p/google-authenticator/wiki/PamModuleInstructions

 


Fortificando la autenticación de usuarios en WordPress

Al margen de la elección de contraseña, es una opinión, y cada vez más generalizada, que para aumentar la seguridad en la autenticación de los usuarios, debemos recurrir a sistemas MFA (Multi-Factor Authentication). Estos sistemas consisten en incluir diferentes factores de autenticación (2 o más): uno basado en algo que conocemos (por ejemplo, el clásico de la contraseña); otro en algo que poseemos (el móvil, por ejemplo) y/o algo que solo es el usuario (por ejemplo, su huella o cualquier característica biométrica).

Si queremos mejorar la seguridad de nuestro blog, existen pluggins que implementan un mecanismo 2FA (doble factor de autenticación) basado en Google Authenticator. En este blog estoy probando: WP Google Authenticator.

Es muy fácil de utilizar:

  1. Lo instalamos (Plugins>Añadir Nuevo y tras esto: Activar)
  2. Tras este proceso, en Ajustes, tendremos las opciones del plugin. En mi caso activé que el número máximo de veces que se puede autenticar un usuarios sin 2FA sea de 3)
  3. En Usuarios>Tu Perfil, abajo aparece información importante. Por un lado, el botón Get QR Code al que pulsaremos para obtener el código QR  sincronizará la aplicación Google Authenticator de nuestro móvil con el plugin. Para esto:
    • Arranqueremos en nuestro móvil Google Authenticator,
    • En Menú: Configurar Nueva cuenta,
    • Escanear código ¡et voila!
  4. Además en Usuario>Tu perfil tendremos el código de recuperación y tu clave secreta que no debes compartir con nadie.

Ahora, cada vez que queremos acceder al control de nuestro WordPress, nos encontraremos con:

Captura de pantalla de 2014-07-30 12:57:32

Quien disponga de un hosting propio al que se conecte con sesiones de trabajo que quiere fortalecer, también podemos utilizar Google Authenticator para implementar  un 2FA en el servicio SSH. Esto, en otra entrada que publicaré en breve 😉


Super User DO

SuDO es una herramienta que, como comentamos en esta entrada anterior, nos permite realizar una buena gestión de privilegios e implementar una administración compartida de los sistemas. En general, lo que nos permite es ejecutar las órdenes deseadas con los identificadores de usuario (UID y EUID) y grupo (GID y EGID) necesarios para su correcta ejecución, no es necesario que sea solo para  root. En el caso (bastante deseable) de que se necesite autenticar al usuario, esta acción se realizará con la contraseña del usuario que ejecuta la orden y no con la del usuario objetivo (es decir, NO con la de root).

La instalación es sencilla (sistemas Debian):

apt-get install sudo

Para la configuración: /etc/sudoers

Este es un fichero de texto en el que, cada línea, debe seguir la siguiente sintaxis:

[usuario/%grupo] [equipo] = [(id:gid del usuario objetivo)] órdenes

También admite alias con esta sintaxis:

alias nombre = elemento_alias

Los alias pueden ser de órdenes: Cmnd_Alias para lista de órdenes; User_alias para listas de usuarios; Host_alias, para listas de equipos

Un ejemplo de /etc/sudoers que usamos en la EPS es:

Cmnd_Alias CMDADMIN = /sbin/shutdown, /etc/init.d/sshd, /etc/init.d/network, /etc/init.d/rsysklog, /etc/init.d/nscd, /etc/init.d/tomcat, /etc/init.d/httpd, /etc/init.d/apache2
User_Alias USRWWWDATA = www-data, wwwadm
USRWWWDATA ALL= NOPASSWD: CMDWWWDATA

En este ejemplo se han definido 2 alias: CMDADMIN con la lista de comandos que van a poder ejecutar los usuarios listados en USRWWWDATA.

La última línea habilita la ejecución de las órdenes listadas en CMDWWWDATA por los usuarios definidos en USRWWWDATA como si las estuviera ejecutando el usuario root (no pone usuario objetivo por lo que es root). La expresión “como si las estuviera ejecutando” es una forma de expresarme. Como he comentado antes, la ejecución es con UID, EUID, GID y EGID de root (para este caso, en otros, con el del usuario objetivo.

De esta forma, los usuarios wwwadm y www-data pueden parar, reiniciar, lanzar Apache, Tomcat, nscd, ssh,… sin necesidad de conocer la contraseña del administrador.

También podríamos usar la directiva Defaults con la que podríamos definir determinadas opciones globales de comportamiento de sudo. Un uso interesante es:

Defaults env_reset, timestamp_timeout=1,passwd_timeout=2,passwd_tries=1

que implica que los usuarios tendrán:

  • Un solo intento de autenticación (passwd_tries=1),
  • tiempo de sesión sin solicitar de nuevo la contraseña de 1 minuto (timestamp_timeout=1),
  • timeout de 2 minutos.

Con la opción env_reset lo que se pretende es eliminar todas las variables de entorno del usuario salvo LOGNAME, SHELL, USER, USERNAME, MAIL y las de SUDO_*

Referencias:

  1. man 8 sudo
  2. man 5 sudoers
  3. Hardening de servidores GNNU/Linux, Carlos Álvarez Martín y Palo González Pérez, 0xWord, 2013

Administración de sistemas compartida

En mis clases de Administración de sistemas operativos en Red me gustaba recalcar, dentro del tema de gestión de usuarios, la importancia del usuario administrador (root) y cómo llegar a serlo. Su importancia radica, como sabemos, en que es el encargado de la ejecución de las tareas de administración, instalación, configuración, monitorización y seguridad de los sistemas de tal forma que, en infraestructuras de cierto tamaño, es fácil que existan varios administradores.

En estas circunstancias ¿cómo se reparten el trabajo? ¿por equipos/servidores? Y si el responsable de un servidor no está, ¿el resto se desentiende?  Para responder a esta última pregunta como un equipo profesional, debemos permitir la administración compartida y colaborativa  entre varios administradores y que puedan, cualquiera de ellos, administrar (ejecutar tareas de un administrador) un mismo sistema.

Una manera es conociendo todos la contraseña de root. En mi opinión no es una buena opción ya que diluye la responsabilidad. En GNU/Linux existe una utilidad que nos permite, precisamente, obtener las bondades mencionadas anteriormente sin necesidad de que todos los administradores conozcan la contraseña de root: sudo.

El uso de sudo tiene las siguientes ventajas:

  • Alta contabilidad: se registra las órdenes y quién las ejecutó en los registros de eventos del sistema (los logs)
  • Como ya he comentado: se limita el conocimiento del passwd de root a una única persona y sin limitar la labor de los operadores, por ejemplo, a los que les podemos dar autorizaciones concretas.
  • No se necesitan establecer sesiones de trabajo de root.
  • Los privilegios pueden ser revocados cuando se necesite.
  • Tenemos una lista de todos los usuarios con privilegios de root y qué es lo que pueden hacer con esta responsabilidad (está en la configuración del comando).
  • Las restricciones de acceso son dependientes del host, un fichero simple puede ser usado para el control de acceso a una entidad de red.

Como no es oro todo lo que reluce, también tenemos varias desventajas:

  • Una brecha en la seguridad de la cuenta de usuarios es equivalente a una brecha en la de root (para las acciones autorizadas)
  • Una mala configuración, como es el uso de path relativos para describir las órdenes autorizadas, puede provocar problemas debido a engaños con ejecuciones del “programas no controlados” como si fuera un programa permitido. Se arregla con el uso sin path absolutos en las configuraciones.

Para utilizarlo, debemos instalarlo y configurar el fichero /etc/sudoers, pero esto, será otro día…

 


¿Estamos bajo un ataque DoD o DDoS?

Esta tarde he estado leyendo esta entrada (y a la que le “he robado el título”). Como bien comenta el autor, una de las características que un ataque de denegación de servicio (DoS) presenta, ya sea distribuido o no, es el gran número de conexiones que recibirá nuestro sistema. En esta entrada, podéis consultar una serie de órdenes de shell que nos permiten obtener información sobre las conexiones de nuestro servidor y, en función de ésta, detectar un posible ataque.

Algo parecido hace el guión de Python que os copio debajo. Si le introducimos uno de los estados en los puede estar una conexión, nos indica, para cada IP que ha establecido contacto con nuestro servidor, cuantas conexiones están en ese estado (y para cualquier puerto). El guión da para mucho y, evidentemente, también para detectar situaciones anómalas en las que tenemos muchas conexiones “SYN_REC” que denotaría un posible DoS (o DDoS, dependiendo del número de IPs) e, incluso, un posible escaneo de puertos.

#!/usr/bin/python
#encoding:utf-8
try:
 import optparse, sys, re, socket
except:
 print("Error executing 'import optparse, sys, re, socket' command")
 exit(1)
try:
 import socket
 from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
 import psutil
 from psutil._compat import print_
except:
 print "Error importing socket & psutil module. It is possible you need running 'apt-get install python-psutil'"
 exit(1)
def main():
 parser = optparse.OptionParser("usage%prog " + "-s <state>")
 parser.add_option('-s', dest = 'state', type = 'string', help = 'Please, specify the connection state to analize', default="ESTABLISHED")
 (options, args) = parser.parse_args()
 ipConnected = { }
 for conn in psutil.net_connections(kind='inet'):
 if conn.status == options.state:
 ip=conn.raddr[0]
 if (ip in ipConnected):
 ipConnected[ip]= ipConnected[ip]+1
 else:
 ipConnected[ip]=1
 print "Remote IPtt|# " + options.state + " connections"
 print "---------------------------------"
 for ip in ipConnected.keys():
 print "%stt|%s" % (ip, str(ipConnected[ip]))
if __name__ == '__main__':
 main()

El guión admite muchas mejoras. Por ejemplo, y para el caso comentado, poner un límite a partir del cual nos avise o active un filtro para esa IP. También podríamos comprobar lo mismo, pero solo para un servicio (puerto) determinado y que podríamos introducir como parámetro de entrada.

¡Espero que os sea útil!

 


IGMP: tráfico multicast y filtros

Cuando diseñamos una red una de las tecnologías/infraestructuras que planificaremos será la instalación de un cortafuegos*. En estas circunstancias tenemos que tener claro qué paquetes dejamos pasar, cuales desechamos, y todo en función de nuestra política de seguridad y sin perder la funcionalidad para la que estamos diseñando nuestra red.

Si utilizamos OSPF o, en general, si queremos manejar tráfico multicast, debemos habilitar los paquetes IGMP en nuestros filtros (suponiendo que tenemos la estrategia de denegar todo lo que no está explicitamente habilitado) ya que es el protocolo que utilizaran hosts y routers para establecer los miembros de los grupos de multicast. De este protocolo, debemos tener en cuenta, sobre todo, que se encapsula en datagramas IP con el número 2 de protocolo (esto implica que NO utiliza UDP ni TCP ni, por tanto, tiene puertos). Otro detalle que debemos tener en cuenta es que el TTL de los paquetes de IGMP, por defecto, es 1, lo que implica que no “atravesarán” los routers y no saldrán de la subred en la que se genera, aunque puede aumentarse para localizar servidores lejanos utilizando este campo como “barrera” y configurando los routers para que sean transparentes y no decrementen el TTL**.

La ejecución de las siguientes órdenes provocará que nuestro router de filtrado acepte y saque mensajes IGMP:

iptables -A INPUT -p igmp -j ACCEPT
iptables -A OUTPUT -p igmp -j ACCEPT

Para el caso de los grupos multicast relacionados con OSPF que comentábamos en la entrada anterior, podríamos limitar las reglas habilitando solo los grupos relacionados con OSPF:

iptables -A INPUT -p igmp -d 224.0.0.5 -j ACCEPT
iptables -A INPUT -p igmp -d 224.0.0.6 -j ACCEPT
iptables -A OUTPUT -p igmp -d 224.0.0.5 -j ACCEPT

Referencias

  1. Building Internet Firewalls, de Elizabeth D. Zwicky, Simon Cooper y D. Brent Chapman
  2. https://tools.ietf.org/html/rfc3376, RFC para IGMP versión 3
  3. http://tools.ietf.org/html/rfc2236, RFC para IGMP versión 2

* Prefiero usar el concepto de cortafuegos para la infraestructura de protección de red que diseñamos y que puede estar compuesta por varios elementos donde, uno de ellos, el dispositivo de red que filtra paquetes y que -casi- todo el mundo denomina cortafuegos, yo prefiero denominarlo router de filtrado.

** Una orden genérica para este caso es: iptables -A FORWARD -p igmp -j ACCEPT Si queremos, por ejemplo, especificar que el tráfico que queremos es el relacionado con el audio/vídeo: iptables -A FORWARD -p udp -m udp -d 239.0.0.0/16 –dport 5001 -j ACCEPT

 


Filtros de red para OSPF (Open Shortest Path First)

Si en nuestros routers utilizamos la estrategia de denegar todo por defecto y permitir expresamente lo que deseamos, en el caso de que estos equipos tengan configurado que aprendan sus rutas con OSPF, debemos habilitar dicho protocolo. Para ello, debemos tener en cuenta que OSPF

  • se encapsula en datagramas IP con el número 89 de protocolo (esto implica que NO utiliza UDP ni TCP ni, por tanto, tiene puertos),
  • usa tanto paquetes multicast (los grupos 224.0.0.5 y 224.0.0.6 y lo que nos obliga a configurar, usar y habilitar en nuestros filtros IGMP*) como unicast,
  • el TTL de sus paquetes es 1, por lo que no atravesarán un cortafuegos, salvo que configuremos un túnel (http://www.cisco.com/en/US/tech/tk583/tk372/technologies_configuration_example09186a00800a43f6.shtml),
  • y por último, dispone de un identificador de tipo de paquete (nos permite mejorar las reglas, aunque dependemos del software de filtrado).

Con iptables, la forma más fácil es ejecutar las siguientes ordenes**:

iptables -A INPUT -p 89 -j ACCEPT
iptables -A OUTPUT -p 89 -j ACCEPT

Si queremos ser más “finos”, debemos indicar las IPs de origen, destino y, si lo permite el software de filtrado, el tipo de paquete de OSPF. Las reglas en este caso***:

#hello ospf between rt_ext and rt_int
iptables -A INPUT -s rt_ext -d 224.0.0.5 -p 89 -j ACCEPT
iptables -A OUTPUT -s rt_int -d 224.0.0.5 -p 89 -j ACCEPT
#database description, link state request, asking for information about a particular link and request/update link state
iptables -A INPUT -s rt_ext -d rt_int -p 89 -j ACCEPT
iptables -A OUTPUT -d rt_int -s rt_int -p 89 -j ACCEPT
#link state update, flooding all link states from rt_ext router
iptables -A INPUT -s rt_ext -d 224.0.0.5 -p 89 -j ACCEPT
iptables -A OUTPUT -s rt_int -d 224.0.0.6 -p 89 -j ACCEPT
iptables -A INPUT -s rt_ext -d 224.0.0.6 -p 89 -j ACCEPT
iptables -A OUTPUT -s rt_int -d 224.0.0.5 -p 89 -j ACCEPT
#rt_int router link state update from rt_ext router
iptables -A OUTPUT -s rt_int -d 224.0.0.5 -p 89 -j ACCEPT
iptables -A INPUT -s rt_ext -d 224.0.0.6 -p 89 -j ACCEPT
iptables -A OUTPUT -s rt_int -d 224.0.0.6 -p 89 -j ACCEPT
iptables -A INPUT -s rt_ext -d 224.0.0.5 -p 89 -j ACCEPT

Referencias

  1. Building Internet Firewalls, de Elizabeth D. Zwicky, Simon Cooper y D. Brent Chapman

* Es muy sencillo, pero lo dejo para otra entrada 😉

**Estamos considerando que NO queremos reenviar (forward). Si quisiéramos hacerlo, ver el punto 3 de las consideraciones de OSPF que he escrito en la entrada. Además, estas reglas deben ejecutarse en los routers designados.

***Las reglas se deben de ejecutar en los router afectados (en rt_ext cuando ‘-s rt_ext’ o en rt_int si ‘-s rt_int’), salvo que dispongamos de un cortafuegos específico y, en ese caso, se ejecutan todas en él. Recordad que debe disponer de un túnel (ver **)


Las cookies nos permiten ofrecer nuestros servicios. Al utilizar nuestros servicios, aceptas el uso que hacemos de las cookies. Más información.