Archivo de la categoría: Cuadernillo Técnco

¿De qué hablamos cuando hablamos de contraseñas seguras? Un enfoque estadístico

En teoría de la información, un mensaje es equivalente a un texto codificado como una ordenación de símbolos (letras, espacios, signos de puntuación), lo que comúnmente llamamos una cadena de caracteres. Si deseáramos calcular qué tan segura es una contraseña, esto es, qué tan capaces somos de predecir el contenido del mensaje que la conforma, buscaríamos conocer qué tan aleatoria es la cadena de caracteres que la componen. Esta medida del desorden o incertidumbre es lo que conocemos como Entropía de la información (H).

Si consideramos una contraseña como un texto codificado y quisiéramos que la entropía de esta clave sea la máxima (tan aleatoria como sea posible) deberíamos asegurarnos que la entrada de caracteres sea poco probable de pronosticar, que cada caracter se repita o esté ordenado de una manera impredecible. Ahora bien, ¿cómo calculamos la Entropía de una contraseña? Habrá que entrar en el terreno duro de las matemáticas y la estadística.

Las matemáticas detrás de una contraseña

En estadística, llamamos Espacio Muestral (Ω) a todos los estados posibles de un experimento. Por ejemplo, al lanzar un dado, nuestro espacio muestral son los seis números correspondientes a cada una de las caras del dado, Ω={1,2,3,4,5,6}. En el caso de una contraseña, nuestro espacio muestral estará conformado por todas las permutaciones posibles en el universo de caracteres para cada combinación de los mismos. Esto es:

Ω (N,K) = {k1,k2,…,ki}

Dónde ki es cada uno de los estados (subconjunto de caracteres) posibles de los N caracteres del conjunto y K es la cantidad de caracteres del subconjunto o longitud de la contraseña.

Ahora bien, las claves las construimos a partir de un subconjunto de letras mínusculas y mayúsculas, números y símbolos escogidos de manera aleatoria. Por lo tanto, inicialmente el grado de indeterminación de un mensaje equivale a ki: existen ki estados posibles, cada uno de logitud K. Entonces, la probabilidad de aparición de cada una de las combinaciones que formen nuestra contraseña será:

P = 1 / ki

Y por lo tanto, la entropía del mensaje (H(x)) alcanzará el valor medio ponderado de la suma de probabilidades de los diversos estados del mismo expresado en binario (queremos medir “bits”). Es decir:

H(x) = — P(xi) log2[P(xi)]

; para todo i desde 1 hasta ki

Como habíamos mencionado, cada caracter de la cadena es escogido de manera aleatoria y por lo tanto, todos los estados (permutaciones) son equiprobables. Sintetizando: entre un total de N caracteres aleatorios formando una contraseña de longitud K, podemos expresar que:

H(x) = K log2[N]

Algunos ejemplos:

Supongamos que nuestra contraseña tiene 4 caracteres y es una combinación de números del 0-9. Entonces:

K = 4; N = 10

H(x1) = 4 log2[10] = 4 x 3,32192809489

H(x1) = 13,2877123796

Supongamos ahora que a la contraseña anterior le añadimos letras minúsculas y mayúsculas sin modificar su longitud. Ahora:

K = 4; N = 62 (26 min + 26 may + 10 núm)

H(x2) = 4 log2[62] = 4 x 5,95419631039

H(x2) = 23,8167852415

Para un último ejemplo, esta vez nuestra contraseña tendrá 8 caracteres:

K = 8; N = 62

H(x3) = 8 log2[62] = 8 x 5,95419631039

H(x3) = 47,6335704831

¿Qué representan estos resultados?

Hemos visto cómo aumentando tanto el tamaño de nuestro universo de caracteres como la longitud del subconjunto, la entropía aumenta. Pero, ¿qué representa este resultado en términos de seguridad de la información? Pues bien, como mencionaba, el valor está expresado en binario (bits) y por lo tanto 2^H(x) equivale a calcular el tamaño de nuestro espacio muestral, es decir: ¿de cuántas maneras se pueden permutar y combinar los caracteres para obtener una contraseña de una determinada longitud?

Entonces, para cada uno de los ejemplos anteriores:

2^H(x1) = 2^13,2877123796 = 10.000

