Seguridad en GNU/Linux

De GLASS

Tabla de contenidos

Introducción

Tras leer este capítulo sabrá los pasos que debe dar para mantener un sistema estable y seguro. Podrá implementar políticas de filtrado en un firewall Linux para proteger los hosts de sus redes y sabrá construir un router con Linux.

¿Qué es la seguridad?

En un primer lugar debería plantearse una pregunta, que aunque parezca trivial, no se responde con una sola palabra. ¿ Qué es la seguridad ? La seguridad como tal se relaciona con varios términos, aunque puede que el primero que se nos venga a la cabeza sea el de “privacidad de la información”, pero cabe aún tener en cuenta otros aspectos como son: Integridad. Se entiende como la necesidad de que la información no sea modificada en tránsito, para lo que será necesario establecer los mecanismos criptográficos adecuados, o la necesidad de que la información que reside en los sistemas no se degrade o pueda ser manipulada.

Disponibilidad. Evitar la parada o interrupción de los sistemas, así como posibles ataques de DoS (Denial of Service). En caso de fallo de un servidor, que sea otro el que ofrezca los servicios que prestaba aquél.

Consistencia. Evitar fallos de software y/o del hardware (copias de seguridad, unidades redundantes, técnicas de balanceo de carga, sistemas de alta disponibilidad, etc.)

Existen en la actualidad multitud de programas de seguridad en el mercado como pueden ser NFR, Snort, BlackIce, NetProwler o ISS, de excelente calidad todos ellos y los cuales nos permitirán un control prácticamente absoluto sobre cualquier sistema. Pero todos ellos van a ser inútiles si no sabemos interpretar los resultados que nos muestran. Si queremos crear políticas de seguridad, podemos seguir detalladamente los RFC's (Request For Comments). El RFC 1224, es un documento que describe como crear nuestra propia política de seguridad, y otros como el RFC 1281, muestran un ejemplo de política de seguridad descrita paso a paso.

No es nuestro objetivo tratar estos temas de una forma tan detallada, y vamos a centrarnos en los aspectos más relacionados con el sistema operativo en sí, y no en un conjunto de medidas y contra medidas de seguridad. En todo caso, en la siguiente dirección se puede consultar información de referencia sobre las políticas de seguridad aplicadas en diferentes instituciones universitarias, siendo un buen ejemplo en el que basarse:

ftp://coast.cs.purdue.edu/pub/doc/policy/

Instalación

A continuación se van a detallar algunos puntos básicos de administración de sistemas, orientados a ofrecer una mayor seguridad física, o lo que es lo mismo, una mayor seguridad a nivel de host.

El error de agrupar un sistema Linux en una sola partición

Dos directorios habituales a los que los usuarios tienen acceso son /tmp y /home. Dividir la estructura de estos directorios en particiones separadas también evita que los usuarios llenen cualquier sistema de ficheros crítico (un / lleno es algo bastante malo). Un /home lleno podría dar como resultado la incapacidad de que los usuarios pudiesen hacer login, y es precisamente por esa razón por la que el directorio del root se halla en /root y no en /home. Incluso si se llenara el directorio /tmp, podría dar como resultado que no se guarden los logs del sistema, y eso es algo que hemos de evitar a toda costa.

En cada caso la tabla de particiones debe adecuarse a las necesidades de la máquina y el servicio que ofrezca, pero la tabla de a continuación muestra una estructura de particiones recomendable en la mayoría de los casos:

Particiones
Directorio Partición Física
/ /dev/hda1
/tmp /dev/hda2
/root /dev/hda3
/usr /dev/hda4
/home /dev/hda5
/var /dev/hda6
swap /dev/hda7

Administración básica del sistema

Dado el carácter multiusuario del que gozan los sistemas GNU/Linux, es necesaria la creación de cuentas de usuario y de diferentes grupos para cubrir las necesidades de accesibilidad a los recursos y de seguridad sin perder flexibilidad.

La creación de una cuenta de usuario se realiza por medio de la orden adduser. Con ello se logra introducir las lineas relativas al nombre de usuario, su GID (identificador de grupo), su UID (identificador de usuario) y la shell asignada por defecto en el fichero /etc/passwd.

joan:x:500:500:Joan Carles N.:/home/joan:/bin/bash

Esta línea contiene 7 campos separados por el carácter “:”, que se dividen en:

Comprensión de los campos del fichero /etc/passwd
Campo Contenido (ejemplo) Descripción
Login joan Login de usuario, identifica al usuario dentro del sistema
Password x(usa shadow) Password encriptada del usuario (si hubiera)
Número de usuario 500 Identifica al usuario en el sistema mediante este número
Número de grupo 500 Grupo al que pertenece el usuario
Información GECOS Joan Carles N Descripción del usuario
Directorio home /home/joan Directorio /home de este usuario
Shell //bin/bash Shell asignada a este usuario al entrar en el sistema

Definir políticas para grupos

Existen tres clases diferentes de usuarios de un fichero y tres modos diferentes de acceso al fichero. Estas tres clases de usuarios son los siguientes:

Propietario. Usuario que ha creado el fichero. El propietario tiene la capacidad de controlar quien puede acceder al fichero.

Grupo. Grupos de usuarios, normalmente relacionados por un departamento o una misma función. Un usuario de este tipo puede acceder al fichero, pero no puede cambiar a su vez los atributos de aquellos que puede acceder a él. Otros. Cualquier otro usuario del sistema. Estos usuarios pueden únicamente acceder al fichero si tienen permiso para ello.

Para cada una de estas tres clases de usuario, existen otros tres modos de acceso diferente:

Comprensión de los campos del fichero /etc/passwd
Modo Fichero ordinario Fichero directorio
Lectura (r) Permite examinar el contenido del fichero Permite listar los contenidos en el directorio
Escritura (w) Permite cambiar el contenido del fichero Permite crear y borrar ficheros
Ejecución (x) Permite ejecutar el fichero como un comando Permite buscar en el directorio

Los permisos se establecen con la orden /bin/chmod. Los valores asignados pueden expresarse por la suma de sus pesos en base dos (Ver: Permisos).

Para cambiar los permisos para que sólo el propietario pueda leer un fichero determinado, escribiríamos;

[joan@Belluguet joan]$ chmod 600 fichero

Como veremos más adelante existe un fichero de configuración llamado umask, el cual tiene como función, definir los permisos por defecto de los ficheros.

Controles de acceso

Los niveles de seguridad en una máquina, se pueden clasificar por los criterios seguidos en el TSEC, o más conocido como Orange Book (libro naranja). Las especificaciones cambian por países, encontrando de este modo la CTCPEC Canadiense, el “Orange Book” Alemán, the UK Criteria, el ITSEC (Criterio Estandarizado Europeo), etc.

Las clasificaciones se hacen por niveles de seguridad, siendo la privacidad uno de los aspectos más valorados. Así podemos encontrar cuatro grupos, de A hasta D, donde este último tiene el nivel de seguridad más bajo. Estas evaluaciones se aplican a configuraciones específicas, no a los productos en si. Por ejemplo, Microsoft Windows NT 3.51, recibió una evaluación C2, pero sólo en la configuración en la que arrancaba desde disquete y con la tarjeta de red deshabilitada.

Existen varios modelos de acceso al sistema, pero estos son los más conocidos:

Control de acceso discrecional (DAC). En este modelo de control, un usuario bien identificado, normalmente el creador o propietario del recurso, decide cómo protegerlo, y decidiendo cómo compartirlo mediante controles de acceso impuestos por el sistema (rwxrwxrwx). El modelo DAC se ha venido usando profusamente en sistemas operativos de propósito general con clasificación de seguridad TCSEC C1 o superior, y en virtualmente todos los sistemas de bases de datos, aplicativos y sistemas de comunicaciones de propósito comercial.

ACL's, SGID y SUID. Las ACL's son una serie de utilidades y parches para el kernel que actúan como una capa de filtrado entre el sistema de ficheros y los usuarios. Las ACL's permiten una mayor granularidad y control en el acceso al sistema de ficheros. Por ejemplo se puede otorgar al usuario A acceso total a un fichero, al usuario B permiso de lectura, al grupo C permiso de lectura y ninguno para el resto de usuarios. Con el sistema común de control de permisos de GNU/Linux, hacer esto sería imposible.

Por su lado los bits de SUID y SGID permiten al usuario que ejecuta un programa determinado, poder acceder a ficheros que de otra forma no podría, adoptando el UID del propietario durante la ejecución del mismo. Cuando un programa tiene activado el bit de SUID, aparece una 's' en lugar de una 'x' en los permisos del propietario del fichero.

El sticky bit, válido tanto para ficheros como para directorios, tiene como finalidad que ningún usuario pueda borrar o renombrar en un directorio determinado, aquellos ficheros pertenecientes a otros usuarios. En este caso la letra que se sustituye es la 'x' por una 't'.

