node.js Expess https gives ERR_CONNECTION_REFUSED - node.js

nodejs version v6.11.5
When hosting via Express, the website loads, i.e,
app.listen(port, function () {
console.log("The Server Has Started!");
});
But, when hosting via https, I get ERR_CONNECTION_REFUSED error. For hosting with https, I'm using
var options = {
ca: fs.readFileSync(__dirname+'/keys/sitname.ca-bundle'),
key: fs.readFileSync(__dirname + '/keys/sitname.key'),
cert: fs.readFileSync(__dirname + '/keys/sitname.crt'),
};
var app = express();
.... the app .....
https.createServer(options, app).listen(port, function(){
console.log("server started at port "+port);
});
The port is set to 80 and the ufw rules are as following
To Action From
-- ------ ----
22 LIMIT Anywhere
80 ALLOW Anywhere
443 ALLOW Anywhere
22 (v6) LIMIT Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
Any response will be highly appreciable.

For https you have to set the port to 443 because https uses this port by default. Another option would that you define that you want to use port 80 for https when you send your request: my-domain.com:80. But I'm not sure if this works.

From #floriangosse's comment,
HTTPS uses port 443 by default and thus using port 80 for HTTPS gives ERR_CONNECTION_REFUSED.
Switching to port 443 worked.

Related

Flutter Socket IO with nodejs - receiving timeout on connection

I'm using flutter socket io to communicate to my server that's running node/express.
The server code:
var express = require('express');
var bodyParser = require('body-parser')
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var mongoose = require('mongoose');
app.use(express.static(__dirname));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}))
var Message = mongoose.model('Message',{
name : String,
message : String
})
app.get('/', (req, res) =>{
res.send("Hello");
});
io.on('connection', () =>{
console.log('a user is connected')
});
var server = http.listen(8080, "<MyServerIP>", () => {
console.log('server is running on port', server.address().port);
});
My Flutter code :
connect() async {
try {
String connectionPoint = "http://<MyServerIP>:8080";
//Connect to Socket.IO
socket = IO.io(
connectionPoint,
OptionBuilder()
.setTransports(['websocket']) // for Flutter or Dart VM
//.disableAutoConnect() // disable auto-connection
//.setExtraHeaders({'id': tokenId}) // optional
.build());
//socket.connect();
socket.onConnecting((data){
print("Connecting");
});
socket.onConnectError((data) {
print("Error Connecting - > $data");
});
socket.onConnectTimeout((data) => null);
socket.onDisconnect((data) => null);
} catch (e) {}
}
When ever i try to connect I'm getting a timeout error that's caught in onConnectError.
The node server is running debian, and I've checked the firewall status:
To Action From
-- ------ ----
27017 ALLOW Anywhere
80 ALLOW Anywhere
3000 ALLOW Anywhere
22 ALLOW Anywhere
Samba ALLOW Anywhere
8080 ALLOW Anywhere
27017 (v6) ALLOW Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
3000 (v6) ALLOW Anywhere (v6)
22 (v6) ALLOW Anywhere (v6)
Samba (v6) ALLOW Anywhere (v6)
8080 (v6) ALLOW Anywhere (v6)
3000 ALLOW OUT Anywhere
3000 (v6) ALLOW OUT Anywhere (v6)
When I open the url via chrome I'm getting the "Hello" message.
When I try netcat "nc -vz MyServerIp 8080 and I'm getting a success in connecting. I've also checked my local firewall and I've allowed all connections for qemu to my MyServerIp.
Just need some help as to try to work out why I'm getting the timeout and whether there are any ways to debug this ?
##Edit:
MyServerIP is the actual server ip of my server.
##Edit 2:
I used my device to test whether it was something that was local issue to the android emulator. And, I received the same error (I also took the device off my wifi to eliminate any local firewall issues). I'm assuming that this would mean that it has something to do with my server.
The issue being faced was due to the mis-match between the server version and the package being installed with Flutter. The version on the server was > 3. The latest version installed for flutter is not compatible with a server version. There is a beta version that needs to be used.
At the moment there are two options :
Option 1: Downgrade the servers version so that its compatible.
Option 2 use the beta version. (this is the option I took).
Update pubspec.yaml to socket_io_client: ^2.0.0-beta.2 and it connects.

How do you write an SSL redirect in NodeJS running on AWS EC2 without using port 80 (http) or port 43 (https)?