2^H(x2) = 2^23,8167852415 = 14.776.335,9995

2^H(x3) = 2^47,6335704831 = 2,18340105586e+14

Es decir, para una contraseña de ±47 bits contamos con ±2e+14 (un 2 seguido de 14 ceros) permutaciones posibles. Esto significa que si tuviésemos un programa automatizado capaz de calcular 1.000.000 de permutaciones por segundo, para dar con nuestra clave (desde el punto de vista probabilístico), necesitaría aproximadamente 7 años de continuo procesamiento.

Finalmente, es fácil demostrar que 2^H(x) = N^K y por lo tanto:

2^H(x1) = 10^4 = 10.000

2^H(x2) = 62^4 = 14.776.335,9995

2^H(x3) = 62^8 = 2,18340105586e+14

Sintetizando, esta fórmula se puede expresar como:

complejidad^longitud

ó en bits:

H(x) = log2[complejidad^longitud]

Consideraciones finales

Para terminar, quisiera añadir tres puntos de chequeo que considero importantes al momento de construir una contraseña segura.

La aletoriedad es imporante

Como vimos, la entropía se maximiza en base a la probabilidad de un evento. Si los diversos estados de un mensaje no son equiprobables, la entropía disminuye. Por ejemplo, si en lugar de usar combinaciones aleatorias usamos palabras comunes (casa, cerveza, operando) la probabilidad de que los caracteres más usados del alfabeto (a, e, c, m) caigan en la contraseña es mayor que la de los menos usados (k, w, x) y por lo tanto este cambio en el valor de la suma ponderada de las probabilidades hará que nuestra clave sea menos segura, independientemente de la complejidad y longitud.

Usar contraseñas distintas para cada cuenta

Esto puede ser agotador y hasta aburrido. Además, requiere que llevemos algún tipo de sistema de administración de claves, pues todos tenemos nuestras limitaciones al momento de memorizar cadenas de caracteres aleatorios. Esto, puede jugar en contra si no somos cuidadosos con nuestro sistema (por ejemplo, tener todas las claves en un cuaderno que llevamos con nosotros a todas partes).

Sin embargo, es altamente aconsejable que cada cuenta tenga su contraseña y que cada contraseña tenga una complejidad y longitud diferentes. Por ejemplo, si usamos una clave para todo y un atacante da con esa clave, tendrá acceso a todas nuestras cuentas. Por otro lado, si las claves son distintas, pero todas tienen la misma longitud, cuando un atacante sepa una de las claves, tendrá información suficiente para buscar las demás.

Cambiar las contraseñas cuando sospechamos que pudo ser vulnerada

Muchos consideran innecesario estar cambiando una clave cada cierto tiempo: si la contraseña es lo suficientemente segura, no es necesario modificarla; si la entropía de la vieja clave es igual a la de la nueva, cambiarla no modificará la probabilidad de que un atacante la descifre. Entonces, ¿por qué tantos recomiendan cambiar las contraseñas periódicamente?

Desde mi punto de vista, debemos estar atentos a las operaciones que realizamos en nuestra informática diaria. Si por algún despiste (que ocurren seguido) hemos dejado vulnerable nuestra clave, lo natural sería cambiarla. Lo mismo si nuestros equipos se traspasan a otros usuarios: regalamos nuestro teléfono móvil, vendemos una laptop para comprar una nueva, etcétera.


Fuentes:
Entropía (información) – Wikipedia, la enciclopedia libre


Conectarse a un servidor ssh inaccesible atravesando otro servidor ssh intermedio

Estoy en casa cuando repentinamente recuerdo que dejé una tarea pendiente en la oficina para la cuál necesito acceder a mi equipo. Es viernes por la tarde y la inminente llegada del fin de semana representa un problema: en la oficina ya todos se fueron y nadie en su sano juicio regresaría para terminar el trabajo. Por suerte, estoy consciente de que la computadora está encendida y el servidor ssh está corriendo. Pero claro, cómo acceder remotamente cuando la máquina no es accesible desde Internet. La buena noticia es que hay un servidor en la red al que sí puedo conectarme por ssh desde casa y desde allí ingresar al equipo.