Es recomendable tener controlados los ficheros con bit de SUID o sticky activados por lo que la utilidad de la siguiente orden es encontrar este tipo de ficheros en el sistema:

find ./ -type f -perm -002000 -o -perm -004000

Control de acceso mandatori (MAC). En el modelo de acceso mandatori (MAC), es el propio sistema el que protege los recursos. Todo recurso del sistema, y todo principal (usuario del sistema o entidad que lo represente), tiene una etiqueta de seguridad (política de seguridad multinivel). Una etiqueta de seguridad se compone de una clasificación o nivel de seguridad (número en un rango, o un conjunto de clasificaciones discretas, como por ejemplo, desde DESCLASIFICADO hasta ALTO SECRETO) y una o más categorías, también llamados compartimentos de seguridad (CONTABILIDAD, VENTAS, I+D, etc.). En este tipo de controles, todas las decisiones de seguridad las impone el sistema, comparando las etiquetas de aquel que accede a las del recurso que es accedido, siguiendo un modelo matemático (Bell LaPadula, 1973). Los criterios de seguridad TCSEC correspondientes al nivel de seguridad B1 o superior incluyen este modelo. Aquí ni siquiera el usuario root puede alterar un sistema habilitado con MAC.

Para dotar a GNU/Linux de este tipo de controles, existen en el mercado herramientas como PitBull LX de Argus-Systems, que aunque no reemplazan los accesos de tipo DAC, sí añaden filtros extra, por lo cual tanto los ficheros protegidos como los procesos o los IPC's mismos, deben pasar por ambas comprobaciones, consiguiendo emular el control de accesos MAC.

Control de acceso por roles (RBAC). Desde los años 80 se ha propuesto un modelo de control de accesos basado en roles, como intento de unificar los modelos clásicos DAC y MAC, consiguiendo un mecanismo de control gestionado por el sistema, pero sin las restricciones rígidas impuestas por las etiquetas de seguridad. Básicamente un rol establece un nivel de indirección entre los usuarios y los derechos de acceso en base a un par de relaciones; la asignación de roles a los usuarios, y la asignación de permisos y privilegios a los roles. Las políticas de acceso basadas en roles, regulan el acceso de los usuarios a la información en términos de sus actividades y funciones de trabajo, representándose así de forma natural, la estructura de las organizaciones.

Otros modelos de control de acceso. La industria ha venido usando otros modelos de control de accesos, como complemento a los anteriores, como es el modelo de capacidades, donde parte de las decisiones de autorización se toman a partir de “derechos”, “capacidades” o “atributos de privilegio”, contenidos en las credenciales que un usuario adquiere durante la autenticación. Es normal encontrar estos atributos de autorización integrados en un objeto conocido como PAC (Certificado de Atributos de Privilegio), siendo como la acreditación de un visitante, emitida por una autoridad en la que se confía, que no identifica al individuo, pero sí lo categoriza. Estos permisos son de duración limitada y no encierran en si mismos privilegios o permisos.

Primeros pasos

Hay algunos preceptos básicos a seguir en la administración de máquinas que ejecuten servicios críticos, aquí enumeramos las más importantes:

Uso de la cuenta de root para lo mínimo imprescindible. No es recomendable usar la cuenta de root para el trabajo diario, ya que los permisos de los que dispone son elevados, en ocasiones demasiado. Nadie asegura que no se vaya a cometer un error mientras se trabaja, y cuando ocurre (porque suele ocurrir), las consecuencias suelen ser irreparables. Es por ello que lo primero que hay que hacer tras instalar un nuevo sistema GNU/Linux, es crear una cuenta de usuario de bajos privilegios. Del mismo modo, es igualmente recomendable crear una segunda cuenta con identificador 0 (privilegios de super usuario), con un nombre cualquiera, y configurar el sistema para que nos avise en caso de que alguien se registre en el sistema con el nombre de usuario root.

Registros. En los sistemas *UNIX, se generan gran cantidad de información en forma de registros. Su complejidad y grado de granularidad, dependerán en gran medida de la configuración del demonio syslogd. El fichero de configuración de este demonio es el /etc/syslogd.conf. El directorio /var/log guarda los archivos de registro, también llamados logs. Es recomendable hacer uso de herramientas como logrotate, las cuales comprueban el tamaño de los registros y generan copias de seguridad comprimidas para liberar el espacio de este directorio.

Igualmente recomendable es generar scripts dedicados a rastrear entre los logs en busca de patrones extraños como:

  • Registros cortos o incompletos
  • Registros con fecha extraña o incorrecta
  • Registros con permisos de usuarios o propietarios incorrectos
  • Registros de reinicio de la máquina o de sus servicios
  • Registros perdidos
  • Entradas con el comando su, o accesos remotos
  • Accesos inusuales a recursos http (access.log y error.log)

Seguridad básica

La seguridad empieza por aquellos procesos o ficheros a los cuales el sistema primero accede. Los ficheros de arranque: /etc/profile y ~/.profile. A menudo los intrusos malintencionados copian versiones modificada de programas dentro de la estructura del sistema, los llamados Caballos de Troya, o sencillamente, troyanos. Para estar seguros de que este tipo de programas no amenazan la integridad de nuestro sistema, hay que comprobar que el identificador de directorio actual “.”, no se encuentra incluido como variable de path en los ficheros que se cargan en los inicios de sesión, como por ejemplo; .cshrc, .login o .profile.

Un ejemplo sencillo podría ser por ejemplo modificar el fichero de inicio del editor vi, el .exrc y realizar lo siguiente:

!(cp /bin/bash /tmp/.bash ; chmod 4555 /tmp/.bash)&

umask. Este comando puede utilizarse para determinar los permisos por defecto que van a tener los nuevos archivos. Si se genera un fichero nuevo sin tener en cuenta los permisos, el usuario podría estar proporcionando de forma inadvertida, permisos de escritura o lectura a alguien que no debería tenerlo. Las máscaras de umask más típicas son 022, 027 y 077, la más restrictiva. Normalmente esta máscara se establece en el fichero /etc/profile, de forma que es aplicable a todos los usuarios del sistema. El valor de los permisos de los ficheros, se obtiene al efectuar la diferencia entre 777 y el valor de umask.

Shells restringidas. Este tipo de shells están pensadas para dar una mayor seguridad a determinadas configuraciones. Su comportamiento es exactamente el mismo que el de las shells convencionales, excepto por una serie de acciones que están deshabilitadas. Por ejemplo:

  • Cambiar de directorio con el comando cd que la shell incorpora.
  • Habilitar o deshabilitar las variables de la shell, tales como SHELL, PATH, ENV o BASH_ENV.
  • Especificar nombre de comandos conteniendo contra barras, contra ataques de variables de shell (obsoleto)
  • Importar definiciones de funciones de la variable de entorno de la shell al iniciarse

Si se desea dar de alta un usuario, pero no queremos asignarle ningún tipo de shell, como puede ser el caso de las cuentas de correo, se puede especificar /bin/false.

Ataques a contraseña

Para llevar una buena gestión del sistema, el administrador debe realizar periódicamente pruebas de vulnerabilidad de clave con programas de ataque a diccionario como John the Ripper, passeval, crack o checkpasswd. Para realizar los ataques recopilan información del campo GECOS del fichero /etc/passwd, el hostname de la máquina o passwords típicos (qwerty, 1234, etc.)

Las encuestan revelan que el 25% de las contraseñas en los sistemas se pueden romper en menos de una hora, y lo que es lo peor, el 4% de los usuarios utilizan su propio nombre como contraseña.

Los ficheros relacionados con este tipo de programas son:

/etc/passwd. Fichero que contiene un mapa de nombres de usuarios, identificadores y la ID del grupo al que pertenece cada uno. Las contraseñas, al pesar de lo que nos pueda parecer se almacenan en otro fichero llamado /etc/shadow.


/etc/shadow. Alberga pares de nombres de usuario y contraseñas, así como información administrativa, como la fecha de expiración y otros campos especiales. Este fichero debe protegerse a TODA costa, y sólo el root debería tener acceso de lectura a él.


/etc/group. Contiene toda la información de pertenencia a grupos. Es posible que un grupo no contenga ningún miembro. Debe ser accesible por todos los usuarios para un correcto funcionamiento.


/etc/gshadow. Similar al shadow, pero relativo a grupos. No suele hacerse uso de él.


/etc/shells. Aquí se guarda un listado con todas las shells válidas, de modo que si un usuario tiene asignada una shell no contenida en este fichero, puede que no funcione.


/etc/securetty. Este fichero contiene una lista de tty's desde los que el root puede hacer login. Los tty's de la consola suelen ir de /dev/tty1 a /dev/tty6. Los puertos serie son /dev/ttyS0, y son útiles por si se quiere hacer un login vía módem, por ejemplo. Lo normal es no permitir el acceso del root desde la red, y si a los usuarios, de modo que si se desea trabajar con nivel de superusuario, se ejecute sudo.

