Por qué openssl rand no puede crear la clave que tls-crypt necesita
OpenSSL produce bytes aleatorios; tls-crypt necesita un archivo de clave estática estructurado, y tls-crypt-v2 necesita una clave que solo el servidor puede envolver. Use openvpn --genkey.
OpenSSL ya está instalado, el host tiene entropía, y generar una clave con él parece el atajo obvio. La salida será aleatoria y secreta y completamente inutilizable, y el fallo llega como un error del canal de control en lugar de como algo que mencione un formato de clave. Esa desorientación es la parte costosa, porque lleva a la gente a inspeccionar sus cifrados. Lo que lee la VPN es una estructura de archivo concreta, no un bloque arbitrario de bytes, y una variante de la función no puede producirse fuera del servidor en absoluto.
Lo que el archivo en disco tiene que ser en realidad
Un archivo de clave estática de OpenVPN es texto. Empieza con una línea de comentario que declara qué es, lleva datos hexadecimales en filas de ancho fijo y suma 256 bytes de material de clave. OpenVPN lo lee como el secreto compartido del canal de control, no como un certificado, no como una frase de contraseña y no como algo que una biblioteca TLS reconocería.
El mismo tipo de objeto sirve para ambas funciones del canal de control. Con tls-auth, cada par también necesita una dirección para que los paquetes de un lado no puedan reflejarse de vuelta hacia él. Con tls-crypt, un único secreto compartido cifra y autentica el canal de control en ambas direcciones, lo que oculta el handshake además de protegerlo.
Nada de eso es conocimiento secreto, y el formato no es el punto. El punto es que el archivo tiene que coincidir exactamente con lo que el lector espera: cabecera, ancho de fila, salto de línea final y longitud total. Un archivo que se desvía en una fila se carga como basura o falla directamente. Comparar dos pares byte a byte es, por tanto, una primera prueba legítima, y es más rápida que leer cualquiera de los dos archivos de configuración.
La forma admitida de crear uno
Genere la clave estática simple con la herramienta que la va a consumir y luego haga referencia a ella desde ambos extremos:
openvpn --genkey secret /etc/openvpn/tc-shared.key
tls-crypt /etc/openvpn/tc-shared.key
La grafía de la opción cambió con el tiempo: las instalaciones antiguas de la era 2.4 usaban una forma con un indicador separado antes del nombre del archivo, mientras que las compilaciones actuales aceptan la más corta. En cualquier caso, el archivo resultante es el mismo tipo de objeto, así que la comprobación es si ambos pares tienen bytes idénticos.
La segunda generación añade una estructura que ningún generador externo puede inventar. Una clave de servidor se crea una vez, y cada cliente recibe una clave envuelta derivada de ella:
openvpn --genkey tls-crypt-v2-server /etc/openvpn/tc-v2-server.key
openvpn --genkey tls-crypt-v2-client /etc/openvpn/laptop1.key --tls-crypt-v2 /etc/openvpn/tc-v2-server.key
Lo que recibe el cliente no es la propia clave del servidor duplicada. Es un objeto envuelto que lleva metadatos que solo el servidor puede desenvolver, y ese envoltorio es la razón por la que un archivo por dispositivo puede revocarse sin tocar ningún otro dispositivo. Mantenga la clave del servidor en el servidor y trátela como la raíz de esa confianza por dispositivo.
Dónde fallan los bytes hechos a mano
Imprimir 256 bytes aleatorios como hexadecimal bajo una cabecera correcta daría, en teoría, un archivo de clave estática que se carga. Sigue siendo una mala idea. Cada detalle de formato se convierte en una ocasión de producir material que falla al cargar o, peor, deja a dos pares con valores distintos que solo se revelan como un fallo de autenticación.
Nada equivalente es posible con la variante v2. Una clave de cliente envuelta existe solo como salida del proceso de clave del servidor, y el servidor conserva el material necesario para desenvolverla. Un bloque aleatorio será rechazado o simplemente fallará al descifrar, y ninguno de los dos mensajes mencionará la aleatoriedad.
La compatibilidad de versiones está por encima de todo esto. La primera generación necesita una versión que la admita en ambos extremos, y la segunda necesita otra versión más nueva. Un cliente compilado antes de que existiera la función no puede completar un handshake con un servidor que solo acepta material envuelto, y el fallo que informa apunta al canal de control en lugar de a la versión.
Rotar sin dejar a todos fuera
Rotar un único secreto compartido es un ejercicio de coordinación, no técnico. Cada cliente necesita el archivo de reemplazo en mano antes de que el servidor retire el anterior, y cualquier máquina que aún tenga el valor antiguo falla en el momento en que eso ocurre. No empiece esa rotación en mitad de una jornada laboral.
Con el esquema v2, la rotación es por dispositivo: emita una nueva clave envuelta para una máquina y retire la antigua solo para esa máquina. Ese es el argumento principal para cambiar una vez que todos los clientes estén en una versión que lo admita.
Los permisos de archivo pertenecen a la misma conversación. La clave debería ser legible solo por la cuenta que ejecuta el servicio, y no debería vivir en el mismo repositorio que los perfiles que protege. La referencia de OpenVPN 2.6 documenta las formas de generación y las secciones de material de clave, que es una fuente mejor que un comando copiado de una publicación de foro.