Este tipo de escenarios, que a mi me gusta llamar SSH Multi-Huésped, es algo común entre los administradores de sistemas y existen muchos métodos para resolver la conexión: desde un rudimentario, inseguro e ineficiente direccionamiento de puertos hasta una conexión ssh en escalas, algo así:

usuario@casa$ ssh usuarioservidor@servidor
Password for usuarioservidor@servidor:
Last login: Fri Dec  2 17:01:43 2016 from 'ip_casa'

usuarioservidor@servidor$ ssh usuariooficina@oficina
Password for usuariooficina@oficina:
Last login: Fri Dec  2 17:02:15 2016 from 'ip_servidor'

usuariooficina@oficina $

Está claro que no es la manera que una administrador de sistemas usaría. La alternativa es habilitar el direccionamiento del agente a través de los equipos y pasarle la opción -t para forzar la asignación de una pseudo-tty para contar con una shell interactiva.
 

usuario@casa $ ssh -A -t usuarioservidor@servidor ssh -A usuariooficina@oficina
Password for usuarioservidor@servidor:
Password for usuariooficina@oficina:
Last login: Fri Dec  2 17:05:39 2016 from 'ip_casa'

usuariooficina@oficina $

Bonito ¿no? No, es horrible. Basta imaginar que el camino entre el equipo de mi casa y el de la oficina tuviera tres o cuatro máquinas intermedias. Ni hablar si lo que buscamos es copiar un archivo desde un extremo al otro con scp. Sin duda, estos métodos carecen de toda elegancia. Lo que yo necesito es realizar esta operación de una manera simple, transparente y eficiente.

Para esto contamos con dos herramientas: por una lado, tenemos netcat (Netcat – Wikipedia, la enciclopedia libre), que debe estar instalado en las máquinas intermedias; por otro, la opción ProxyCommand habilitada en nuestro cliente ssh. Para configuralo, hay que añadir algunas líneas al final del archivo de configuración /etc/ssh/ssh_config en el equipo desde el cual iniciamos la conexión.
 

usuario@casa $ sudo nano /etc/ssh/ssh_config

/etc/ssh/ssh_config

[…]
Host oficina
User usuariooficina
HostName oficina
Port 22
ProxyCommand ssh -q usuarioservidor@servidor nc %h %p

Para explicar un poco el contenido agregado al archivo:
Host es un nombre arbitrario que nos servirá para identificar fácilmente el huésped al que buscamos conectarnos
User, Hostname y Port representan las variables que netcat usará para conectar los húespedes
ProxyCommand: aquí se ejecuta el comando requerido para iniciar la conexión. La opción -q (quiet mode) suprime los mensajes de advertencia y diagnóstico; nc ejecuta netcat propiamente dicho y los valores %h y %p se obtienen de User-HostName y Port respectivamente

 

usuario@casa $ ssh oficina
Password for usuarioservidor@servidor:
Password for usuariooficina@oficina:
Last login: Fri Dec  2 17:10:05 2016 from 'ip_casa'

usuariooficina@oficina $

El procedimiento es simple y transparente. Como es natural, la cadena de equipos intermedios puede poseer más de un huésped y por supuesto, es posible configurar un sin número de conexiones diferentes. Además, con este método es posible la copia de manera sencilla de archivos desde y hacia el equipo remoto con scp, el uso del protocolo sftp, la conexión a través del gestor de archivos y como si esto fuera poco, podemos dirigir aplicaciones gráficas a través de X-forwarding. Aquí algunos ejemplos:

usuario@casa $ scp oficina:/ruta/archivo_remoto /ruta/archivo_local
Copia del archivo_remoto desde el equipo en la oficina hacia la máquina en casa.

 

usuario@casa $ ssh -X oficina pcmanfm
Ejecutando el gestor de archivos pcmanfm del equipo en la oficina en la máquina en casa a través de X-forwarding.

 

De esta manera me ocupo de terminar el trabajo pendiente y me dispongo a disfrutar de una tarde de viernes como es debido.
 

Tor+Privoxy en GNU/Linux con OpenRC

Quienes usamos OpenRC sabemos que al momento de instalar un paquete debemos tener en cuenta que por lo general existe una versión específica para este init. Además, en muchos casos no alcanza simplemente con instalar el paquete correspondiente, sino que también los archivos de configuración suelen requerir diferentes parámetros.

