AWS EC2 client/server can't communicate via Node HTTP server - javascript

I have two AWS EC2 instanses. A Server and a client Node JS app.
Locally my code is working fine.
But at AWS the client simply shuts down after some time - like 30 sec - without any warning/exception (For some reason it can't find and connect to the server)
Both AWS instances are running: Windows Server 2016 Base.
Both AWS instance have their own sererate "AWS security group". Just to make sure i'm not blocking any thing both security groups currently allow:
"All traffic to ANY IP" - both Ingoing and Outgoing traffic.
Both instances run in the same "Availability zone" in AWS.
The server is listening at host: '0.0.0.0', port: 4080.
And the client tries to connect to the server's IP at port 4080. I have tried to connect to all possible options - like:
Public DNS (IPv4)
IPv4 Public IP
Elastic IP
Private IPs
I can't even ping the server's IP from the client or from my own PC. I can access both AWS instances fine via RDP.
Here is a bit of my code:
SERVER.JS
var server = require('http').createServer();
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ server: server });
server.on('request', app);
server.listen(_port, '0.0.0.0', function () { console.log('SERVER STARTED! (listening on port # ' + _port + ')') });
CLIENT.JS
var WebSocket = require('ws');
var _ws = new WebSocket(THE_SERVER_IP);
_ws.on('open', function open() {
...
});
_ws.on('message', function (data, flags) {
...
});
_ws.on('close', function close() {
...
});

Solution: I added a custom TCP rule to the Windows Firewall in the server where my server.js app is running - which allow the client's IP to connect to port 4080. Done.

Related

ERR_SSL_SSLV3_ALERT_CERTIFICATE_UNKNOWN thrown by wss server when client tries to connect to it

recently I've been trying to create a WebSocket server (using the ws library for node.js). At first I used the ws unencrypted protocol, but then I had to switch to wss. This brought some client authentication issues. When the client (running on a browser)
(client.js)
this.socket = new WebSocket(`wss://ipv4.address:port`);
... tries to connect to the Node.js-based server
(server.mjs:)
const server = createServer({
cert: readFileSync('/path/to/ssl_certificate.cer'),
key: readFileSync('/path/to/private_key.key'),
ca: [
readFileSync('/etc/ssl/certs/ca-certificates.crt'),
readFileSync('/path/to/ssl_certificate_INTERMEDIATE.cer')
],
rejectUnauthorized: false
});
const wss = new WebSocketServer({ server });
server.listen(port, "hostname", () => {
//the server actually listens, so this line of code is printed
console.log(`listening on wss://${wss.address().address}:${server.address().port}`);
});
server.on("tlsClientError", (err, tlsSocket) => {
console.error("TLS client error", err);
tlsSocket.destroy();
});
... it goes into "tlsClientError", printing this:
TLS client error [Error: C0D71E8ECB7F0000:error:0A000416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1584:SSL alert number 46
] {
library: 'SSL routines',
reason: 'sslv3 alert certificate unknown',
code: 'ERR_SSL_SSLV3_ALERT_CERTIFICATE_UNKNOWN'
}
This looks like the server isn't willing to accept the client's certificates. How do I set them? Is there something I'm not understanding about WebSockets over TLS?
I tried following the advice of many answers from StackOverflow, disabling rejectUnauthorized, but the node https server is still failing, even after adding the same SSL certificates my website is using (same hostname, different port)
EDIT:
I forgot to mention, that connecting from the same host as the server works (i.e. using the ws client part on the node side), as per https://github.com/websockets/ws/blob/master/examples/ssl.js, and even when disabling rejectUnauthorized (because I'm not using a self-signed certificate)

Connecting 2 servers via Node Websockets

I have 2 Raspberry Pi running on the same Network.
I am using one as a local web server for my house, I then have another one connected to some devices. I want them to both be able to communicate to each other via web sockets but am having some problems.
My server looks like this:
express = require('express'); //web server
app = express();
server = require('http').createServer(app);
io = require('socket.io').listen(server); //web socket server
server.listen(8080); //start the webserver on port 8080
app.use(express.static('public')); //tell the server that ./public/ contains the static webpages
io.sockets.on('connection', function (socket) { //gets called whenever a client connects
socket.on('Testing',function(data){
console.log("Testing connection");
});
});
My problem comes with the client connection I am really not sure what code to use to try and connect.
I have installed Express and Socket.io on my client and used this code:
console.log('1');
// Connect to server
var io = require('socket.io')
var socket = io.connect('http://192.168.1.138:8080', {reconnect: true});
console.log('2');
// Add a connect listener
socket.on('connect', function(socket) {
console.log('Connected!');
});
console.log('3');
But this leads to an error on the io.connect is not a function.
I am not really sure how to get the client to work so any advice is appreciated.
I should add that connecting to my webserver directly via the ip and port does load the webpages I have created successfully.
When using socket.io on the server side as a client you need to do var socket = require('socket.io-client')('http://192.168.1.138:8080', ...);. See https://www.npmjs.com/package/socket.io-client

