Как использовать самозаверяющий SSL с WebSockets между AngularJS и Raspberry? - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть приложение AngularJS, работающее на сервере, защищенном SSL.Теперь я хочу связаться с RaspberryPI через веб-сокет, чтобы получить потоковые данные.Raspberry не имеет своего собственного веб-сервера (nginx / apache), поэтому я не могу использовать, например, letsencrypt, но только самозаверяющие сертификаты.Проблема в том, что это не работает, и я не смог найти работающее решение (после 6 часов чтения форумов).Вот мой код:

Я создал свой самозаверяющий сертификат через:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 9999 -nodes

В AngularJS я делаю просто:

const ip = IPADDRESS:9030
connection = new WebSocket('wss://' + ip);

Сервер узла работает наМалина.Это выглядит так:

const net = require('net');
const fs = require('fs');
const https = require('https');

var options = {
    key:    fs.readFileSync('ssl/key.pem'),
    cert:   fs.readFileSync('ssl/cert.pem'),
    requestCert: false,
    rejectUnauthorized: false
};

//pass in your express app and credentials to create an https server
const httpsServer = https.createServer(options);
      httpsServer.listen(9030);

/**
 *  server
 */
let connections = {};
let WebSocketServer = require('ws').Server;
let wss = new WebSocketServer({server: httpsServer}),

wss.on('connection', function(ws) {
    ...
}

При запуске сервера с node server.js и запуске моего приложения AngularJS я получаю сообщение об ошибке:

WebSocket connection to 'wss://IPADDRESS:9030/' failed: Error in connection establishment: net::ERR_CERT_AUTHORITY_INVALID

Что я могу сделать, чтобы получить егоРабота?Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 23 февраля 2019

Что ж, после многих игр и тестирования все выглядит так, что кажется невозможным работать с самозаверяющими сертификатами.

Последнее решение, которое я использовал сейчас, - это использование Letsencrypt.Вот шаги.Я надеюсь, что кто-то найдет это полезным:

Прежде всего, ваш маршрутизатор должен быть доступен через Интернет.Поэтому порт HTTP 80 и порт HTTPS 443 должны быть открыты для пересылки входящего TCP на Raspberry.

Шаг 1: Подготовьте Raspberry и установите сервер nginx:

sudo apt-get install nginx
sudo /etc/init.d/nginx start

Шаг 2: Установка LETSENCRYPT:

cd ~
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

./letsencrypt-auto -d DDNSNAME_ROUTER --redirect -m EMAILADDRESS

В процессе установки вам будут заданы некоторые вопросы.Не забывайте вводить DNS-имя для [CN].

Шаг 3: Измените некоторые разрешения, поскольку файлы по умолчанию не читаются:

sudu chmod -r 775 /etc/letsencrypt/live
sudu chmod -r 775 /etc/letsencrypt/archive

Шаг 4: Включить автоматическое обновление LETSENCRYPT:

./letsencrypt-auto renew
sudo crontab -e

0 0 1 * * /home/pi/letsencrypt/letsencrypt-auto renew

Вот и все!Теперь вы можете использовать WebSocket wss:// внутри вашего приложения Angular / AngularJS.

Узел-сервер, который может обрабатывать запросы HTTP и HTTPS, теперь выглядит следующим образом (мой сервер прослушивает порт 9030 и9031 для любых данных. Поэтому, пожалуйста, измените их в соответствии с вашими потребностями. В config.json хранятся только некоторые переменные.):

const net = require('net');
const fs = require('fs');
const https = require('https');
const config = require('./server-config.json');

//
//  SSL SERVER
//
try {
    const privateKey = fs.readFileSync('/etc/letsencrypt/live/' + config.DNSROUTERNAME + '/privkey.pem', 'utf8');
    const certificate = fs.readFileSync('/etc/letsencrypt/live/' + config.DNSROUTERNAME + '/cert.pem', 'utf8');
    const ca = fs.readFileSync('/etc/letsencrypt/live/' + config.DNSROUTERNAME + '/chain.pem', 'utf8');

    const options = {
        key: privateKey,
        cert: certificate,
        ca: ca
    };  

    //pass in your express app and credentials to create an https server
    let httpsServer = https.createServer(options);
        httpsServer.listen(9031);
}
catch (e) {
    console.log("LETSENCRYPT certificates not found! HTTPS server not started!");
    console.log(e)
}

/**
 *
 *  server
 *
 */
let connections = {};
let WebSocketServer = require('ws').Server;

// start WS via HTTP
const wss1 = new WebSocketServer({port: 9030});

wss1.on('connection', function(ws) {
    console.log('connection via HTTP');

    ws.on('close', function () {
        console.log('close HTTP!');
    })
})


// start WS via HTTPS
if (typeof httpsServer !== 'undefined') {
    const wss2 = new WebSocketServer({server: httpsServer});

    wss2.on('connection', function(ws) {
        console.log('connection via HTTPS');

        ws.on('close', function () {
            console.log('close HTTPS!');
        })
    })
}

...

Я надеюсь, что это поможет, и вы сэкономили часть своей жизни.

PS: пожалуйста, дайте мне знать, если кто-то нашел решение, чтобы заставить его работать без веб-сервера.Мне не очень нравится подход к установке веб-сервера только для сертификата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...