WebSocket thru Amazon ELB or directly (remote IP issue) - node.js

We use WebSockets to communicate with our EC2 instances.
Our script is served using nodejs and Express, and then initialize the WebSocket.
Right now ELB is used which makes life harder to identify the client IP.
Using x-forwarded-for header we can get the IP in the context of HTTP, but when it comes to WebSocket context in the server, it looks like it's not forwarded by Amazon.
We identified 2 options:
Communicate the WebSocket directly with the instance (using its public DNS).
Maintain some sort of sessionid, in which store the IP when in the context of HTTP and associate it with the sessionid. The client side will get its sessionid using the HTTP response, and will use it to on the WebSockets. The the server will be to identify the client and resolve its IP from the cache.
Both options are not great: 1 is not fault tolerant and 2 is complex.
Are there more solutions? Can Amazon somehow forward the IP? What is the best practice?
Thanks

I have worked with websockets and I have worked with ELB, but I've never worked with them together, so I didn't realize that an HTTP forwarder on an Elastic Load Balancer doesn't understand websocket requests...
So I take it you must be using a TCP forwarder, which explains why you're using a different port, and of course the TCP forwarder is protocol-unaware, so it won't be adding any headers at all.
An option that seems fairly generic and uncomplicated would be for the http side of your application to advise the websocket side by pushing the information across rather than storing it in a cache for retrieval. It's scalable and lightweight, assuming there's not an obstacle in your environment that makes it difficult or impossible to implement.
While generating the web page that loads the websocket, take the string "ipv4:" and the client's IP ("192.168.1.1," for example), concatenate and encrypt them, and make the result url-friendly:
/* pseudo-code */
base64_encode(aes_encrypt('ipv4:192.168.1.1','super_secret_key'))
Using that example key with 128 bit aes and that example IP address, I get:
/* actual value returned by pseudo-code above */
1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk=
Then when rendering the html for the page containing the websocket, dynamically build the url:
ws = new WebSocket('ws://example.com/sock?client=1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk=');
Assuming the querystring from the websocket is accessible to your code, you could base64_decode and then aes_decrypt the string found in the query parameter "client" using the super-secret key, and then verify that it begins with "ipv4:" ... if it doesn't, then it's not a legitimate value.
Of course, "ipv4:" (at the beginning of the string) and "client" (for the query parameter) were arbitrary choices and do not have any actual significance. My choice of 128 bit AES was also arbitrary.
The problem, of course, with this setup is that it is subject to a replay: a given client IP address will always generate the same value. If you only using the client IP address for "informational purposes" (such as logging or debugging) then this may be sufficient. If you are using it for anything more significant, you may want to expand this implementation -- for example, by adding a timestamp:
'ipv4:192.168.1.1;valid:1356885663;'
On the receiving end, decode the string and check the timestamp. If it is not +/- whatever interval in seconds that you deem safe, then don't trust it.
These suggestions all hinge on your ability to dynamically generate the websocket url, the browser's ability to connect with it, and you being able to access the querystring portion of the URL in the websocket request... but if those pieces will fall into place, maybe this will help.
Additional thoughts (from comments):
The timestamp I suggested, above, is seconds from the epoch, which gives you an incrementing counter that requires no statefulness in your platform -- it only requires that all of your server clocks are correct -- so it doesn't add unnecessary complexity. If the decrypted value contains a timestamp less than (for example) 5 seconds different (+/-) from the server's current time, then you know you're dealing with an authenticated client. The time interval permitted only needs to be as long as the maximum reasonable time for a client to attempt its websocket connection after loading the original page, plus the maximum skew of all your server clocks.
It is true, of course, that with NAT, multiple different users could be behind the same source IP address. It's also true, though far less less likely, that a user could actually make the websocket connection from a different source IP than the one where they originated the first http connection, and still be quite legitimate... and it sounds like the identity of the authenticate user may be a more important value for you than the actual source IP.
If you include the authenticated user's ID within the encrypted string as well, you have a value that is unique to origin IP, user account, and time, to a precision of 1 second. I think this is what you're referring to by additional salt. Adding the user account to the string should get you the information you're wanting.
'ipv4:192.168.1.1;valid:1356885663;memberid:32767;'
TLS should prevent discovery of the this encrypted string by an unauthorized party, but avoidance of replayability is also important because the generated URL is available in clear text in a user's browser's "view source" for the html page. You don't want a user who is authorized today but unauthorized tomorrow to be able to spoof their way in with a signed string that should be recognized as no longer valid. Keying to a timestamp and requiring it to fall in a very small valid window prevents this.

