LinuxParty

NUESTRO SITIO necesita la publicidad para costear hosting y el dominio. Por favor considera deshabilitar tu AdBlock en nuestro sitio. También puedes hacernos una donación entrando en linuxparty.es, en la columna de la derecha.

Ratio: 5 / 5

Inicio activadoInicio activadoInicio activadoInicio activadoInicio activado
 

Administrar la seguridad de la red

Dejamos atrás de cierta forma todo lo que aquí se recoge con respecto a la seguridad local y damos paso al primer o segundo muro con el que chocará un atacante, y decimos primer o segundo por el mismo motivo que comentábamos en la sección de la seguridad local, puesto que dependerá desde donde se produzca el ataque. Lo que ya tenemos claro es que contra mas piedras pongamos en el muro mas difícil o mas tiempo llevará su derribo y con ello su penetración.

En esta sección del capítulo vamos a estudiar aquellos aspectos a tener en cuenta con referencia a la red. Haremos una pequeña introducción sobre alguna de las técnicas mas usadas para el ciberataque y algunas posibles contramedidas.

Técnicas utilizadas en los ataques y contramedidas

La ciberseguridad es algo que se encuentra en constante cambio, siempre existen mejoras y al poco tiempo se encuentran vulnerabilidades que explotar para esas nuevas mejoras. Se pueden encontrar vulnerabilidades a nivel de software o hardware por lo que es importante mantenerse siempre actualizado. A continuación se enumerarán algunas técnicas de ataque o tipos de vulnerabilidades y sus contramedidas o posibles métodos preventivos para la detección de lo que puede estar sucediendo en nuestro sistema:

 

  • Bugs: También llamados holes o agujeros. Son fallos en el software, hardware, servicios, protocolos o directamente en el sistema operativo que se aprovechan para romper la seguridad del sistema y explotar los recursos, obtener información, elevación de privilegios, etc… Para ello se utilizan los llamados bugs exploits, que no son mas que fragmentos de código malicioso y comandos, que realizan técnicas de ataques genéricos o particulares para el elemento afectado. Para aquellos bugs que aún no han sido conocidos y que están siendo explotados suele utilizarse el termino día cero (tanto para el bug como para el exploit). Para remediar en lo posible caer en un ataque por bugs, es aconsejable mantenerse actualizado a nivel de software, hardware y servicios del sistema, así como a la desactivación e incluso desinstalación de todos aquellos programas que han quedado obsoletos o no son utilizados. Como administrador de sistema es igualmente importante mantenerse actualizado con respecto a las vulnerabilidades encontradas, como mínimo de aquellos programas de los que hacemos uso.
  • Virus: Son programas normalmente adjuntos a otros que utilizan técnicas de autocopiado y transmisión, para infectar un sistema. Suelen anexarse a programas que permiten lenguaje de macros (no verificados) como ejecutables, correo electrónico e incluso documentos. En Linux si no hacemos un uso abusivo de root o no ejecutamos programar que desconocemos, estamos casi totalmente a salvo ya que no se utiliza lenguaje de macros no verificados, ni en los documentos ni en el correo electrónico. No obstante, pudiesen aparecer a consecuencia de bugs en el sistema o incluso podemos llamar correo “virulento” a aquel que se pueda reenviar haciendo uso de nuestro sistema vía email como el spam. Para frenar un virus la primera medida a adoptar es la de instalar un sistema de antivirus, anti spam y anti malware. Luego será cosa nuestra el no ejecutar programas sospechosos, sistemas macros no verificados, crear reglas de filtrado tanto a nivel de correo electrónico como de firewall, etc..-
  • Worm: El termino worm o gusano es utilizado para identificar a aquellos programas que aprovechan algún agujero del sistema para realizar ejecuciones de código malintencionado sin permisos, con el fin de hacer uso de los recursos del sistema, como por ejemplo la CPU. Al igual que los virus usan técnicas de autocopiado y transmisión. Una buena medida a adoptar para saber si podemos estar infectados por un gusano es monitorizar nuestro sistema, comprobar el uso de los recursos que se está haciendo, los usuarios que hacen uso de este y sobre todo la explotación de recursos de hardware a horas en las que no existe un porque para que la máquina este trabajando de forma constante. Igualmente importante es analizar el tráfico de entrada y salida a la red.
  • Trojan Horse: El caballo de Troya o troyano son programas útiles pero que ocultan funcionalidades malintencionadas utilizadas para obtener información del sistema o comprometerlo de manera que por ejemplo pueda ser utilizado en un futuro por su creador. Suelen ser buenos métodos de transmisión programas aparentemente muy útiles y utilizados como por ejemplo los generadores de claves usados para crackear algún programa, video-juegos, etc… Las aplicaciones web desarolladas en Java, JavaScript o ActiveX, en caso de existir bugs en estas, pueden ser un buen método de transmisión una vez que el usuario acepta y consiente la ejecución de la aplicación. Si queremos comprobar la integridad de un programa de lo mejor que podemos hacer es verificarlo mediante los mecanismos de suma de verificación y firmado (md5 o gpg). Como con los gusanos, deberemos de prestar atención al uso de red que se está produciendo, filtrando mediante firewall posible tráfico sospechoso.
  • Backdoor: Puerta trasera en Español y que referencia posibles métodos de entrada ‘escondidos‘ en una aplicación o sistema, con el fin de poder evitar la seguridad y acceder a él. En numerosas ocasiones las backdoor son creadas a propósito con el fin de poder acceder a un sistema o programa bajo circunstancias estrictamente necesarias. Lo que se hace básicamente es introducir una secuencia especial dentro del código de programación con el fin de poder evitar los sistemas de seguridad del algoritmo (autentificación) para acceder al sistema o herramienta. Existen herramientas como Netcat que pueden ser empleadas para abrir puertas traseras o defenderse de ellas. Para saber si un software que vamos a proceder a instalar contiene backdoors, es primordial obtener de los proveedores del mismo la certificación de que éste no contiene ningún tipo de puerta trasera escondida no documentada. Si tenemos un programa ya descargado que se ha verificado y probado que no contiene puertas traseras, estaría bien crear una suma de verificación o respaldo del mismo de manera que podamos evitar la creación de una backdoor a posteriori volviendo atrás o comprobando su integridad mediante la suma.
  • Keyloggers: Utilizado para captar la interacción del usuario con el teclado de manera que pueda ‘secuestrar‘ la contraseña del usuario en cuestión. Pueden ser programas individuales o troyanos incorporados en otros programas.
  • Rootkits: La palabra rootkit proviene de la unión de ‘root‘, es decir raíz o administrador en sistemas Linux y ‘kit‘, conjunto de herramientas que permiten a un atacante obtener acceso con privilegio a la máquina esquivando los métodos de autenticación. Los rootkits se han catalogado como malware aunque por si solo no tiene porque afectar el rendimiento de la máquina ya que su función principal es la de esconder la presencia del atacante en el sistema (a él, a los puertos que utiliza, sus conexiones de red, etc..) mediante un conjunto de herramientas (cada unas destinada a un fin concreto). Lo que está claro es que no se instala un rootkit, algo que hace el atacante una vez que ha accedido por primera vez al sistema objetivo (ya sea por Ingeniería Social, fuerza brutal o cualquier otra forma) para nada, es decir instalar un rootkit implica que la máquina va a ser usada con un determinado fin por el atacante y en numerosos casos se trata de explotar sus recursos.

Para defendernos de los keyloggers y los rootkits en la manera de lo posible, conviene revisar con frecuencia o bajo sospecha, los archivos que mantenemos abiertos usando por ejemplo la herramienta que ya conocemos ‘lsof‘, los procesos que se encuentran ejecutándose en el sistema con ‘ps‘ o bien auditar nuestra red con herramientas como netstat o wireshark (entre otras) por si se diera el caso de que un keylogger estuviese realizando envíos externos.