Este es el caso del sistema de enrutamiento por capas TOR, el que habitualmente instalo junto a Privoxy para integrarlo como una cadena de proxys.

Dado que actualmente uso Manjaro OpenRC, los comandos están enfocados en esta distribución.
$ sudo pacman -S tor-openrc privoxy-openrc proxychains torsocks lynx
Instalo los paquetes necesarios en su versión para OpenRC y además añado proxychains y torsocks para integrar los proxys al uso en consola de comandos.

Posteriormente, se edita el archivo de configuración de Privoxy, indicándole la dirección ip de escucha y añadiendo al final del archivo la línea de encadenamiento al proxy socks.

$ sudo nano /etc/privoxy/conf

/etc/privoxy/conf

[…]
listen-address 127.0.0.1:8118
[…]
forward-socks5 / 127.0.0.1:9050 .

Luego, hay que trabajar sobre la configuración de TOR. Para esto, se hace una copia de seguridad del archivo original y se crea un nuevo archivo que contenga las líneas requeridas para que OpenRC gestione el daemon.

$ sudo mv /etc/tor/torrc.bck

$ sudo nano /etc/tor/torrc

/etc/tor/torrc

User tor
PIDFile /var/run/tor/tor.pid
Log notice syslog
DataDirectory /var/lib/tor/data

Sólo resta añadir los servicios al inicio y arrancarlos.

$ sudo rc-update add tor default

$ sudo rc-update add privoxy default

$ sudo sudo service tor start

$ sudo service privoxy start

Por último, comprobamos que todo funciona correctamente.

$ proxychains lynx check.torproject.org 
Congratulations. This browser is configured to use Tor.
This page is also available in the following languages: [English____________________] Go

Congratulations. This browser is configured to use Tor.

Your IP address appears to be: xxx.xxx.xxx.xxx

Instalando i3wm en FreeBSD

Para muchos el entorno de escritorio es una pieza fundamental y quizá imprescindible en su maquinaria. Para otros, todo lo contrario, amantes del minimalismo, buscan vivir lo más posible dentro de la consola. En la amplia gama intermedia de estos dos extremos estamos quienes al mismo tiempo que nos sentimos plenamente cómodos trabajando en la consola, no sólo para tareas administrativas, sino que también acostumbramos tener algún reproductor de música, gestor de archivos, lector de correo y hasta navegadores web en una interfaz de línea de comandos (CLI), también tenemos una amplísima batería de aplicaciones gráficas (GUI), ya sea por gusto, comodidad, facilidad de interacción, versatilidad.

Habiendo terminado la instalación de FreeBSD en mi equipo, empecé a preguntarme qué entorno le daría vida en formas y colores a mi reciente sistema aún en temprana fase TTY. Y así me voy dando cuenta de que puedo andar sin un entorno de escritorio del tipo “robusto y completo”. Un entorno gráfico minimalista parece ser la mejor opción esta vez.

Para disfrutar de una interfaz gráfica en FreeBSD es necesario instalar el servidor Xorg y decirle al sistema, mediante el archivo /etc/rc.conf que inicie los servicios dbus y hal al arranque.

$ pkg install xorg hal dbus

$ Xorg -configure

$ echo "hald_enable="YES"" >> /etc/rc.conf

$ echo "dbus_enable="YES"" >> /etc/rc.conf

$ reboot

Al iniciar nuevamente, podré arrancar las Xs simplemente con:

$ startx

Todo funciona a la perfección. Pero las Xs así de fábrica son feas, poco intuitivas y con una practicidad casi nula. Insatisfecho pues con esto, me viene a la mente aquel gestor de ventanas en mosaico, ligero, ampliamente configurable y tan amado por los usuarios con corazón de hacker y entrañas de geek. Por si fuera poco, funciona de manera autónoma, lo que me resulta muy conveniente. Hablo ni más ni menos que de i3wm.

$ pkg install i3 i3lock i3status dmenu

$ echo "/usr/local/bin/i3" >> /usr/home/usuario/.xinitrc

$ chown usuario /usr/home/usuario/.xinitrc

$ reboot

