Waarom openssl rand de sleutel niet kan maken die tls-crypt wil
OpenSSL produceert willekeurige bytes; tls-crypt heeft een gestructureerd statisch sleutelbestand nodig, en tls-crypt-v2 heeft een sleutel nodig die alleen de server kan inpakken. Gebruik openvpn --genkey.
OpenSSL is al geïnstalleerd, de host heeft entropie, en er een sleutel mee genereren voelt als de voor de hand liggende kortere weg. De uitvoer wordt willekeurig en geheim en volstrekt onbruikbaar, en de fout komt als een controlekanaalfout in plaats van als iets dat een sleutelformaat noemt. Die misleiding is het dure deel, want ze stuurt mensen hun cijfers te onderzoeken. Wat de VPN leest is een specifieke bestandsstructuur, geen willekeurig blok bytes, en één variant van de functie kan helemaal niet buiten de server worden gemaakt.
Wat het bestand op schijf werkelijk moet zijn
Een statisch sleutelbestand van OpenVPN is tekst. Het begint met een commentaarregel die aangeeft wat het is, draagt hexgegevens in regels van vaste breedte, en bevat in totaal 256 bytes sleutelmateriaal. OpenVPN leest het als het gedeelde geheim van het controlekanaal, niet als een certificaat, niet als een wachtwoordzin en niet als iets wat een TLS-bibliotheek zou herkennen.
Hetzelfde objecttype dient beide functies van het controlekanaal. Bij tls-auth heeft elke peer ook een richting nodig, zodat de pakketten van de ene kant niet naar hem teruggekaatst kunnen worden. Bij tls-crypt versleutelt en authenticeert één gedeeld geheim het controlekanaal in beide richtingen, wat de handshake verbergt en tegelijk beschermt.
Niets daarvan is geheime kennis, en het formaat is niet het punt. Het punt is dat het bestand precies moet passen bij wat de lezer verwacht: kop, regelbreedte, afsluitende nieuwe regel en totale lengte. Een bestand dat één regel ernaast zit, laadt als rommel of mislukt helemaal. Twee peers byte voor byte vergelijken is daarom een legitieme eerste test, en het is sneller dan een van de twee configuratiebestanden lezen.
De ondersteunde manier om er een te maken
Genereer de gewone statische sleutel met het gereedschap dat hem zal gebruiken, en verwijs er dan vanaf beide kanten naar:
openvpn --genkey secret /etc/openvpn/tc-shared.key
tls-crypt /etc/openvpn/tc-shared.key
De spelling van de optie veranderde in de loop der tijd: oudere installaties uit het 2.4-tijdperk gebruikten een vorm met een aparte vlag voor de bestandsnaam, terwijl huidige builds de kortere accepteren. Hoe dan ook, het resulterende bestand is hetzelfde soort object, dus de controle is of beide peers identieke bytes hebben.
De tweede generatie voegt een structuur toe die geen enkele externe generator kan bedenken. Een serversleutel wordt één keer gemaakt, en elke client ontvangt een ingepakte sleutel die ervan is afgeleid:
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
Wat de client ontvangt is niet de eigen sleutel van de server gedupliceerd. Het is een ingepakt object dat metadata draagt die alleen de server kan uitpakken, en die inpakking is de reden waarom een bestand per apparaat kan worden ingetrokken zonder een ander apparaat aan te raken. Houd de serversleutel op de server en behandel hem als de wortel van dat vertrouwen per apparaat.
Waar handgemaakte bytes stuklopen
256 willekeurige bytes als hex afdrukken onder een correcte kop zou in theorie een statisch sleutelbestand opleveren dat laadt. Het blijft een slecht idee. Elk formatteringsdetail wordt een kans om materiaal te produceren dat bij het laden mislukt of, erger, twee peers met verschillende waarden achterlaat die zich pas als een authenticatiefout openbaren.
Niets gelijkwaardigs is mogelijk met de v2-variant. Een ingepakte clientsleutel bestaat alleen als uitvoer van het serversleutelproces, en de server bewaart het materiaal dat nodig is om hem uit te pakken. Een willekeurige blob wordt geweigerd of kan eenvoudigweg niet ontsleutelen, en geen van beide berichten noemt willekeur.
Versiecompatibiliteit ligt bovenop dit alles. De eerste generatie vereist een release die hem aan beide kanten ondersteunt, en de tweede vereist weer een nieuwere release. Een client die is gebouwd voordat de functie bestond, kan geen handshake voltooien met een server die alleen ingepakt materiaal accepteert, en de fout die hij meldt wijst naar het controlekanaal in plaats van naar de versie.
Roterend zonder iedereen buiten te sluiten
Eén gedeeld geheim roteren is een coördinatieoefening, geen technische. Elke client moet het vervangende bestand in handen hebben voordat de server het vorige intrekt, en elke machine die de oude waarde nog heeft, faalt op dat moment. Begin die rotatie niet midden op een werkdag.
Met de v2-indeling is rotatie per apparaat: geef een nieuwe ingepakte sleutel uit voor één machine en trek de oude alleen voor die machine in. Dat is het belangrijkste argument om over te stappen zodra elke client op een release zit die het ondersteunt.
Bestandsrechten horen in hetzelfde gesprek. De sleutel mag alleen leesbaar zijn voor het account dat de dienst draait, en hij hoort niet in dezelfde repository te staan als de profielen die hij beschermt. De OpenVPN 2.6-referentie documenteert de genereringsvormen en de secties over sleutelmateriaal, wat een betere bron is dan een gekopieerd commando uit een forumpost.