Nota: Podemos comprobar el funcionamiento de un keylogger muy básico con el comando script o verificar los rootkits con chrootkit.

  • Scanner: Es un paso previo a un ataque. Durante el scanner se recolecta información sobre posibles objetivos a través de herramientas que examinan la red en busca de máquinas con puertos abiertos (TCP, UDP, etc…). Una herramienta de uso común para tal propósito es nmap.
  • Sniffers o husmeadores: Este tipo de herramienta captura los paquetes que circulan por una determinada red, de modo que podemos recopilar información acerca de la activad de la red como por ejemplo capturar contraseñas, protocolos utilizados, posibles servicios y servidores, clientes que aceden, etc… Al igual que los scanner no son un ataque en si ya que sirven tanto para auditar nuestra propia red como para encontrar vulnerabilidades en otra. En el Capítulo 8 vimos las herramientas propicias para tal fin y algunos de los puertos a los que deberíamos de prestar especial atención.
  • Hijacking: Conocido como ‘secuestro’ ya que su pretensión es la de “pinchar” las comunicaciones de manera de que se pueda reproducir el funcionamiento o uso de una máquina remota. Esta técnica es comunmente utilizada para captar correos electrónicos, transferencias de ficheros o navegación web. Con respecto a la navegación web lo que se vendría a realizar es una captura de la sesión de manera que tengamos la información  de navegación del usuario(páginas visitadas, tiempo de visita, interacción con formularios, etc…). Contra el hijacking la mejor herramienta es utilizar servicios seguros con encriptación y autentificación, a poder ser con renovación periódica.
  • Denial of Service: Ataque de denegación de servicio o ataque DoS utilizados para dejar una máquina inaccesible a través de la sobrecarga de uno o varios de sus servicios. Básicamente el objetivo es crear muchas peticiones (envíos de miles de paquetes) hacia uno o varios servicios de una máquina hasta provocar su saturación y con ello la caída de la máquina. Una variante de este tipo de ataque es el ataque Distribuido de Denegación de Servicio o ataque DDoS en el que se utiliza una red de ordenadores distribuidos, conocida como botnet, ampliando enormemente la potencia y eficacia de la sobrecarga remota. Estos tipos de ataques suelen estar dirigidos normalmente a servidores que utilizan servicios web como apache o DNS como bind en los que se han encontrado bugs o quizás no estén lo suficientemente actualizados dejando en evidencia sus vulnerabilidades al atacante. Por ejemplo si un atacante detecta que el servidor al que quiere atacar tiene abierto el puerto 80 y además tiene instalado un servidor web, el siguiente paso sería comprobar la versión del servidor web y si está desactualizada, podría irse a páginas del propio servicio en la que se informan de los bugs conocidos para una determinada versión y a raíz de ahí comenzar el ataque concreto. Normalmente estos servicios suelen caer al recibir mas conexiones o peticiones a conexiones de las que pueden soportar.
  • spoofing: Es una de las técnicas mas complejas y suele englobar varios métodos de ataque. Por lo general el fin del spoofing es la falsificación de datos, ya sean IP (falsifican la identidad de una máquina para enviar o recibir datos), interlocutores, correo electrónico falso con el que robar datos empleando Ingeniería Social, etc…
  • Ataque por fuerza bruta: Consiste en averiguar la contraseña de un usuario mediante la combinación de palabras, frases, números, etc… que normalmente se encuentran en uno o varios diccionarios. Básicamente funciona así; conociendo el algoritmo de codificación de la contraseña, se recurre a la comprobación de esas palabras o combinaciones de ellas que posteriormente se codifican con el mismo algoritmo y se comprueba su coincidencia, si no coincide se pasa a otra combinación y así hasta que alguna combinación codificada resulte ser la de la contraseña que buscamos. Para intentar evitar en la medida de lo posible que nuestra contraseña sea averiguada deberemos de seguir una serie de pautas que veremos en secciones posteriores, pero básicamente hay que elegir una contraseña con un mínimo de caracteres, combinando números, letras mayúsculas y minúsculas y caracteres de puntuación de manera que generemos una combinación de caracteres difícil de adivinar. Además es aconsejable modificar la contraseña cada cierto tiempo.

CONCLUSIÓN: Aceptar el software procedente únicamente de fuentes verificadas y de confianza es algo que deberemos de tener siempre en cuenta para frenar de algún modo cualquiera de las técnicas de intrusión o infección anteriormente descritas, además de tenerlo siempre lo mas actualizado posible y mantenernos informado acerca de vulnerabilidades (bugs) que vayan surgiendo. El uso de firewalls y auditores de red (scanners, sniffers, comprobadores de puertos, etc..) pueden sernos de gran utilidad para detectar un tráfico sospechoso entre nuestro sistema y la red, así como detectar puertos que no deberían de mantenerse en escucha, por ejemplo por que no los estemos utilizando. Es de suma importancia con respecto al entorno local, mantener contraseñas consistentes empleando métodos de fabricación de contraseñas que las hagan menos vulnerables, monitorizar el uso de los recursos de hardware, sobre todo en horas en los que el ordenador no debería de tener un funcionamiento constante, controlar los procesos que se están ejecutando, así como los archivos que mantenemos abiertos. Si llevamos a cabo estas estrategias de control seremos menos vulnerables, de lo contrario no esperemos estar seguro suponiendo que ‘alguien‘ o ‘algo‘ está haciendo el trabajo por nosotros, por que no será real.

 Controlar los puertos de red que se están utilizando

Una buena herramienta con la que podemos hacer un seguimiento de los puertos que tenemos abiertos e incluso saber como se ve nuestra máquina (con respecto a los puertos) desde el exterior (esto quiere decir que también nosotros podremos ver los puertos “accesibles” desde el exterior para una determinada máquina remota) es nmap.

Nmap es capaz de realizar exámenes mas sofisticados, incluyendo entre otros, exámenes “secretos” que probablemente no detecten la mayoría de cortafuegos, y exámenes mediante ping para detectar que hosts están activos.

Alguno de los usos que podemos hacer de nmap son los siguientes:

  • Comprobar como se muestra nuestra máquina de cara a la red (TCP/UDP)
# nmap -sTU localhost
  • Comprobar si el objetivo está “vivo” (examen de ping):
# nmap -sP <dirección-IP>
  • Quizás el host remoto esté configurado para bloquear intentos de ping, en este caso:
# nmap -nP <dirección-IP>
  • Comprobar únicamente un rango de puertos:
# nmap -p U:53,111,137,T:21-25,80,139,8080 <dirección-IP>

Nota: Se aconseja visitar la página man del comando y practicar con esta herramienta.

Ahora que ya sabemos en que estado se encuentran los puertos en nuestra máquina podremos hacer un análisis y posteriormente tomar precauciones, es decir, quizás existan puertos desconocidos que se encuentren escuchando conexiones, o servicios activos que jamás hemos utilizado o simplemente no son lo suficientemente seguros, por lo que deberemos de hacer algo con ellos. En estos casos lo mas normal es recurrir a los archivos /etc/services en el que podremos ver a que servicio corresponde un determinado puerto o /etc/protocols si tenemos problemas a la hora de identificar un protocolo concreto. Seguramente debamos de utilizar acto seguido herramientas de estado como netstat con la que seguir el rastro de aquellos puertos que desconocemos, para comprobar la posible actividad de puertos sospechosos o de servicios que aparentemente no usamos. Cuando tengamos localizado a que servicio corresponde cada uno de los puertos y tengamos claro si es conveniente utilizarlo o no, podremos entonces desactivar aquellos servicios que nos sean innecesarios. Para desactivar un servicio deberemos normalmente de acudir a nuestra herramienta de administración de servicios (service, initctl o systemd para sysV, upstart y systemd respectivamente) y pasar la opción stop para pararlo. Sería conveniente también desactivarlo del arranque, esto según que sistema de inicialización tengamos podremos hacerlo de una u otra forma, por ejemplo para sysV podremos eliminar el enlace del servicio en cuestión que se encuentre en el directorio de nivel de arranque con el que iniciamos, o utilizar la herramienta chkconfig, para upstart podremos eliminar, renombrar o editar el archivo de configuración de inicio del servicio en /etc/init o /etc/init.d si conserva el modelo de sysV, si estamos utilizando systemd tendremos que trabajar con las units y targets correspondientes ayudándonos de la herramienta systemd.

Muchos servicios están gestionados por por un súper servidor. Los dos súper servidores mas utilizados en Linux son inetd y xinetd, siendo este último el mas utilizado a en la actualidad. Para las distribuciones derivadas de Red Hat es xinetd el súper servidor por defecto, mientras que en derivados de Debian de suele utilizar inetd, aunque podremos sustituirlo sin problemas por xinetd. En próximas secciones hablaremos sobre estos súper servidores y veremos como configurarlos para que tomen el control de ciertos servicios y poder así activarlos o desactivarlos según nuestra necesidad.

Comprobar las conexiones de red existentes y los servicios que las provocan

Para esta tarea podemos usar una gran cantidad de herramientas cada cual mas sofisticada y útil. Algunas de ellas podrían ser netstat, nessus o wireshark. Cualquiera de estas tres herramientas nos puede informar de una manera u otra de que es lo que está ocurriendo en nuestra red. netstat es la que vamos a ejemplerizar aquí y digamos que es una herramienta que muestra el estado de la red en un momento concreto, nessus es un detector de vulnerabilidades que se basa en una seríe de plugings y tiene una estructura cliente-servidor, por último, wireshark que es un sniffer o husmeador de redes.