It depends on how serious the application is.
Basing any kind of decision on client IP address is a risky proposition. Basing security on it, even more so. While the suggestions offered so far work well within the given constraints, it would not be sufficient for a robust enterprise application.
Client IP addresses can be obscured by NATs, as already pointed out. So people accessing the Web from their place of work will often appear to have the same IP address. People's routers at home act as a NAT, so every family member at home accessing the Web will appear to the have the same IP address. Or even the same person accessing the application from a PC and a tablet...
Whether behind a NAT or not, using the application from two browsers on the same machine will appear to the have the same address. Similarly, multiple tabs in the same browser will appear to have the same address.
Other junction points like proxies or load balancers may also hide the original client IP address such that the thing behind the proxy/load balancers thinks they are the client. (More sophisticated or lower level intermediaries can prevent this, which is what makes them more sophisticated or expensive.)
Given all of the above, a serious application should not rely on client IP address for any kind of important decision, especially around security.

Related

Regarding the conversion of hostnames to ip address

Can two or more domains be hosted on the same server? If yes what is the ip address we are going to get for the two domains?
as a user can i know how a server resolves the host name and assign unique id to different host names
After looking at my comment above and as you are a user, not an administrator, just look at the documentation of nslookup(1). It is a tool to make DNS queries to servers. It allow you to make dns resolution and to investigate the ways you are getting the answer (there are many ways to answer a query, believe me)
First you need to know how the asking is being done. Normally, clients make recursive queries (they want definitive answers to a query and want the server to do the heavy work) and servers do iterative ones (they approximate the answer by asking the servers in the chain to the final domain you are looking for) Servers and clients normally cache results for future questions and provide several ways of fault tolerance, so you cannot control normally how a query is solved. As this is probably the most requested service in internet, the protocol has been optimized to get quick answers even in the worst case.
Once you get an answer, it can be a partial one, it can be cached, it can be non-authoritative (meaning the server is serving a cached entry, not a locally administered one)
When you have several responses to a query (ok, this can happen) you receive them normally in order, depending where are you querying from. The server makes a best effort to order them on proximity to the client (the nearest address is served first) and/or randomly ordered, so you can make round robing to each of the addresses you receive. It depends on the client software, the server implementation, the administrator policy, etc.
Even you can receive a different response depending on who you are. Several corporate servers serve different views of the database depending on where the clients come from. If they come from the inside of the company, they serve addresses for servers not visible from the outside. For example, if you try to access the corporate web server, you can receive the private address to reach it, not the public address of the server accesible from the internet. This concept is called view, and many servers implement it, so the answer to your question is: it depends :)

referrer ip manipulation