I have two node servers on a single host. One HTTP server with the responsibility of redirecting to HTTPS, and one HTTPS server responsible for serving my application:
const express = require('express');
const https = require('https');
const http = require('http')
const fs = require('fs');
const app = express();
const httpsOptions = {
key: fs.readFileSync('./local-ssl/key.pem'),
cert: fs.readFileSync('./local-ssl/cert.pem'),
passphrase: '*****'
}
//other stuff
http.createServer(function (req, res) {
res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80);
https.createServer(httpsOptions, app).listen(443)
This works great locally.
The issue is, when I deploy this code and run these servers on AWS EC2 you cannot start servers on ports 80 and 443. I am trying to figure out how I can get around this issue. If I run them on different ports, the servers will not respond, and worse, redirect incorrectly.
Example:
If I serve HTTP on 8081 and HTTPS on 8443, when a redirect occurs, the code redirects to
https://my-fun-url.com:8081
which of course does not work because I am not responding to HTTPS on port 8081.
Now, I've explored the option of port forwarding, but how would this work? If I forward ports 80 and 443 to internal ports (let's say) 3000 and 4000 the same redirection problem will occur.
I have scoured the internet for so long and to me this is a simple requirement for any web-app. I would very much appreciate some detailed guidance on my strategy.
If you want to keep ports 8081 and 8443, then you simply replace 8081 with 8443 in the host header:
httpsHost = req.headers.host.replace('8081', '8443');
res.writeHead(301, {
"Location": "https://" + httpsHost + req.url
});
Now, I've explored the option of port forwarding, but how would this work? If I forward ports 80 and 443 to internal ports (let's say) 3000 and 4000 the same redirection problem will occur.
Not exactly. When someone navigates to http://my-fun-url.com (80) the request is forwarded to 3000. Your http server will respond with a redirect to https://my-fun-url.com (443) which will be forwarded to 4000, and the https server will take it from there.
The difference between the two methods is that with ports 80 and 443 being the default, they are implied and therefore can be left out from the host part of the URL. Which makes the redirect easier as there's no port in the host to replace in the first place, just the protocol part (HTTP/HTTPS).

Access node app on digital ocean - This site can't be reached

I am unable to access my digital ocean node js app. I've already SSH'ed in, cloned my Node app from Git, npm installed, and successfully started the app on the droplet, yet I get error
This site can't be reached
Digital Ocean docs say you can access your publicly facing website simply by going to <your website's ip>:<port>:
I did this by going to 67.205.185.63:9000/ (my app is running on port 9000 as you can see):
root#nodejs-512mb-nyc1-01:~/demos# npm start
live-demos#1.0.0 start /root/demos
node app.js
Demos is listening on port 9000
How else should I be accessing my node app?
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var port = process.env.PORT || 9000;
...
app.listen(port, function () {
console.log('Demos is listening on port ' + port);
});
Some Digital Ocean droplets (mainly one-click apps) come with ufw firewall installed and by default all ports except for 22, 80, and 443 are blocked.
To check if ufw is installed and which ports are blocked/open do:
sudo ufw status
Output:
To Action From
-- ------ ----
22 LIMIT Anywhere
80 ALLOW Anywhere
443 ALLOW Anywhere
22 (v6) LIMIT Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
To allow traffic on port 9000 do:
sudo ufw allow 9000/tcp
Add the 9000 port by writing following command
sudo ufw allow 9000

Openshift - port to use on deployment

I have the following start.js file:
var express = require('express');
var app = express();
app.use(express.static('static'));
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
In my NodeJs application on Openshift. However, when I run rhc tail-a app-name
I can see that there is an error of :
Error: listen EADDRINUSE :::8080
I've tried 80 and 443, and received those errors:
Error: listen EACCESS 0.0.0.0:443
Or 80
Which port should I use as default on my app?
Thanks!
Use Nginx,
Nginx (pronounced "engine x") is a web server. It can act as a reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer and an HTTP cache.
It isn't good practice to run your application with root privileges or directly run your application on port 80 and your port 8080 is in use. Try different port and use reverse proxy.
But if you want to run on port 80 or 443, run your application with root privileges.

How to forward request to Node.js from nginx with tcp_proxy_module?

Now, I had patched nginx with the nginx_tcp_proxy_module, and it is running OK on port 8080.
How do I connect the clients to port 80 of nignx, not port 8080 of Node.js,
so that having the nginx forward the request to Node.js?
Just change 8080 to 80. But TCP and HTTP on the same port is not possible.
Aleternative solution:
Use HAProxy on port 80
Set up nginx to listen on port 81
Run your node.js app on port 8080
Configure HAProxy to
forward Host: your.nodejs.socketio.com to 127.0.0.1:8080
forward everything else to 127.0.0.1:81
If you go down this route you will probably want to preserve client IPs:
Configure HAproxy
Use RealIP module in nginx
Use X-Forwarded-For in socket.io
socketio.handshakeData = function(data) {
var d = socketio.Manager.prototype.handshakeData(data);
d.ip = data.request.headers['x-forwarded-for'] || data.request.connection.remoteAddress;
return d;
};

Resources