Una última cuestión a considerar es que parece haber un problema al momento de crear el archivo de configuración. Por esto, lo recomendable es copiar el archivo que viene por defecto (/usr/local/etc/i3/config) y luego editarlo a nuestro gusto.

$ cp /usr/local/etc/i3/config ~/.i3/

Ahora, al iniciar sesión en modo TTY, sólo debo escribir startx para iniciar una sesión gráfica con i3wm.

Activar el repositorio kde-unstable y tener lo último de KDE en Archlinux

Como usuario de Archlinux estoy acostumbrado a estar siempre a la última en cuanto a actualizaciones, especialmente porque soy de los que habilitan los repositorios inestables en la configuración de pacman. Sin embargo, en muchas ocasiones los diferentes proyectos que proveen aplicaciones, programas, entornos de escritorio, espacios de trabajo, van un tanto más adelante que los mantenedores de los repositorios oficiales de las distribuciones GNU/Linux que usamos a diario (incluso con los repositorios inestables) y mientras el proyecto está en fase más avanzada, notamos que no estamos tan a la última como deseamos.

Uno de los casos es el del proyecto KDE. Mientras la gente de KDE trabajaba en el lanzamiento de la versión 5.6.95 de su entorno de escritorio Plasma y al mismo tiempo la versión 5.7 de este proyecto entraba en fase Beta, yo me encontraba con la versión 5.6.5 en mi instalación de Archlinux.

$ plasmashell --version
plasmashell 5.6.5

Aquí comencé a preguntarme cómo podría disponer de las últimas actualizaciones, es decir, de la versión 5.6.95 próxima a publicarse, la cual incluye muchas de las novedades que vienen con la siguiente (Plasma 5.7). Pues bien, en Archlinux disponemos del repositorio kde-unstable y para habilitarlo debemos editar el archivo /etc/pacman.conf.

$ sudo nano /etc/pacman.conf

/etc/pacman.conf


REPOSITORIES

[kde-unstable]
Include = /etc/pacman.d/mirrorlist
 
[testing]

Básicamente hemos agregado [kde-unstable] a nuestro listado de repositorios personalizados. Es importante colocarlo encima de los demás para que tenga prioridad sobre estos.

Ahora bastará con actualizar el sistema y volver a ejecutar el comando plasmashell --version.

$ sudo pacman -Syyu
...

$ plasmashell --version
plasmashell 5.6.95

 

Bien, hasta acá este pequeño artículo. Debo aclarar que al momento de preparar la entrada, la versión 5.6.95 aún no se lanzaba oficialmente. Hoy ya está disponible en repositorios oficiales de Archlinux. Sin embargo, igual sirve para futuras actualizaciones en fase previa a su lanzamiento.

Implementar nuestra propia VPN con OpenVPN en Debian

Razones para montar un servidor VPN hay muchas. En mi caso es simple: por mi trabajo me toca viajar y estar lejos de casa muy seguido por lo que necesito acceder a mi red para realizar distintas tareas que requieren que mis equipos se vean unos a otros como si estuvieran conectados a la misma LAN, todo siempre de la manera más segura posible. Si bien es cierto que muchas de esas tareas las realizo sobre SSH, hay otras que prefiero hacerlas a través de un servicio VPN.

Esta entrada está enfocada en cómo implementar este tipo de servidores usando OpenVPN en una distribución Debian. Para tales fines, se puede montar un servidor utilizando un equipo antiguo que ya no utilices, o bien, disponer de algún dispositivo tipo RaspberryPI.

No hace falta aclarar que necesitamos una ip pública fija o en caso contrario, usar un servicio tipo NoIP para acceder al servidor desde fuera de la LAN. Para no extenderme demasiado, voy a pasar por alto los detalles sobre esto y voy a ir directamente al grano.

Instalación y configuraciones iniciales

Instalamos el servidor, las herramientas de administración de certificados y ufw para simplificar las configuraciones del firewall.

$ sudo apt update && apt install openvpn easy-rsa ufw

Posteriormente, vamos a descomprimir y copiar el archivo de configuración de ejemplo que viene con la documentación de openvpn al directorio correspondiente para luego editarlo.

$ sudo gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

$ sudo nano /etc/openvpn/server.conf

/etc/openvpn/server.conf