Some applications are providing security only by accepting requests from certain IPs. Is this a good way of making that app secure. Is there any way to manipulate this referrer IP during request period?
getRemoteAddr, getRemoteHost and getRemotePort
Is there any way to set the values above when making the request?
Yes, it is possible to "spoof" the source IP of packets to make the request appear to be from a different IP address than it really is. However, this is not a concern because the three-way handshake of TCP will not complete if the IP address has been spoofed, with a few exceptions (such as the attacker sniffing packets and generating a response when the packet passes on the wire). Generally speaking though, it is very hard to do.
This is not good security practice, however, even though it is typically reliable. The reason is that IP addresses can be assumed by anyone, and they are frequently changed in packets due to techniques like NAT and fire-walling.
Consider that if you have two users on the same private network using NAT, and they both make requests to your server at the same time, your server will see the IP addresses as the same, with different source ports. The differentiating factor that allows routing to happen properly is the source port, not the IP address. To make this even less reliable, the source port will change on every new request, which can happen dozens of times during a single HTTP session.
That being said, there is some benefit to IP filtering. You can make it much harder for someone from a certain country or area to connect by filtering by IP. This should not be your only security, but it can help because it is usually non-trivial to obtain a valid IP address from a a different range. Some organizations will block all non-US based IPs by default, for example. This is used in conjunction with user accounts. This makes it much more difficult for non-local attackers to reach the server.

How to submit a web page with different IP?

