How to get node.js/socket.IO server work with cloudflare? - javascript

I have a node.js/socket.IO server that has been under attack recently, so I decided to start using cloudflare to hide my server IP. However, anyone can easily get the server IP from the client javascript file. Is there anything I can do to connect through cloudflare and not my server directly, so I can help prevent attackers from getting the server IP?
E.g.:
var client = io.connect('http://141.101.xxx.xxx:466');
That would be the IP when I ping the domain that is using cloudflare. I try to connect to it directly.
Even attempting to connect to the domain itself doesn't seem to work
var client = io.connect('http://mydomainthatusescloudflare.com:466');
Only thing that works is directly connecting to the server, without going through cloudflare (thus revealing the IP)
var client = io.connect('http://217.xxx.xxx.xxx:466');

You can use cfdomain:80 for socket.io and add this line,
io.set("transports", ["xhr-polling", "jsonp-polling"]);
but disconnected event isnt work. I am trying to fix it.

Related

Proper way to connect two NodeJS servers

I am trying to build an app to retrieve data from a local database, The structure of the app that I have a mobile app, server(on a hosting service), and local server(on my pc), I am trying to make the mobile app request data from the server via a normal HTTP request then the server request the data from the local server but the problem that I could not be able to connect with my local server I believe that I could not connect to my local server because my local server does not have a public IP, so I am trying to find a better way to achieve my idea.
I read something about Websocket but I don't know if it suitable for my idea beacuse it is Bi-directional connection and It most used for chatting app
I want to build the app with NodeJs, so what should I do to implement this idea, and thank you for the help.
Each server is on a different network the main server is on Heroku host and the local server is on my personal computer
Life would be a lot easier for you if you move your local server to Heroku where they can much more easily and securely talk to one another.
You can't connect from your Heroku server to the server on your private local network because it is behind a firewall in your home router. To allow such a connection, you have to configure a known public IP address for your home network (that won't change or use DDNS if it can change) and configure port forwarding in your firewall/router so incoming connections from the internet on a specific port can reach your local server. You will then have to harden your local server against random internet attacks since it will then be open to the internet.
One other possibility is that you could have your local server connect to your Heroku server (perhaps with a webSocket connection using some sort of secret credential). Since your Heroku server is already reachable from your home network, this would require less networking configuration change. Depending upon what you're trying to do between the two servers, you could either have the local server just make a regular http request to the Heroku server (either sending data or asking for data) or you could make a webSocket connection and then data can be sent either way of the webSocket connection.

Allow remote server to access API server on localhost