[…]
# Puerto para las conexiones VPN. Por defecto 1194
port 1194
[…]
# Protocolo a utilizar
;proto udp
proto tcp
[…]
# Tipo de túnel
# TUN emula un dispositivo punto a punto
# TAP simula una interfaz ethernet (bridge o puente)

;dev tun
dev tap
[…]
# Bits de las claves RSA
dh dh2048.pem
[…]
# Redirigir el tráfico web hacia el destino que corresponda
push “redirect-gateway local def1 bypass-dhcp”
[…]
# Configuración de los DNS
push “dhcp-option DNS 208.67.222.222”
push “dhcp-option DNS 208.67.220.220”
[…]
# Permisos de usuarios y grupos
user nobody
group nogroup
[…]

Ahora bien, debemos avisarle al sistema que todo el trafico proveniente desde los clientes tiene que continuar su camino hacia la Internet, de lo contrario, el tráfico se detendría en el servidor. Para esto, ejecutamos:

$ sudo echo 1 > /proc/sys/net/ipv4/ip_forward

$ sudo nano /etc/sysctl.conf

/etc/sysctl.conf

[…]
net.ipv4.ip_forward=1
[…]

Además de ejecutar el comando, editamos el archivo /etc/sysctl.conf para que esta configuración sea persistente, es decir, resistente a reinicios.

 

Configurar el firewall

Como ya mencioné, usaremos ufw para simplificar la administración del firewall para nuestra VPN. Lo primero será abrir el puerto y protocolos respectivos por dónde transitarán los paquetes y luego vamos a permitir el tráfico SSH, básicamente para poder acceder al servidor cuando lo necesitemos (recordemos que el servidor está en un equipo que no necesariamente tiene un monitor conectado).

$ sudo ufw allow ssh

$ sudo ufw allow 1194/udp

Establecemos las políticas y reglas en el firewall.

$ sudo nano /etc/default/ufw

/etc/default/ufw

[…]
DEFAULT_FORWARD_POLICY=”ACCEPT”
[…]

$ sudo nano /etc/ufw/before.rules

/etc/ufw/before.rules

[…]
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
# ufw-before-input
# ufw-before-output
# ufw-before-forward
#
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
#
# Don’t delete these required lines, otherwise there will be errors
*filter
[…]

Finalmente, activamos el firewall

$ sudo ufw enable

 

Crear y configurar la autoridad certificadora (CA), los certificados (crt) y las claves (rsa-keys)

El paquete easy-rsa provee varios scripts que facilitan la tarea de crear y configurar los certificados y claves de identificación cliente-servidor

Copiamos los scripts predefinidos del paquete easy-rsa al directorio /etc/openvpn. Luego creamos el directorio /etc/openvpn/easy-rsa/keys donde se almacenarán los certificados y claves.

$ sudo cp -r /usr/share/easy-rsa/ /etc/openvpn

$ sudo mkdir /etc/openvpn/easy-rsa/keys

Editamos el archivo que contiene la información requerida para crear la autoridad certificadora. Los datos de país, ciudad, nombre y correos de la compañía, etcétera podemos completarlos con cualquier valor que deseemos. La clave (KEY_NAME) la llamaremos server para simplificar su uso e identificarla como la clave del servidor fácilmente.

$ sudo nano /etc/openvpn/easy-rsa/vars

/etc/openvpn/easy-rsa/vars

[…]
export KEY_COUNTRY=”US”
export KEY_PROVINCE=”TX”
export KEY_CITY=”Dallas”
export KEY_ORG=”My Company Name”
export KEY_EMAIL=”sammy@example.com”
export KEY_OU=”MYOrganizationalUnit”
[…]
export KEY_NAME=”server”
[…]

Generamos los parámetros Diffie-Hellman con el comando:

$ sudo openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Cambiamos la sesión de la consola para trabajar como root. Nos movemos al directorio donde se encuentran los scripts e iniciamos la infraestructura de claves (PKI).

$ su -
Contraseña:

# cd /etc/openvpn/easy-rsa

# . ./vars

Limpiamos las claves que hayan sido generadas previamente y que ya no se usan, construimos el certificado y la clave del servidor.

# ./clean-all

# ./build-ca