i dont want to do something illegal with it(e.g. vote continuously, in fact, somebody is doing it), but i only feel curious about it. For i have learned TCP/IP, and i found there are many software such like "IP changer",using which you can submit a website with different IP. WOW it is really magic! so i analysed some possible mechanism about it. But every possible way was denied by me.
i thought that they might connect and disconnect the internet continuously. because each time they connect the Internet, the ISP will dispatch a new IP address, and the hacker can make use of the new IP to submit the website, and disconnected after submitting successfully, and then connect for the next time...But it is impossible to some extent, for if do like this, every submitting will last a long time, and it doesn't work in some areas.
Modify TCP/IP data packets.For some time i did think it might be all right. but then i denied it. Assuming that i would submit a website, and i changed the IP address of the data packet which i will submit to the web site. it seems that everything is OK, but the web server will send message to the fake IP, so i wont get any information from the website. but in some circumstances where we only needn't reply it should work. Right? netfilter and iptables in linux may realize it, but i am not sure because i dont know the tools very well.
Using proxy server. i also think it is impossible to some extent.is there any method to get lots of free proxy servers? and most free proxy servers is very unstabitily, for there is a possible circumstance that you cannot use the proxy server in one day.Of course, paid proxy server may be permanent. but with these money you can do something better.
IMO the three methods all have disadvantages. and the realization may be none of them. Can anybody tell me the real mechanism of the technique?
Use lots of proxy servers. That will do the trick and since they can be harvested quite easily that's not very hard. Proxy's can be installed on hacked websites for example.
The added question:
Using proxy server. i also think it is impossible to some extent.is there any method to get lots of free proxy servers?
By simply hacking lots of webservers, totally automated, this is possible. For example searching for bad Joomla installs could allow you to install software at each webserver. Also normal computers can be used off course. Like a botnet.
and most free proxy servers is very unstabitily, for there is a possible circumstance that you cannot use the proxy server in one day. Of course, paid proxy server may be permanent. but with these money you can do something better.
Stability is off course important but in this case not really actually. You just send out lots and lots and lots of requests. Don't care which one succeeds and which one doesn't. It doesn't matter for your target.
1. ISP reconnect
This will not work for some (most?) ISPs which will reassign the same IP on a reconnect (as my provider does). Even if it works, you are likely to get the same IP address after some reconnects.
2. IP spoofing
That's the term describing your second method. You change the src-address of the outgoing IP packet. There are two problems with that:
Most ISP's routers don't allow it. They detect that the src address can't come from inside their network, so they simply drop it.
If you have a machine that is allowed to do this (maybe a dedicated server), you can only fake exactly one IP frame. This allows you to, e.g. spoof a DNS request but as you said, you will never get the response. Especially you cannot establish a connection within a stateful protocol like TCP, because this requires a bidirectional handshake. So you can't, e.g., fake a HTTP request using this (even if you don't need the answer)
Proxying
This is the only method that works. You have several options here:
Use open proxy servers (can be found using a search engine, although some will identify themselves as proxies and provide the original IP in the X-Forwarded-For HTTP header, which makes them basically useless for this use case)
Use hacked servers/desktop machines as proxies (maybe from a botnet)
Use free networks like JAP or TOR (the latter of which is probably your best bet, because you can change the exit nodes using some trickery)
If you are going to do something illegal, you might as well go all the way in. There ARE people who run "botnets" which are basically just armies of a few hundred to a few thousand indfected computers (that's what most viruses do). The people who run these armies, actually can charge people a certain amount of money for their "slaves" to visit a website for you (and rate/vote whatever) so you get a few hundred or a few thousand more ratings...
I can't exactly tell where or how much these services cost, since I haven't done it myself, but I know for sure that people over at "H#ckf0rums.net" will do it for you.

ip masking a specific ip address

so suppose I detect a user's ip using some code to perform restrictions....
is there a way for a user to circumvent this by arbitrarily setting their ip to any ip they want anytime they want (eg. via proxy server or something) hence allowing them to choose a specific ip to be displayed when I detect it
There are several tunneling and proxy-based techniques that will effectively present a different IP address for any HTTP requests than the one belonging to the originating computer. I have mentioned several methods in this answer, as well as here. In many cases it is actually impossible to tell apart a relayed connection from the real thing...
In general you cannot forge the source of a TCP connection on the Internet to be an arbitrary address for a number of reasons, some of which are:
TCP is a stateful protocol and packets go back and forth even in order to establish the connection. Forging an IP source address means that you cannot get any packets back.
Some ISPs will drop packets generated within their own network that do not have a source IP within the proper subnet. This is usually done at the client connection level to protect the ISP network and prevent random packets from leaking client information to the Internet due to simple misconfiguration issues client-side.
ISP filters will also prevent users from just setting an arbitrary IP - if not for any other reason, then just because ISPs sell connections with static IP addresses at significantly higher prices and having users set their own IPs would spoil that. Not to mention the mess that would result if there could be IP conflicts among the clients of an ISP...
So in general you cannot just spoof the source of a TCP connection. You have to use an intermediate computer to relay the connection.
Keep in mind, however, that motivated and experienced attackers may have at their disposal botnets that consist of millions of compromised computers belonging to innocent users. Each and every one of those computers could theoretically be used as a connection relay, thus allowing a potential attacker quite a wide variety of IP addresses to chose from.
The bottom line is that simple IP-based checks and filters cannot in any form ensure the legitimacy of a connection. You should be using additional methods to protect your service:
HTTPS and proper user accounts.
Extensive logging and monitoring of your service.
Intrusion detection systems and automatic attack responders (be careful with those - make sure you don't lock yourself out!).
We cannot really provide a more concrete answer unless you tell us what service you are providing, what restrictions you want to apply and what kind of attacks you are so worried about...
Sort of - as you mentioned, proxies are a risk, however it makes life a wee bit harder for the attacker so it is still worth using IP bans.
Monitor your logs, automate alerts and if attacks come from another IP - ban it too. If you make life hard enough for an attacker they may give up.

Identifying HTTP clients

my software-house is developing a component for advertisement in some of ours portals. The advertisement is click based, thus the source portal that more originates click's is the winner. My preucupation is about "fake clicks", malicious HTTP clients raising requests. It's possible for a attacker to falsify the IP source address of a HTTP request? How i can prevent this? We are observing so much random requests in a little interval of time
It is possible to go via some proxy, there is a plenty of free proxies around the net and you can pretend to have a bunch of different IPs even when you are physically sitting in front of one computer. This is probably very hard to detect although it can be considered "malicious".
As far as I know there is no simple way to change the IP without physically going via a machine with this IP, but I am not an expert here so probably somebody else will give you more confidence.
I think your best bet is going to be some sort of cookie & IP technology together. Realistically though the other poster is right. You can clear cookies and use TOR to come out of any number of unique IP addresses.

Resources