Un uso básico y bastante informativo sería utilizar netstat de la siguiente manera:

# netstat -punta

Con estas opciones estamos indicando que muestre el PID del proceso que está haciendo uso de la conexión (-p), informar sobre los puertos UDP además de los TCP,algo que ya hace por defecto (-u), expresar los nombres de hosts y puertos en dígitos (-n), mostrar el estado de las conexiones (-t), muestra todas las conexiones y puertos de escucha (-a)

Cuando anteriormente ejecutamos el comando nmap -sTU quizás obtuvimos alguno puerto desconocido (unknow) podríamos investigar mas sobre este de la siguiente manera:

# netstat -punta |grep <num-puerto> 

Los súper servidores inetd y xinetd

Muchos servicios de red que tenemos instalado en nuestro sistema abren puertos de conexión y permanecen en estado de escucha (LISTENING) de forma directa, sin intermediarios. No obstante existen otros muchos servicios que si que operan a través de otro programa el cual los controla de cierta forma, a este programa o servicio se le conoce con el nombre de súper servidor. El súper servidor escucha las conexiones de red para estos otros programas y cuando detectan un inicio de conexión para alguno de ellos, es entonce cuando este (el súper servidor) le pasa el control al programa en cuestión. Este sería el procedimiento desde el punto de vista de los puertos de red, pero igualmente el súper servidor puede controlar quién puede o no acceder a un determinado servicio, arrancar o parar un servicio, configurar los parámetros de seguridad, etc… Estas medidas de seguridad se suelen conseguir gracias a los TCP Wrappers.

TCP Wrappers o simplemente wrappers es básicamente un servicio que actúa de intermediario llamado tpcd (/usr/sbin/tcpd) que se utiliza junto a los súper servidores (xinetd lo lleva ya implementado en su propio paquete) y que sustituye al servicio gestionado por el súper servidor, de manera que cuando TCP Wrappers recibe una petición de acceso al servicio, verifica el usuario y el origen de esta, para determinar si su configuración le permite o no utilizarlo. Además de esto permiten generar logs e informar por correo de los posibles intento de acceso.

Puede que una cierta aplicación venga ya compilada con la biblioteca de wrappers, por lo que podremos gestionar sus permisos directamente desde los archivos /etc/hosts.deny en el que especificaremos que servicio denegamos y a quién, y /etc/hosts.allow donde indicaremos los servicios que vamos a utilizar seguido de la lista de máquinas a las que se le permitirá el acceso. Existen dos comandos útiles para gestionar los wrappers que son tcpdchk con el que verificaremos la configuración y tcpdmatch al que pasaremos un determinado servicio y cliente y nos informará de como reaccionaría ante esta situación.

Podemos recurrir al archivo /etc/services para identificar aquellos servicios que queremos indicar en los archivos de configuración. Se pueden utilizar comodines o ALL para especificar todos los servicios. Para indicar uno o varios clientes podremos utilizar el nombre de las máquinas, la dirección IP o dirección de red, o bien usar el nombre de la propia máquina o dominio. Podemos usar el comodín ALL para cubrir el acceso a todas las máquinas o EXCEPT para generar excepciones.

Nota: /etc/hosts.deny y /etc/hosts.allow son los archivos de configuración de TCP Wrappers. Si una máquina aparece en ambos archivos, tendrá preferencia /etc/hosts.allow

Otra ventaja de utilizar un súper servidor es que podemos reducir la carga de memoria, ya que si este controla muchos servicios que raramente se utilizan solo permanecerán en memoria el súper servidor y uno o dos de los servicios que controla.

Nota: Si queremos saber si estamos utilizando algún súper servidor y en caso afirmativo de cual de ellos se trata, podemos comprobarlo con el comando ps de la siguiente manera:

ps ax | grep inetd

Configurar inetd y xinetd

Tanto la configuración de inetd como xinetd pueden contener varios archivos de configuración, es decir no se trata de una configuración monolítica en la que únicamente se depende de un archivo de configuración. Como en numerosos servicios, existe un archivo de configuración principal desde el que se puede referenciar a un directorio en el que encontrar otros archivos de configuración. Los archivos de configuración principal son /etc/inetd.conf y /etc/xinetd.conf para inetd y xinetd respectivamente, así como el directorio que puede contener archivos de configuración independientes para cada uno de los servicios controlados por estos súper servidores son /etc/inetd.d y /etc/xinet.d.

Nota: Mientras que el archivo de configuración principal de inetd puede contener líneas de configuración de servicios o referencia a un directorio en el que se almacenan archivos de configuración independientes, el archivo de configuración de xinetd contiene solo opciones globales para el súper servidor y una directiva para incluir los archivos almacenados en /etc/xinetd.d. Estos archivos son creados automáticamente cuando se instala un servicio que es gestionado por xinetd.

Si quisiéramos configurar el servicio ftpd bajo inetd podríamos crear una línea como la siguiente en /etc/inetd.conf:

ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.ftpd -l

donde:

  • ftp : Indica el nombre del servicio
  • stream : En este segundo campo se indica el tipo de socket, es decir que tipo de conexión se espera. En este caso se trata de una conexión fiable en dos sentidos (stream). Otros tipos podrían ser dgram, conexión menos fiable pero con menos sobrecarga o conexión de bajo nivel a la red (raw). Este tipo de información podremos conocerla a través de la documentación de la propia aplicación.
  • tcp : Protocolo utilizado, normalmente tcp o udp.
  • nowait : En este cuarto campo se indica una posible acción, espera/sin espera (wait/nowait). nowait indica que el servidor se conectará a su cliente y liberará el socket, en cambio, wait procesará todos sus paquetes y, después se desconectará pasado un tiempo determinado.
  • root : Las opciones mas habituales para este campo son root o nobody y como se prevé, indica el usuario con  el que se ejecutará el servicio. No obstante, siempre que fuese posible deberíamos de ejecutar el servicio con un usuario con poco privilegios.
  • tcpd : En este penúltimo campo se suele referenciar al binario del servicio, pero como estamos utilizando como intermediario a TCP Wrappers, indicamos que se ejecute primero tcpd quién hará de intermediario recibiendo así las peticiones de conexión.
  • in.ftpd -l : En el último campo se nombrará al servicio final al que van destinada las conexiones, es decir, al servicio que vamos a usar, en este caso ftp. Se aceptan parámetros.

Esto sería con respecto a la configuración de un servicio bajo inetd pero ¿Y para xinetd?. Ya sabemos que en el archivo principal de xinetd (/etc/xinetd.conf) lo que se configura son los parámetros y opciones absolutas, es decir, las que afectan al propio súper servidor, delegándose la configuración de los servicios al directorio /etc/xinetd.d, donde existirá un archivo de configuración por cada servicio instalado que corra bajo xinetd. La configuración para un servicio que corre bajo xinetd no es muy diferente a aquel que lo hace con inetd, lo que ocurre es que el formato utilizado es muy diferente. A continuación vamos a ver un ejemplo, en el que usaremos el archivo de configuración del servicio ftp pero esta vez ejecutándose sobre xinetd.

service ftp
 {
 socket_type = stream
 protocol = tcp
 wait = no
 user = root
 server = /usr/sbin/in.ftpd
 server_args = -l
 }

Existe un parámetro adicional (disable) con el que poder activar o desactivar un servicio. De modo que si quisiéramos desactivar este mismo servicio podríamos haber añadido disable = yes. Si lo que queremos es desactivar varios servicios en una sola línea podremos añadir este mismo parámetro seguido de los nombres de todos los servicios a desactivar en lugar de ‘yes‘ en la sección defaults del archivo /etc/xinetd.conf.

Esto mismo ocurre con la configuración de la seguridad de los servicios. Por ejemplo podremos implementar la seguridad de forma individual para cada servicio con parámetros como:

  • bind : Indica a xinetd en que direcciones IP se escuchará en busca del servicio. Podemos restringir la escucha de manera que solo se disponga del servicio de forma local indicando la interfaz de circuito cerrado (127.0.0.1)
  • only_from : Aceptará solo conexiones provenientes de las direcciones IP, direcciones de red o nombres que indiquemos. Es similar a la función que realiza el archivo /etc/hosts.allow de tcpd.
  • no_acces : Idéntico a only_from solo que en este caso rechaza conexiones. Parecido a la función que ejerce /etc/hosts.deny de tcpd.
  • acces_time : Define el rango horario en el que el servicio estará disponible para los usuarios. Se especifica en formado hora:min-hora:min.