# ./build-key-server server
El último comando descrito creará los archivos ca.crt, server.crt y server.key y los alojará en el directorio /etc/openvpn/easy-rsa/keys.

Ahora, volveremos al archivo de configuración del servidor para configurar la ruta de los archivos generados con easy-rsa.

$ sudo nano /etc/openvpn/server.conf

/etc/openvpn/server.conf

[…]
ca easy-rsa/keys/server.crt
cert easy-rsa/keys/server.crt
key easy-rsa/keys/server.key # Este archivo debería permanecer secreto
[…]

Ya estamos en condiciones de iniciar el servidor.

$ sudo service openvpn start

 

Configuración de los clientes

El primer paso será construir la clave de identificación del cliente

$ su -
Contraseña:

# cd /etc/openvpn/easy-rsa

# ./build-key cliente1
Donde cliente1, cliente2, clienteN serán el nombre que le daremos a cada cliente que deseemos conectar

Ahora trabajaremos en el archivo de configuración. Primero, copiamos el archivo de ejemplo en la documentación de openvpn y lo abrimos para su edición:

$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/cliente1.ovpn

$ sudo nano /etc/openvpn/easy-rsa/keys/cliente1.ovpn

/etc/openvpn/easy-rsa/keys/cliente1.ovpn

[…]
# Tipo de túnel
;dev tun
dev tap
[…]
# Protocolo
;proto udp
proto tcp
[…]
# Dirección y puerto del servidor
remote ip_del_servidor 1194
remote miservidor.com 1194
remote miservidor2.org 1194
[…]
# Parámetros SSL/TLS
ca .vpn/ca.crt
cert .vpn/cliente1.crt
key .vpn/cliente1.key
[…]
# Privilegios de usuario
user nobody
group nobody
[…]

A partir de este momento dejamos el servidor y comenzamos a trabajar en el equipo cliente.

Creamos un directorio oculto en /home y mediante el uso de alguna herramienta de transferencia de archivos debemos copiar los archivos necesarios desde el servidor al cliente.

$ mkdir .vpn

$ scp usuario@ip_del_servidor:/etc/openvpn/easy-rsa/keys/{ca.crt,cliente1.crt,cliente1.key,cliente1.ovpn} .vpn/
Aquí utilizo scp (SSH) para transferir los archivos desde el servidor hacia el directorio oculto /home/.vpn en el cliente.

El último paso será iniciar el cliente. Si este cliente corre un sistema GNU/Linux, ejecutaremos en la consola:

$ sudo openvpn --config .vpn/cliente1.ovpn
Nota: en algunos sistemas es necesario ejecutar como superusuario

Seguridad adicional con TLS-AUTH

OpenVPN nos ofrece la posibilidad de mejorar la seguridad en la identificación a través de la verificación de las negociaciones mediante el uso de una firma de tipo HMAC. Para habilitar esta función, trabajaremos en la configuración tanto del servidor como del cliente.

En el servidor generamos la clave secreta y luego editamos el archivo de configuración:

$ sudo openvpn -genkey -secret ta-key

$ sudo nano /etc/openvpn/server.conf

/etc/openvpn/server.conf

[…]
tls-auth ta.key 0
[…]

Nota: en el servidor el valor es 0 (tráfico entrante)

En el cliente, copiamos la clave ta.key en el directorio de configuración de openvpn y editamos el archivo de configuración del cliente

$ sudo nano /etc/openvpn/cliente1.ovpn

/etc/openvpn/server.conf

[…]
tls-auth ta.key 1
[…]

Nota: en el servidor el valor es 1 (tráfico saliente)

OpenVPN en dispositivos móviles

Si sos de los que usan su teléfono para todo, inclusive trabajar, podrás utilizar el servicio VPN que acabamos de implementar para conectarte a tu red de área local. Para esto, instalaremos una aplicación que podemos encontrar en los repositorios de F-Droid: “OpenVPN for Android”.

Una vez instalada, copiamos al dispositivo los archivos necesarios (digamos: ca.crt, cliente_cyanogenmod.crt, cliente_cyanogenmod.key, cliente_cyanogenmod.ovpn), iniciamos la aplicación, seleccionamos los archivos y configuramos según los datos que correspondan a la conexión.

