Сервер WebSocket не работает с SSL

У меня есть рабочее приложение чата, использующее websockets. Я хочу сделать еще один шаг и включить шифрование в своих подключениях, однако, когда я переключаю HTTP-сервер с https, один из которых запускает мои подключения.

Я создал самозаверяющий сертификат, который я использую на всех моих сайтах (под тем же TLD, что означает, что это подстановочный знак). Я могу подтвердить, что это действительный сертификат, поэтому проблемы не должно быть.

Это то, что работает (незашифрованное)

var webSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function() {});
server.listen(webSocketsServerPort, function () {
    log("system", "Server is listening on port " + webSocketsServerPort);
});

var wsServer = new webSocketServer({
    httpServer: server
});

Используя это, теперь я могу подключиться к ws://my.domain:port.

Это то, что работает не

var webSocketServer = require('websocket').server;
var http = require('https');
var fs = require('fs');

var server = http.createServer({
    key: fs.readFileSync("path/to/host.key"),
    cert: fs.readFileSync("path/to/host.pem")
});
server.listen(webSocketsServerPort, function () {
    log("system", "Server is listening on port " + webSocketsServerPort);
});

var wsServer = new webSocketServer({
    httpServer: server
});

С помощью этого кода сервер запускается также, я вижу сообщение журнала "Сервер прослушивает..", но когда я пытаюсь подключиться в wss://my.domain:port, соединение не может быть установлено.

Я добавил исключение в свой браузер для сертификата, потому что моя клиентская страница и адрес сервера веб-сервера находятся под одним и тем же доменом и поддоменом.

В чем может быть проблема?

Ответ 1

Плохая практика в сочетании с плохими привычками ведения журналов была причиной проблемы.

При открытии нового соединения произошла проверка, выполняемая для проверки происхождения запроса, который был там hardcoded http://, и поскольку я запрашивал его с защищенной страницы (https://), проверка больше не передавалась и соединения были невозможны.

Ответ 2

Недостаточно добавить сайт, из которого вы хотите подключиться к веб-расписанию в качестве исключения. Перейдите на сайт https://my.domain:port (адрес веб-сайта) и добавьте его в качестве исключения. (Это, безусловно, необходимый шаг в Firefox)

В качестве альтернативы вы можете импортировать сертификат в диспетчере сертификатов в полномочия.

Изменить: Я могу рассказать вам, что работает для меня.

> openssl genrsa -out key.pem
> openssl req -new -key key.pem -out csr.pem
> openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem

установив общее имя как localhost

в main.js

var https = require('https');
var ws = require('websocket').server;
var fs = require('fs');

var options = {
    key:fs.readFileSync('key.pem'),
    cert:fs.readFileSync('cert.pem')
};

var server = https.createServer(options,
    function(req,res){res.writeHeader(200);res.end();});
server.listen(8000);
var wss = new ws({httpServer:server});

wss.on('request',function(req){
    req.on('requestAccepted',function(conn){
        conn.on('message',function(msg){
            conn.send(msg.utf8Data + " received");
        });
    })
    req.accept(null,req.origin);
});

затем в браузере (Firefox) в https://localhost:8000 (добавлен сертификат как исключение)

var ws = new WebSocket('wss://localhost:8000/')
ws.onmessage = function(msg){console.log(msg.data)}
ws.send("test")

и получил test received.