Tag: security

Gestión de certificados (PKI) – easy-rsa

Reading time: 51 – 85 minutes

Serie

  1. Gestión de certificados (PKI) – easy-rsa
  2. MQTT Broker (Mosquitto) con certificado servidor (self-signed)
  3. MQTT Broker (Mosquitto) con certificado servidor (self-signed) y certificado en los clientes
  4. MQTT Broker (Mosquitto) con certificado servidor (Let’s Encrypt)
  5. Formatos de Certificados: PEM, DER y PKCS#12 y Manipulación de Claves Privadas

Introducción a la Infraestructura de Clave Pública (PKI)

Una PKI, o Infraestructura de Clave Pública, es un sistema que gestiona certificados digitales y claves para garantizar comunicaciones seguras. Vamos a desglosar los conceptos básicos.

Conceptos Clave

  • PKI: Es el sistema completo que conecta Certificados de Autoridad (CA), claves y certificados para garantizar la confianza entre entidades.
  • CA (Certificate Authority): Es el “jefe” de la PKI. Firma y valida certificados, garantizando que son de confianza.
  • Certificado: Documento digital que incluye una clave pública, información sobre la entidad, y la firma del CA. Es como un pasaporte digital.
  • Solicitud de Certificado: Es un “borrador” del certificado que una entidad envía al CA para que lo firme.
  • Par de Claves (Keypair): Un conjunto de dos claves: una pública (para compartir) y otra privada (secreta). Por ejemplo, la pública es como tu dirección de correo y la privada como la contraseña.

¿Qué es un CA y por qué es importante?

El CA es el núcleo de una PKI y su clave privada es extremadamente sensible porque firma todos los certificados. Para protegerla, se recomienda mantenerla en un entorno seguro, como un sistema dedicado o incluso desconectado de la red.

¿Cómo funciona todo esto?

  1. Creación del CA: Se genera un par de claves y la estructura necesaria para gestionar certificados.
  2. Solicitud de Certificado: Un cliente (por ejemplo, un servidor VPN) crea un par de claves y envía su solicitud al CA.
  3. Firma y Certificado: El CA verifica la solicitud y utiliza su clave privada para firmar el certificado, que luego devuelve al cliente.

¿Cómo se verifica un certificado? Ejemplos prácticos

La verificación de certificados varía según el contexto, y quiero explicarlo con dos ejemplos claros: una conexión a una VPN, donde yo tengo un par de claves y un certificado, y una conexión a un banco, donde no necesito un par de claves, solo la confianza en la CA.

Ejemplo 1: Conexión VPN (yo tengo mi par de claves y certificado)

Cuando me conecto a una VPN, tanto el cliente como el servidor necesitan un par de claves (pública y privada) y certificados firmados por la misma CA. El proceso es el siguiente:

  1. Yo genero mi par de claves y solicito un certificado al CA, que verifica mi identidad y firma mi certificado.
  2. Cuando intento conectar al servidor VPN, este me presenta su certificado.
  3. Yo verifico que el certificado del servidor fue firmado por el CA en el que confío.
  4. Luego, envío mi propio certificado al servidor, que hace la misma verificación con su copia del CA.
  5. Si todo es válido, ambos usamos nuestras claves privadas para intercambiar información cifrada y establecer una conexión segura.

Por ejemplo, si trabajo remotamente y necesito acceder a la red de mi empresa, configuro un cliente VPN con mi certificado y claves. El servidor verifica que yo soy quien digo ser y me deja entrar solo si la verificación es correcta.

Ejemplo 2: Conexión a un banco (sin par de claves, solo confianza en la CA)

Cuando accedo a la web de mi banco desde mi navegador, no necesito un par de claves personal. Simplemente, confío en los certificados emitidos por las CA incluidas en la lista de confianza de mi navegador. Así funciona:

  1. El servidor del banco me envía su certificado.
  2. Mi navegador verifica que el certificado fue firmado por una CA en su lista de confianza y que este no está caducado ni revocado.
  3. Si la verificación es exitosa, se establece una conexión segura mediante TLS/SSL.
  4. Durante la conexión, el banco usa su clave privada para demostrar que es legítimo, firmando datos que mi navegador valida con la clave pública incluida en el certificado del banco.

Por ejemplo, cuando accedo a https://mi-banco.com, mi navegador me muestra un candado en la barra de direcciones. Esto significa que ha validado el certificado del banco y ahora la conexión es segura. Aunque yo no tengo claves en este caso, confío en la autoridad que firmó el certificado del banco.

Vamos a crear nuestra propia PKI y la gestión de certificados usando easy-rsa

Easy-RSA es una herramienta poderosa y sencilla para gestionar una infraestructura PKI (Infraestructura de Clave Pública). Con ella puedo emitir certificados para servidores VPN, páginas web, y clientes que necesiten conexiones seguras. Aquí explicaré cómo utilizar Easy-RSA para construir esta infraestructura y cómo interpretar sus resultados.

