If I use this solution:
new ServerSocket(9090, 0, InetAddress.getByName("localhost"))
...and the user changes it's system hosts file to access my website as "localhost", will this fail to prevent access from non-local client?
(in response to the bounty call)
As always in computer security, guarantee depens on attacker capabilities.
The attacker is lame and knows nothing. Then yes, localhost guarantees the locality of the client.
The attacker has login access to the system and can run SSH to the outer world. Then no guarantees - SSH can forward internal ports through tunnels:
ssh -R *:8080:localhost:9090 some.external.server
Executing this command on the box with your java server will result in establishing a tunnel. All requests addressed to some.external.server:8080 will be delivered to localhost:9090 of the target box.
VPS nowdays costs almost nothing, so the attacker can easily rent such external box and use it as the proxy between your localhost and the whole world.
You may try to protect your server by filtering out all requests where Host header is not localhost. It could be easily countermeasured by including a header-rewriting proxy, such as nginx, to the forwarding chain.
Summary
As you can see, guarantee means that users in the target box must be severely limited: no forwarding software. It implies denying users access to system utilities like ssh or installing and/or running them with user privileges. This is highly unlikely unless the box is a set-top box without any user login or software reconfiguration.
Localhost address
The first comment to the question suggests a trick with localhost name resolution:
the user could probably override localhost to that it's no longer 127.0.0.1
The idea is to place a record to /etc/hosts or c:\Windows\System32\Drivers\etc\hosts that binds localhost name to another IP address.
If your box has an Ethernet connection with, say, address 1.2.3.4, then the line
1.2.3.4 localhost
might cause change of localhost address. If this happens, then the line
new ServerSocket(9090, 0, InetAddress.getByName("localhost"))
will bind the port 9090 on the external network interface, that is accessible from the outside of the box.
I tried this on Ubuntu 18.04, and it worked. I successfully connected to the app running on localhost in the box on the other side of Pasific.
BUT
Once upon a time MS Windows developers hardcoded localhost to be 127.0.0.1. Here is the Medium post about that.
I checked with my Windows 10 box. Confirmed: localhost resolves to 127.0.0.1. The test program
package org.example;
import java.net.*;
import java.io.*;
public class TryLocalhost {
public static void main(String[] args) throws IOException {
System.out.println("localhost: " + InetAddress.getByName("localhost"));
}
}
produces
localhost: localhost/127.0.0.1
while hosts file tried to bind localhost to the link-local address
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
192.168.0.198 localhost
The comment is original, from Microsoft.
I have implemented a server application in Java that I am trying to deploy in the cloud. I have a problem with this part of the code
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(myHost,myPort));
When I set String myHost = "localhost", everything works fine. However, I would like to it to work with the public Ip of the remote machine. I have tried 2 different things
String myHost = "10.0.0.4" (the Ip I get when running ifconfig). In that case I get
java.net.BindException: Cannot assign requested address
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)
String myHost = "publichost", and I add a line 10.0.0.4 publichost to my /etc/hosts/ file. In that case I get
java.net.SocketException: Unresolved address
at sun.nio.ch.Net.translateToSocketException(Net.java:131)
at sun.nio.ch.Net.translateException(Net.java:157)
at sun.nio.ch.Net.translateException(Net.java:163)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:76)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)
What I am doing wrong?
The first error (typically) means that you are binding to an IP + port combination that is already in use.
Use netstat -lntp to list all of the programs listening on a tcp port, and look for the port you are trying to use. Then either shutdown the program ... or pick a different port.
It might also mean that you are using the wrong IP entirely. When you call bind on a server socket, the address and port should be the IP and port on which your application expects to receive incoming connections. So the IP must be an IP for this host (NOT the remote host). Note that you can also use 0.0.0.0 ... which means "all IP addresses for this host".
The second error could mean:
Your DNS resolver is not looking at your "/etc/hosts" file.
The /etc/hosts entry is incorrect; you are supposed to put the fully qualified name for your host into the entry; see Fully qualified machine name Java with /etc/hosts
Something else.
But I suspect that if you fixed the "Unresolved address" problem without fixing the cause of the original "Cannot assign requested address", the latter would reappear. You shouldn't need a DNS entry to bind a server socket!
After I registered dnsjava as default Java DNS provider I get a problem. It can't resolve local addresses which described in /etc/hosts file on my Linux machine. This file look something like this:
127.0.0.1 localhost
127.0.1.1 servername
So if I try to resolve one of such names UnknownHostException happens:
org.xbill.DNS.Address.getByName("localhost");
org.xbill.DNS.Address.getByName("servername");
It's not a problem when you're using dnsjava along with default dns provider. Being a sole provider, dnsjava causes lots of errors in default libraries, which turn out to be highly dependent on localhost resolution capability. So, the question is: how to change behavior of dnsjava to resolve local hostnames?
Edit. Next code works fine:
java.net.InetAddress.getByName("localhost");
But java.net.InetAddress.getLocalHost() method throws:
java.net.UnknownHostException: servername
dnsjava is a DNS client library; it talks to DNS servers. /etc/hosts is not part of the DNS protocol nor does dnsjava know anything about it.
See this old post on a the dnsjava users mailing list from the guy who wrote it: http://old.nabble.com/DNS-Resolve-from-hosts-file-first-then-DNS-Server-td15431381.html
Nothing has changed in that regard.
If java.net.InetAddress.getByName() is working, then your DNS server is configured to respond to queries for localhost.
i have one server installed in my system.It takes one of the ip addresses and acts as own system.
In my java program i connect to that server using the following code.
ServiceInstance si = new ServiceInstance(new URL("https://10.100.13.36/sdk"), "user", "password", true);
true indicates the ignore certificate to be true.
when i tried to execute with false parameter it says the following error.
CertificateException: No subject alternative names matching IP address 10.100.13.36 found
i got here that i have to use the dns name instead of ip address in case of certificate mode of server.
So i found in the server configuration settings that the server is taking the DNS name as localhost.localdomain
so i tried with the url as https://localhost.localdomain/sdk
it has shown the error that localhost.locadomain has not been found.
i guess it has some problem with DNS name resolution with localhost as my system and localhost.localdomain as my server dns name.
can we find the dns name with giving ip address through java program.So that it finds the DNS name on its own and pass the value in the url.
can anybody give some suggestion on this.
Thank you..
A DNS name is assigned by your local DNS server. The name localhost.localdomain is usually assigned in the host file so various local operations function (e.g., system logging, sending email to the root user from periodic tasks). I would guess that your server is not registered in the local DNS server. It is rare that locally run virtual machines actually have a valid registration in DNS - this is especially true for Linux systems running in a Windows environment.
If it were registered in DNS and both your server and client were using the same DNS hierarchy, then all that you need to do is create an java.net.InetAddress using the IP address of the machine and call getCanonicalHostName() to retrieve its DNS name. If it does not have a name registered in the local DNS server, then you will simply get the IP address back.
What are the steps I should take to solve the error:
java.net.UnknownHostException: Invalid hostname for server: local
I added the new virtual host name at Android emulator but the result returns to
java.net.UnknownHostException virtualhostname at
java.net.InetAddress.lookUpHostByName(InetAddress.java:506)
When I type my virtualhost URL on my PC, it works on display. Then again, when I ran on Emulator and check on Logcat, I couldn't be able to read or check the HTTP status if 200, 202, or an error code number. It simply returned to UnknownHostException
I was having the same issue on my mac. I found the issue when I pinged my $HOSTNAME from terminal and it returned ping: cannot resolve myHostName: Unknown host.
To resolve:
Do echo $HOSTNAME on your terminal.
Whatever hostname it shows (lets say myHostName), try to ping it : ping myHostName. If it returns ping: cannot resolve myHostName: Unknown host then add an entry into your /etc/hosts file.
For that edit /etc/hosts file and add following:
127.0.0.1 myHostName
What the exception is really saying is that there is no known server with the name "local". My guess is that you're trying to connect to your local computer. Try with the hostname "localhost" instead, or perhaps 127.0.0.1 or ::1 (the last one is IPv6).
From the javadocs:
Thrown to indicate that the IP address
of a host could not be determined.
127.0.0.1or ::1 or "localhost" should always be the loopback interface, so if that doesn't work I'd be really surprised.
If there really is a server called "local" on your network - examine your DNS settings or add it to your hosts file.
java.net.UnknownHostException: Host is unresolved:
Thrown to indicate that the IP address of a host could not be determined.
This exception is also raised when you are connected to a valid wifi but router does not receive the internet. Its very easy to reproduce this:
Connect to a valid wifi
Now remove the cable from the router while router is pluged-in
You will observe this error!!
You can't really solve this, You can only notify the user gracefully. (something like - "Unable to make a connection")
This is not specific to the question, but this question showed up when I was Googling for the mentioned UnknownHostException, and the fix is not found anywhere else so I thought I'd add an answer here.
The exception that was continuously received was:
java.net.UnknownHostException: google.com
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
...
No matter how I tried to connect to any valid host, printing it in the terminal would not help either. Everything was right.
The Solution
Not calling trim() for the host string which contained whitespace. In writing a proxy server the host was obtained from HTTP headers with the use of split(":") by semicolons for the HOST header. This left whitespace, and causes the UnknownHostException as a host with whitespace is not a valid host. Doing a host = host.trim() on the String host solved the ambiguous issue.
Your hostname is missing. JBoss uses this environment variable ($HOSTNAME) when it connects to the server.
[root#xyz ~]# echo $HOSTNAME
xyz
[root#xyz ~]# ping $HOSTNAME
ping: unknown host xyz
[root#xyz ~]# hostname -f
hostname: Unknown host
There are dozens of things that can cause this. Please comment if you discover a new reason.
For a hack until you can permanently resolve this issue on your server, you can add a line to the end of your /etc/hosts file:
127.0.0.1 xyz.xxx.xxx.edu xyz
This might happen due to various reasons
1) Check if you have VPN connected, you might get this error sometimes if yes
"Your hostname, localhost resolves to a loopback address: 127.0.0.1; using 10.xxx.1.193 instead (on interface cscotun0)"
2) Check your $HOSTNAME
3) try to ping $HOSTNAME on commandline and if it doesnt work, tweak the system settings to make your local host respond to pings
Try the following :
String url = "http://www.google.com/search?q=java";
URL urlObj = (URL)new URL(url.trim());
HttpURLConnection httpConn =
(HttpURLConnection)urlObj.openConnection();
httpConn.setRequestMethod("GET");
Integer rescode = httpConn.getResponseCode();
System.out.println(rescode);
Trim() the URL
Trying to connect to your local computer.try with the hostname "localhost" instead or perhaps ::/ - the last one is ipv6
Please try to set SPARK_LOCAL_IP environment variable to the ip address(can be localhost i.e. your own ip address) you want to connect. E.g.
$ export SPARK_LOCAL_IP=182.95.208.152
This way you will not be required to alter existing linux settings.
Worked for me, hope helps you too.
Connect your mobile with different wifi connection with different service provider.
I don't know the exact issue but i could not connect to server with a specific service provider but it work when i connected to other service provider. So try it!
I had this issue in my android app when grabbing an xml file the format of my link was not valid, I reformatted with the full url and it worked.
If you are here because your emulator gives you that Exception, Go to Tools > AVD Manager in your android emulator and Cold boot your Emulator.
I had the same issue.
Restart docker was the fix for me. For some reason it needed a restart, I donĀ“t know why, but it worked.
If your /etc/localhosts file has entry as below:
Add hostname entry as below:
127.0.0.1 local host (add your hostname here)
::1 (add hostname here) (the last one is IPv6).
This should resolve the issue.