Ataques al sistema de ficheros

La mayoría de sistemas suelen tener cientos de mega bytes reservados como espacio swap, para resolver peticiones de clientes. Así, típicamente es usado para crear procesos menores con un periodo de vida corto. Una denegación de servicio podría estar basada en el llenado del espacio reservado para la swap. Para ello existe el comando ulimit, el cual puede usarse para especificar el tamaño máximo de un directorio, como es el caso del ejemplo siguiente:

/usr/bin/which -d 10240

Es por ello recomendable en todo sistema expuesto a sus usuarios, se usen cuotas de disco, para evitar precisamente, que uno de ellos pueda copar el espacio de disco y degradar el funcionamiento del sistema.

Encriptación

En este capítulo vamos a abordar algunos de los mecanismos que ofrecen los sistemas Linux para la securización de las transmisiones, contemplando aspectos como la privacidad de los datos, su integridad y su autenticidad. Para ello vamos a centrarnos en el grupo de programas SSH, en la tecnología SSL/TLS y finalmente en IPSec.

SSH

SSH (Secure Shell) es un programa que permite ejecutar servicios de red de modo seguro sobre redes inseguras, como por ejemplo Internet.

El concepto de shell segura fue concebido originalmente en los sistemas UNIX, como sustituto a los programas rsh, rcp y rlogin de los “Berkeley sevices”. SSH sustituye también a otras aplicaciones inseguras como telnet y ftp, ofreciendo un modo seguro de hacer login en un sistema remoto, así como realizar copias remotas seguras, ejecución de comandos, exportación de sesiones X11, y proporciona, evidentemente, comunicaciones seguras (encriptadas) y autenticadas entre dos sistemas remotos. Del mismo modo los puertos TCP/IP se pueden redirigir sobre canales seguros, habilitando conexiones seguras, como por ejemplo el servicio de correo electrónico.

La suite de protocolos IP fue diseñada para proporcionar una comunicación estable y escalable sobre cualquier tipo de red, funcionando correctamente mientras Internet consistía en unos pocos cientos de sistemas controlados. La situación actualmente ha cambiado con decenas de millones de ordenadores interconectados y con ellos, se han incrementado también los ataques así como las vulnerabilidades, siendo las mas usuales: Espionaje de las transmisiones. Búsqueda de contraseñas, números de tarjetas de crédito o cualquier tipo de información confidencial.

Hijacking. Situación en la que un atacante interviene una comunicación y modifica los datos entre ambas partes. IP spoofing. Falsificación de la dirección IP.

El protocolo SSH ha sido diseñado para proteger las comunicaciones de red contra todas estas vulnerabilidades.

Características del protocolo SSH

El conjunto de protocolos SSH ha sido estandarizado por la IETF(Internet Engineering Task Force). El protocolo SSH dispone de las siguientes características:

  • Sesiones de terminal seguras usando encriptación.
  • Total reemplazo de los programas ftp y telnet, así como la serie de comandos ‘r’ en UNIX (rlogin, rcp, rsh).
  • Múltiples algoritmos y métodos de autenticación.
  • Múltiples algoritmos de encriptación, como 3DES, Blowfish, y AES.
  • Túnel transparente y automático para conexiones X11 y aplicaciones basadas en la suite de protocolos TCP/IP tales como el correo electrónico.
  • Autenticación automática y segura en ambos extremos de la conexión, evitando el spoofing, troyanos, etc.

Múltiples canales que permiten múltiples terminales y transferencias de ficheros a través de una única conexión segura.

La versión actual del protocolo SSH es la 2, estando actualmente la versión 1 obsoleta y no se recomienda su uso, ya que es un protocolo vulnerable. Mas información disponible en:

www.ssh.com

En el caso de establecer una sesión con un servidor que ejecuta una versión insegura de este protocolo, SSH2 permite realizar una emulación para guardar la compatibilidad, sin tener que utilizar un programa SSH1 adicional. El software de encriptación SSH se desarrolla en Europa por lo cual no está sujeto a las regulaciones de exportación americanas. Por ello, este software puede ser utilizado en cualquier país que permita el uso de la encriptación, incluyendo los Estados Unidos de América.

El funcionamiento de esta aplicación, como todo lo relacionado con el mundo de la criptología, es bastante complejo, pero en esencia sus mecanismos son transparentes al usuario. SSH2 usa, entre otros, un método de llave pública al igual que lo hace RSA: El cliente usa su llave privada para firmar la sesión, la cual se encuentra en el fichero ~/.ssh/known_hosts, y envía el resultado al servidor. El servidor por su lado comprueba que la llave pública corresponda con la listada en el fichero correspondiente al tipo de encriptación utilizada en el directorio /etc/ssh/, y garantiza el acceso si ambas llaves concuerdan y la firma es correcta. El intercambio de llaves se realiza por medio del algoritmo Diffie-Hellman, pero la comunicación encriptada se realiza por medio de un algoritmo de encriptación simétrico como pueden ser el AES de 128/192/256 bits, el 3DES (triple DES), Blowfish, CAST128 o Arcfour, junto con algoritmos de hashing como hmac-md5 o hmac-sha1. Más adelante profundizaremos en estos detalles, pero por ahora veamos la estructura del fichero ~/.ssh/known_hosts:

localhost ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA60I/pLe/ZGyleEUoWZ WtQjFzc1gBLq+Wn8eNsOgCO4krCPGaOFdt7C4i41V3JS17nGDa/bRwjR4QGAGkhm3aX4hDSnVlmNPxf7hDktGvdxMKiFgoqw+ZzzQKbB4mzXFC/B+hur6usdkXCOBT8huL2BMFktiN9yZkdSmhI3MNWQk=
belluguet ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA60I/pLe/ZGyleEUoWZ WtQjFzc1gBLq+Wn8eNsOgCO4krCPGaOFdt7C4i41V3JS17nGDa/bRwjR4QGAGkhm3aX4hDSnVlmNPxf7hDktGvdxMKiFgoqw+ZzzQKbB4mzXFC/B+hur6usdkXCOBT8huL2BMFktiN9yZkdSmhI3MNWQk=

Tal como se observa en el ejemplo anterior, hay tres campos principales separados por espacios. El primero de ellos es el nombre del host al que hemos accedido, seguido por el tipo de algoritmo a usar y finalmente la propia clave.

Para utilizar una conexión segura basta con escribir la secuencia de comandos descrita en el ejemplo de a continuación:

[joan@Belluguet joan]$ ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is e6:1d:8d:30:2d:aa:b1:8d:4a:aa:71:9a:a7: fa:d8:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
joan@localhost's password:
[joan@Belluguet joan]$

La shell segura no es el único componente de la suite de comandos de SSH, sino que también podemos encontrar los siguientes:

  • scp. Secure copy, permite copiar ficheros entre sistemas remotos através de una conexión segura. A diferencia de rcp, scp precisa de una contraseña para funcionar correctamente.
  • sftp. Secure ftp, permite la transmisión de ficheros con un sistema orientado a conexión y seguro. Puede funcionar de modo interactivo o manual, siempre después de autenticarse debidamente.

El programa que proporciona el servicio de SSH, el demonio sshd, proporciona varios métodos de autenticación como la clave pública, autenticación de host, por contraseña o por desafío. Su fichero de configuración se encuentra en /etc/ssh/sshd_config, y se suele arrancar en el proceso de bootstrap en alguno de los ficheros rc del sistema (/etc/rc.d/rc.ssh). Este servidor soporta tanto clientes SSH1 como SSH2, incluso de manera simultánea.

SSL LIBRERÍA SSL/TLS OPEN SSL

SSL (Secure Socket Layer), fue desarrollado inicialmente por Netscape en el año 94 y más tarde fue adoptado y evolucionado por el IRTF (Internet Research Task Force) en el 96, renombrándolo a su denominación actual TLS, y definido en el RFC2246.

Técnicamente hablando, la librería ssl OpenSSL, implementa la tecnología de seguridad SSL v2/v3 y la capa de seguridad a nivel de transporte, mas conocida como TLS v1(Transport Layer Security). En otras palabras, SSL ofrece un canal de comunicación seguro para cualquier aplicación basada en TCP (HTTP, NNTP, SMTP, etc.), utilizando algoritmos de hashing como MD5 y SHA, además de encriptación convencional con clave de sesión como DES, 3DES, RC2, RC4 e IDEA. Mediante el uso de SSL se obtienen las siguientes ventajas:

  • Privacidad. Nadie puede ver el contenido.
  • Integridad. Nadie puede alterar el contenido.
  • Autenticación. El usuario establece conexiones con quién realmente dice ser.


Se necesita un método seguro para intercambiar la clave de sesión, esta es la función de TLS. Esta clave tiene los siguientes usos:

Key pair, se usa un juego de claves para que uno de los interlocutores pueda encriptar y el otro desencriptar. Esta tecnología es más lenta que la criptografía convencional, por ello se usa para transmitir la clave de otro algoritmo de encriptación simétrica.

Sólo se comparte una clave, mientras la otra, permanece como privada. Puede escogerse para ello RSA o Diffie-Hellman.

Para garantizar la integridad de los mensajes TLS, utiliza MAC (Message Authentication Code) lo cual no es más que realizar un HASH del mensaje, junto con una clave de sesión y un número de secuencia. Todo esto se transmite junto con el mensaje de modo que si la información fuera alterada en el camino el MAC no coincidiría. TLS puede utilizar los algoritmos de hashing MD5 o SHA-1.

TLS también autentica verificando la identidad de los usuarios mediante el uso de certificados, los cuales garantizan la autenticidad de la clave pública. El mecanismo de inicio o de establecimiento de sesión, está formado por las siguientes etapas:

  • Ambos extremos se ponen de acuerdo en el uso de los algoritmos.
  • Intercambio de claves.
  • Realizar autenticación.

A este proceso de establecimiento de sesión se le conoce con el nombre de “handshake”. A partir de este momento los datos transferidos en la capa de aplicación lo hacen de manera íntegra y privada.

Algoritmos

Los algoritmos que se usan en criptografía pueden dividirse en varios grupos. Por un lado están los algoritmos de hashing y los de encriptación. Ambos grupos se dividen a su vez en otros grupos que veremos a continuación.

Hash

A este grupo de algoritmos pertenecen tanto MD5 como SHA-1. Su principal función consiste en reducir un texto de entrada de longitud variable a uno de salida de longitud fija, con la característica de que una pequeña modificación en el original, provoca un cambio radical en el texto de salida. Estas funciones no son reversibles pues internamente realizan operaciones AND. Su funcionamiento es, a grandes trazos, el siguiente:

  • El usuario A envía un mensaje al usuario B, adjuntándole un resumen hash.
  • El usuario B recibe el mensaje, realiza su propio resumen hash y lo compara con el que le ha enviado el usuario A.

Este tipo de algoritmos se dividen a su vez en dos tipos:

  • Los que realizan un resumen del mensaje.
  • Los que usan una llave para hacer el hash del mensaje.

Este tipo de algoritmos se valoran según dos parámetros estadísticos. El primero los clasifica según la probabilidad de hallar dos mensajes diferentes que obtengan el mismo valor hash. El segundo es la dificultad de encontrar un texto del cual se obtenga un valor de hash dado.

Es prácticamente imposible encontrar dos textos que den el mismo valor de hash, teniendo en cuenta que MD5 trabaja con 128 bits de longitud de bloque, o SHA-1 que usa 160 bits.

Simétricos

Este tipo de algoritmos usan una misma clave tanto para el proceso de encriptación como para el de desencriptación. El algoritmo basa toda su seguridad en la confidencialidad de esta clave, llamada también clave simétrica o secreta.

Los algoritmos simétricos basan su funcionamiento en las dos operaciones básicas siguientes:

Sustituciones. Sustituyen unos valores por otros según los parámetros de la clave.

Permutaciones. Cambian los bits de orden para aumentar el nivel de entropía, evitando de este modo el análisis estadístico.

Finalmente, los algoritmos simétricos combinan ambos métodos para aumentar su seguridad.

A continuación se detallan las principales características de los algoritmos simétricos más conocidos:

  • DES (Data Encryption Standard)
    • Clave fija de 58 bits más 8 de paridad.
    • Bloques de texto de 64 bits.
    • Está muy extendido, pues ha sido estándar del NIST, la agencia de estándares americana, hasta el año 2000
    • Su clave de 58 bits es corta, aunque a día de hoy su análisis no sea práctico.
  • 3DES (Triple DES)
    • Clave de 128 bits (16 de paridad y 112 de clave), compatible con DES sencillo, aplicando la misma clave hacia adelante, atrás y finalmente adelante.
  • IDEA (International Data Encryption Algorithm)
    • Algoritmo de libre distribución creado en Europa.
    • Clave de 128 bits.
    • Bloques de texto de 64 bits.
  • RC5
    • Permite diferentes longitudes de clave.
    • Creado por la empresa RSA Data Security Inc. e implementado por la empresa Netscape en su sistema de seguridad SSL.
  • AES (Advanced Encryption Standard)
    • Nuevo estándar del NIST, sustituyendo a DES.
    • Claves de 128, 192 o 256 bits.
    • Bloques de texto de 128, 192 o 256 bits.
    • Los tamaños de las claves y los bloques no tienen porque coincidir.

Asimétricos

Este tipo de algoritmos usan tanto claves diferentes como algoritmos diferentes para encriptar y desencriptar. Cada usuario posee un par de claves:

  • Clave pública. Conocida por todo el mundo, se almacena en lugares públicos como bases de datos, directorios LDAP, etc.
  • Clave privada. Sólo es conocida por el propio usuario.

La información encriptada con una clave puede ser desencriptada con la otra, y siendo imposible desencriptar la información conociendo sólo la clave con la que se encriptó, y averiguar el valor de una clave conociendo la otra.

Las bases que hacen posible este tipo de algoritmos son unas funciones matemáticas conocidas como one-way, en las que es prácticamente imposible volver hacia atrás para obtener el original a partir del criptograma (mensaje encriptado). Por ejemplo:

Imagen:one-way.png

Debido a que existe una relación entre las claves pública y privada, los ataques a los que se suele someter a este tipo de algoritmos son los de prueba y ensayo. Para solucionar este inconveniente se usan claves muy largas que luego penalizan en velocidad.

Algunos de los algoritmos asimétricos más conocidos son:

  • RSA.
    • Claves de 1024 o 2048 bits. La seguridad depende de la longitud de la clave.
    • Se basa en la dificultad de descomponer de forma analítica un número muy grande en factores primos.
    • Se usa para firma electrónica y distribución de claves simétricas.
  • Diffie-Hellman.
    • Fue el primer algoritmo de clave pública.
    • Se basa en logaritmos discretos.
    • Sólo sirve para distribuir claves simétricas.

Netfilter: Filtrado y enrutamiento

Linux es por excelencia el Sistema Operativo más indicado para ejecutar servicios y aplicaciones de red, lo que supone un alto riesgo para los datos contenidos en cualquier estación que se encuentre conectada a la misma. En el momento en que sus datos forman parte de una red, corporativa o no, corren el peligro de ser objeto de intrusión y robo, y muchas veces ello puede comportarle pérdidas lamentables en la estructura de su sistema. Si desea proteger sus datos, la mejor opción es actualizar y securizar las aplicaciones que los comparten con otros clientes dentro de una red, pero la prevención de intrusiones o ataques mediante la implementación de un firewall es algo que no puede obviarse dado que es la herramienta más eficaz contra el tráfico de información no deseado.

Linux posee implementado directamente en el núcleo el código de una serie de funciones específicas para construir firewalls. Reciben en conjunto el nombre de Netfilter, y la aplicación que las engloba es Iptables. Con Iptables usted puede construir una herramienta que examine constantemente el tráfico que atraviesa una máquina, y a la vez decidir lo que desea hacer con ese tráfico: aceptarlo (dejarlo pasar), denegarlo (no dejarlo pasar) o rechazarlo (no dejarlo pasar, informando de ello al remitente).

Netfilter es la parte del núcleo 2.4.x de Linux que le permite filtrar y enrutar (NAT) paquetes de información. Es el rediseñado y mejorado código de Ipchains (kernel 2.2.x) e Ipfwadm (kernel 2.0.x). Netfilter es un conjunto de funciones del código de Linux 2.4 implementadas en la pila TCP/IP que se activan cada vez que un paquete de información atraviesa el host. Iptables es la estructura de una tabla sobre la que se pueden definir reglas. Cada regla consta de unas condiciones de coincidencia, y una acción asociada a cada coincidencia.

Posiblemente usted se pregunte lo que es un filtro. Un filtro es una parte de software que observa las cabeceras de los paquetes que llegan al host sobre el que está implementado, siendo capaz de decidir el futuro de ese paquete. EL filtrado de paquetes en Linux está programado en el código fuente del kernel, como un módulo o incluido en su imágen.

Funcionamiento del filtrado

Existen tres tablas sobre las que implementar reglas para el filtrado de paquetes, en el momento de arrancar su ordenador podrá comprobar que se encuentran vacías. Los nombres de dichas tablas son Filter, Nat, y Mangle.