Importante mencionar que easy-rsa no son más que unos scripts que simplifican el uso de OpenSSL que es la verdadera herramienta que hay por detrás gestionando los certificados, claves y demás.

Obtener easy-rsa:

git clone https://github.com/OpenVPN/easy-rsa.git

Configuración del archivo vars en Easy-RSA

El archivo vars permite configurar parámetros básicos y avanzados antes de iniciar el PKI con init-pki, ahorrando tiempo y garantizando consistencia. Para empezar, copio vars.example a vars y relleno las partes que me interesen, como:

  • Datos del certificado: País, ciudad, organización, etc.
  • Claves y algoritmos: Tamaño (2048 bits) y tipo (RSA o EC).
  • Duración: Expiración de la CA y certificados.
set_var EASYRSA_REQ_COUNTRY "ES"
set_var EASYRSA_REQ_ORG "MiEmpresa"
set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_CA_EXPIRE 3650
set_var EASYRSA_CERT_EXPIRE 825

Paso 1: Preparar Easy-RSA

Primero, descargo Easy-RSA desde su repositorio oficial. Como no requiere instalación, simplemente extraigo el archivo comprimido (.tar.gz para Linux/Unix o .zip para Windows) en el directorio que prefiera.

Para comenzar, inicializo el directorio de PKI con:

./easyrsa init-pki

Esto crea una estructura de directorios básica para gestionar los certificados. El directorio pki incluye:

  • private/: Guarda claves privadas (debe mantenerse muy seguro).
  • reqs/: Contiene solicitudes de certificados.
  • issued/: Almacena certificados emitidos.
  • ca.crt: El certificado de la CA (Autoridad Certificadora).
  • private/ca.key: La clave privada de la CA, crítica para la seguridad de toda la infraestructura.

Paso 2: Crear la Autoridad Certificadora (CA)

La CA es el corazón de mi PKI. Es quien firma los certificados y garantiza su validez. Creo la CA con:

./easyrsa build-ca

Durante este proceso, defino un nombre común (Common Name, CN) para identificar mi CA, y se me pedirá configurar una frase de contraseña fuerte para proteger la clave privada (ca.key). Este archivo es extremadamente sensible, y su seguridad es crítica.

El resultado principal de este paso es:

  • ca.crt: El certificado público de la CA, que compartiré con clientes y servidores para verificar certificados.

Paso 3: Generar claves y solicitudes de certificados

Para que un cliente o servidor VPN funcione, primero genero un par de claves (privada y pública) junto con una solicitud de certificado (CSR). Esto se hace con:

./easyrsa gen-req <nombre-del-certificado|FQDN>
# muy importante usar FQDN (Fully Qualified Domain Names) para evitar
# problemas de matching con los hostnames usados en la conexión.

Por ejemplo, para un servidor VPN:

./easyrsa gen-req vpn-server.example.tld

El comando genera dos archivos:

  1. private/<nombre-del-certificado>.key: La clave privada. Este archivo debe permanecer en el servidor o cliente correspondiente y nunca compartirse.
  2. reqs/<nombre-del-certificado>.req: La solicitud de certificado (CSR). Este archivo se envía al CA para ser firmado.

Paso 4: Firmar solicitudes de certificados

Una vez que tengo la solicitud (.req), la importo en el CA y la firmo. Esto se realiza con:

1. Importar la solicitud

# solo hay que hacer este paso si el certificate request 
# lo hemos copiado de otra máquina. Esto lo coloca en path
# para que todo vaya automático, incluidas futuras 
# renovaciones.
./easyrsa import-req /the-path/vpn-server.example.tld.req vpn-server.example.tld

2. Firmar la solicitud

./easyrsa sign-req server vpn-server.example.tld

Easy-RSA generará un certificado firmado en pki/issued/servidor-vpn.crt. Este archivo es lo que el servidor VPN utiliza para identificarse de forma segura ante sus clientes.

Paso 5: Configuración de un servidor y cliente VPN

Servidor VPN

Para configurar un servidor VPN (como OpenVPN), necesitaré los siguientes archivos generados por Easy-RSA:

  1. Clave privada (private/servidor-vpn.key): Usada por el servidor para encriptar las comunicaciones.
  2. Certificado firmado (issued/servidor-vpn.crt): Garantiza que el servidor es confiable.
  3. Certificado de la CA (ca.crt): certificado y clave pública de nuestra PKI.

Estos archivos se colocan en el directorio de configuración del servidor VPN y se referencian en su configuración.

Cliente VPN

Hay que repetir el paso 4, en este caso una buena práctica es poner como “nombre-del-certificado” el nombre del usuario, o el cliente, que pide el certificado de acceso. En algunos casos de uso, eso permite no tener que pasar por un proceso de autenticación.

