Je crée un simple proxy POP3 compatible STARTTLS dans Node.JS et je rencontre des difficultés.NodeJS STARTTLS Utiliser SNI
Le proxy sert de serveur frontal pour de nombreux serveurs principaux. Il doit donc charger ses certificats de manière dynamique, en fonction de la connexion du client. J'essaie d'utiliser le SNICallback, qui m'apporte le nom de serveur que le client utilise, mais je ne peux pas définir le bon certificat après cela, car j'ai besoin d'un certificat avant d'avoir cet appel, quand je crée le le contexte.
Le code est comme ci-dessous:
// Load libraries
var net = require('net');
var tls = require('tls');
var fs = require('fs');
// Load certificates (created with openssl)
var certs = [];
for (var i = 1; i <= 8; i++) {
var hostName = 'localhost' + i;
certs[hostName] = {
key : fs.readFileSync('./private-key.pem'),
cert : fs.readFileSync('./public-cert' + i + '.pem'),
}
}
var server = net.createServer(function(socket) {
socket.write('+OK localhost POP3 Proxy Ready\r\n');
socket.on('data', function(data) {
if (data == "STLS\r\n") {
socket.write("+OK begin TLS negotiation\r\n");
upgradeSocket(socket);
} else if (data == "QUIT\r\n") {
socket.write("+OK Logging out.\r\n");
socket.end();
} else {
socket.write("-ERR unknown command.\r\n");
}
});
}).listen(10110);
et upgradeSocket() se présente comme suit:
function upgradeSocket(socket) {
// I need this 'details' or handshake will fail with a message:
// SSL routines:ssl3_get_client_hello:no shared cipher
var details = {
key : fs.readFileSync('./private-key.pem'),
cert : fs.readFileSync('./public-cert1.pem'),
}
var options = {
isServer : true,
server : server,
SNICallback : function(serverName) {
return tls.createSecureContext(certs[serverName]);
},
}
sslcontext = tls.createSecureContext(details);
pair = tls.createSecurePair(sslcontext, true, false, false, options);
pair.encrypted.pipe(socket);
socket.pipe(pair.encrypted);
pair.fd = socket.fd;
pair.on("secure", function() {
console.log("TLS connection secured");
});
}
Il poignées de mains correctement, mais le certificat que j'utilise est celui statique dans 'détails', non celui que je reçois dans le SNICallback.
Pour le tester, je suis en cours d'exécution du serveur et en utilisant gnutls-cli comme client:
~$ gnutls-cli -V -s -p 10110 --crlf --insecure -d 5 localhost3
STLS
^D (Control+D)
La commande ci-dessus est censé me obtenir le certificat « localhost3 », mais il devient le « localhost1 » parce que c'est défini dans 'details' var; Il y a juste trop d'exemples sur Internet avec HTTPS ou pour les clients TLS, ce qui est très différent de ce que j'ai ici, et même pour les serveurs, mais ils n'utilisent pas SNI. Toute aide serait appréciée.
Merci d'avance.
Je viens de voir ce bug ouvert à Node.js github, je me demande si elle est, en fait, le problème: https://github.com/nodejs/node/issues/4878 –