Aviso: El rango horario indica las horas a las que se puede acceder al servicio, independientemente de las horas de las que se haga uso, es decir si el rango está marcado en 08:00-17:30 y un usuario comienza a hacer uso del servicio a las 17:29 podrá hacer uso de él desde ese minuto en adelante, es decir, que no se le va a cortar el acceso en cuanto pase al minuto 17:30, eso si, un nuevo usuario que intente hacer uso del mismo servicio a las 17:31 obtendrá un acceso denegado.

Al igual que ocurría con el parámetro disable, si queremos implementar opciones e seguridad de forma general deberemos de indicarlas en la sección defaults del archivo de configuración principal /etc/xinetd.conf

Importante: Siempre que se realicen cambios en la configuración, tanto a nivel global como individual e independientemente del súper servidor que estemos gestionando, deberemos de recargar su archivo de configuración con reload o bien reiniciar el súper servidor con restart.

Protección mediante Firewalls

¿Que es un firewall?

Un firewall o cortafuegos es un sistema o dispositivo que se instala en una red con el objetivo de filtrar el flujo de datos (tráfico) que por ella discurre, de manera que sea capaz de separar los diferentes tipos de ‘conversaciones’ y tratarlas según nosotros, los administradores, hayamos decidido cuando creamos las reglas.

El filtrado actúa mediante la inspección de los paquetes, que representan la unidad básica de transferencia de datos entre ordenadores en Internet.

Al crear las reglas de filtrado en un cortafuegos, normalmente se tienen en cuenta diferentes aspectos, como el origen y destino de los paquetes (por ejemplo desde Internet hacia nuestra red privada), el protocolo utilizado y el puerto de destino. Una vez hemos considerado algunos de estos aspectos, provocaremos que se ejecute una acción. Algunas de ellas podría ser: permitir la entrada de los paquetes, redirigirlos, denegarlos o “perderlos”.

Nota: Existe una diferencia clave entre denegar una conexión (reject rechaza los paquetes) a perderla (drop). Cuando se rechaza una conexión el emisor obtiene un “mensaje de respuesta” (normalmente un paquete ICMP) con el que se informa de la denegación, mientras que si hacemos que se pierdan los paquetes el emisor no recibirá ningana información al respecto.

Un cortafuegos correctamente configurado añade una protección extra a la red, pero en ningún caso debe considerarse suficiente. Cualquier tipo de ataque informático que use tráfico aceptado por el cortafuegos seguirá constituyendo una amenaza.

Un cortafuegos no puede protegernos de aquellos ataques cuyo tráfico no pase a través de él, ni de los fallos de seguridad de los servicios y protocolos cuyo tráfico esté permitido.

Algunas configuraciones

Existen diferentes formas de implementar el firewall en la red, pero sin duda dos de las mas comunes podrían ser las siguientes:

  • Un firewall como muro de una red interna: En este tipo de configuración suele utilizarse un router (el encargado de proporcionarnos el acceso a Internet y redirigir el tráfico de la red) conectado a un switch o directamente a un equipo (un pequeño ordenador portátil o de sobremesa valdría) en el que disponemos de dos interfaces de red. Una de las interfaces será la que conecte al router (nuestra puerta de acceso) mientras que la otra será conectada a un switch donde se comunicará con el resto de ordenadores y servidores de la red interna. Por esta segunda interfaz es por donde pasará todo el tráfico filtrado por nuestro firwall.
  • Un firewall como barrera protectora de un único sistema: La mayoría de las distribuciones Linux traen (activado o no) un cortafuego, se trata del Netfilter IPtables. Con IPtables podremos crear reglas de filtrado de manera que podamos hacer mas segura nuestra conexión con Internet. En ocasiones se suele utilizar para hacer NAT o redirigir conexiones según los puertos (port forwarding), por ejemplo cuando tenemos varios servidores como smtp, web, ftp, etc.. en diferentes ordenadores de la red privada.

NAT (Network Address Translation) : técnica que permite ocultar varios ordenadores (red privada) tras una sola IP pública. Esto se logra mediante el NAT masquerading. Los routers proporcionados por nuestro ISP (Internet Service Provider) emplean esta técnica además de implementar un firewall en la mayoría de los casos.

Netfilter: IPtables

IPtables permite realizar diferentes configuración mediante el uso de las reglas que afectan al sistema de filtrado, ya sea generación de logs, acciones de pre y post routing de paquetes, NAT o forwarding.

IPtables se constituye en tres tablas: filter (para el sistema de filtrado), nat (enmascaramiento y reenvío) y mangled (configuración de opciones de paquetes). Estas tablas a su vez contienen una serie de cadenas que agruparán determinadas reglas según su función. Por ejemplo para la tabla NAT contamos con PREROUTING que permitirá modificar paquetes entrantes antes de su enrutamiento, POSTROUTING los modificará antes de que salgan al destino y OUTPUT que modifica los paquetes generados una vez se hayan enrutado, mientras que en la tabla FILTER podemos añadir reglas a las cadenas (chains) INPUT para los paquetes que entran, OUTPUT para los que salen y FORWARD si quisiéramos realizar un reenvío.

Importante: Cuando queremos hacer forwarding de paquetes, por defecto GNU/Linux no trae habilitada la opción por lo que deberemos de activarla nosotros. Podemos hacerlo de forma temporal (será volátil) a través del sistema de ficheros /proc o bien de forma estática:

  • Volátil:
echo 1 > /proc/sys/net/ipv4/ip_forward
  • Permanecerá a reinicios: deberemos de editar el archivo /etc/sysctl.conf y añadir:
net.ipv4.ip_forward = 1

Los paquetes son analizados primeramente por la tabla NAT, a continuación la tabla FILTER decidirá si pasarán (en caso de que vayan destinado a nosotros) o si hay que reenviarlos a otro destino.

No podemos abarcar ni 1% de lo que supone IPtables por lo que se recomienda acudir a su página man. No obstante se va a explicar como crear algunas reglas básicas para las tablas FILTER y NAT.

Para comenzar a utilizar IPtables deberemos de tener el servicio corriendo. Esto ya sabremos como hacerlo, en función del sistema de inicialización que estemos usando. Para sysV bastará con /etc/init.d/iptables start (stop para pararlo).

Sería interesante comprobar de que reglas dispone la configuración actual de IPtables:

$ sudo iptables -L

Crear reglas en la tabla FILTER

Para crear una regla básica en la tabla FILTER y en la cadena INPUT, podríamos utilizar la siguiente sintaxis:

$ sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

Con -s <ip> indicamos el origen (source) con -j la acción (en este caso aceptar) y podríamos haber utilizado -d para indicar un destino.

El orden de las reglas es importante, por lo que deberemos de colocar siempre las menos restrictivas en las primeras posiciones, podemos hacerlo directamente desde la línea de comandos, tal que así:

$ sudo iptables -I INPUT 3 -s 192.168.1.0/24 -j ACCEPT

Esto haría que la regla se colocara en la tercera posición. La opción -A simplemente añade, -I inserta en una determinada posición.

Podremos eliminar por ejemplo esta misma regla si pasamos la opción -D

$ sudo iptables -D INPUT 3

o

$ sudo iptables -D INPUT -s 192.168.1.0/24 - ACCEPT

Una regla mas elaborada podría quedar así:

$ sudo iptables -A INPUT -p tcp --dport 80 -s 0.0.0.0 -d 192.168.1.23 -j ACCEPT

Con esta regla indicamos que cualquier conexión proveniente (-s) de cualquier origen con destino (-d) al equipo con IP 192.168.1.23 concretamente por el puerto 80 (–dport, puerto destino) con protocolo tcp (-p) sea (-j) aceptada.

Y con alguna opción:

$ sudo iptables - A INPUT -p tcp --dport 80 -s 0.0.0.0 -d 192.168.1.23 -j REJECT --reject-with tcp-reset

Aquí rechazamos las conexiones (REJECT) y ademas emitimos una respuesta del tipo tcp-reset