Después de generar la petición y haberla importado, como indica la primera parte del paso 5. Hay que ir muy en cuidado con el segundo paso. Al firmar el certificate request hay que hacerlo indicando que su uso será de cliente, no de servidor.

# creamos el certificate request
./easyrsa gen-req mi-nombre-de-usuario

# importamos el certificado si es necesario en la PKI
./easyrsa import-req /the-path/mi-nombre-de-usuario.req mi-nombre-de-usuario

# firmamos el certificate request indicando el uso como cliente
./easyrsa sign-req client mi-nombre-de-usuario

Después de firmar el certificate-request ya tenemos los ficheros que deberá usar el cliente para conectarse al servidor:

  1. Clave privada (private/mi-nombre-de-usuario.key): Usado por el cliente para encriptar las comunicaciones.
  2. Certificado firmado (issued/mi-nombre-de-usuario.crt): Garantiza que el servidor es confiable.
  3. Certificado de la CA (ca.crt): certificado y clave pública de nuestra PKI.

NOTA:

Cuando se firma un certificado las posibles opciones a seleccionar son:

  • client – es para TLS client, típicamente usado para usuarios de VPN, o para navegadores Web
  • server – para TLS server, típicamente servidores Web y servidores VPN.
  • ca – cuando queremos crear CA (Certificate Authorities) en cascada, esto emite un certificado intermedio. Técnicamente, lo llaman chaining certificate.
  • serverClient – certificado que serve tanto para cliente como para servidor TLS.

Paso 6: Configuración para servidores web

El proceso es similar para un servidor web (HTTPS). Genero una solicitud de certificado para el dominio del servidor (por ejemplo, mi-servidor.com) y la firmo con la CA. Los archivos necesarios serán:

  1. Clave privada (private/mi-servidor.key): Exclusiva del servidor web.
  2. Certificado firmado (issued/mi-servidor.crt): Identifica al servidor web.
  3. Certificado de la CA (ca.crt): Permite a los navegadores validar la conexión.

Estos archivos se configuran en el servidor web (como Apache o Nginx) para habilitar HTTPs.

Gestión de certificados emitidos, CRL y Validación en Tiempo Real con OCSP

Easy-RSA no solo permite emitir y revocar certificados, sino que también facilita la gestión de la revocación mediante la generación de listas de certificados revocados (CRL) y la implementación de validación en tiempo real a través de OCSP. Cuando se detecta que una clave privada ha sido comprometida o un certificado ya no es necesario, se procede a su revocación:

  1. Revocar un certificado:
    Utiliza el comando: ./easyrsa revoke <nombre-del-certificado> Esto marca el certificado como revocado dentro de la base de datos de la PKI.
  2. Generar la CRL:
    Una vez revocados los certificados, es necesario generar una nueva lista de revocación. Esto se realiza con: ./easyrsa gen-crl Este comando genera dos ficheros:
    • crl.pem: La CRL en formato Base64.
    • crl.der: La CRL en formato binario.
      Estos archivos deben publicarse en un servidor accesible para que los clientes puedan descargarlos y comprobar el estado de los certificados.

Aunque la CRL es la solución tradicional para gestionar certificados revocados, presenta limitaciones como el tamaño de la lista y la necesidad de descargarla por completo en cada comprobación. Para solventar estas deficiencias, se puede implementar OCSP (Online Certificate Status Protocol).

OCSP es un protocolo definido en el RFC 2560 que permite a un cliente consultar el estado de un certificado de forma puntual y en tiempo real, sin tener que procesar toda la CRL. Entre sus ventajas destacan:

  • Información actualizada: Permite obtener el estado de revocación de un certificado al momento de la consulta.
  • Eficiencia: Reduce el tráfico y la carga de procesamiento en el cliente, ya que se consulta solo el certificado específico.
  • Privacidad: Evita la exposición de información potencialmente sensible contenida en la CRL.
  • Escalabilidad: Emplea mecanismos optimizados (a menudo basados en motores de base de datos) para gestionar consultas incluso en entornos con un gran número de certificados.

Implementación de un Servidor OCSP con OpenSSL:

Para poner en marcha un servidor OCSP, utiliza el siguiente comando:

openssl ocsp -index /ruta/a/tu/index.txt -port 2560 -ignore_err -rsigner /ruta/a/tu/ocsp.crt -rkey /ruta/a/tu/ocsp.key -CA /ruta/a/tu/ca.crt -text -out /ruta/a/tu/log_ocsp.txt &

Donde:

  • -index indica el archivo que contiene el índice de certificados emitidos.
  • -port define el puerto en el que el servidor OCSP escuchará (en este ejemplo, 2560).
  • -ignore_err permite que el servidor continúe operando incluso si recibe peticiones malformadas.
  • -rsigner y -rkey especifican el certificado y la clave privada del OCSP responder.
  • -CA señala el certificado de la CA emisora.
  • -text -out guarda un log detallado de las operaciones.

Para consultar el estado de un certificado (por ejemplo, newcert.pem), ejecuta:

openssl ocsp -CAfile /ruta/a/tu/ca.crt -issuer /ruta/a/tu/ca.crt -cert newcert.pem -url http://tu-dominio:2560 -resp_text

Esta consulta permite verificar de forma inmediata si el certificado está revocado o sigue siendo válido.

Integrar la generación y publicación de CRL con un servidor OCSP proporciona un mecanismo completo para la gestión de certificados emitidos. Mientras que la CRL ofrece una solución tradicional basada en la descarga de una lista completa, OCSP permite a los clientes obtener el estado de un certificado de forma ágil y en tiempo real, optimizando el proceso de validación y reduciendo la carga en la red. Este enfoque combinado asegura que, tanto en entornos de pruebas como en producción, se disponga de mecanismos robustos para mantener la integridad y seguridad de la infraestructura PKI.

Renovar un certificado

Normalmente, poco antes de caducar un certificado se pide su renovación. Esto emitirá otro fichoero de certificado firmado por la CA como el que se emetió la primera vez, pero con una nueva fecha de caducidad:

./easyrsa renew <nombre-del-certificado>

una vez generado el nuevo certificado en:

  • issued/mqtt.example.tld.crt – certificado renovado

es buena idea ejecutar el siguiente comando para asegurarse que el viejo certificado queda obsoleto:

./easyrsa revoke-renewed <nombre-del-certificado>

esto nos acaba forzando a generar una nueva lista de certificados revocados. O sea, hay que ejecutar:

./easyrsa gen-crl

y en consecuencia distribuir el nuevo fichero CRL.

Conclusión

Easy-RSA simplifica la creación y gestión de una infraestructura PKI, lo que me permite emitir y administrar certificados para VPNs y servidores web. Sus outputs, como las claves privadas, certificados firmados, y el certificado de la CA, son los componentes esenciales para garantizar conexiones seguras. Con esta herramienta, puedo construir mi propia red confiable para asegurar tanto servidores como clientes en diferentes escenarios.

Referencias

WireGuard Over TCP Using udp2raw: Securing and Expanding Connectivity – Point-to-Multipoint – CookBook

Reading time: 76 – 126 minutes

Scenario Overview

The architecture for this setup is illustrated below:

Install udp2raw, Wireguard and generate keys

cd /tmp
wget https://github.com/wangyu-/udp2raw/releases/download/20230206.0/udp2raw_binaries.tar.gz
tar xvfz udp2raw_binaries.tar.gz
cp udp2raw_amd64 /usr/local/bin/udp2raw
rm udp2raw*
# based on Ubuntu
apt install wireguard
# we'll work on /etc/wireguard
cd /etc/wireguard
# generate privatekey
wg genkey | sudo tee /etc/wireguard/private.key
sudo chmod go= /etc/wireguard/private.key
# obtain public key
sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key

When eveything is installend and configured, just run in all endpoints next commands:

sudo wg-quick up wg0
# for status check:
wg
# udp2raw logs at:
tail -f /var/log/udp2raw.log
# enable automatic wireward service in Ubuntu
sudo systemctl enable wg-quick@wg0.service
# start and stop service like always
sudo systemctl start wg-quick@wg0.service
sudo systemctl stop wg-quick@wg0.service
sudo systemctl status wg-quick@wg0.service

Configuration Files

Endpoint A /etc/wireguard/wg0

# local settings for Endpoint A
[Interface]
PrivateKey = WMUerfcUpSxUlOp1UmaS2uwelnk8AxhAFrlIWpjheWM=
Address = 192.168.111.1/24
ListenPort = 51822

# receive wg through udp2raw
MTU = 1342
PreUp = udp2raw -s -l 167.99.130.97:55055 -r 127.0.0.1:51822 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true

# Enable NAT for traffic forwarding (corporate and fallback internet access)
PreUp = echo 1 > /proc/sys/net/ipv4/ip_forward || true
PreUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE || true
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE || true

# remote settings for Endpoint B
[Peer]
PublicKey = XWl8HeAinHlAZTvaCXDlmO9n/CQLg5qH8jmtROK4jBg=
AllowedIPs = 192.168.111.2/32
PersistentKeepalive = 120

# remote settings for Endpoint C
[Peer]
PublicKey = I+gi8l9QRe00W8pTpp8CSoIabz/RXXQXwquXj7eKNwU=
AllowedIPs = 192.168.111.3/32
PersistentKeepalive = 120

Endpoint B /etc/wireguard/wg0

# Endpoint B
[Interface]
PrivateKey = +BB3NI2SUYeKcRoPrZE2+Ot5KnLZJBycPzJ17kfbn34=
Address = 192.168.111.2/24

# Route configuration for public IP
PreUp = ip route del default || true
PreUp = ip route add 167.99.130.97 via 10.2.0.1 dev eth0 || true
PostDown = ip route del 167.99.130.97 via 10.2.0.1 dev eth0 || true
PostDown = ip route add default via 10.2.0.1 || true