Cada una de ellas acumula reglas con diferentes fines. Las reglas de una tabla nunca interfieren en la acción realizada por las reglas de otra tabla, aunque muy posiblemente usted deseará aprovechar la funcionalidad de una tabla para facilitar el trabajo de otra. La tabla Filter hospeda las reglas relacionadas con el filtrado de paquetes y la decisión de si deben cruzar o no el host. La tabla Nat se refiere a las reglas que implementan el intercambio de destinos de un paquete, de tal modo que si a un host le llega un paquete con una petición que coincide con una regla, ésta puede desviar dicho paquete a otra máquina dentro de su red. La tabla Mangle contiene reglas que le permiten examinar paquetes y realizar sobre ellos diferentes tipos de marcas que después otras aplicaciones podrán leer para realizar otras acciones sobre la información.

Los conjuntos o listas de reglas implementadas en cada tabla reciben el nombre de cadenas o chains.

Existen tres tipos de cadenas diferentes según la tabla.

Las reglas dentro de la tabla Filter se agrupan en las cadenas INPUT, OUTPUT y FORWARD. La cadena INPUT especifica reglas sobre los paquetes que llegan de fuera (dígase Internet), y la decisión sobre si deben dejar que pasen o no. La cadena OUTPUT agrupa reglas que afectan a los paquetes que llegan de dentro de la red local (o de la misma máquina) y tienen destino en el exterior, y también deciden si dichos paquetes deben o no dejarse pasar. La cadena FORWARD reúne reglas referentes a los paquetes que llegan por una interface (tarjeta de red, por ejemplo) y deben salir por otra interface. Decide si una interface debe ser capaz de verse con la otra para que leenvíe los paquetes que ha recibido.

Las teglas dentro de la tabla Nat se agrupan en las cadenas POSTROUTING, PREROUTING, y FORWARD. La cadena PREROUTING hace referencia a los paquetes que provienen del exterior y deben ser desviados a una máquina dentro de la red local. La cadena POSTROUTING se refiere a los paquetes que provienen de las máquinas que forman la red local y que desean acceder a internet. La cadena FORWARD decide si deben poderse enviar paquetes entre dos interfaces conectadas a la máquina que ejecuta el filtrado.

Operaciones sobre una cadena

Una vez arranque el ordenador las cadenas de cada tabla estarán vacías, y a partir de este momento usted debe comenzar a trabajar con ellas creando reglas y agrupándolas en cadenas. Entre las accionesque pueden realizarse sobre una cadena de la tabla Filter están las siguientes:

· Crear una nueva cadena (-N)

· Borrar una cadena vacía (-X)

· Cambiar la política por defecto de una cadena (-P)

· Listar las reglas contenidas en una cadena (-L)

· Borrar las reglas de una cadena (-F)

· Resetear los contadores de paquetes y bytes en una cadena (-Z)


Hay varias maneras de manipular las reglas dentro de una cadena:

· Añadir una nueva regla a la cadena (-A)

· Insertar una nueva regla a la cadena (-I)

· Reemplazar una regla dentro de una cadena (-R)

· Borrar una regla dentro de una cadena (-D)


Puede comprovar el estado de las tablas y sus cadenas mediante la opción -L mencinada anteriormente. Verá que existen las tablas y las cadenas, pero que ninguna de ellas contiene regla alguna:

root@hash:~# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination  

Primeros filtros

Ésta es la parte más suculenta del filtrado de paquetes: el manejo de las reglas. Normalmente usted usará los comandos de añaadir (-A) y borrar (-D) reglas. Las opciones de insertar (-I) y reemplazar (-R) son meras extensiones de estos conceptos.

Las interfaces de red se reconocen con el comando ifconfig. Si lo ejecuta verá posiblemente una interface llamada eth0 (su interface de red) y otra llamada simplemente lo, es la interface de loopback generada por el propio sistema operativo para poder probar aplicaciones de red con usted mismo sin necesidad de tener una tarjeta de red o estar conectado a ninguna red. Puede usar el comando ping para generar paquetes que circulen por la interface de loopback, y acto seguido implementar un filtro que deniegue dichos paquetes.

Pruebe por ejemplo a lanzar un ping contra su propia dirección IP de loopback (127.0.0.1):

# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#

Puede echar un vistazo a la sentencia que declara el primer filtro:

# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP

Analizando la estructura de la sentencia distinguirá los siguientes campos:

iptables – comando de ejecución de filtrado -A – añadir una nueva regla a la cadena INPUT – nombre de la cadena a la que se añade la regla -s – opción para especificar el orígen de los paquetes 127.0.0.1 – dirección de su interface de loopback -p – opción para especificar el tipo de protocolo icmp – tipo de protocolo del paquete -j – opción para especificar la decisión del futuro del paquete DROP – denegación del paquete

La regla podría leerse del siguiente modo: Cualquier paquete que provenga de la dirección 127.0.0.1 y utilice protocolo ICMP, no debe traspasar el filtro. Dicho paquete jamás se habrá recibido...

Implemente ahora la siguiente línea de filtrado:

# iptables -A INPUT -i eth0 -s 0/0 -d 192.168.1.1 - -dport 0:1023 -j DROP

Puede interpretar la línea como sigue:

Cualquier paquete que entre por la interface eth0, que provenga de cualquier dirección, con destino a mi dirección (192.168.1.1) y a un puerto entre 0 y 1023, no debe traspasar el filtro.

Las opciones en este caso han variado. El significado de las que ha incorporado es el siguiente:

-s 0/0 – la opción -s hace referencia a la dirección de origen (source address) especificada en la cabecera del paquete. En el ejemplo anterior usted había especificado 127.0.0.1, que es la dirección de su interface de loopback. En el ejemplo actual la ha sustituido por 0/0, que hace referencia a cualquier dirección posible. La explicación es sencilla: Usted sabe que la red 192.168.1.0/24 hace referencia a una red de clase C (256 hosts) con rango 192.168.1, la dirección 192.168.0.0/16 hace referencia a una red de clase B (65535 hosts), la dirección 192.0.0.0/8 se refiere a una red de clase A (cerca de 17 millones de hosts), y por tanto la dirección 0.0.0.0/0 se refiere al total de posibles direcciones IP (usando IP versión 4). Es una simple cuestión de máscaras.

-i eth0 – La interface de red por la que llega el paquete. La opción que especifica la interface no es siempre -i. Si el paquete llega a la interface en dirección hacia el interior de la red local, entonces el paquete llega por la cadena INPUT (un paquete que entra). En este caso la interface se especifica con la opción -i. Si el paquete saliese de la red interna y se dirigiese al exterior, llegaría por la cadena OUTPUT, y la interface se declararía con la opción -o. No olvide esta regla, de lo contrario recibirá un error a la salida de su comando.

Ahora ha tecleado dos lineas de filtrado, puede observar en la tabla de filtrado como la cadena INPUT contiene las dos entradas. Para ello teclee simplemente:

# iptables -t filter -L -n

Podrá observar el formato de la tabla filter bajo el cual se acumulan las reglas. Posiblemente la visualización de las tablas le ayude a entender mejor el concepto del funcionamiento de Netfilter.

Posiblemente ahora le moleste tener esas reglas cargadas. Puede borrarlas con el siguiente comando:

# iptables -t filter -F INPUT

Sobre las opciones que acepta la declaración de reglas en la tabla filter, pueden resumirse del siguiente modo:

-s – Especifica la dirección de origen (source address) del paquete.

--sport – Puerto de orígen del paquete.

-d – Dirección de destino (destination address) del paquete.

--dport – Puerto de destino del paquete.

-p – Protocolo que usa el paquete (TCP, UDP ó ICMP).

-i / -o – Interface de entrada o salida (respectivamente) del paquete.

-f – Paaquetes fragmentados. A veces un paquete es demasiado largo para enviarlo por el medio, de modo que el orígen lo fragmenta en paquetes más pequeños.

--icmp-type – Tipo de mensaje ICMP (echo-reply, echo-request, traceroute-request...)

--mac-source – Dirección MAC de lainterface remota que ha enviado el paquete.

Negación de una opción

Usted puede estar interesado en generar una regla que se cumpla en casi la totalidad de los casos, pero efectuando una excepción. Imagine por ejemplo que no desea dejar que nadie acceda a su ordenador por el puerto 23 (telnet), pero sí desea habilitar ese acceso para una dirección IP concreta (por ejemplo la del administrador del sistema). Podría hacerlo usando la negación del siguiente modo:

# iptables -A INPUT -i eth0 -s ! 192.168.1.25 -d 192.168.1.254 --dport 23 -j DROP

Donde la dirección IP del suspuesto administrador es 192.168.1.25, y la del ordenador que desea proteger es 192.168.1.254. Si se fija, el símbolo ! ejerce la negación a la regla general. Podría entenderse de la siguiente manera:

Cualquier paquete que entre por la interface eth0, que provenga de cualquier dirección QUE NO SEA 192.168.1.25, con destino a la dirección local (192.168.1.254), dirigido al puerto 23, no debe atravesar el filtro.

