Dos clientes pueden abrir ambos el host de salto y aun así no tener ningún negocio abriéndose el uno al otro. Alcanzar un servicio es una decisión de reenvío, mientras que alcanzar a un par es una decisión de política, y la mayoría de las pilas VPN las guardan en objetos separados. Nada de lo que configure para la primera impone la segunda. Por tanto, la tarea no es añadir una regla, sino encontrar el objeto que decide el tráfico entre pares en este servidor, escribir allí la denegación y demostrarla desde un cliente.

Una ruta al servicio compartido no es un permiso entre pares

Anunciar la subred de clientes le dice a un par cómo poner un paquete en el cable hacia la dirección de otro cliente. Si ese paquete se entrega se decide después, por lo que lo reenvía. En una puerta de enlace Linux es la cadena FORWARD; dentro de un demonio en espacio de usuario es la propia tabla de sesiones del túnel. Una ruta responde a la accesibilidad y deja el permiso intacto.

Por eso una comprobación de aislamiento que solo lee rutas no demuestra nada. Se puede empujar una /24 a cada cliente mientras cada paquete entre pares se descarta en el gancho de reenvío. El caso peligroso es el contrario: ninguna regla explícita, un valor predeterminado permisivo y un aislamiento que solo existe porque nadie lo probó.

Escriba el requisito en una línea antes de abrir un terminal. Llegue al bloque de servicios y al host de salto, no llegue a nada más dentro del bloque de clientes.

Averigüe quién reenvía realmente el paquete entre pares

Dos comportamientos del servidor se ven iguales desde el lado del cliente y necesitan reglas distintas. O el núcleo reenvía el paquete por la interfaz del túnel otra vez, o el demonio lo copia entre sesiones y el núcleo nunca lo ve.

WireGuard pertenece al primer grupo: no tiene interruptor entre pares, así que un paquete de 10.8.0.4 a 10.8.0.5 llega por wg0, toca el gancho de reenvío y se vuelve a encaminar por wg0 cuando AllowedIPs cubre ambas direcciones. OpenVPN es el segundo grupo en cuanto client-to-client está definido en la configuración del servidor, porque esa directiva entrega el paquete entre sesiones en espacio de usuario. Revise la configuración cargada en busca de esa directiva antes de escribir nada. Una regla del núcleo que nunca ve tráfico no se distingue de una regla que funciona, y así es como un despliegue acaba sin ningún aislamiento.

Lea la configuración efectiva en lugar del archivo que supone cargado, porque los paquetes de distribución traen sus propias inclusiones. Si el demonio hace el reenvío, la denegación pertenece a sus propios controles por cliente, y el cortafuegos del host solo filtra el tráfico dirigido al host. Si el núcleo reenvía, el gancho de reenvío es el único lugar que importa.

Los despliegues enrutados y traducidos necesitan una comprobación más: la fuente que ve un cliente lejano puede no ser la que espera. Entonces una regla que coincide con la subred de clientes no coincide con nada. Anote la dirección que sobrevive a la traducción antes de escribir la coincidencia, y prefiera hacer coincidir el par de interfaces en lugar de adivinar direcciones NAT.

Dé a cada dirección una identidad que se pueda revocar por sí sola

El aislamiento se derrumba en cuanto dos dispositivos comparten una credencial. Una regla ligada a esa identidad no puede separarlos, y revocar un portátil perdido revoca todo el grupo. Certificados por dispositivo o claves por par mantienen la revocación local y la política legible, porque cada dirección corresponde exactamente a una persona o máquina. Donde el diseño no pueda hacerlo, dígalo en el manual de operaciones en lugar de describir la regla como granular.

La asignación de direcciones debe concordar con la política. Reserve un bloque para servicios, un bloque para clientes, y reparta direcciones de clientes desde un conjunto que controle en lugar de un rango de primero en llegar. Si el servidor traduce o hace puente, mantenga la tabla de mapeo junto a la configuración, porque esa tabla es lo que el siguiente lector necesita para volver a derivar la regla.

Ponga la denegación donde el paquete cruza el túnel

En una puerta de enlace que reenvía tráfico de WireGuard, dos reglas cubren el caso: permita el bloque de servicios y luego descarte el resto del bloque de clientes. El par de interfaces importa tanto como las direcciones, porque coincidir solo en el destino también atrapa el tráfico que llega de la LAN. Cárguelas en ese orden para que el permiso se evalúe primero.

Con nftables el par entra en una tabla inet filter existente, primero el permiso y después el descarte. Ambas coincidencias fijan el par de interfaces además de las direcciones.

nft add rule inet filter forward iifname "wg0" oifname "wg0" ip saddr 10.8.0.0/24 ip daddr 10.8.2.0/24 accept
nft add rule inet filter forward iifname "wg0" oifname "wg0" ip saddr 10.8.0.0/24 ip daddr 10.8.0.0/24 drop

Vuelva a leer la cadena después de cargarla en lugar de confiar en el estado de salida, y confirme que ambas reglas están en el orden que pretendía. Añada reglas ip6 coincidentes para el conjunto IPv6, o el par v4 es decorativo en un túnel de pila doble. Si el servidor ya tiene una política de reenvío permisiva, añada el descarte en lugar de sustituir la cadena entera.

Cuando client-to-client está activado en OpenVPN, estas reglas de reenvío nunca coinciden con el tráfico entre pares y la denegación debe vivir en los controles propios del demonio. Mantenga las reglas del núcleo para el tráfico dirigido al host, pero no las cuente como el control de aislamiento.

Demuestre la denegación desde un cliente, no desde el servidor

Probar desde la puerta de enlace no demuestra nada, porque el tráfico generado localmente toma la ruta de salida y nunca cruza el gancho de reenvío. Use dos clientes reales: uno que debería alcanzar el servicio y otro que debería ser rechazado. Ejecute primero el caso permitido, para que un túnel roto no se confunda con una política que funciona.

Desde el cliente permitido, confirme que el servicio responde en su puerto. Desde el mismo cliente, pruebe la dirección del par y espere un descarte silencioso en lugar de un rechazo:

ping -c 3 -W 2 10.8.0.5
nc -z -w 2 10.8.0.5 22
nft list chain inet filter forward
iptables -vnL FORWARD
ping -6 -c 3 -W 2 fd00:8::5

Un paquete descartado y un par desconectado se parecen ambos a un tiempo de espera, así que revise los contadores antes de concluir nada. Confirme que el contador de la regla de descarte aumenta mientras el par está demostrablemente activo. Repita por IPv6, donde una regla ip6 ausente deja la denegación v4 como si fuera efectiva. Anote los resultados aceptados y rechazados en el manual con la fecha, porque la próxima migración volverá a derivar la regla.

Artículos relacionados