MTU = 1342
PreUp = udp2raw -c -l 127.0.0.1:50001 -r 167.99.130.97:55055 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true

# Endpoint A
[Peer]
PublicKey = z73wM1b7fhMRA8fmeQw4FntRvgJ9JwTdsQHssXHg3DE=
Endpoint = 127.0.0.1:50001
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 120

Endpoint C /etc/wireguard/wg0

# Endpoint C
[Interface]
PrivateKey = YCGzsfeed8QumpfE8bdWRheMzBiUsTB7vXj0YVOQQX0=
Address = 192.168.111.3/24

# Route configuration for public IP
PreUp = ip route del default || true
PreUp = ip route add 167.99.130.97 via 10.2.0.1 dev eth0 || true
PostDown = ip route del 167.99.130.97 via 10.2.0.1 dev eth0 || true
PostDown = ip route add default via 10.2.0.1 || true

MTU = 1342
PreUp = udp2raw -c -l 127.0.0.1:50001 -r 167.99.130.97:55055 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true

# Endpoint A
[Peer]
PublicKey = z73wM1b7fhMRA8fmeQw4FntRvgJ9JwTdsQHssXHg3DE=
Endpoint = 127.0.0.1:50001
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 120

WireGuard Over TCP Using udp2raw: Securing and Expanding Connectivity

Reading time: 30 – 50 minutes

In this post, I’ll share how I set up a WireGuard VPN over TCP using udp2raw, which provides secure access to corporate networks and serves as a fallback for internet access when customer networks impose heavy restrictions. Inspired by Pro Custodibus, this solution enables IoT gateways to seamlessly connect to both the company’s internal services and the broader internet under constrained conditions.

Scenario Overview

The architecture for this setup is illustrated below:

Key Features of the Solution:

  1. Access to Corporate Networks: IoT Gateways securely connect to the corporate network for accessing internal services.
  2. Fallback Internet Access: When the customer’s network restricts internet access but allows TCP connections to the company infrastructure, the IoT Gateway routes its internet traffic through the company’s network.

How It Works:

  • Endpoint A (Client): An IoT Gateway connects through the restrictive customer network.
  • Endpoint B (Server): The WireGuard server is accessible via a public IP (134.122.74.29) on TCP port 55055.
  • Traffic flows through a TCP tunnel created with udp2raw, enabling the gateway to securely access the corporate network or relay internet traffic via the company’s infrastructure.

This dual-purpose setup ensures robust connectivity for IoT devices even in challenging environments.

Video Demonstration (in Spanish)

I’ve created a video demonstration in Spanish showcasing the entire setup and functionality of this scenario. The video walks through the following steps:

  1. Explaining the problem and network constraints.
  2. Demonstrating the configuration of both endpoints (client and server).
  3. Showing the connection initiation and testing, including how traffic flows through the VPN tunnel.
  4. Verifying fallback internet access through the company network.

This video is ideal for those who prefer visual explanations or need extra guidance in implementing this solution.

Configuration Files

1. Endpoint B (server, /etc/wireguard/wg0.conf)

This configuration allows Endpoint B to act as a gateway for both corporate access and fallback internet connectivity:

# local settings for Endpoint B
[Interface]
PrivateKey = EMqyADu4Xeu95ZpNZE97FET5eKzN1WSwBkeBWtX1yGg=
Address = 192.168.111.1/32
ListenPort = 51822

# receive wg through udp2raw
MTU = 1342
PreUp = udp2raw -s -l 134.122.74.29:55055 -r 127.0.0.1:51822 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true

# Enable NAT for traffic forwarding (corporate and fallback internet access)
PreUp = echo 1 > /proc/sys/net/ipv4/ip_forward || true
PreUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE || true
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE || true

# remote settings for Endpoint A
[Peer]
PublicKey = Xt70DJy8ldPcDNW4YM2Dt94n16pTQKFxhmvpgKvJyng=
AllowedIPs = 192.168.111.2/32
PersistentKeepalive = 120

Key Points:

  • NAT Rules: These rules enable traffic originating from Endpoint A to use Endpoint B for accessing the internet.
  • MTU Adjustment: The MTU is set to 1342 to prevent fragmentation issues over the TCP tunnel.

Assumptions:

  • eth0, is the name of the interface for reaching Internet.
  • 192.168.111.0/24 is available for point-to-point connections in the tunnels.
  • ud2raw is in PATH.
  • Don’t re-use my pub and private keys. Neither the pre-shared key of used by udp2raw.
Endpoint A (client, /etc/wireguard/wg0.conf)

This configuration sets up Endpoint A to route all traffic (corporate and internet) through Endpoint B:

[Interface]
PrivateKey = yAxByb468bAuMdg5S6AlfYkxbeYDOMEKxdaJ7d2p83g=
Address = 192.168.111.2/32