El mismo proceso puede servirle para ejercer una negación sobre un puerto o un tipo de protocolo.

Limitación

Usted puede limitar el número máximo de veces que un paquete coincida con una regla. Puede entenderse como el número máximo de veces que debe aplicarse una acción a un paquete que coincida con una determinada regla. Imagine que no desea que entren más de 10 paquetes por segundo provinentes de una cierta dirección IP. Puede hacerlo del siguiente modo:

# iptables -A INPUT -i eth0 -s 192.168.1.25 -m limit --limit 10/second -j ACCEPT

Preste atención a la parte del final, antes de la acción. La opción -m limit especifica que se va a limitar el número máximo de veces que se debe ejecutar la acción sobre el paquete coincidente. Acto seguido puede ver --limit 10/second, lo que especifica el número exacto de la limitación y la medida de tiempo que se debe tomar por referencia: 10 paquetes por minuto.

Puede afinar la limitación aplicando un número máximo de ráfagas por coincidencia antes de que se aplique el límite especificado anteriormente. Para ello puede hacer lo siguiente:

# iptables -A INPUT -i eth0 -s 192.168.1.25 -m limit --limit 10/s --limit-burst 5 -j ACCEPT.

Fíjese primero que especificar --limit 10/second es lo mismo que especificar --imit 10/s, es una mera abreviación. Despues puede fijarse en el límite de la ráfaga. Es decir, la coincidencia se aplicará 10 veces por segundo, y antes de volverse a aplicar se dejará pasar 5 coincidencias sin aplicar la acción asociada.

Registro (Logging)

No sólamente puede filtrar los paquetes que coincidan con las reglas, sino que a la vez puede tambien logearlos, esto es, guardar un registro en el sistema de logging de Linux para que usted pueda ver en un fichero de texto los paquetes que han llegado a su red y la acción que se les ha aplicado. Para ello se aplica la acción LOG del siguiente modo:

# iptables -A INPUT -i eth0 -s 192.168.1.25 -m limit --limit 10/s --limit-burst 5 -j LOG --log-level DEBUG

El comando genera una regla que no acepta ni deniega el paso al paquete coincidente, sino simplemente deja una entrada en el registro de logs del sistema. Además, para no cargar excesivamente el tamaño de dicho registro, logea sólamente 10 coincidencias por segundo, dejando entre medio un intervalo de 5 coincidencias sin aplicarles ninguna acción.

La opción --log-level DEBUG especifica el nivel del registro en el que se debe crear la entrada. El registro del sistema (Syslog) posee un archivo de configuración (/etc/syslog.conf) en el que usted puede ver como las diferentes incidencias que el sistema genera quedan registradas en diferentes niveles, significando únicamente el nivel el fichero de texto en el cual se deben guardar las entradas del registro. Esto es para no llenar los registros con entradas excesivas y demasiada información que pueda no ser de interés para el administrador. Evidentemente la única razón por la que el registro se separa en niveles es para mantener un cierto órden ante la complejidad de entendimiento que aportan los registros.

Enrutamiento

Tal como se explica al principio de este capítulo, Netfilter le aporta la posibilidad de realizar el filtrado de paquetes, así como la de configurar su host a modo de router, esto es, utilizarlo para conectar dos o más redes diferentes.

Por norma general usted poseerá una red formada por varios ordenadores que necesiten salir a Internet a través de una única linea de acceso. Entiéndase Internet como cualquier otra red. La función de un router es la de encaminar la información provinente de una red hacia otra red. De este modo, Netfilter le ofrece la posibilidad de conectar una red con otra teniendo dos interfaces de red (tarjetas de red por norma general), formando cada una parte de una red diferente.

El primer caso supone que usted posee una red de ordenadores que deben salir a Internet. Su red contiene máquinas cuyas direcciones IP se numeran dentro del rango de clase C 192.168.1.0/24. La dirección IP externa (visible desde internet) que tiene asignada su ordenador es 195.98.24.126. Veamos las órdenes necesarias para conseguir que los ordenadores de su red alcancen Internet:

# iptables -P FORWARD ACCEPT
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 195.98.24.126
# echo 1 > /proc/sys/net/ipv4/ip_forward

La primera línea habilita la visibilidad entre las dos interfaces (tarjetas) de red que le conectan a sendas redes respectivamente.

La segunda línea genera una regla dentro de la cadena POSTROUTING en la tabla Nat, que especifica que a cualquier paquete que salga por la interface (tarjeta) eth0 provinente de la red interna (192.168.1.10/24) se le debe ejecutar la acción SNAT para hacer que salga al exterior con dirección de orígen 195.98.24.126 (su dirección externa).

Las siglas NAT significan Network Address Translation, proceso que implica el cambio de una dirección IP por otra diferente. En el caso actual, en el que las máquinas de su red local deben salir a Internet, para ello deben hacerlo con una dirección IP válida, de modo que en la cabecera del paquete se sustituirá la dirección IP orígen (direccion IP de red interna, no válida en Internet) por la dirección IP que a usted le ha asignado su proveedor, y que es perfectamente válida en Internet. EL proceso de NAT recordará ese cambio para luego saber modificar el paquete de respuesta, cambiando la dirección de destino (la dirección externa) por la dirección interna de la máquina que originalmente lanzó la petición. Este proceso recibe el nombre de Source NAT (SNAT) ó IP MASQUERADING (enmascaramiento de direcciones IP).

En caso de que usted tenga un servidor web dentro de su red local y desee que las peticiones al puerto 80 que reciva su firewall sean enviadas al servidor web, el proceso se invierte aunque el funcionamiento es el mismo, y el nombre con el que se conoce el proceso es en este caso Destination NAT ó Port Forwarding. Veamos un ejemplo en el que la dirección IP del servidor web es 192.168.1.15:

$iptables -t nat -A PREROUTING -p TCP -i eth0 --dport 80 -j DNAT --to-destination 192.168.1.15:80

Automatización del proceso

Usted puede comenzar a teclear reglas de filtrado y enrutado. Estas serán válidas durante el periodo de tiempo que el ordenador pase encendido, pero una vez lo apague las perderá puesto que se guardan en memoria volátil. Una vez encienda su ordenador de nuevo, el filtrado y enrutamiento que había tecleado ya no serán vigentes y usted habrá perdido laconfiguración de su firewall.

Para automatizar el proceso y no tener que volver a teclear todo el filtrado y el enrutamiento usted puede generar un archivo de texto que contenga las órdenes de filtrado y enrutamiento, y una vez guardado darle permisos de ejecución. De este modo una vez encendida la máquina no tendrá mas que ejecutar el fichero que contiene la implementación desu firewall.

Es muy posible que usted desee ejecutar el firewall automáticamente al encender su ordenador, de manera que no tenga que ejecutarlo manualmente. Suele ser así en el caso de las líneas de conexión permanente. En tal caso, siguiendo la metodología estándar del sistema de arranque es una buena opción generar un fichero llamado rc.firewall y alojarlo en el directorio correspondiente que pertoque al sistema de arranque que utilice su distribución de Linux. En el caso de BSD puede colocarse directamente en /etc/rc.d/rc.firewall. En el caso de System V debería colocarse en el subdirectorio correspondiente al default runlevel, siguiendo la nomenclatura de los ficheros en el sistema de arranque System V.

Si usa sistema de arranque BSD y ha generado un fichero /etc/rc.d/rc.firewall, puede editar el fichero que arranca el runlevel por defecto de su sistema y añadirle elcódigo necesario para la ejecución del firewall. En el caso de Slackware puede editar el fichero /etc/rc.d/rc.M y añadir las siguientes líneas:

if [ -x /etc/rc.d/rc.firewall ] ; then
  echo “Starting firewall...”
  /etc/rc.d/rc.firewall
fi

Dependiendo de la versión de Slackware es posible que no necesite hacerlo, dado que el script /etc/rc.d/rc.inet2 ya realiza esta comprovación.

En el caso de una conexión por línea telefónica con módem, puede generar el mismo fichero y alojarloen el mismo lugar, pero en lugar de lanzarlo desde el sistema de arranque (recuerde editar y modificar entonces /etc/rc.d/rc.inet2) puede editar el fichero /etc/ppp/ip-up y almacenar en él una línea que ejecute el fichero conla implementación del firewall. El fichero ip-up (si existe) se ejecuta en el momento en que el módem ha conectado con el proveedor de servicios.

Si lo desea también puede implementar la ejecución del firewall directamente dentro de /etc/ppp/ip-up y olvidar el sistema de arranque. SI lo hace así tendrá la ventaja de poder sustituir en las reglas su dirección por un $4, ya que al ejecutarse ip-up automáticamente sustituye el valor de $4 por la dirección IP que le asigna su proveedor.

Firewall de ejemplo