Transferring data through tcp sockets using nodejs

I have a simple node application that sends data through tcp sockets. Essentially it’s two node applications a sender and a receiver, or a client and server. I can open two terminal shells on my localhost and see data transferring though tcp sockets, so I know it works. I want to send data from my localhost to my server with these applications but I can’t figure it out.. wether its the ip address routing or if I have to open tcp ports or disable firewalls, not sure. here's what the server and client apps look like when I can successfully send data on my localhost. I want to use this client app on my localhost and host the server app on my centos server and transfer data, is this possible?
/*** TCP Client ***/
/* Dependencies */
var fs = require('fs');
var hl7 = require('simple-hl7');
/* Build TCP Server */
var server = hl7.Server;
var tcpClient = server.createTcpClient();
/* Connection */
tcpClient.connect('127.0.0.1', 6969);
/* Get XML */
var msg = fs.readFileSync('./data/example.xml').toString();
/* Send Message */
setTimeout(function() {
tcpClient.send(msg, function(ack) {
console.log("ACK: ",ack.toString());
console.log("\nsuccessful transfer");
tcpClient.close();
});
}, 500);
the server can be found here. click here
but heres the config code..
/*
Config class
vars:
baseFolder: Where to save the messages
port : What port to listen on
ip : what ip to listen on
*/
var Config = new function() {
this.baseFolder = "data";
this.port = 6969;
this.ip = '127.0.0.1';
}
Ofcouce it is possible. Set server's IP and listening port in client. Then since client gonna connect to server, you will have to open this port on the server in both directions. And then just connect.
Basically here tcpClient.connect('127.0.0.1', 6969); Instead of 127... should be server's real external IP address.

Why doesn't this IP address work for Node.js clients?

I have an unusual problem. I am running a simple node.js app. The code below works.
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
app.listen(8000, '127.0.0.1');
However, if I use app.listen(8000, '192.168.1.4');, no client is able to connect to the server. 192.168.1.4 is the IP address of my local machine.
One thing I noticed is that even when app.listen(8000, '127.0.0.1'); is used, on the local browser, http://localhost:8000/ works but http://192.168.1.4:8000/ does not work.
Can anyone what have I done wrong?
The line:
app.listen(8000, IP_ADDRESS);
means to listen to port 8000 on the device (ethernet, wifi, loopback) that owns that IP address for connections destined to that IP address.
Therefore, if you use 127.0.0.1 only localhost can connect to it and if you use 192.168.1.4 localhost cannot connect to it and only machines on the 192.168.1.xxx network can connect to it (I'm assuming a netmask of /8).
In order to allow both networks to connect, you can listen to both IP addresses:
var http = require('http');
var app1 = http.createServer(handler);
app1.listen(8000, '127.0.0.1');
var app2 = http.createServer(handler);
app2.listen(8000, '192.168.1.4');
Or, if you don't care about where the request comes from and want it to listen to packets coming from anywhere, simply don't pass it an IP address:
// listen to port 8000 on all interfaces:
app.listen(8000);
127.0.0.1 (localhost) is the IP address for the loopback adapter. The loopback adapter is a special interface that essentially allows programs to talk to each other on the same machine (communication bypasses physical interfaces).
Your actual IP address (the one that doesn't work in your example) is bound to a network device such as an ethernet adapter.
As suggested, using 0.0.0.0 (all available interfaces) should work if you want to expose your API externally.

Express application not responding to outside traffic

I have a webservice (private-bower) that listen on port 5678 on a remote ubuntu machine.
netstats:
tcp 0 0 0.0.0.0:5678 0.0.0.0:* LISTEN 10605/node
I don't have any rules in my iptables and the ufw status is inactive.
I get a response by doing $curl ip:5678 only within my remote machine, but when I do it on my local one, I receive no response what so ever.
The remote ip is pingable from my local machine btw.
I didn't write that webservice, here's the line where it starts to listen:
var server = app.listen(_config.port, function() {
logger.log('Bower server started on port ' + _config.port);
});
How can I let external ip address to make request on that port?
thanks!
app.listen by default listens on localhost, you can pass in a different bind address as the second argument as described in docs. as I understand it: 0.0.0.0 represents 'all available interfaces' and localhost represents 'only loopback interface'
var server = app.listen(_config.port, '0.0.0.0', function() {
logger.log('Bower server started on port ' + _config.port);
});

Categories