# Route configuration for public IP
PreUp = ip route del default || true
PreUp = ip route add 134.122.74.29 via 10.2.0.1 dev eth0 || true
PostDown = ip route del 134.122.74.29 via 10.2.0.1 dev eth0 || true
PostDown = ip route add default via 10.2.0.1 || true

MTU = 1342
PreUp = udp2raw -c -l 127.0.0.1:50001 -r 134.122.74.29:55055 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true

[Peer]
PublicKey = VUN2JqZiGQ1V46PDoFECw/nMs3/o6n8PvGMV+ad+Hww=
Endpoint = 127.0.0.1:50001
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 120

Key Points:

  • Fallback Internet Routing: The AllowedIPs = 0.0.0.0/0 directive ensures all traffic is routed through Endpoint B, including internet traffic.
  • Dynamic Route Adjustments: The PreUp and PostDown commands manage routes for efficient fallback connectivity.

Here’s the improved Implementation Steps section based on your feedback and expertise in WireGuard and udp2raw:

Implementation Steps

This section outlines the precise steps required to set up the WireGuard VPN over TCP using udp2raw. Follow these instructions carefully for both Endpoint A (client) and Endpoint B (server).

1. Pre-requisites

  • WireGuard Installation: Ensure WireGuard is installed on both systems. This can usually be done via the package manager of your operating system (e.g., apt install wireguard for Debian-based distributions).
  • udp2raw Binary: Download the appropriate udp2raw binary from its GitHub Releases Page. Binaries are available for various architectures. For simplicity:
    1. Extract the binary from the tarball (e.g., udp2raw_amd64 for most x86_64 systems).
    2. Place the binary in a directory accessible from your PATH (e.g., /usr/local/bin).
    3. Verify the installation: which udp2raw udp2raw -h # Should display the help menu

2. Prepare the Configuration Files

The configuration files should be located at /etc/wireguard/wg0.conf. Each endpoint has its own specific configuration:

  • Endpoint A: Use the wg0.conf provided earlier, replacing placeholders like keys and IPs as needed.
  • Endpoint B: Use the wg0.conf provided earlier.

Ensure both files reflect the IP addresses, MTU settings, and public/private keys accurately.

3. Generate WireGuard Keys

WireGuard requires public-private key pairs for secure communication. Generate them as follows:

  1. Generate the Private Key: wg genkey > privatekey
  2. Generate the Public Key from the private key: cat privatekey | wg pubkey > publickey
  3. Place the private key in the [Interface] section of the respective configuration file (PrivateKey = ...) and the corresponding public key of the peer in the [Peer] section (PublicKey = ...).

Note: Never share your private keys.

4. Start the VPN Tunnel

  1. Start the Server First (Endpoint B):
    • Bring up the WireGuard interface using wg-quick: sudo wg-quick up wg0
    • Verify that the interface is active: wg show
  2. Start the Client (Endpoint A):
    • Bring up the client WireGuard interface: sudo wg-quick up wg0
    • Verify that the interface is active: wg show

5. Test the Connection

Once both endpoints are active, initiate traffic from Endpoint A to Endpoint B. This step ensures the udp2raw TCP socket is properly established and functioning:

  1. Ping Endpoint B’s WireGuard IP: ping 192.168.111.1
    • If the ping succeeds, the connection is working as expected.
    • If it fails, check the logs for udp2raw and WireGuard on both endpoints for errors: less /var/log/udp2raw.log
  2. Once the initial handshake completes, the tunnel will remain active as long as PersistentKeepalive is configured in the client configuration (e.g., PersistentKeepalive = 120).

6. Validate Fallback Internet Access

To confirm the fallback internet routing through Endpoint B:

  1. On Endpoint A, run a test to confirm external connectivity: curl -I https://www.google.com
    • If the response headers are received, the internet routing through Endpoint B is functioning.
    • Verify that the traffic is routed through the WireGuard tunnel: traceroute google.com
  2. If fallback internet access fails, ensure that NAT is correctly configured on Endpoint B: iptables -t nat -L -n

7. Troubleshooting

  • Log Files:
    • Check the udp2raw logs on both endpoints for issues (e.g., MTU mismatches, handshake failures).
    • Review WireGuard logs for additional details.
  • MTU Issues:
    • If large packets fail but small packets (e.g., ping) succeed, reduce the MTU (e.g., to 1280).

8. Automate Startup

To ensure the VPN starts automatically on boot:

  1. Enable the WireGuard service: sudo systemctl enable wg-quick@wg0
  2. Add udp2raw commands to a systemd service or the PreUp directive in wg0.conf (as shown in the configuration files).

With these steps, you now have a fully operational WireGuard tunnel over TCP, enabling secure communication between endpoints and fallback internet connectivity via the company’s infrastructure.

Conclusion

This configuration provides a robust solution for IoT Gateways operating in restrictive environments. By leveraging udp2raw, WireGuard traffic is tunneled over TCP, enabling:

  1. Seamless Corporate Access.
  2. Fallback Internet Connectivity through the company network when customer environments impose constraints.