Palabras finales

Para finalizar el artículo es mi deber aclararles que para no extenderme demasiado decidí no entrar en detalle respecto de cómo asegurar el servidor contra los distintos ataques que pueda recibir, por lo que será tarea para ustedes ponerse a investigar y a trabajar en la seguridad de su servidor VPN.

Limitar la cuota de disco de los usuarios del sistema [Cuadernillo Técnico]

Establecer un límite o cuota de espacio disponible para almacenamiento en una partición determinada para los distintos usuarios de un sistema GNU/Linux puede ser de gran utilidad en muchos escenarios. En esta entrada voy a enfocarme especialmente en cómo implementar esta característica en una distribución de tipo Archlinux.

Instalar y habilitar

En primer lugar, instalamos los paquetes necesarios y editamos el archivo /etc/fstab

$ sudo pacman -S quota-tools

$ sudo nano /etc/fstab

/etc/fstab

/dev/sdaX /home ext4 defaults,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv2 1 1

Como se ve, hemos añadido las opciones para establecer el uso de cuotas para usuarios (usrjquota), grupos (grpjquota)y el formato (jqfmt) en la partición /dev/sdaX que el sistema monta en el punto /home.
Personalmente tengo preferencia por habilitar “Journaling” para las cuotas de disco y utilizo el formato vfsv2. Encontrarás más información sobre esto en https://wiki.archlinux.org/index.php/Disk_quota.

Lo siguiente será remontar la partición /home y crear el índice

$ su -
Contraseña:************

# mount -vo remount /home

# quotacheck -vgum /home
Verás que he tenido que cambiar la sesión en la consola e iniciar como root. Esto es necesario para poder remontar la partición /home. El comando quotacheck creará los archivos de índice aquota*. En caso que hayas habilitado cuotas para más de una partición, el comando correspondiente es quotacheck -vguma.

Finalmente, habilitamos el servicio:

# quotaon -av

 

Configurar

Para configurar las cutoas que deseamos establecer para cada usuario debemos ejecutar como root:

# edquota usuario
Reemplazando el usuario por el correspondiente a quien editaremos sus cuotas.
Disk quotas for user usuario (uid xxxx):
Filesystem   blocks     soft        hard        inodes    soft     hard
/dev/sda1    657313     10000000    15000000    100       0        0

Por último, establecemos el período de gracia para superar el valor soft de la cuota:

# edquota -t

 

¿Qué representan los valores en cada columna? Pues bien:

blocks/inodes: es la cantidad de datos en bloques/inodes que tiene escritos el usuario actualmente.

soft: es el límite de datos en Kilobytes (1GB=1.000.000KB) que el usuario puede escribir antes de ser advertido sobre el uso de su cuota. A partir de que el usuario alcance este valor, podrá continuar almacenando datos por encima del mismo durante el período de gracia establecido con edquota -t. El valor 0 implica “sin límite”.

hard: es el valor límite máximo que el usuario puede escribir en el disco, es decir, nunca podrá superar este valor. El valor 0 implica “sin límite”.

Las modificaciones en la configuración de las cuotas es un aspecto que requiere especial atención. Esto se debe a que si aumentamos el valor de las cuotas para un usuario, éste podrá aumentar su nivel de datos almacenados de manera inmediata y sin problema. Sin embargo, al reducir el valor de una cuota, si el usuario tiene actualmente una cantidad de datos escritos mayor al nuevo límite permitido, no podrá iniciar sesión en el sistema.

Por último les dejo una lista de comandos útiles:

$ repquota /particion
Indica las cuotas aplicadas a una determinada particion.
$ quota -u usuario

$ quota -g grupo
Indica la cuota que aplican a un usuario/grupo.
$ edquota -p usuario1 usuario2 usuarion

$ edqouta -g -p grupo1 grupo2 grupon
Copia la configuración de cuotas del usuario1 a los otros usuarios/grupos descritos.
$ quotastats
Muestra las estadísticas asociadas al uso de las cuotas.

 

Bueno, hasta acá esta entrega de mi Cuadernillo Técnico: anotaciones que he llevado a lo largo de varios años como ayuda memoria para configurar e implementar herramientas en mis sistemas GNU/Linux. Espero les sea de utilidad.