I'm trying to do some home automation with my Raspberry Pi.
Right now I've set up a Node+Express API server (address http://192.168.100.100:3000, local folder ~/api), used to send the signal to a Air Conditioner and get the info from it.
Aside I've built a webapp with Vuejs to manage the AC, and setup a Nginx server to access the webapp (address: http://192.168.100.100, local folder ~/controller/dist).
Everything works perfectly on the local network, but I want to access to everything remotely. So I've forwarded the port 80, and I can access the webapp over the internet, but it doesn't work, because it can't access the API server.
Is it normal, and I have to forward also the port 3000, or is there a way to tell the app to look for the API on the localhost?
Both should work in the local network because everybody knows who's who. If the communication is server to server, both should work too because it's the same scenario. But if client perform Ajax to communicate to server, you should forward port 3000 too. Because the request is out of the local context (if you are out of your network).
server to server: localhost -> localhost
client(browser) to server: internet -> localhost
You could avoid the forward if server(local) perform a request to a client(remote).
You can forward port 3000, and it should work.
Another option is to use ngrok. It allows you to open a tunnel (regardless of your firewall settings) straight to your API. All you have to do it register a free account and you will be able to have a single tunnel running indefinitely. Only drawback is that you need to use their shortUrl (Like https://asdasd12.ngrok.io which changes every time you restart. You can pay to get rid of that, and get a permanent subdomain(Like https://myniceapi.ngrok.io)

Client-side socket.io without a node.js server

To use socket.io on the client side, usually we start a node.js server and go like this:
<script src="/socket.io/socket.io.js"></script>
or with specific port:
<script src="http://localhost:3700/socket.io/socket.io.js"></script>
Question is:
is it necessary to use node.js server to serve socket.io.js ?
...or is it possible to
make a local copy of socket.io.js instead of goes to server every single time we need socket.io?
like, we go to view source and copy everything we got from the source of script tag,
paste and save it as socket.io-local.js so that next time we use:
<script src="socket.io-local.js"></script>
will that work ?
Updates
Thanks for everyone's great response,
I'm asking this because in the case I'm involved, I don't actually have access to the server:
I am writing the client-side to connect to other developer's Socket Sever which is written in Java.
Therefore I'll have to think a way to work around the fact that I don't have a server there for me.
from what I've been testing,
this way seems to work but I really don't know what's happening behind the scene.
You obviously can host the socket.io client library anywhere and pull it in to a page. However, it will almost certainly not work with your Java-based server.
To understand why, you need to understand what socket.io is really doing behind the scenes; the client library is only a small part of it.
Socket.io actually defines and implements its own protocol for realtime communication between a browser and a server. It does so in a way that supports multiple transports: if—for example—a user's browser or proxy doesn't support WebSockets, it can fall back to long polling.
What the socket.io client actually does is:
Makes a XHR GET request for /socket.io/1. The server responds with a session ID, configured timeouts, and supported transports.
The client chooses the best transport that the user browser supports. In modern browsers, it will use WebSockets.
If WebSockets are supported, it creates a new WebSocket to initiate a WebSocket connection (HTTP GET with Upgrade: websocket header) to a special URL – /socket.io/1/websocket/<session id>.
If WebSockets aren't supported by the browser or fail to connect (there are lots of intermediaries in the wild like proxies, filters, network security devices, and so forth that don't support WebSocket requests), the library falls back to XHR long polling, and makes a XHR request to /socket.io/1/xhr-polling/<sesion id>. The server does not respond to the request until a new message is available or a timeout is reached, at which point the client repeats the XHR request.
Socket.io's server component handles the other end of that mess. It handles all the URLs under /socket.io/, setting up sessions, parsing WebSocket upgrades, actually sending messages, and a bunch of other bookkeeping.
Without all of the services provided by the socket.io server, the client library is pretty useless. It will just make a XHR request to a URL that doesn't exist on your server.
My guess is that your Java-based server just implements the WebSockets protocol. You can connect directly to it using the browser-provided WebSocket APIs.
It is possible that your server does implement the socket.io protocol – there are a few abandoned Java projects to do that – but that's unlikely. Talk with the developer of your server to find out exactly how he's implemented a "socket server."
A standalone build of socket.io-client is exposed automatically by the socket.io server as /socket.io/socket.io.js. Alternatively you can serve the file socket.io-client.js found at the root of this repository.
https://github.com/LearnBoost/socket.io-client
I have a module called shotgun-client that actually wraps socket.io. I needed to serve a custom client script as well as the socket.io client script, but I didn't want every user of my module to have to include multiple script references on their pages.
I found that, when installed, you can serve the generated client script from socket.io by reading the file /node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js. So my module adds a listener for its own URL and when it serves my custom client script it also serves the socket.io client script with it. Viola! Only a single script reference for the users of my module :)
While this is technically possible, I don't see why you'd need to do that. If you're concerned about reducing the data that goes over the wire, this change won't actually do much beyond the few characters saved in the shorter src tag. Simply changing the location of the JS file on the server won't actually improve performance - the JS has to be sent.
Proper caching (which Socket.IO has) will return a 304 Not Modified (and not re-send the JS file every time you load a page).

socket.io referring to localhost despite being set as a specfic IP

I'm trying to use web sockets to connect from a Google Chrome browser on my phone to a server running node.js and socket.io.
Using the remote debugging tool in Google Chrome I get this error in the console
Failed to load resource http://localhost/socket.io/1/?t=1368744562638
This happens despite me specifying my internal LAN IP in code for the client like so:
var socket = io.connect('http://192.168.1.3');
Furthermore it seems like the first heartbeat request makes it but starts to fail after that.
The code runs as expected when running the client on the server.
I am of course a idiot. I had another javascript file that had not been updated to connect to the specific IP I had set and was still set to "localhost".
After updating the host that socket.io should connect to in that javascript file everything is now running smoothly :)

Now.js and secure

i've made some chat application in Node.js with now.js. And now I think up about something.
There are two files.. server.js, and client.js and everyone can steal client.js file and run it on another hosting to get benefits of my server.js work. How can I prevent it?
This is about that client.js connect with host by domain and port:
window.now = nowInitialize("http://address.com:6564");
How make it more secure, for example only clients (js files) from my host(address.com) can connect with my host.
If your concern is that other servers can use your server with the client code:
this should not be an issue because of the Same Origin Policy. Only if your server specifically allows it, will clients from other hosts be able to communicate with it.
Just try it out from a different domain name (or even localhost): you will see your browser won't let you make cross-domain requests.
(As an example, you can see this StackOverflow post were a user could not get Socket.IO working over different host/post combinations.)
UPDATE
It would work like this:
How does your users get authentified into you chat? Is there a registration or anything?
Maybe a token or a secure key would do it? Or a secure cookie ( sorry ... but at least invisible to the user ) with the said token? And without a token you couldn't access your services?

Categories