How do I get unique incoming request IP address - java

There are four people who are sharing a same wifi connection,
according to below definition there IP must be unique.
An IP address is a numerical label assigned to each device participating in a computer network that uses the Internet Protocol for communication.
Q1. IS IT SO OR NOT?
For uniquely identifying them I tried:
request.remoteAddress
But I get same IP for those all four person.
Q2.HOW UNIQUELY IDENTIFY THEM?(should I say them to pass some token like thing to identify them uniquely? but I will prefer unique IP)

The correct phrasing is that they all 4 are behinds a NAT firewall -- that is;
They all have unique IP addresses on their internal network (like 192.168.x.x or other internal IP address) see http://en.wikipedia.org/wiki/Private_network and RFC1918 for details.
They are connecting to the public internet though a firewall/gateway which does network address translation (see http://en.wikipedia.org/wiki/Network_address_translation for details).
This is the common way for most home/office networks to connect to the internet, for two reasons -- it require much fewer public internet addresses, and it also makes the network more secure as avoiding public addresses for internal resources means that there is less likelyhood for that you fail to configure you firewalls correctly.
The downside is that IP addresses are by no means a unique ID for the users -- that is what Cookies are for.

It may be that these 4 persons are connected from the same network. In this case the ip address will be seen as the same ip address for the external networks.

Requests sent from a router to a server outside that local network will all have the same IP address. This is one reason session ids are useful. If you need an identifier that MUST be unique for each user even if they are underneath the same local network you will need to use session variables.
Consider looking at this post
Where is session.id in Play 2.0?
Essentially create your unique ID. (Code taken from referenced SO post)
// Generate a unique id
String uuid=session("uuid");
if(uuid==null) {
uuid=java.util.UUID.randomUUID().toString();
session("uuid", uuid);
}

All the 4 users are accessing using the same internet line. Thus the Public IPAddress of all of them will be same. If you have a native application, then on first request that you make to your server, send the device ID with the request. Device ID combined with IP Address should be fairly unique, unless the device ID on all the devices are same (very rare). Another solution can be that you generate a unique Id (JSessionID when session is created on server can be used) on the first request to the server and send it in response. Then pass the unique Id on all subsequent request.
If you are using web browser of the mobile, then you can create session (JsessionId cookie will be generated by server). Mobile browser will take care of sending the jsessionid cookie with each request.

I am afraid there is no easy way to identify users since they can always modify the data they send you. That is why almost all the web services require log in (their own system or Facebook, Google, etc.). The problem, however, is, if someone registers enough accounts they can keep requesting you all the time. To avoid this problem, you may want to introduce Captcha verification every so often even after registration.
Also, not every user has static IP meaning they can change IP every time they get blocked (if you do block by IP, if I understand the question correctly).

They all have unique IP addresses on their internal network (like 192.168.x.x or other internal IP address) see http://en.wikipedia.org/wiki/Private_network and RFC1918 for details.
They are connecting to the public internet though a firewall/gateway which does network address translation (see http://en.wikipedia.org/wiki/Network_address_translation for details).

Related

How do I get client's ip address with cidr

I tried getting Public IP address from HttpServletRequest object using
httpServletRequest.getRemoteAddress();
which returns simple public ip address e.g. 123.21.21.12 but what I need is 132.21.21.12/8.
I have checked this How to get client's IP address using javascript only? but all of these provide simple ip addresses not with CIDR bits.
Thank you.
As others stated in the comments to your question, there is no way to extract subnet mask information just from the IP address alone, and there is no reliable way to get this information from the server. Firstly, you are communicating with a single IP address and not the whole subnet, so the correct CIDR is, as others said, /32. Secondly, network mask is network layer information and the way IP routing works doesn't require any other information to be provided other than a destination IP address.
It is important to know what exactly are trying to accomplish and are using this information for. Do you need this just to fulfill some format requirements or you really need the subnet mask. Anyway, if we're talking about ordinary web client/server I could see two different scenarios:
1) You need exact information about client network configuration
Even if you would be able to programmatically obtain such data, I'm not sure how useful it would be. Because of the shortage of IPv4 addresses and the way ISPs allocate addresses to customers most of the clients are behind their home router which does NAT or in some cases behind carrier grade NAT. Having bunch of clients that all have the same 192.168.1.2/24 address would be a bit pointless.
2) You need the public information (used for global routing) to group customers or something related to that.
This means getting the public IP address (the one you get with httpServletRequest.getRemoteAddress();). There's no way to obtain the exact subnet with 100% accuracy but you can get the route object from a RIR (Regional Internet Registry) database that delegated the scope that IP belongs to. LIRs (organizations that got the address block) have the obligation to update this database with various information and one of those is creating these route objects. For that you can use Whois protocol which is really simple and easily implemented. Basically you just need to open TCP connection to a port 43, send a command that contain the IP address you need the info on and parse the output.
For your example (123.21.21.12) the route object would look like:
~ # whois -T route 123.21.21.12
% [whois.apnic.net]
% Whois data copyright terms http://www.apnic.net/db/dbcopyright.html
% Information related to '123.21.16.0/20AS45899'
route: 123.21.16.0/20
descr: VietNam Post and Telecom Corporation (VNPT)
descr: VNPT-AS-AP
country: VN
origin: AS45899
remarks: mailto: noc#vnn.vn
notify: hm-changed#vnnic.net.vn
mnt-by: MAINT-VN-VNPT
changed: hm-changed#vnnic.net.vn 20100810
source: APNIC
% This query was served by the APNIC Whois Service version 1.69.1-APNICv1r0 (UNDEFINED)
We can see that that IP address belongs to a AS45899 (VNPT) and that the route object is 123.21.16.0/20, which gives you the CIDR you wanted.
And if we query that IP address from a router that has a full BGP table:
# show bgp ipv4 unicast 123.21.21.12
BGP routing table entry for 123.21.16.0/20, version 71369881
Paths: (3 available, best #1, table default)
we do see that indeed the Whois database is updated and that IP belongs to 123.21.16.0/20 route.
Keep in mind that this /20 could be aggregated route, but that's the best you can get. That's the routing information that's globally available and used by routers around the world to route traffic. How that /20 prefix is used inside the ISP network is up to their internal organization and policies and you can't check that. You also shouldn't get routes smaller than /24 this way.

Get actual machine's ip address

I need to get the actual (not the gateway) ip address of my computer but all the solutions I have tried are returning the gateway IP address. For instance, all suggestions from this link Get the client IP address using PHP return the gateway address. Is there a way I can get the actual ip address (public) of my computer - either in php or java?
From the comments, it sounds like you want to create a unique identifier for each computer accessing the server. There is no one piece of information that you can get that will act as such an identifier, here's why:
IP Address
The IP address that you can see is the public address, not the private address of a device behind a NAT'd router.
MAC Address
The MAC address of each network card in each computer is unique, but that information is not available outside of the LAN segment.
You may be able to use a combination of pieces of information (like the IP address and user agent) to make an educated guess that a given request is coming from a unique user, but this would be a guess.. there's no way to be certain of it.
Use $_SERVER['REMOTE_ADDR'] to get the user's public address, and then $_SERVER['USER_AGENT'] to get their user agent. If the combination of these two are unique, then there's a good chance that the request is coming from a unique user.
Another way to do this would be to set a cookie that has a distant future expiration date, or a session ID. But this all depends on how long you need to keep track of the user, if you need to keep track of them after they've closed their browser and then later returned, etc. The only full-proof way is to create an account where they authenticate on your site.
java's InetAddress class might be useful.
InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP is := "+IP.getHostAddress());
Output: IP is := 10.100.95.228

Session State Using Client IP

I am attempting to determine if there is a security flaw using the proposed method of maintaining session state when the client has cookies blocked.
Normally I store a UUID in the clients cookies and auto login if the UUID matches whats stored in the database. However, if the client has cookies blocked, I can't access a UUID on their machine and therefore have to resolve to using their IP address and match against the database that way.
I determine the IP address using:
String ip = request.getHeader("X-FORWARDED-FOR");
if(ip == null) {
ip = request.getRemoteAddr();
}
I'm a little green in this area, but I think there might be a security flaw in this approach. For instance, if the user accesses the application on a public wifi network (in a coffee shop, airport, hotel... whatever) it will store the public ip and match their account to that ip. Anyone coming in behind them on that same ip will have complete access to their account unless they specifically remember to log out. How do I prevent this? I'm not totally against using another approach when cookies are blocked besides matching to the ip. I'm just not sure what other approach their might be besides just totally disallowing user logins when cookies are not available. Is this the only truly secure method?
UPDATE
Based on T.J. Crowders comment, recent stats show that 2% of users actual have cookies blocked. I chose to rely on cookies for a number of reasons and show a warning when session state cannot be managed due to cookies being blocked.
...but I think there might be a security flaw in this approach. For instance, if the user accesses the application on a public wifi network (in a coffee shop, airport, hotel... whatever)...
Not just that. People who have wireless broadband in their home will all seem to be from the same IP, so if two people who live together both want to use your site simultaneously (maybe one recommended it to the other), they'll conflict.
If you can't use cookies, you could use the old J2EE technique of putting the session ID in every URL. If you're already using J2EE, you can use its built-in support for this (HttpServletResponse#encodeURL and such), which will use ;jsessionid=token on the URL. If you aren't, it's simple enough to implement the technique using a query string parameter.
The servlet API allows tracking sessions without cookies, using URL-rewriting (every URL pointing to the app in a given session will contain the session ID). This is automatic if you respect a few rules:
always use HttpServletResponse.encodeRedirectURL() when redirecting
always use HttpServletResponse.encodeURL() when generating a URL (for a link, image or whatever)
Note that the JSTL's <c:url> calls encodeURL() for you.

IP Masquerading in java

I Have to get Data of users from different sites by sending a HttpRequest over the different URl in JAVA. One Problem what I am getting is that the requested URL blocks me after successive number of request that depends on URL to URL . The one solution to this problem is that I have to send request to same URL number of times by changing the IP every time the request is send . But I Have not having any idea to send the request by changing the IP over time to time IN Java.
I Have Tried with IP Masquerading but i could not found any tutorial for this step by step. I am new to this technology. I am trying this in linux(Fedora)
In java Please Help me in getting that.
IP masquerading won't help you, it is used the other way around (usually so that private IP ranges can use public networks by masquerading behind one public IP). The problem you're having would require that you can use multiple public IP addresses.
You say you have data incoming from several users. What you could try to do as a workaround is have the request to the blocked URL done from the client side, so from the user's IP address. Then send the result to your server and use it there.

How Java WebStart application Obtain the MAC address for accessing my webpage

I am writing a java webstart application to deploy from website so users can click and run my software. I need to have a kind of unique machine identification to avoid abusing the accessing of the files. I would like to use the client's MAC address as a unique key so that the server can ensure that no client downloads too much.
Of course, a user may have multiple network cards, so how can my Java application determine the MAC address of the network card that the user is using to access my web site?
..machine identification..
Why not instead do a kind of 'session identification'? As each app. loads (you might want to implement the SingleInstanceService to enforce one app. per PC.) have it contact the server to establish an unique session. Use that to identify it for each request.
To thwart the user from 'using up' their allowance and stopping/restarting the app. (within a time limit), store some details using the PersistenceService.
You can use java.net.NetworkInterface.getNetworkInterfaces to obtain the network interfaces, and call getHardwareAddress() on them to get the MAC address.
You may want to filter out loopback with if.isLoopBack() (where "if" is the interface object). Also filter out any interface where if.getHardwareAddress() returns null. Then pick out one. You could sort them by name, if.getName(), and take the first one. For your purposes it doesn't really matter if it is the actual interface used to download your files or not, just that you can identify the computer somehow. Finally if.getHardwareAddress() gives you an array of bytes with the MAC address. If you'd rather have a String, format each byte with "%02x".format(byte) and join them with a ":" as separator.
As suggested in another answer it may be better to use PersistenceService.
Using the MAC address can however be useful if you want to persist different data for the same user on different computers in the case where the user has the same files/homedirs on each computer. You can use the MAC address as part of the URL you pass to PersistenceService#create() and get(). Useful if you want per-computer data rather than per-user data.
Short example Scala-code:
def computerID: String = {
try { // mac address of first network interface
return java.net.NetworkInterface.getNetworkInterfaces
.filter(!_.isLoopback)
.filter(_.getHardwareAddress != null)
.toList.sortBy(_.getName).head
.getHardwareAddress.map("%02x".format(_)).mkString(":")
} catch {
case _ => return "0" // no mac address available? use default "0"
}
}

Categories

Resources