Securing my HTTP connections - node.js

I am currently working on a Home Automation project. The following is my setup.
A ESP8266 WiFi module will be connected to various sensors. A light
web server will be running on the module. There will be a Linode Cloud
deployed running certain NodeJS scripts and MongoDB database. The
mobile application(Client) will be sending requests to cloud to
control and monitor various sensors. I will be securing the connection
between the application and cloud using JSON Web Tokens. Also I will
try to use HTTPS to secure this connection.
I am confused on how to secure the communication between the Cloud server and the ESP8266 module. I did a lot of research. Got to know certain concepts but could not get a clear and complete picture. Someone please guide me. Thank You.

Use a token in headers between all you apps.
And when you send request, this will look something like this:
request.post({
url: 'https://mycoolserver.com/',
headers: {
Authorization: 'lalalablablabla'
}
})
UPDATE: As far as you send request, the server on that side checks if your token matches the one he has. There are a lot of security tricks to keep you tokens safe, this one I suggested, is very basic security, but you can do it easily just on flight. Later on you can increase your security level.

Assuming you have a real time clock in both system (Client and Server)
Generate a function something like (((unixTime)/1000) + SomeNumbers) * ASmallNumber Where (unixTime)/1000 is unixTime in second, SomeNumbers is a static number like 897645, ASmallNumber is a small number like 7
This formula will generate a number depends on time. Send this number to the receiver. In receiver (with same SomeNumbers and ASmallNumber value), decode the number and check unixTime using receiver unixTime
example: if (unixTime - decodedUnixTime < 5 && unixTime - decodedUnixTime >0) then message is trusted

Related

ESP8266 sending data to web server

I need to make an WEB based monitoring system using ESP8266, which could display the data. The system will have a user registration form, which should allow to display the data for a particular user. For this purpose I got a remote server (domain). Now I'm facing with some problems, how could I send data to this domain from the ESP? My ESP module uses NodeMCU firmware and I can program it using Lua. I read that there is HTTP GET and POST request methods and I unsuccessfully spent a few days trying to implement one of these methods... Maybe someone could put me on the road What should be the sequence of steps to start sending data to the external server? That would be a big step forward if I could send f.e. constant value variable.
Assuming your NodeMCU is connected to a network and had internet access, you can just do
http.post(url, headers, body, callback)
and it should send a post request to the given URL. HTTPS also works here, but has limitations.
Note that you need to compile the firmware with the HTTP (and TLS if you want HTTPS) module(s) by uncommenting the corresponding line(s) in the app/include/user_modules.h file.

Prevent DDOS on websocket server nodejs

I have a app which lets yoy keep your notes at a single place its realtime bw all the devices you are logged in I am using a nodejs wesocket it was working fine but a recently i found out someone was sending a huge amount of requests to my websocket server. He sent a large amount of data through websockets to my mongodb and the data was sent just for the purpose of taking the app down (useless crap data just had 'aaaaa')
What i want is prevent those clients from using the websockets who are making more than 10requests per minute.
As mentioned in the comments its better to go with services like CloudFlare, but for your specific use case (to implement directly on server) you should look at ways to rate limit the requests.
Here is an example of an library to rate limit web-sockets in node
https://www.npmjs.com/package/ws-rate-limit

Stress testing in NodeJS/Socket.io for 1000 users?

I'm currently working on a chat-like application. There's users, chatrooms, messages—all that stuff. The app is powered by Node.js and Socket.IO.
One thing I am interested in doing, though, is stress testing the application. The tests that currently exist are simply some feature tests that make use of 1 client. However, I want to do things like test 1000 people logging into the application at the same time, many people entering the chatroom, everyone sending a message in that room, etc...
How do I go about doing this? Google searches appear to bring up unrelated results.
I've noticed that some have identified this as a duplicate. However, that question involves ASP.NET, and the use of Selenium is out of the question. In addition, I originally intended to get answers that involve doing special actions within the node.js framework. Another developer (no longer part of the team) wrote some stress tests that involve defining a custom user object and iteratively signing up those users, joining a room, etc. Those test are incomplete and no longer usable though since much in the codebase has changed since they were written. Anyways an answer that somehow allows for stress testing the application another way is acceptable.
EDIT: Here's my attempt of stress testing with many users.
function client() {
// Define a testing client that responds to socket io events and the like
}
...
testers = [];
for (int i = 0; i <= 1000; i++) testers.push(new client());
// Each client connects to server with option 'force new connection: true'
it('Should login many users simultaneously') {
// Use async.each on testers
// Use client.login() on each client.
}
I've found that this turns out to be problematic. The test simply doesn't advance after logging in about 250 users. What is the issue here? Could it have to do with the limitations of node.js and socket.io?
The solution that my team and I ended up going with is as follows:
We defined a Client object in its own file (client.js), with various actions and events defined in response to Socket.IO on events and such. In the test.js file, we would instantiate many instances of a Client object, creating many connections and clients.
The limitations that we encountered likely involve the capabilities of the computer that runs the tests (the device that hosts the server can run the test with 1000 users, though).
You can use Apache JMeter tool where you can simulate N number of concurrent users using single client.
Go with, for example, Apache ab.
Just create an API (only for testing purposes) and use and endpoint of that API to send a lot of messages from apache ab.
ab -n 1000 -c 10 -T 'multipart/form-data; boundary=1234567890' -p post.txt http://yourdomain.com/yourproject/api/sendmessage/
And post.txt would contain something like:
--1234567890
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
from=myId&to=yourId&message=alrighty
<base64 data>
--1234567890
Where base64 data should be a long string that represents (base64) the data of that POST request.