#!/bin/sh
#
# Filter-Mussol v1.3
# Iván Belmonte <ttyp0@inet2u.com>
#############################################
# OBSERVACION: 
# en este firewall muchas cosas estan logeadas con --log-prefix. 
# Esto es para que una vez en ejecucion, el filtrado muestre 
# claramente lo que hace cada cosa. 
# Si os molesta solamente debeis borrar esa parte de las lineas 
# de filtrado. Si no quereis logear las entradas y/o salidas de 
# vuestro sistema, solo debeis borrar las lineas pertenecientes 
# al logging de cada filtrado (estan repetidas, si os fijais hay 
# una con la entrada de LOG y otra con el filtro). 
# Para mas informacion podeis dirigiros a la documentacion oficial 
# de Netfilter:
#
# -------> Linux 2.4 Packet Filtering HOWTO:
# http://netfilter.samba.org/unreliable-guides/packet-filtering-HOWTO/packet-filtering-HOWTO.linuxdoc.html
#
# -------> Linux 2.4 NAT HOWTO:
# http://netfilter.samba.org/unreliable-guides/NAT-HOWTO/NAT-HOWTO.linuxdoc.html
#
#-----------------------------------------------------------------------
# ttyp0 <ttyp0@inet2u.com> - Marzo 2k2
#
# 

########################################
# Declaracion de variables #############
########################################
set_variable_definitions(){

  echo -n "-> Setting up variable definitions"
  echo " "
  IPTABLES="/usr/sbin/iptables"
  EXTIP="217.126.51.143"
  EXTIFACE="eth0"
  WLANIP="192.168.2.253"
  WLANIFACE="wlan0"
  WLANMASK="192.168.2.0/24"
  OUTADDR="0/0"
  LOCALIP="192.168.1.254"
  LOCALMASK="192.168.1.0/24"
  LOCALIFACE="eth1"
  LOG_LEVEL="DEBUG"
  WEBSERVER="192.168.1.10"
  MXSERVER="192.168.1.10"
  SYSADMIN="192.168.1.1"
  YAHOO_USER="192.168.1.100"
  YAHOO_TCP_PORTS="5000 5001 5050 5100"
  YAHOO_UDP_PORTS="5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010"
  EMULE_USER="192.168.1.100"
  EMULE_TCP_PORTS="4661 4662 4663 4664 4665"
  EMULE_UDP_PORTS="4661 4662 4663 4664 4665 4672"
  IANA_RESERVED="
  0.0.0.0/8 1.0.0.0/8 2.0.0.0/8 5.0.0.0/8 7.0.0.0/8 23.0.0.0/8 \
  27.0.0.0/8 31.0.0.0/8 36.0.0.0/8 37.0.0.0/8 39.0.0.0/8 \
  41.0.0.0/8 42.0.0.0/8 58.0.0.0/8 59.0.0.0/8 60.0.0.0/8 \
  69.0.0.0/8 70.0.0.0/8 71.0.0.0/8 72.0.0.0/8 73.0.0.0/8 \
  74.0.0.0/8 75.0.0.0/8 76.0.0.0/8 77.0.0.0/8 78.0.0.0/8 \
  79.0.0.0/8 82.0.0.0/8 84.0.0.0/8 85.0.0.0/8 86.0.0.0/8 \
  87.0.0.0/8 88.0.0.0/8 89.0.0.0/8 90.0.0.0/8 91.0.0.0/8 \
  92.0.0.0/8 93.0.0.0/8 94.0.0.0/8 95.0.0.0/8 95.0.0.0/8 \
  96.0.0.0/8 97.0.0.0/8 98.0.0.0/8 99.0.0.0/8 100.0.0.0/8 \
  101.0.0.0/8 102.0.0.0/8 103.0.0.0/8 104.0.0.0/8 105.0.0.0/8 \
  106.0.0.0/8 107.0.0.0/8 108.0.0.0/8 109.0.0.0/8 110.0.0.0/8 \
  111.0.0.0/8 112.0.0.0/8 113.0.0.0/8 114.0.0.0/8 115.0.0.0/8 \
  116.0.0.0/8 117.0.0.0/8 118.0.0.0/8 119.0.0.0/8 120.0.0.0/8 \
  121.0.0.0/8 122.0.0.0/8 123.0.0.0/8 124.0.0.0/8 125.0.0.0/8 \
  126.0.0.0/8 127.0.0.0/8 197.0.0.0/8 201.0.0.0/8 219.0.0.0/8 \
  220.0.0.0/8 221.0.0.0/8 222.0.0.0/8 223.0.0.0/8 240.0.0.0/8 \
  241.0.0.0/8 242.0.0.0/8 243.0.0.0/8 244.0.0.0/8 245.0.0.0/8 \
  246.0.0.0/8 247.0.0.0/8 248.0.0.0/8 249.0.0.0/8 250.0.0.0/8 \
  251.0.0.0/8 252.0.0.0/8 253.0.0.0/8 254.0.0.0/8 255.0.0.0/8" 

return;
}

###########################
# Liberacion de variables #
###########################
unset_variable_definitions(){ 

  echo -n "-> Unsetting variable definitions"
  echo " "
  unset IPTABLES
  unset EXTIP
  unset EXTIFACE
  unset OUTADDR
  unset LOCALIP
  unset LOCALMASK
  unset LOCALIFACE
  unset LOG_LEVEL
  unset WEBSERVER
  unset MXSERVER
  unset SYSADMIN
  unset IANA_RESERVED
  unset YAHOO_USER
  unset YAHOO_TCP_PORTS
  unset YAHOO_UDP_PORTS
  unset B4U_USER
  unset B4U_TCP_PORTS
  unset B4U_UDP_PORTS 

return;
}

#####################################
# Vaciado de las chains principales #
#####################################
rule_flush(){ 

   echo -n "-> Flushing filter chains"
   echo " "
   $IPTABLES -F INPUT
   $IPTABLES -F OUTPUT
   $IPTABLES -F FORWARD 

   echo -n "-> Flushing nat chains"
   echo " "
   $IPTABLES -t nat -F PREROUTING
   $IPTABLES -t nat -F POSTROUTING
   $IPTABLES -t nat -F OUTPUT 

return;
}
############################################
# Establecimiento de politicas por defecto #
############################################
set_default_policy(){ 

   echo -n "-> Setting default policies for filter chains"
   echo " "
   $IPTABLES -P INPUT ACCEPT
   $IPTABLES -P OUTPUT ACCEPT
   $IPTABLES -P FORWARD ACCEPT 

return;
}


#####################################################
# Instalacion de los modulos necesarios para el NAT #
#####################################################
load_nat_modules()
{
   echo -n "-> Loading NAT modules"
   echo " "

   INSTALLED_MODULES=`lsmod | cut -d ' ' -f 1`
   if test -n "echo $INSTALLED_MODULES | grep iptable_nat"; then
      /sbin/modprobe iptable_nat
   fi
   if test -n "echo $INSTALLED_MODULES | grep ip_conntrack_ftp"; then
      /sbin/modprobe ip_conntrack_ftp
   fi
   if test -n "echo $INSTALLED_MODULES | grep ip_conntrack_irc"; then
      /sbin/modprobe ip_conntrack_irc
   fi
   if test -n "echo $INSTALLED_MODULES | grep ip_nat_ftp"; then
      /sbin/modprobe ip_nat_ftp
   fi
   if test -n "echo $INSTALLED_MODULES | grep ip_nat_irc"; then
      /sbin/modprobe ip_nat_irc
   fi
   return;
} 

#####################################
### Implementacion de IP MASQUERADE #
#####################################
load_masq_rules(){ 

  echo -n "-> Loading IP-MASQUERADE rules"
  echo " "
  $IPTABLES -t nat -A POSTROUTING -o $EXTIFACE -s $LOCALMASK -j SNAT --to-source $EXTIP 

  echo -n "-> Loading IP-MASQUERADE WLAN rules"
  echo " "
  $IPTABLES -t nat -A POSTROUTING -o $EXTIFACE -s $WLANMASK -j SNAT --to-source $EXTIP 

return;
}

#####################################
# Implementacion de Port Forwarding #
#####################################
load_nat_rules(){

  echo -n "-> Loading NAT rules"
  echo " "

  $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport 80 -j DNAT --to-destination $WEBSERVER:80
  $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport 25 -j DNAT --to-destination $MXSERVER:25
  $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport 110 -j DNAT --to-destination $MXSERVER:110
  $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport 20 -j DNAT --to-destination $WEBSERVER:20
  $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport 21 -j DNAT --to-destination $WEBSERVER:21
  $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport 22 -j DNAT --to-destination $WEBSERVER:22 

  # Yahoo Messenger port forwarding
   for TCP_PORT in $YAHOO_TCP_PORTS; do
    $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport $TCP_PORT -j DNAT --to-destination $YAHOO_USER:$TCP_PORT
    done

   for UDP_PORT in $YAHOO_UDP_PORTS; do
    $IPTABLES -t nat -A PREROUTING -p UDP -i $EXTIFACE --dport $UDP_PORT -j DNAT --to-destination $YAHOO_USER:$UDP_PORT
    done

   # eMule port forwarding
   for TCP_PORT in $EMULE_TCP_PORTS; do
    $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTIFACE --dport $TCP_PORT -j DNAT --to-destination $EMULE_USER:$TCP_PORT
   done

   for UDP_PORT in $EMULE_UDP_PORTS; do
    $IPTABLES -t nat -A PREROUTING -p UDP -i $EXTIFACE --dport $UDP_PORT -j DNAT --to-destination $EMULE_USER:$UDP_PORT
   done
return;
}

