Closed gettyhub closed 3 years ago
Hi @gettyhub, welcome!
Did you put the let's encrypt certificates in the ssl folder
?
And how does let's encrypt
generate them, what are the names of the certificates
?
Attach me here server.js
with all your changes.
Thanks
Error message is: ERR_SSL_VERSION_OR_CIPHER_MISMATCH from the browser.
Letsencrypt has cert.pem privkey.pem chain.pem fullchain.pem
When I address the files for the certificates it only wants to stay within the directory of where the mirotalk files are.
Is there a way I can run it under my http server to do https? I tried copying the directory under http server, but there is no index file, so it just lists directory contents.
server.js:
//const http = require('http');
const https = require('https')
const fs = require ('fs');
const options = {
key: fs.readFileSync(path.join(__dirname, 'privkey.pem'), 'utf-8'),
cert: fs.readFileSync(path.join(__dirname,'cert.pem'), 'utf-8'),
};
// const server = http.createServer(app);
const server = https.createServer(app);
const { Server } = require('socket.io');
const io = new Server().listen(server);
const ngrok = require('ngrok');
const yamlJS = require('yamljs');
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = yamlJS.load(path.join(__dirname + '/api/swagger.yaml'));
const { v4: uuidV4 } = require('uuid');
const port = process.env.PORT || 3000; // must be the same to client.js signalingServerPort
// const localHost = 'http://' + 'localhost' + ':' + port; // http
const localHost = 'https://' + 'sitename' + ':' + port;
I not try it with let's encrypt, but try this:
Put all file generated in mirotalk/ssl folder
, then
server.js:
const localHost = 'https://' + 'localhost' + ':' + port;
client.js
function getSignalingServer() {
return 'https://' + 'localhost' + ':' + signalingServerPort;
}
Eventually try to change port
and signalingServerPort
to 443
And one important
thing, You need a host
that support node.js
.
Have the niode.js installed on v 12.X or 14.X.
Then install all dependencies by npm install
and then start it with npm start
.
Where are you looking to run it?
The web server is already using 443.
My nodejs supplied by distribution is 16.x.
I used sitename as it would be part of https most likely instead of localhost. It would have to resolve against the sitename and not localhost. But it seemed to work over the local network, but still no audio/video permission leading into joining the room from anywhere except localhost. I guess I can talk to myself.
Using openssl s_client -connect sitename:3000
returns that there is no SSL connection or certificates
CONNECTED(00000003)
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 321 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
Already have a voice only chat running, but people are enamored by the video chat.
No point in seeing everybody in their bedrooms on a video chat and the bandwidth is wasted doing that.
Looks like I may have a build script for node.js 14.x in the off hand section for the distribution. Looks like my other chat uses node.js also.
May take awhile to build it from source.
Ok, running 14.x, but no change on the ssl. I don't need to rebuild anything do I?
Ok I think let's encrypt need also the chain.pem
, so add the last line to the const options
:
const options = {
key: fs.readFileSync(path.join(__dirname, 'privkey.pem'), 'utf-8'),
cert: fs.readFileSync(path.join(__dirname,'cert.pem'), 'utf-8'),
ca: fs.readFileSync(path.join(__dirname,'chain.pem'), 'utf-8'),
};
From letsencrypt:
`This directory contains your keys and certificates.
privkey.pem
: the private key for your certificate.
fullchain.pem
: the certificate file used in most server software.
chain.pem
: used for OCSP stapling in Nginx >=1.3.7.
cert.pem
: will break many server configurations, and should not be used
without reading further documentation (see link below).
WARNING: DO NOT MOVE THESE FILES! Certbot expects these files to remain in this location in order to function properly!
We recommend not moving these files. For more information, see the Certbot User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates. `
Nothing.
Switched between 16 and 14 and no change either.
Not even adding this line of code?
ca: fs.readFileSync(path.join(__dirname,'chain.pem'), 'utf-8'),
If not, as soon as I have more time, I'll try it with let's encrypt for you. Between, try to see if you discover something new ;)
PS: You can use also ngrok
to test MiroTalk outside of Your Network, starting it from your Local PC.
More details here
Thanks
It didn't work even with that line.
Your demo servers use a different certificate.
Hey @gettyhub, You don't need to expose it in https. Just use Ngnix and Let's encrypt.
Put Ngnix in front, then something like this:
sudo vim /etc/nginx/sites-enabled/default
# HTTP — redirect all traffic to HTTPS
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
# HTTPS — proxy all requests to the Node app
server {
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name YOUR-SERVER-DOMAIN;
# Use the Let’s Encrypt certificates
ssl_certificate /etc/letsencrypt/live/YOUR-SERVER-DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR-SERVER-DOMAIN/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
....
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
...
}
sudo nginx -t
service nginx restart
In this way in theory all traffic is Secured by Nginx-Let's encrypt and Ngnix proxed traffic to
proxy_pass http://localhost:3000/;
that is the entry point of the app ;)
Do some test and let me know if ok, I'm not tested it.
In my demo MiroTalk is not exposed in HTTPS all this is done by Railway - Heroku... that in theory have these settings that I wrote you ;)
Thanks
That’s similar to what I was trying to do with the other voice chat only except it was using web sockets and never could get it to route inside 443 for the extra ports involved. Only way I could see to get it through 443, was to use the web socket as a web server. And port 3000 is still technically exposed.
And there is a reverse proxy method to do the same thing in Apache. I could run nginx off to the side to test to see if it will go.
So can I consider this issue resolved or not? I gave you some inputs and possible solutions
Hi, miroslavpejic85. I'm new to all this github comments and contributing to projects.
I have a question though. Have you perhaps forked the project and had a look if you can fix the problem on you own machine. Perhaps you could see or find a small mistake that gettyhub missed. I'm not 100% sure. I'm still new to all this and not sure if forking is a common practice.
Hi @Th3DevG1ant, welcome! I think with these settings: https://github.com/miroslavpejic85/mirotalk/issues/65#issuecomment-907588280 You will be able to expose correctly MiroTalk on SSL, thanks to Nginx - Let's Encrypt without touching, the current code at all. Do some tests and then in case update here if done or what you find difficulty in ;) Regards
Maybe this would help:
https://advancedweb.hu/how-to-use-lets-encrypt-with-node-js-and-express/
Await might require some modification.
https://www.stefanjudis.com/today-i-learned/top-level-await-is-available-in-node-js-modules/
I'm getting into a redirect loop with nginx.
Ok I've got the https through the node js now. You missed a line
const server = https.createServer (options, app);
You had the certificates defined, but you didn't include them in the createServer call.
But now still can't get the microphone/video to enable. So this is directly to port 3000 without apache or nginx.
What you mean for: can't get the microphone/video to enable? Are you see errors on the web console?
What you mean for: can't get the microphone/video to enable? Are you see errors on the web console?
When I go to your demo site, it asks me for allow video/microphone, but not on my private site. I can see myself in the camera on your site, but not mine. It doesn't go past the page to tell me to allow microphone/video, but it doesn't ask for permission, and it doesn't go on to ask me for a handle if I enable it in site settings.
Some browsers are showing not webrtc capable browser also.
Console errors:
polling-xhr.js:198 GET https://sitesomewhere.org/socket.io/?EIO=4&transport=polling&t=somevalue net::ERR_FAILED
Someroom:1 Access to XMLHttpRequest at 'https://sitesomewhere.org/socket.io/?EIO=4&transport=polling&t=somevalue' from origin 'https://sitesomewhere.org:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Just for curiosity, if you set a port-forward, something like this, do you have the same error?
Name | Protocol | Port Wan | Port Lan | IP Destination |
---|---|---|---|---|
MiroTalk |
TCP |
3000 | 3000 | Your Local IP |
For Your Local IP, I mean the local ipv4 IP where MiroTalk is run. What I see the problem is in the connection between client and internal signaling server. When the connection is successful, then you will be asked for the permissions for the audio-video
Just for curiosity, if you set a port-forward, something like this, do you have the same error?
Name Protocol Port Wan Port Lan IP Destination
MiroTalk
TCP
3000 3000Your Local IP
For Your Local IP, I mean the local ipv4 IP where MiroTalk is run. What I see the problem is in the connection between client and internal signaling server. When the connection is successful, then you will be asked for the permissions for the audio-video
I'm not running behind a firewall. So I'm not even using stun or turn. I'm running straight on a VPS. I get to about the same place as if I run it on my local lan. Still doesn't mic/vid up.
I tested and works with self-signed certificate.... but if you use Let's Encrypt it should be the same, it just changes the path where the certificates are.
client.js
const signalingServerPort = 3000; // must be the same to server.js PORT
function getSignalingServer() {
return 'https://' + 'sitesomewhere.org' + ':' + signalingServerPort;
}
server.js
// const http = require('http');
// const server = http.createServer(app);
// const { Server } = require('socket.io');
// const io = new Server().listen(server);
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync(path.join(__dirname, '/ssl/key.pem'), 'utf-8'),
cert: fs.readFileSync(path.join(__dirname, '/ssl/cert.pem'), 'utf-8'),
};
const server = https.createServer(options, app);
const { Server } = require('socket.io');
const io = new Server().listen(server);
const port = process.env.PORT || 3000; // must be the same to client.js signalingServerPort
const localHost = 'https://' + 'localhost' + ':' + port;
//const localHost = 'http://' + 'localhost' + ':' + port; // http
restart MiroTalk Then: https://sitesomewhere.org:3000/join/test
For Let's Encrypt, the options should be something like:
const options = {
key: fs.readFileSync(/etc/letsencrypt/live/sitesomewhere.org/privkey.pem), 'utf-8'),
cert: fs.readFileSync(/etc/letsencrypt/live/sitesomewhere.org/cert.pem), 'utf-8'),
ca: fs.readFileSync(/etc/letsencrypt/live/sitesomewhere.org/chain.pem), 'utf-8'),
};
Keep this config, and you will be able to use MiroTalk on secure SSL/TLS...
You have localhost in server.js and the site some where in client.js. I was wondering about that. Because typically the certificate has to match the site in some challenge.
I have the site some where in server.js localHost, but apparently client.js is where it matters.
Ok, so I finally have it it looks like I have it.
does this still work now
Follow this doc also on how to self host it in https, without touching the source code.
Made changes to server.js and client.js to expose https using letsencrypt certificate self hosting, instead of self signed certificate.
Can't connect with browser. Says cannot negotiate SSL/TLS.
And trying to connect to it from localhost mode from another computer on the same network doesn't ever allow access to microphone/video and doesn't continue into the room.