autenticación

  • Este artículo explica cómo implementar autenticación Basic con Nginx en Debian/Devuan o Ubuntu.

  • En el artículo Cómo autenticar con clave pública en SSH expliqué detalladamente todos los pasos necesarios para autenticar con clave pública un usuario a través de SSH.

    Para que el usuario con el que ejecutamos ansible (en este caso root) sea capaz de autenticar con clave pública (sin contraseña) en los servidores, será necesario agregar la clave pública del mismo en cada archivo authorized_keys perteneciente al usuario con el cual queremos autenticar en cada sistema remoto. Es una tarea tediosa, pero debe realizarse una única vez.

  • Recientemente me tocó configurar un servidor MySQL para autenticar usuarios mediante certificados SSL en lugar de contraseñas. El mecanismo de autenticación necesita un certificado para el servidor MySQL y un certificado para cada usuario, todos firmados por la misma autoridad certificante (CA).

  • ¿Cansado de tener que tipear el usuario y contraseña cada vez que ejecutamos un push hacia GitHub? Este artículo explica cómo configurar la autenticación con clave pública por SSH para no tener que tipear nuestro usuario y clave nunca más.

  • En este artículo voy a explicar cómo autenticar una sesión SSH utilizando clave pública, para permitir que un usuario se conecte a un sistema remoto sin necesidad de escribir la contraseña. Esta configuración es útil para cuando se requiere trabajar con scripts que se conectan a sistemas remotos de forma automática desde tareas programadas, por ejemplo los sistemas de respaldo (backup).

  • En sistemas Unix y derivados (Linux, *BSD, etc.) la implementación de TCP/IP considera especiales a los puertos debajo del 1024 (llamados "puertos privilegiados"), en el sentido de que a los usuarios no privilegiados no se les permite iniciar servicios o escuchar peticiones en los mismos. Los puertos TCP y UDP entre 1 y 1023 están reservados para procesos corriendo con privilegios de superusuario (es decir, como root). A aquellos procesos corriendo con un ID de usuario distinto de 0 no se les permite escuchar peticiones en dichos puertos (bind).

    Esta característica de seguridad es una especie de protección para los clientes en el sentido de que, si se conectan a un servicio escuchando en un puerto bajo, pueden estar seguros de que se trata de un servicio confiable (y no uno falso levantado por un impostor) ya que para ello debe haber sido autorizado por el administrador del servidor. Esta protección es importante, ya que en la mayoría de los servicios los clientes envían credenciales de autenticación. Si un usuario no privilegiado es capaz de recibir conexiones entrantes en puertos privilegiados, podría llegar a impersonar servicios y robar credenciales.

    Sin embargo, la implicancia que tiene esta protección (desde el lado servidor), es que todos los servicios deben correr como superusuario (root). Ante un bug o vulnerabilidad en cualquiera de los servicios, resulta comprometido todo el servidor, ya que se logra automáticamente el acceso como root.

    Lo que la mayoría de los servicios implementan para minimizar la superficie de ataque (por ejemplo Apache), consiste en iniciar primero un proceso mínimo corriendo como root (el cual abre el puerto bajo necesario para trabajar) para luego iniciar hijos corriendo con un usuario no privilegiado, los cuales se encargan de procesar las peticiones. De esta forma, ante una vulnerabilidad en el procesamiento, resulta comprometido un proceso corriendo como usuario no privilegiado.

    root@www:~# ps -C apache2 -o user,pid,time,stat,start,comm
    USER       PID     TIME STAT  STARTED COMMAND
    www-data  7681 00:00:00 S    10:32:04 apache2
    www-data  7808 00:00:00 S    10:36:53 apache2
    www-data  7812 00:00:00 S    10:36:54 apache2
    www-data  7819 00:00:00 S    10:37:01 apache2
    www-data  7832 00:00:00 S    10:37:32 apache2
    www-data  7833 00:00:00 S    10:37:33 apache2
    www-data  7846 00:00:00 S    10:38:13 apache2
    www-data  7849 00:00:00 S    10:38:35 apache2
    www-data  7851 00:00:00 S    10:38:39 apache2
    www-data  7852 00:00:00 S    10:38:39 apache2
    www-data  7853 00:00:00 S    10:38:40 apache2
    www-data  7854 00:00:00 S    10:38:40 apache2
    www-data  7857 00:00:00 S    10:38:59 apache2
    www-data  7871 00:00:00 S    10:39:01 apache2
    www-data  7872 00:00:00 S    10:39:01 apache2
    www-data  7873 00:00:00 S    10:39:01 apache2
    www-data  7874 00:00:00 S    10:39:01 apache2
    www-data  7877 00:00:00 S    10:39:02 apache2
    www-data  7879 00:00:00 S    10:39:02 apache2
    www-data  7881 00:00:00 S    10:39:02 apache2
    www-data  7883 00:00:00 S    10:39:02 apache2
    www-data  7885 00:00:00 S    10:39:07 apache2
    root     19377 00:07:40 Ss     May 28 apache2
    

    El proceso principal (el cual escucha en los puertos 80 y 443) corre como root, y sus hijos (los cuales se encargan de procesar las solicitudes) corren como el usuario no privilegiado "www-data" (o "apache" en Red Hat y derivados). Notar además, en las fechas de inicio (STARTED), que los procesos hijos pueden ser iniciados a demanda, e incluso "reciclados" cada determinado período de tiempo.

    Pero, ¿qué pasa si tenemos un servicio que requiere escuchar en un puerto bajo y no implementa esta separación de privilegios? Por ejemplo, alguna bazofia desarrollada en Java (mi experiencia dicta que los desarrolladores Java son los que menos idea tienen o menos se preocupan por la seguridad, a tono con dicha tecnología, por cierto). Lógicamente no queremos que dicho servicio tenga privilegios de root en nuestro servidor (si no es capaz de implementar una separación adecuada de privilegios, poco podemos esperar de su seguridad, confiabilidad y robustez en general). Ante estos casos afortunadamente existen diferentes técnicas que permiten implementar una correcta separación de privilegios, por fuera del servicio. En este artículo se presenta la herramienta authbind. Otra técnica conocida consiste en levantar el servicio en un puerto alto e implementar una redirección de tráfico con iptables (siempre que el servicio permita configurar su rango de puertos de trabajo).

  • En uno de los servidores Web que administro, una nueva aplicación requirió proteger el acceso a un directorio mediante autenticación Digest. En el artículo Proteger con contraseña un directorio Web expliqué cómo configurar la autenticación Basic en Apache. Pero para el caso de Digest, el procedimiento es levemente diferente ya que se debe configurar correctamente el Realm de cada usuario y directorio.

  • Tanto la API HTTP como el cliente de línea de comandos (que también utiliza la API HTTP para conectarse al motor) de InfluxDB, incluyen un mecanismo de autenticación simple basado en credenciales de usuario (nombre de usuario y contraseña). Cuando se habilita la autenticación en InfluxDB, el motor sólo ejecuta los pedidos HTTP que incluyan credenciales válidas. Este mecanismo de autenticación no está habilitado por defecto, por ende este artículo explica cómo habilitar la autenticación en un servidor InfluxDB, y cómo crear un usuario con privilegios de sólo lectura (para Grafana), a fin de mejorar la seguridad de la instalación.