Как я могу ввести новый сертификат SSL и ключ в работающий узел http.Server?
Я использую безопасный прокси websocket для службы TCP. Это использует стандарт http.Server
настроить как:
var webserver = http.createServer(
{
key: fs.readFileSync(srv.ssl_key),
cert: fs.readFileSync(srv.ssl_cert),
},
function(request, response) {
response.writeHead(404);
response.end();
},
function(err) {
srv.log(err);
}
);
Как видите, мы уже используем смешные недокументированные средства: параметры и аргументы обработчика ошибок для http.createServer()
,
Ключ SSL и сертификат периодически восстанавливаются сертификатом LetsEncrypt. Когда это происходит, я хотел бы ввести новый ключ и сертификат в веб-сервер, не создавая новый или повторно инициализируя мой веб-сокет.
Какой еще недокументированный объект позволит мне это сделать?
2 ответа
Ты должен:
- Закройте текущий веб-сервер с помощью
webserver.close()
- Создайте новый экземпляр веб-сервера с вашим новым ключом и сертификатом (есть
.setOptions()
метод, который вы могли бы использовать для измененияkey
а такжеcert
опций, но нет способа заставить его генерировать новые учетные данные TLS после создания экземпляра) - Смонтируйте новый веб-сервер на сервере веб-сокетов с помощью
websocketServer.mount(websocketOptions)
, гдеwebsocketOptions.httpServer
ваш новый экземпляр веб-сервера
Это будет работать красиво и плавно, не мешая работе соединений.
Используйте SNICallback
На самом деле, вы не должны предоставлять cert
а также key
и вместо этого используйте SNICallback на их месте.
(HTTPS на самом деле является просто оболочкой для HTTP и TLS, поэтому часто лучше взглянуть непосредственно на документацию TLS для всего, что связано с сертификатами)
Например:
function getCerts(servername, cb) {
cb(null, tls.createSecureContext({
key: '...' // privkey.pem
, cert: '...' // cert.pem + '\\r\\n' + chain.pem
}));
}
http.createServer({ SNICallback: getCerts });
Важно отметить, что ошибки проглатываются и приводят к ошибке подключения tls браузера. Если у вас есть ошибка, я настоятельно рекомендую вам console.error(err)
до тебя cb(err)
так как нет способа поймать его или узнать, что это за ошибка. Это было преднамеренное решение команды узла.
Greenlock сделает это за вас
Это именно то, что я делаю с менеджерами сертификатов ssl, которые я написал, Greenlock.js и Greenlock для Express.js, которые будут:
- предоставление SSL автоматически
- динамически для любого домена, который вы разрешаете
- продлить срок действия сертификатов автоматически
- горячая загрузка новых сертификатов
- плагин хранения может обрабатывать пользовательскую логику, так как он запускается до выпуска или обновления
Он выдает сертификаты автоматически через ACME / Let's Encrypt, однако, если вам нужно более нестандартное решение, вы можете переопределить плагин хранилища по умолчанию, чтобы всегда возвращать сертификат, и тогда он никогда даже не попадет в API ACME.