This versatile setup ensures uninterrupted operations and secure communications for IoT devices. Explore the Pro Custodibus guide and udp2raw GitHub repository for additional insights.

References

Accessing Zerotier’s REST API

Reading time: 6 – 10 minutes

Zerotier offers a powerful REST API that allows for seamless integration and management of your network. By default, the API is accessible on TCP port 9993. To securely interact with this API, an authentication token is required.

The authentication token is stored in the following file:

/var/lib/zerotier-one/authtoken.secret

To check if the Zerotier service is running correctly, you can use the curl command with the necessary authentication header. Here’s how to do it:

curl -Lv -H "X-ZT1-Auth: $(cat /var/lib/zerotier-one/authtoken.secret)" http://localhost:9993/status 2>&1|less

Breaking Down the Command:

  • curl -Lv
    • -L: Follows any redirects the server might issue.
    • -v: Enables verbose mode, providing detailed information about the request and response.
  • -H "X-ZT1-Auth: $(cat /var/lib/zerotier-one/authtoken.secret)"
    • Adds a custom header X-ZT1-Auth with the value of your authentication token. This is essential for authorized access to the API.
  • http://localhost:9993/status
    • The endpoint to check the current status of the Zerotier service.
  • 2>&1 | less
    • Redirects both standard output and standard error to less for easy reading and navigation of the output.

I hope you found this guide helpful in navigating Zerotier’s REST API.

Enhancing SSH Security with StealthSSHAccess

Reading time: 4 – 7 minutes

In today’s interconnected world, maintaining the security of your server infrastructure is paramount. One critical point of vulnerability is the SSH (Secure Shell) service, which allows remote administration of servers. Despite using a non-default port, many administrators still find their servers bombarded with brute-force and denial-of-service attacks. To address this challenge, I’ve developed a solution called StealthSSHAccess.

The Problem

Attackers often employ brute force attacks to gain unauthorized access to servers via SSH. Even if you’ve changed the default SSH port, determined attackers can still discover the new port and target it. These attacks can lead to service disruption, unauthorized data access, and potential breaches of sensitive information.

The Solution: StealthSSHAccess

StealthSSHAccess is an innovative approach to managing remote SSH access while mitigating the risks associated with brute-force attacks. Let’s delve into how it works and why it’s an effective solution:

Dynamic Access Control

StealthSSHAccess takes a dynamic and personalized approach to SSH access control. It operates as a smart gateway between potential attackers and your SSH service. Here’s a simplified breakdown of how it functions:

  1. Monitoring for Intent: Instead of directly exposing the SSH port, StealthSSHAccess monitors a non-SSH TCP port for connection attempts. Attackers, unaware of this, can’t target the SSH port directly.
  2. Capture and Response: When an attempt is made on the monitored port, StealthSSHAccess captures the IP address of the requester. This initial connection attempt fails, serving as a signal of intent to access SSH.
  3. Secure Access Window: Based on this signal, StealthSSHAccess temporarily opens the SSH port exclusively for the captured IP address. This allows for a secure connection from that specific source.
  4. Time-Bound Access: Access is granted for a predetermined duration. If SSH access isn’t established within this timeframe, the port is automatically closed for that specific IP. This tightens the window of exposure and bolsters security.
  5. Automatic Closure: If the port remains unused during the allowed time, StealthSSHAccess automatically revokes access and closes the port. A continuous monitoring mechanism controls this process.

Benefits and Features

1. Enhanced Security: By hiding the SSH port from attackers, StealthSSHAccess reduces the attack surface and minimizes exposure to potential threats.

2. Selective Accessibility: With StealthSSHAccess, you control who gains access by simply attempting a connection to a specific port. This provides an additional layer of security.

3. Minimal Configuration: Implementing StealthSSHAccess is easy thanks to its Docker-based deployment. This means you can integrate it seamlessly into your existing system.

4. Persistence Across Restarts: StealthSSHAccess ensures continuity by persisting IP timer information across service interruptions or restarts. This keeps the system aware of pending access requests.

Getting Started with StealthSSHAccess

To deploy StealthSSHAccess, follow these steps:

  1. Requirements: Ensure you have Docker and Docker Compose installed.
  2. Configuration: Set up environment variables using the provided .env file. Customize parameters like LOGLEVEL, IFACE, PORT_TO_MONITOR, and more to match your environment.
  3. Building and Running: Build the images using docker-compose build, and then launch the services with docker-compose up -d.
  4. Data Persistence: IP timer data is stored in the ./data directory, so make sure it’s writable by the Docker user.
  5. Security Note: Be aware that these services run with privileged access due to their interaction with the system’s network configuration. Understand the security implications before deployment.

Conclusion