Route traffic to multiple node servers based on a condition

I'm coding an online multiplayer game using nodejs and HTML5 and I'm at the point where I would like to have multiple maps for people to play on, but I'm having a scaling issue. The server I'm running this on isn't able to support the game loops for more than a few maps on its own, and even though it has 4 cores I can only utilize one with a single node process.
I'd like to be able to scale this to not even necessarily be limited to a single server. I'd like to be able to start up a node process for each map in the game, then have a master process that looks up what map a player is in and passes their connection to the correct sub process for handling, updating with game information, etc.
I've found a few ways to use a proxy like nginx or the built in node clusters to load balance but from what I can tell the examples I've seen just give a connection to whatever the next available process is, and I need to hand them out specifically. Is there some way for me to route a connection to a node process based on a condition like that? I'm using Express to serve my static content and socket.io for client to server communication currently. The information for what map the player is in will be in MongoDB along with the rest of the player data, if that makes a difference.
There are many ways to adress your problem, here are two suggestions based on your description.
1 - Use a router server which will dispatch players queries to "Area servers" : in this topology all clients queries will arrive to your route server, the server tag each query with a unique id and dispatch it to the right area server, the area server handle the query and sendit back to the route server which will recognize it from the unique tag and send back the response to the client.
this solution will dispatch the CPU/memory load but not the bandwidth !
2 - Use an authentication server which redirect client to the servers with less load : in this case, you'll have multiple identical servers and one authentication server, when a client authenticate, send the url and an auth token of available server to the client and an authentication ticket to the server.
the client then connect to the server which will recognize using the auth toekn/auth ticket.
this solution will dispatch all CPU/Memory/Bandwidth, but might not be suited to all games since you can be sent to different server each connection and you'll not see the players in the same area if you are not on the same server.
those are only two simple suggestions, you can mix the two approaches or add other stuff (for example inter-communication area servers etc) which will solve the mensioned issues but will add complexity.

Socket connection on iPhone (IOS 4.x)

I am working on a Chatting application (needs to connect to a server) on iPhone. The sending packet from iPhone shouldn't be a problem.
But I would like to know whether it is possible for iPhone to establish a incoming socket connection to server continuously or forever under mobile environment.
OR What do I need to do to give the connection alive ? Need to send something over it to keep it alive ?
Thanks.
Not sure why you want to have chatting app to have persisted connection... I'd better use SMS like model. Anyways, Cocoa NSStream is based on NSSocket and allows a lot of functionality. Take a look at it.
Response to the question. Here is in a nutshell, what I would do:
Get an authentication token from the server.
this will also take care of user presence if necessary but now we are talking about the state; once presence is known, the server may send out notifications to clients that are active and have a user on their contact list.
Get user's contact list and contact presence state.
When a message send, handle it according to addressee state, i.e. if online, communicate back to the other user, if offline, queue for later delivery or reject.
Once token expires, reject communication with appropriate error and make the client to request a new token.
Communication from server to client, can be based on pull or push model. In first case, client periodically makes a request and fetches all messages. This may sound not good but in reality, how often users compose and send messages? Several times a minute? That's not too much. So fetching may happen every 5-10 seconds.
For push model, client must be able to listen and accept connections.
Finally, check out SIP, session initiation protocol. No need to use full version of it though. Just basic stuff.
This is very rough and perhaps simplified. I don't know the target complexity of your chatting system. For example, the simplest thing can also be that server just enables client to client communication by distributing their end points and clients take care of everything themselves.
Good luck!
Super out of date response, but maybe it will help the next person.
I would use xmppframework and a jabber server.

Resources