##############################
# Implementacion de filtrado #
##############################
load_filter_rules(){

  echo -n "-> Loading filter rules"
  echo " "

# Por orden logico, primero aceptamos las cosas concretas, 
# y luego cerramos todo el resto
# ----------------------------------------------------
# Conexiones que aceptamos
# a la misma maquina

# Entrada de SSH 

  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 22 -m limit --limit 5/m -j LOG --log-prefix "SSH Input: " --log-level DEBUG
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 22 -j ACCEPT

# Entrada de FTP (logged) y FTP-DATA
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 21 -m limit --limit 5/m -j LOG --log-prefix "FTP Input: " --log-level DEBUG
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 21 -j ACCEPT
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 20 -j ACCEPT

# Entrada de http
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 80 -m limit --limit 5/m -j LOG --log-prefix "HTTP Input " --log-level DEBUG
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 80 -j ACCEPT

# Entrada de correo
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 25 -m limit --limit 5/m -j LOG --log-prefix "SMTP Input " --log-level DEBUG
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 25 -j ACCEPT
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 110 -m limit --limit 5/m -j LOG --log-prefix "POP3 Input " --log-level DEBUG
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 110 -j ACCEPT

# Denegacion de todo lo que provenga 
# de una IP reservada por la IANA
  for NET in $IANA_RESERVED; do
   $IPTABLES -A INPUT -s $NET -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "IANA reserved DROP: "
   $IPTABLES -A INPUT -s $NET -j DROP
  done
# Denegacion de todo lo que PROVENGA DE
# IP's reservadas para redes privadas 
# de clase A, B, D y E diferentes de 
# la nuestra
#
## Clase A
  $IPTABLES -A INPUT -s 10.0.0.0/8 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "A reserved DROP: "
  $IPTABLES -A INPUT -s 10.0.0.0/8 -j DROP

## Clase B
  $IPTABLES -A INPUT -s 172.26.0.0/16 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "B reserved DROP:"
  $IPTABLES -A INPUT -s 172.26.0.0/16 -j DROP

## Clase D 
  $IPTABLES -A INPUT -s 224.0.0.0/4 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "D reserved DROP:"
  $IPTABLES -A INPUT -s 224.0.0.0/4 -j DROP

## Clase E 
  $IPTABLES -A INPUT -s 240.0.0.0/5 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "E reserved DROP:"
  $IPTABLES -A INPUT -s 240.0.0.0/5 -j DROP

# Denegacion de todo lo que SE DIRIJA A
# IP's reservadas para redes privadas 
# de clase A, B, D y E diferentes de 
# la nuestra
#
## Clase A
  $IPTABLES -A INPUT -d 10.0.0.0/8 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "A reserved DROP: "
  $IPTABLES -A INPUT -d 10.0.0.0/8 -j DROP

## Clase B
  $IPTABLES -A INPUT -d 172.26.0.0/16 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "B reserved DROP:"
  $IPTABLES -A INPUT -d 172.26.0.0/16 -j DROP

## Clase D 
  $IPTABLES -A INPUT -d 224.0.0.0/4 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "D reserved DROP:"
  $IPTABLES -A INPUT -d 224.0.0.0/4 -j DROP

## Clase E 
  $IPTABLES -A INPUT -d 240.0.0.0/5 -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "E reserved DROP:"
  $IPTABLES -A INPUT -d 240.0.0.0/5 -j DROP

# Denegacion de paquetes no destinados
# a la red interna
  $IPTABLES -A OUTPUT -o $LOCALIFACE -d ! $LOCALMASK -m limit --limit 5/minute -j LOG --log-level $LOG_LEVEL --log-prefix "NOT-INTERNAL:"
$IPTABLES -A OUTPUT -o $LOCALIFACE -d ! $LOCALMASK -j DROP

# cierre de ident query
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 113 -j LOG -m limit --limit 5/m --log-prefix "Ident Query REJECT:" --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 113 -j REJECT

# Lineas de cerrado de puertos privilegiados
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport :1023 -j LOG -m limit --limit 5/m --log-prefix "TCP privileged ports DROP:" --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport :1023 -j DROP
  $IPTABLES -A INPUT -p UDP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport :1023 -j LOG -m limit --limit 5/m --log-prefix "UDP privileged ports DROP:" --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p UDP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport :1023 -j DROP

# Cierre del puerto de MySQL
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 3306 -j LOG -m limit --limit 5/m --log-prefix "MySQL query DROP: " --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p TCP -i $EXTIFACE -s $OUTADDR -d $EXTIP --dport 3306 -j DROP

# Denegacion de entrada de ICMP 
# de tipo 8 y 13, y salida de 
# ICMP de tipo 0 y 14 (echo request, 
# timestamp request, echo reply 
# y timestamp reply)
  $IPTABLES -A INPUT -p ICMP --icmp-type echo-request -i $EXTIFACE -j LOG -m limit --limit 5/m --log-prefix "Echo-Request DROP: " --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p ICMP --icmp-type timestamp-request -i $EXTIFACE -j LOG -m limit --limit 5/m --log-prefix "Timestamp-Request DROP: " --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p ICMP --icmp-type echo-request -i $EXTIFACE -j DROP
  $IPTABLES -A INPUT -p ICMP --icmp-type timestamp-request -i $EXTIFACE -j DROP
  $IPTABLES -A INPUT -p ICMP --icmp-type 30 -i $EXTIFACE -j LOG -m limit --limit 5/m --log-prefix "Traceroute DROP: " --log-level $LOG_LEVEL
  $IPTABLES -A INPUT -p ICMP --icmp-type 30 -i $EXTIFACE -j DROP

  $IPTABLES -A OUTPUT -p ICMP --icmp-type echo-reply -o $EXTIFACE -j DROP
  $IPTABLES -A OUTPUT -p ICMP --icmp-type timestamp-reply -o $EXTIFACE -j DROP

# Denegacion de entrada de paquetes fragmentados
  $IPTABLES -A INPUT -i $EXTIFACE -f -j DROP
return;
}
#####################
# Funcion SHOW HELP #
# Muestra la ayuda  #
#####################

show_help(){
echo " "
  echo "Usage:"
  echo "rc.firewall start nat    - enable port forwarding mode"
  echo "rc.firewall start masq   - enable ip-masq mode"
  echo "rc.firewall start filter - enable packet filtering mode"
  echo "rc.firewall start all    - enable all modes"
  echo "rc.firewall stop         - disable all firewall modes"
  echo " "
  echo "*** ERROR: Firewall didn't start successfully!"
  echo " "

return;
}

######################################
######################################
### Ejecucion principal del firewall #
######################################
######################################
echo " "
echo "Firewall script by ttyp0 <ttyp0@inet2u.com> - http://assl.ath.cx"
echo " "

case $1 in
    start)
       if `test -z $2`; then
        show_help
       else

         case $2 in
          nat)
            set_variable_definitions
            rule_flush
            set_default_policy
            load_nat_modules
            load_nat_rules
            unset_variable_definitions
            echo " "
            echo "Firewall started successfully on NAT ONLY mode"
            echo " "
            ;;

          masq)
            set_variable_definitions
            rule_flush
            set_default_policy
            load_masq_rules
            unset_variable_definitions
            echo " "
            echo "Firewall started successfully on MASQ ONLY mode"
            echo " "
            ;;

          filter)
            set_variable_definitions
            rule_flush
            set_default_policy
            load_filter_rules
            unset_variable_definitions
            echo " "
            echo "Firewall started successfully on FILTER ONLY mode"
            echo " "
            ;;

          all)
            set_variable_definitions
            rule_flush
            set_default_policy
            load_masq_rules
            load_nat_modules
            load_nat_rules
            load_filter_rules
            unset_variable_definitions
            echo " "
            echo "Firewall started successfully on ALL functions"
            echo " "
            ;;

          *)
           show_help
           ;;
      esac
     fi
   ;;

   stop)
    if `! test -z $2`; then
     show_help
    else
      set_variable_definitions
      rule_flush
      set_default_policy
      unset_variable_definitions
      echo " "
      echo "Firewall stopped all functions!"
      echo " "
    fi
   ;;

   *) show_help
   ;;
esac
Herramientas personales