In the ongoing battle against cybersecurity threats, StealthSSHAccess stands as a beacon of innovative protection for your servers. By intelligently managing SSH access and responding dynamically to legitimate requests, this solution offers heightened security without sacrificing convenience. Whether you’re an administrator or a security-conscious user, consider integrating StealthSSHAccess into your infrastructure to safeguard your servers from the persistent threats of the digital landscape.

To explore the project, access the source code, and learn more about its implementation, visit the StealthSSHAccess GitHub repository. Remember, security is a journey, and with StealthSSHAccess, you’re taking a proactive step toward a more resilient and secure server environment.

OpenSSH public key fingerprint

Reading time: 8 – 14 minutes

Quick and easy, how to get the fingerprint of your SSH RSA key.

# syntax:
openssl pkey -in PATH/PRIVATE_RSA_KEY -pubout -outform DER | openssl md5 -c

# example:
$ openssl pkey -in ~/.ssh/id_rsa -pubout -outform DER | openssl md5 -c
MD5(stdin)= a6:26:23:d9:c1:d3:d5:e5:c0:38:ab:3c:c1:6a:3f:ea

socat: publish a port only available in localhost

Reading time: 11 – 18 minutes

Assume that we have a service only available in localhost (127.0.0.1/8) and we want to expose this port temporarily. Of course, you can use iptables for redirecting the port. But take care, this is not a simple DNAT because packets will not be evaluated by PREROUTING (-t nat) rules.

Another option is using an old-powerful Swiss knife tool: socat (github) (my fork).

# binds public port to any local interface
socat TCP-LISTEN:<public_port>,fork TCP:127.0.0.1:<internal_port>
# binds only to an IP address
SOCAT_SOCKADDR=<interface_IP> socat TCP-LISTEN:<public_port>,fork TCP:127.0.0.1:<internal_port>

# examples:

# binds to all interfaces:
socat TCP-LISTEN:1880,fork TCP:127.0.0.1:1880
# just for an IP address of one interface:
SOCAT_SOCKADDR=10.2.0.110 socat TCP-LISTEN:1880,fork TCP:127.0.0.1:1880

socat tip: VPN without cyphering

Reading time: 3 – 4 minutes

Fast reminder and tip for socat, it can work on two devices or more:

# SERVER:
socat TCP-LISTEN:4443 TUN:192.168.255.2/24,up

# CLIENT:
socat TCP:SERVER_IP:4443 TUN:192.168.255.1/24,up

Cryptomator: create a secure vault for your files

Reading time: 2 – 2 minutes

Yesterday I found a tool called Cryptomator, this is a client-side encryption for your files. You can use it with Dropbox, or any other cloud filesystem or you can use it in your local filesystem. Anyway, this open-source piece of software is really simple to install and is compatible with Windows, Mac and Linux. Once this is installed, using the UI the only thing we have to do is create, or select, a folder where the secure vault is going to be created. It uses a symmetric password for cyphering and when the vault is unlocked a new removable drive appear in your system. So, at the end, the vault is like a pendrive and there is no complexity on add, rename, remove, create folders, etc. inside the new drive. Once the vault is locked, the removable drive is unmounted and if you go to the location where the vault is created a tree structure with cyphered files is the only thing that you can see. Cryptomator works cyphering each file, not the complete vault as a package.

So far I installed the tool on my Windows computer for securing some sensitive files that I have on my laptop. But if it works like I expect I’m going to extend the usage with the rest of my computers. As I said it’s not required any cloud filesystem, by the way, I use Cryptomator in conjunction with Resilio Sync.

Restricted user for SSH port forwarding

Reading time: 7 – 11 minutes

I love “ssh -R” reverse SSH is really useful when you have to get access to a Linux machine behind a NAT or firewall. One of the most powerful scenarios to get that running is use a third machine with a public IP address. The idea will be run reverse SSH command in target Linux and publish a forward port at the third server, so you only have to connect to a published port in that third server and you’ll get the target Linux thanks to the reverse SSH connection open between them.

reverse-ssh-schema

A long time ago I talked about that in my podcast “2×04 SSH avançat“.

With this scenario we have a security challenge with the SSH user account on the “third server”, we want a secure user:

  • without shell and sftp access
  • secure enough to only allow port forwarding features
  • access only allowed with authorized keys

I’m not going to give precise Linux instructions on that limited user, but for user you’re not going to have problems to get that:

/etc/passwd(-):

limited-user:x:1001:1001::/home/limited-user:

/etc/shadow(-):

limited-user:!:17037:0:99999:7:::

/etc/ssh/sshd_config:

Match User limited-user
    GatewayPorts yes
    ForceCommand echo 'This account can only be used for maintenance purposes'

Of course, you’ll have your own UID, GID and use your own username. And at “/home/limite-user/.ssh/authorized_ssh” you’ll have to pub public key of the clients that want to use the service.

I’ve got my inspiration to get that from: How to create a restricted SSH user for port forwarding?. Thank you askubnutu.com.

Scroll to Top