Cuando modificamos las reglas deberemos de salvarlas. Para hacerlo en Red Hat bastaría con pasarle el parámetro ‘save‘ (service iptables save o /etc/init.d/iptables save y estas se guardarán en /etc/sysconfig/iptables.

Si estamos usando una distribución Debian o derivado además de ‘save‘ deberemos de pasarle un nombre por lo que acabarán guardándose en /var/log/iptables/<nombre-reglas>

Aviso: Si el directorio no existe deberemos de crearlo.

Para cargar las reglas podremos pasar el parámetro ‘load‘ en Red Hat y ‘load nombre-reglas‘ en Debian.

Crear reglas en la tabla NAT

Podemos ver las reglas para una determinada tabla con el parámetro -t y en nombre de la tabla:

$ sudo -t nat -L

Si queremos ser mas meticulosos y ver las reglas de una cadena concreta y ademas con detalles:

$ sudo -t nat -L PREROUTING -n -v

La opción -n da resultados numéricos y -v detalla información

Podemos eliminar todas las reglas de una tabla:

$ sudo -t nat -F

O concretar a solo las de una determinada cadena de una tabla concreta:

$ sudo -t nat -F OUTPUT

Podemos además de eliminar todas las reglas, poner los contadores a cero (útil cuando vamos a comenzar a definir reglas desde 0):

$ sudo -t nat -F
$ sudo -t nat -Z

Nota: Podemos omitir la tabla para que afecte de forma global.

Crear la regla de oro, es decir, conectar todos los ordenadores de una red privada con Internet a través de un dispositivo que posee dos interfaces de red, una conectada hacia Internet y la otra hacia el switch de la red privada. Esto recibe el nombre de Source NAT o SNAT (cambia la dirección IP de origen, en este caso para convertirla en la IP pública de nuestro ISP):

$ sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 88.23.144.210

Añadimos esta regla a la cadena POSTROUTING indicando el origen (-s) nuestra red privada. Solo se aplicará a los paquetes que salgan (-o, output) por la interfaz de red ‘eth0‘, la acción (-j) será SNAT y la nueva IP es 88.23.144.210 (la ofrecida por nuestro ISP). Existen diferentes formas de conocer nuestra IP pública, por ejemplo a través del router o de Internet, accediendo a direcciones como http://www.cualesmiip.com

Aviso: Este tipo de regla es configurada de esta manera cuando la IP que nos ofrece nuestro ISP es estática. Suele ser un servicio extra ofrecido por la compañía mediante pago.

Ahora vamos a crear la misma regla pero para una IP dinámica, es decir, lo común en cuanto a las IP ofrecidas por los ISP.

$ sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

Como vemos solo cambia la acción, que en este caso usamos MASQUERADE que lo que hace es usar la IP que tiene en esos momentos configurada nuestra interfaz eth0

Para terminar con la configuración de reglas básicas de IPtables vamos a crear una regla común, que por lo general se suele hacer a nivel ‘casero‘ desde el propio firewall del router ofrecido por nuestro ISP, y es la de direccionar peticiones de acceso a un determinado servicio que escucha en un puerto concreto. El circuito típico sería, una conexión que entra desde la IP pública y que debe ser encaminada hacia una dirección IP privada específica en la cual puede haber corriendo varios servicios pero en concreto queremos configurar el servidor web que por defecto escucha en el puerto 80. Para conseguir esto deberemos de aplicar la regla a la cadena PREROUTING ya que el paquete acaba de entrar y seremos nosotros quien le cree la ruta de encaminamiento.

$ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 192.168.1.52

Nuevas opciones serían la -i (input) y la acción DNAT que es equivalente a –to-destination con la que se modifica la IP de destino.

ufw el front-end de IPtables

Algunas distribuciones como Debian y sus derivados, traen preinstalados el paquete ufw (Uncomplicates Firewall) que no es mas que un front-end para IPtables, de manera que podamos crear reglas de una forma mas sencilla. Para los fanáticos del GUI existe GUFW que igualmente es un front-end (esta vez gráfico) para crear reglas IPtables.

Un uso sencillo de ufw podría ser el siguiente:

  • Denegar todo el tráfico entrante y permitir todo el saliente:
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
  • Abrir un puerto para un determinado servicio (bien por número o por nombre de servicio):
$ sudo ufw allow 139
$ sudo ufw allow samba

Nota: Para eliminar una regla añadimos delete entre ufw y allow

  • Comprobar los nombres de servicio que maneja ufw:
$ sudo ufw app list
  • Abrir un puerto y especificar el tipo de protocolo:
$ sudo ufw allow 443/tcp

Nota: Para abrir un rango usamos xxxx:yyyyy/protocolo

  • Crear una regla algo mas compleja (permitir todas las conexiones ssh a mi máquina cuyo origen se encuentra dentro de mi red)
$ sudo ufw allow from 192.168.1.0/24 to 127.0.0.1 app ssh
  • Ver la configuración actual:
$ sudo ufw status verbose
  • Resetear todas las reglas:
$ sudo ufw reset
  • Habilitar o deshabilitar el servicio al inicio:
$ sudo ufw enable/disable 

Sistemas de detección de intrusos (IDS)

Los sistemas de detección de intrusos (IDS) nos permiten mediante la utilización de nuestros propios recursos y la explotación de nuestro sistema, detectar posibles intrusiones en tiempo real. Lo normal es utilizar un detector de intrusos cuando hemos “terminado” aparentemente de configurar la seguridad de nuestra red y sistemas, de manera que los IDS que instalemos nos encuentren posibles vulnerabilidades que podamos intentar resolver, cerrando con ello agujeros de seguridad no deseados en nuestros sistemas. Igualmente su uso periódico nos informará de posibles ataques, uso malicioso de los recursos del sistema, modificación de ficheros, tráfico sospechoso, puertos que no deberían de permanecer abiertos, etc…

Podemos instalar y explotar un IDS destinado a localizar vulnerabilidades en el sistema local, denominado IDS basado en host, de forma que filtre los registros del sistema producidos por el demonio syslogd y los compare con una base de datos interna en la que se registran vulnerabilidades y ataques conocidos. Aquellos registros de log que hayan sido catalogados como anómalos por el IDS serán re-etiquetados con el nivel de criticidad que estime oportuno el detector de intrusos y se recopilarán en un nuevo log que posteriormente será enviado al administrador para su análisis. Para aquellos archivos de configuración típicos o servicios bastantes usuales, los IDS suelen crear sumas de verificación con md5sum o sha1sum cuyo resultado servirá para ir comparando periódicamente si los archivos han sufrido algún tipo de modificación. Con todo esto podremos encontrar archivos de configuración de servicios típicos que hayan sido modificados, servicios que trabajan de forma sospechosa, explotación indebida de los recursos del sistema, etcétera.

Igualmente podemos analizar la red en busca de servicios mal configurados, puertos abiertos que experimentan tráfico sospechoso, interfaz de red en modo promiscuo, etc…

Algunos de los sistemas de detección de intrusos mas populares son:

  • Tripwire: Es el IDS basado en host mas popular. No está soportado en Red Hat. Mantiene una base de datos de sumas de verificación de los ficheros mas importantes del sistema con la que poder comparar cada cierto tiempo en busca de posibles modificaciones. De esta forma sirve como medida preventiva ante posibles modificaciones en archivos de configuración del sistema provocados frecuentemente por los rootkit. La herramienta libre cuyo funcionamiento se asemeja al de TripWire es AIDE.
  • RPM como IDS basado en host: Es posible usar el gestor de paquetes de Red Hat como un IDS basado en host. Para ello deberemos de importar la GPG de Red Hat a nuestro llavero de claves públicas de forma que se puedan comparar los paquetes instalados con la base de datos de Red Hat. Las opciones que nos ayudarán a esto serán -V, sola o junto con otras opciones como ‘a‘ que verifica todos los paquetes o ‘f‘ que verifica un único archivo dentro de un paquete. Por defecto -V <nombre_de_paquete> verifica todos los archivos que contiene el paquete y -K útil para comprobar la suma de verificación y la GPG de un determinado paquete .rpm. Esta última opción es útil si queremos comprobar que un paquete a sido firmado por Red Hat (veremos las firmas GPG en la última sección de este capítulo).
  • SWATCH: Aunque no fue diseñado para ser un IDS basado en host, hace el trabajo de este al comprobar los registros del sistema y alertar de cualquier posible amenaza.
  • LIDS (Linux IDS): Parche del kernel y herramienta de administración útil para controlar las modificaciones en archivos a través de ACLs.
  • Snort: IDS basado en red de poco peso capaz de realizar análisis del tráfico de red en tiempo real. Permite filtrar por protocolos o contenido mediante la creación de reglas. Snort identifica gran cantidad de intrusiones y pruebas como buffer overflows, escaneos indetectables de puertos, pruebas de SMB, intentos de reconocimientos del sistema operativo, etc…

El servicio SSH

En la sección sobre la seguridad en la red vimos algunos servicios o protocolos de conexión remota (Telnet, ftp, VNC, escritorio remoto mediante X, etc..) los cuales compartían una vulnerabilidad, enviar los datos sin encriptar. Si estuviésemos utilizando algunos de estos servicios y existe en nuestra red un fisgón o intruso que esta monitorizando nuestras transferencias, este podría hacerse fácilmente con nuestras credenciales.

Para cerrar esta gran brecha de seguridad se diseñó el protocolo SSH, el cual utiliza técnicas de encriptación fuerte en todas las partes de la conexión de red, lo que lo convierte en un protocolo de conexión remota mucho mas seguro. El protocolo SSH nos permite transferir archivos (scp), conexión remota con X (ssh -X), utilizar servicios como ftp de forma segura (sftp) e incluso la posibilidad de crear túneles por los que transmitir la información de otros protocolos que no encriptan sus datos.

Nota: Podemos usar el comando scp de manera similar a como lo hacemos con cp, de forma que podamos copiar uno o varios archivos a una máquina remota de forma segura. Para utilizar scp bastaría con utilizar la siguiente sintaxis:

scp <archivo_a_copiar> usuario_remoto@ip_o_nombre_de_máquina_remota:/directorio/donde/copiaremos/el/archivo

Aviso: Es obligatorio conocer la contraseña del usuario remoto, a menos que tengamos activado un acceso sin contraseña, algo que aprenderemos en una sección posterior.

La principal desventaja de SSH es que la encriptación y desencriptación consumen tiempo de CPU lo que ralentiza las conexiones degradando incluso el rendimiento global del sistema.

El servidor mas popular en Linux es OpenSSH (sshd), del que se dispone también de su versión cliente (ssh).

Configurando SSH

Podremos iniciar el servidor sshd desde un súper servidor o mediante su script de inicio. Siempre que modifiquemos su configuración será necesario el reinicio del servicio o recarga del archivo de configuración.

La mayoría de la configuración de sshd se realiza a través de su archivo de configuración /etc/ssh/sshd_config mientras que la configuración del cliente podremos llevarla a cabo mediante el archivo /etc/ssh_config.

El archivo de configuración /etc/sshd_config se compone mayormente de líneas que adoptan el siguiente formato:

opción valor

Por regla general el servicio ssh (tanto el cliente como el servidor) vienen preconfigurado de manera que podemos hacer un uso seguro de él, no obstante conviene revisar algunas de las opciones, sobre todo de cara a la parte del servidor, como por ejemplo:

  • El nivel de protocolo que estamos usando: OpenSSH admite los niveles 1 y 2, siendo el 2 el mas seguro aunque en ocasiones se encuentra límitado con respecto a la comunicación con otros clientes. Podemos configurar el nivel de protocolo de manera que se use uno u otro o incluso los dos que según cual señalemos como primera opción será el que se use por defecto, por ejemplo 2,1.
  • Permitir el acceso directo de root mediante OpenSSH: Una medida de seguridad sería establecer la opción PermitRootLogin en no de manera que para hacerse con privilegios de root no baste con conocer solo su contraseña, si no que deberá de acceder primero con otro usuario vía ssh, por lo que deberá de conocer a parte de la clave de root la de ese determinado usuario y acto seguido cambiar a root mediante su. Ya vimos como además cambiando el shell por defecto del usuario root en /etc/passwd podemos incluso prohibirle el acceso a la consola.
  • Activar X remoto: Con la opción X11Forwarding podremos indicar si deseamos activar la funcionalidad del túnel para X. Si deseamos usar ssh -X usuario@host para acceder de forma remota al servidor X, deberemos de cambiar el valor de esta opción a yes.

Lo ideal sería que configuráramos SSH para que solo aceptara conexiones de nivel 2 del protocolo y rechazara accesos directos como root. Si no es necesario el redireccionamiento de X, deberíamos de desactivar la opción X11Forwarding. En la medida de lo posible deberemos de utilizar un cortafuegos (filtrando el puerto 22) o TCP Wrappers (/etc/hosts.allow y /etc/hosts.deny) para limitar los equipos que pueden contactar con el servidor SSH. Igual que podíamos restringir la conexión directa de root a través de ssh, podemos hacer que se permita solo su acceso. Si existe el archivo /etc/nologin SSH lo tendrá en cuenta y negará el acceso a todos los usuarios menos a root.

Como con todos los servidores deberemos de mantenerlo actualizado pues siempre existe la posibilidad de que un bug cause problemas.

Configurar túneles SSH

Como ya se comentó, SSH tiene la capacidad de crear túneles por donde otros protocolos conducirán sus datos de manera que estos sean encriptados, evidentemente esto precisa de configuraciones adicionales.

Nota: A la creación de túneles SSH para conducir el flujo de datos creados por otros protocolos se le conoce como tunneling

Para que veamos de una forma mas o menos clara el funcionamiento del tunneling vamos a ejemplarizar una configuración en la que se desea que el tráfico de correo electrónico desde el servidor IMAP (en este caso) hacia el cliente, se realice bajo un túnel SSH de manera que se conserve la privacidad. Para ello el servidor de correos dispondrá tanto del servidor IMAP (protocolo que hará uso del túnel) como del servidor SSH, y de la misma manera el cliente deberá de tener ejecutándose un cliente SSH y un cliente del protocolo que hará uso del túnel (un cliente de correos en este caso). Con esto la comunicación será encriptada por SSH y enviada a través del túnel bajo el protocolo IMAP.

Para que esta comunicación sea posible deberemos de activar la opción AllowTcpForwarding en el archivo de configuración del servidor SSH (/etc/sshd_config) y en el lado del cliente deberemos de crear una conexión especial con el servidor de correos como esta:

# ssh -N -f -L 143:mail.freeser.com:143 Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.

donde:

  • -N indica que no ejecute un comando remoto
  • -f que se ejecute en segundo plano tras solicitar la contraseña
  • -L indica el puerto local en el que se escucha (normalmente 143 para el protocolo IMAP, utilizado tanto en el cliente como en el servidor)
  • Tras los primer dos puntos ‘:‘ encontramos la dirección del servidor de correos y el puerto en el que se escucha. El último parámetro el usuario y host con el que estableceremos el túnel.

Una vez establecido el túnel podremos utilizar nuestro programa cliente para conectarnos al puerto local especificado (143)

Uso de las claves SSH

Uno de los sistemas de seguridad que implementa el protocolo SSH es el uso de claves, especialmente dos, la clave pública (con la que podremos desencriptar mensajes) y la clave privada (la utilizada para encriptar mensajes). En una comunicación cifrada cada lado envía su clave pública al otro extremo de manera que solo con esa clave se puedan descifrar los mensajes que han sido encriptados por su respectiva clave privada.

Los datos encriptados con una clave pública solo podrán ser descifrados por la clave privada coincidente. Un ejemplo sería la conexión remota entre un cliente y un servidor bajo ssh, donde el cliente tendrá la clave pública del servidor al que conecta y cuando codifique información lo hará mediante esta clave de manera que solo el servidor bajo su clave privada pueda descifrar estos datos.

Importante: Si algún intruso se hiciese con la clave privada del servidor, correríamos el riesgo de que todos nuestros datos fueran descifrados por el atacante.

Las claves públicas de uso individual de los servidores, se guardan en el directorio ~/.ssh/known_hosts del cliente, mientras que las de uso global se encuentran en el archivo ssh_known_hosts que suele colgar de /etc o /etc/ssh. Una modificación en una clave pública sería motivo de sospecha de falsificación.

En el pasado podíamos comprobar el contenido de estos archivos con editores de texto, en cambio, desde OpenSSH 4.0 es posible habilitar la encriptación para los datos de este archivo de manera que la información se codifique mediante un algoritmo de encriptación de único sentido (hash). Así ni los intrusos ni nosotros mismos, podremos identificar el servidor al que nos conectamos, únicamente el cliente y servidor compararán el hash y si coincide se aceptará la conexión.

Para que este sistema funcione hacen falta un total de cuatro a seis claves generadas automáticamente cuando se ejecuta el script de inicio de sshd. Estas claves necesarias son las correspondiente a las dos o tres herramientas de encriptación que admite SSH (rsa, rsa1 y dsa) y se suelen almacenar bajo /etc/ssh. Las mas corriente suelen ser ssh_host_rsa_key y ssh_host_dsa_key a las que se le añadde la extensión .pub para sus coincidentes claves públicas. Quizás haya sistemas que cuenten con esta otra: ssh_host_rsa1_key

Si no disponemos de la privada y pública (rsa1) y no podemos poner el sistema en funcionamiento, podremos probar a utilizar el comando ssh-keygen de la siguiente manera:

# ssh-keygen -q -t rsa1 -f /etc/ssh/ssh_host_key -C '' -N ''

Esto generará tanto la privada como la pública y también es válido para rsa y dsa.

Aviso: Debemos utilizar permisos restrictivos para los archivos de las claves privadas, normalmente 0600 (rw——-) con propietario root. A las públicas debería de tener acceso todo el mundo.

Accediendo vía SSH

Para acceder a un servidor remoto bajo ssh es tan sencillo como instalar el paquete OpenSSH client y ejecutar el siguiente comando:

$ ssh usuario@maquina

A continuación, si es la primera vez que accedemos al sistema remoto se nos pedirá confirmación, de manera que tras introducir la clave del usuario, la clave pública de la máquina remota será guardada en nuestro llavero de claves públicas (~/.ssh/known_hosts). El resto de las veces no se nos pedirá confirmación pero si la clave del usuario remoto.

Este sería el método normal para acceder bajo SSH a un sistema remoto. No obstante, existen otras formas para acceder sin hacer uso de una password, de manera que podamos loguearnos a través de por ejemplo tareas automatizadas con shell scripting.

Uso de ssh-Agent

Otra opción para conectar es emplear el programa ssh-agent el cual solicitará una contraseña (passphrase) para iniciar las conexiones.

Para utilizar ssh-agent deberemos de seguir unos pasos sencillos pero necesarios:

1 . Desde el sistema cliente (el que utilizaremos para conectarnos al servidor remoto) generaremos una clave SSH versión 2 (rsa y dsa, o rsa1 para versión 1):

$ ssh-keygen -q -t rsa -f ~/.ssh/id_rsa -C ''
2 . Se nos pedirá una frase (passphrase) de contraseña la cual será la que utilicemos para futuras conexiones:

3 . Ahora será el momento de acceder al servidor remoto:

 $ ssh usuario_remoto@servidor

Escribiremos la contraseña del usuario_remoto accediendo ya al servidor. Ahora copiaremos el contenido de nuestro archivo id_rsa.pub (creado en el paso 1) al final del archivo ~/.ssh/authorized_keys o ~/.ssh/authorized_keys2 (anillo de claves públicas) del directorio /home de usuario_remoto. Si no existiese ninguno de estos dos archivos deberíamos de crear uno de ellos.

Nota: Puede que en algunos sistemas tengamos que cambiar los permisos del archivo ~/.ssh/authorized_keys y directorios. Normalmente es suficiente con eliminar los permisos de escritura (0600) y asegurándonos de que el propietario es usuario_remoto.

4 . Ahora ya podremos usar ssh-agent desde el sistema cliente. Para ello ejecutaremos

$ ssh-agent /bin/bash

Esto abrirá un nuevo shell dentro del que hemos usado para ejecutar este comando. No notaremos nada, solo si vemos los procesos ejecutados podremos ver el nuevo proceso creado:

ssh-agent

Desde esta ‘sesión‘ escribiremos primeramente ssh-add ~/.ssh/id_rsa para añadir nuestra clave RSA al conjunto gestionado por ssh-agent. Se nos pedirá que introduzcamos la frase/clave que introducimos al crear el par de claves en el paso 1.

Aviso: Cada vez que queramos volver a realizar accesos al sistema remoto al que hemos facilitado nuestra clave pública no deberemos de dar la contraseña del usuario remoto, pero si que tendremos que repetir el paso 4.

Si utilizamos este sistema con frecuencia desde nuestro usuario local, podemos hacer que cada vez que se inicia bash lo haga ejecutando ssh-agent. Esto podemos lograrlo modificando /bin/bash por ssh-agent /bin/bash en la línea de nuestro usuario del archivo /etc/passwd.

Acceder sin contraseñas

Hemos pasado de acceder a un host remoto bajo credenciales (usuario y contraseña) de un usuario específico de ese sistema, a acceder con un usuario del sistema pero sin que se nos solicite mas clave que una propia creada cuando generamos nuestra clave pública. Lo siguiente es ya acceder directamente sin esa clave, es decir, conectaremos contra un host remoto sin que se nos solicite ningún tipo de password, ni la del usuario remoto, ni la nuestra propia.

Para conseguir esto, podremos recurrir a estas dos opciones:

A. Realizaremos el paso 1, y 3 vistos anteriormente cuando utilizábamos ssh-agent. En este caso el paso 1 debe modificarse añadiendo la opción -N ‘ ‘ quedando así:

$ ssh-keygen -q -t rsa -f ~/.ssh/id_rsa -C '' -N ''

Nos hemos saltado el paso 2 puesto que con este comando no se nos solicitará ninguna clave. En el paso 3 todo igual, el usuario de la máquina remota (usuario_remoto en nuestro ejemplo) debe tener el contenido de nuestra clave pública en su archivo de autorización, normalmente ~/.ssh/authorized_keys

Si ahora salimos del servidor remoto y volvemos a entrar no se nos pedirá ningún tipo de contraseña.

B. Esta forma es aún mas sencilla. Haremos uso del comando ssh-keygen y de ssh-copy-id (con este último, evitaremos tener que entrar al servidor remoto y copiar el contenido de nuestra clave pública en el archivo de autorización del usuario_remoto, es decir, realizar el paso 3 de ssh-agent de forma automática)

1 . Creamos nuestro par de claves:

$ ssh-keygen -b 4096 -t rsa

donde:

-b genera una clave de 4096 bits, por defecto (si no usamos -b) se generará de 2048, que suele ser suficiente.

-t indica el tipo de clave, en nuestro caso rsa para protocolo 2

Nota: Deberemos de pulsar tres veces [ENTER]

2 . Copiamos de forma automática nuestra clave pública en un equipo remoto para un usuario específico, tal que así:

$ ssh-copy-id usuario@ip_del_equipo

En este paso se nos pedirá el password de “usuario”. Con esto habremos acabado. El resto de veces que queramos acceder a esa máquina con ese usuario, NO, se nos solicitará password ni passphrase. Esto resulta muy útil cuando tenemos tareas programas con shell scripts que pretenden acceder a un servidor remoto de forma automática.

Encriptar y firmar datos con GPG

GPG (GNU Privacy Guard) es una herramienta de cifrado y firmas digitales de código libre implementada de la herramienta propietaria PGP (Pretty Good Privacy, Privacidad bastante buena). Con GPG podremos por ejemplo, encriptar mensajes de correo electrónico, de manera que mantengamos una cierta privacidad en cualquier punto de la red que este atraviesa, además de poder firmarlo digitalmente. El firmar un mensaje implica que el destinatario del mismo pueda verificar mediante su herramienta GPG que el contenido no haya sido alterado.

Nota: GPG se utiliza principalmente para proteger y verificar correos electrónicos, por lo que la mayoría de clientes de correo de Linux proporcionan interfaces GPG

Generar, exportar, importar y recovar claves con GPG

Al igual que ocurre con las claves SSH, necesitaremos una clave privada y una clave pública GPG. Con la clave privada firmaremos los mensajes mientras que con la pública los lectores del mismo podrán realizar la verificación de la misma o bien, podremos encriptar un mensaje con la clave pública de un destinatario de manera que solo él mediante su clave privada pueda descifrarlo.

Generar claves

Para generar un par de claves utilizaremos el comando gpg con su opción –gen-key tal que así:

$ gpg --gen-key

Tras responder a una serie de preguntas relacionadas con la clave, como por ejemplo el nombre completo de la persona, dirección de correos, contraseña (muy importante recordarla y no perderla), etc… se crearán las claves en el directorio ~/.gnupg.

Nota: Es posible que generar la clave tarde un poco, esto irá en función del tamaño de clave que hayamos puesto (por defecto 2048 bits) y la rapidez de generación de números aleatorios de nuestro sistema (entropía), podemos forzar esto moviendo continuamente por ejemplo el ratón. Sería interesante que se buscara información de como generar la entropía, no obstante tampoco es un requisito indispensable el saber esto.

Ahora podremos usar la opción -k de gpg para ver el ID de la clave, algo que no será útil para exportarla.

$ gpg -k
pub 2048R/BC9DAD91 2015-03-28 [expires: 2015-03-30]
uid 4sysadmins <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>
sub 2048R/24D3B0D1 2015-03-28 [expires: 2015-03-30]

Exportar las claves

Una vez generadas las claves podremos exportarlas de manera que podamos crear una clave pública para cada usuario que quiera descifrar o verificar nuestro correo, o bien encriptar sus mensajes con ella para que solo nosotros bajo nuestra clave privada podamos leerlo.

Para exportar una clave basta con utilizar el comando gpg pero esta vez con su opción –export. Le pasaremos como parámetro el ID del propietario, normalmente el nombre o correo electrónico que introducimos al crear la clave, o bien el número BC9DAD91 que tenemos en la línea pub de la salida del comando anterior (este ID es solo un ejemplo, deberemos de reemplazarlo por el que generemos nosotros). Podremos utilizar el nombre o correo electrónico del usuario al que irá destinada nuestra clave publica o un identificador global si la vamos a compartir con un departamento, organización, etc… o bien utilizar nuestro nombre o correo de manera que el destinatario relacione la clave con nosotros.

$ gpg --export nuestro_ID > nebul4ck-gpg.pub

o

$ gpg --output nebul4ck-gpg.pub --export nuestro_ID

Con este comando estaremos generando una clave pública (nebul4ck-gpg.pub) la cual se creará en el directorio en el que estamos trabajando y que posteriormente distribuiremos para que puedan verificar nuestros correos/documentos o encriptar sus mensajes para que solo nosotros podamos descifrar.

Si teníamos pensado enviar nuestra clave pública por correo, podríamos haber añadido la opción –armor al comando gpg –export de manera que se generara una salida ASCII.

Otras formas de distribuir nuestra clave puede ser como adjunto en un email, subirla a un sitio Web o a través de un servidor de claves. Un servidor de claves es un servidor de red que funciona como un depósito donde se almacenarán las claves públicas a distribuir. Podemos almacenar nuestra clave pública en un depósito de claves de la siguiente manera:

$ gpg --keyserver pgp.rediris.es --send-keys ID_denuestraclave
  gpg: sending key BC9DAD91 to hkp server pgp.rediris.es

Este comando enviará nuestra clave al servidor de claves pgp.rediris.es (servidor de claves públicas) para que posteriormente pueda ser descargada por algún interesado.

Aviso: Para crear claves públicas anteriormente utilizamos el uid (nombre o correo electrónico) o bien el código de la línea pub de la salida del comando gpg -k. Para subir una clave pública a un depósito de clave solo servirá el ID de la linea pub.

Nota: Existen diferentes servidores públicos de claves gpg públicas. Es muy importante generar un certificado de revocación de clave si hemos decidido enviar nuestra clave a un servidor, ya que está será distribuida en pocos minutos al resto del mundo. Veremos esto en el aparatado “Revocando claves en desuso

Importando claves de terceros

Ahora que hemos visto como exportar nuestra clave, es igualmente importante saber importar la clave de un usuario con el que queremos mantener una cierta privacidad, ya sea porque vaya a firmar documentos que nos interese corroborar que vienen emitidos por el sin ser alterados, o porque vayamos a encriptar información mediante su clave pública de manera que solo él con su clave privada pueda descifrar.

Podremos añadir la clave de un tercero a nuestro depósito de la siguiente forma:

$ gpg --import <nombre-archivo>

O bien, importarla desde un servidor de claves:

$ gpg --key-server <nombre_host> --recv-keys <id_clave>

De la misma manera que comprobamos la existencia de nuestra clave, podremos verificar el uid e id pub de la nueva clave agregada:

$ gpg --list-keys

Nota: Esto es igual que emplear la opción -k

Revocando claves en desuso

Cuando generamos un nuevo par de claves es importante el crear acto seguido un certificado de revocación de clave. Imaginemos que queremos dejar de usar nuestra clave pública por el motivo que sea, por ejemplo porque se encuentre en un depósito de claves público y nuestra clave privada se ha visto comprometida o simplemente hemos olvidado nuestra contraseña de clave y no queremos que se haga mas uso de ella. Una clave pública revocada puede ser utilizada para verificar firmas realizadas en el pasado o descifrar mensajes que hayan sido cifrados antes de la revocación, siempre y cuando el usuario todavía tenga acceso a su clave privada. Lo que no será posible es cifrar datos una vez la clave sea revocada.

Para crear el certificado de revocación haremos lo siguiente:

$ gpg --gen-revoke <ID_clave>

Podemos añadir la opción –output <nombre_archivo.gpg> si en vez de mostrar el certificado por la stdout se añada a un archivo.

Una vez tengamos generado el certificado deberemos de copiar y pegar el texto mostrado por la stdout en un archivo (en caso de que no hayamos agregado la opción –output directamente). Este será nuestro certificado de revocación. Si llega el momento de revocar la clave deberemos de importar este certificado en nuestra clave, bastará con:

$ gpg --import <nombre_archivo.gpg>

Deberemos de distribuir esta revocación a los usuarios que estaban haciendo uso de nuestra clave. Si la teníamos subida a un depósito de claves público, deberemos de volver a usar el comando gpg con las opciones –keyserver y –send-keys para importar nuestra clave revocada.

Cifrar y descifrar documentos

Para cifrar un documento con la clave pública de un usuario (por ejemplo jjgomez) desde el usuario nebul4ck podremos hacer lo siguiente:

1 . Se supone que ta tenemos importada a nuestro anillo de claves la clave pública de jjgomez por lo que vamos a comprobar su ID:

$ gpg -k
/home/nebul4ck/.gnupg/pubring.gpg
--------------------------------
pub 2048R/BCK2ADAK 2015-03-28 [expires: 2015-03-30]
uid nebul4ck <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>
sub 2048R/2AD3B0D9 2015-03-28 [expires: 2015-03-30]
pub 2048R/5GJ945FD 2015-03-30 [expires: 2015-04-01]
uid Jose Julio Gómez (Mi mail) <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>
sub 2048R/CB851754 2015-03-30 [expires: 2015-04-01]

2 . Ciframos de la siguiente manera (usaremos el nombre, correo o ID de jjgomez)

$ sudo gpg --output contabilidad_2015.dot.gpg --recipient 5GJ945FD --encrypt contabilidad_2015.gpg

De esta manera obtendremos un archivo binario, por lo que no podremos pasarlo directamente por email a menos que sea como adjunto. Podremos añadir la opción –armor para codificarlo en ASCII y poder copiar y pegar el texto en un correo.

$ sudo gpg --output contabilidad_2015.dot.gpg --recipient 5GJ945FD --armor --encrypt contabilidad_2015.dot

Ahora vamos a descifrar el documento desde el usuario jjgomez:

$ sudo --output contabilidad_2015.dot --decrypt contabilidad_2015.dot.gpg

Nos pedirá la contraseña (la que introdujo en este caso jjgomez cuando generó su par de claves). Y listo! ya podremos leer el documento.

Firmar mensajes y verificar firmas

Ahora, vamos solamente a firmar el documento anterior (contabilidad_2015.dot) de manera que nuestro destinatario (jjgomez en nuestro caso) pueda verificar que se trata de un documento emitido por nosotros.

Para firmar un documento podremos usar las opciones –sign o –clearsign de gpg. La diferencia entre ambas opciones es que –sign además de firmar el documento, lo encriptará con la clave privada, de manera que el destinatario (jjgomez) podrá verificar que se trata de un documento procedente de nosotros mediante la opción –verify <archivo> pero no podrá leerlo a menos que lo descifre antes con –decrypt. Si utilizamos –clearsign el documento irá sin cifrar, por lo podrá leerse sin problemas y comprobar igualmente mediante –verify que el documento fue emitido por nebul4ck.

Utilizar –sign provocará que se cree un archivo encriptado con el mismo nombre que el original pero con extensión .gpg. Si utilizamos –clearsign el archivo resultando tendrá la terminación .asc

$ gpg --clearsign contabilidad_2015.dot
$ gpg --verify contabilidad_2015.dot.asc

Si queremos profundizar algo mas en el uso de gpg podremos acudir a la siguiente dirección https://www.gnupg.org/gph/es/manual.html, y además leer la página man de gpg.

 


 

Capítulo – 10

 



 

Notas del autor:

 

Licencia Creative Commons
Curso LPIC-1 400 Capítulo 10 por nebul4ck se distribuye bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 4.0 Internacional.

Puede contratar ExtreHost para temas profesionales con sus servidores. No lo dude, contáctenos.

Pin It

Escribir un comentario


Código de seguridad
Refescar



Redes:



 

Suscribete / Newsletter

Suscribete a nuestras Newsletter y periódicamente recibirás un resumen de las noticias publicadas.

Donar a LinuxParty

Probablemente te niegues, pero.. ¿Podrías ayudarnos con una donación?


Tutorial de Linux

Filtro por Categorías