Not all sites can be proxied by java NIO. Why? - java

I have implemented simple proxy server using Java NIO channels, but have a problem, some sites works perfectly, but other give an error about unknown path or redirect on technical page of its hoster with message the resource doesn't exist. Is it my fault or may be some sites don`t allow proxy?
ProxyServer works as this: I enter 'localhost' and in browser I recive site that was set in code. And request from browser I simply resend on target site at such way:
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = ((SocketChannel) key.channel());
Attachment attachment = (Attachment) key.attachment();
channel.write(attachment.buffer);
}
So 'key' - is SelectionKey of target site and in attachment.buffer I store request that was send to proxy server.
So, something worng with my code or its just closed opportunity to proxy by sites?
Update 1. I suppose, I found a problem. Cause I redirect request from localhost to remote server AS IS so in request in field HOST I have 'localhost'. It seems like some sites ignore this fields, other try to use and redirect to 404 page, cause can't find 'localhost' I`m asking for. So question is how to change field 'Host' in request on destination server name?

The target server doesn't know anything about your NIO code, or whether you are a proxy or a real client.
If you got an error page, the proxy is working, and it is the resource being proxied that is the problem: it doesn't exist, you don't have access, etc. Nothing you can do about that in your code and no reason why you should worry. Just send the error page to the client, same as you would send anything else.
Why is that method called connect() when it doesn't connect and does do something else?

I found a problem. filed HOST after proxy contains 'localhost', so some sites accept it, other not. Replace value of this fields with real host fix the problem.

Related

orbot as proxy with jaunt web-scraping

I am working on app (android) that is supposed to visit website & retrieve some data from there. I was thinking it would be nice to use tor so I would not leave so much info about myself.
I've completed scraping part and everything works. Problem is, i can not make proxy accessing internet. I wanted to use Orbot as proxy. I always get 405 error and text:
"this is an http connect tunnel, not a full http proxy it appears you have configured your browser to use this tor port as an http proxy this is not correct: this port is configured as connect tunnel, not an http proxy. please configure your client accordingly. you can also use https; then the client should automatically use http connect"
Code:
UserAgent agent = new UserAgent();
agent.setProxyHost("127.0.0.1");
agent.setProxyPort(8118);
agent.visit("http://stackoverflow.com");
I've tried
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "8118");
instead of the two middle lines from previous code as well plus few other probably not smart things (: and nothing has helped.
From error text about connect tunnel and proxy I figured problem is somewhere in networking but although I searched about it, I couldn't fix it. Perhaps something in Orbot's settings?
My question is, what am I missing please? :)

java.security.cert.CertificateException when connecting to server with multiple certificates

I'm trying to create SSL connection to a website (https://www.otten-markenshop.de/), and using browser or curl it works, but neither wget, no Java manages to connect. I am mostly interested in why does Java code fail.
Here are the error details:
Using WGET:
wget https://www.otten-markenshop.de/
results in
Resolving www.otten-markenshop.de... 217.24.213.167
Connecting to www.otten-markenshop.de|217.24.213.167|:443... connected.
ERROR: certificate common name “www.plentymarkets.eu” doesn’t match requested
host name “www.otten-markenshop.de”.
Using Java:
public static void main(String[] args) throws IOException
{
URL url = new URL("https://www.otten-markenshop.de");
URLConnection connection = url.openConnection();
connection.getInputStream();
}
results in:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException: No subject alternative DNS
name matching www.otten-markenshop.de found.
What else I have noticed is that certificate I receive in browser is different from the certificate I receive when running Java program:
in browser:
Common Name (CN):
www.otten-markenshop.de
Subject Alternative Name:
DNS Name=www.otten-markenshop.de
DNS Name=otten-markenshop.de
in Java:
Common Name (CN):
www.plentymarkets.eu
Subject Alternative Name:
And the certificate I get in Java is the same as I would receive in browser if I try to access the host by IP address: https://217.24.213.167
Thus it appears that server has multiple certificates installed and uses virtual hosts to detect which certificate should be used. But for some reason this detection does not work when client is Java or wget.
Any ideas why is this happening?
P.S. I don't have access to the destination server to see how it is configured.
P.P.S. I am interested more in understanding why the simple Java code does not work, rather than making it work by, for instance, disabling the SSL verification. After all I can connect to the mentioned URL over HTTP without any issues.
Having multiple certificates on the same IP address and port relies on Server Name Indication.
Your server supports it, but your client needs to support it too.
Client-side support for SNI was only introduced in Java in Java 7 (see release notes)(*). I guess you're using Java 6 or below, otherwise your simple example with URLConnection should work out of the box like this.
(You may also need additional settings if you're using another client library, such as Apache HTTP Client, depending on the version.)
(*) And this was introduced on the server side in Java 8, but that's not really your problem here.

The https URL hostname does not match the Common Name (CN) on the server certificate

I am getting the following error
javax.xml.ws.soap.SOAPFaultException: Marshalling Error: The https URL hostname does not match the Common Name (CN) on the server certificate. To disable this check (NOT recommended for production) set the CXF client TLS configuration property "disableCNCheck" to true.
when I try to connect and use the Web Services.
I have added the following lines in cxf.xml but it still doesn't work.
<http-conf:conduit name="*.http-conduit">
<!-- deactivate HTTPS url hostname verification (localhost, etc)
WARNING ! disableCNcheck=true should NOT be used in production -->
<http-conf:tlsClientParameters disableCNCheck="true" />
The cxf.xml file is placed under WEB-INF/classes/CxfService.
Kindly let me know on what would be the issue?.
There may be no real issue with this configuration. The host name that you use in the URL to the web service does not match the host name in the certificate, but this might be for a number of legitimate reasons, while still allowing the access to the right data.
SSL provides two kind of protections.
Privacy: It provides an encrypted channel over which the data passes so that nobody else can see that data
Source Assurance: It also provides assurance that you are connected to site that you asked to be connected to.
You can then see three levels of security:
no protections at all
encrypted channel so nobody can see your data
encrypted channel, as well as assurance that you are connected to the site you expect to.
It is that latter function that you are disabling. The site provides an encrypted certificate that can be decoded to state the DNS name that was used to access the site. If the name you used, and the name in the certificate do not match, you get this warning. As you probably know, there are multiple ways to address a server, and the certificate only matches the one DNS name that the certificate is for. Perhaps you are not accessing the service with the correct name? Or possibly you have a "self-signed" service which offers the encrypted channel, but not the source assurance.
The question to ask yourself: are you worried that someone will hack the DNS system, and cause your request (by DNS name) to be routed to a server which then will serve up false data in place of the web service you expect. It certainly can happen, and I am not going to say that it never happens, but it is very rare. See more discussion of this.
That is the potential issue: someone may spoof the web service you are calling. The security experts will never recommend a compromise position, but you should assess the value of the data, the likelihood of a spoofed service, and the damage that such a spoofing would cause. If this is a significant problem, then you must use a hostname that matches the certificate, or you must get a certificate that matched the hostname that you use.

How to connect to proxy server using Java

I want to write a java(SE) program to connect to a proxy server, lets say 123.123.123.123:8080. How am I going to achieve that? What is the protocol between my machine and the proxy server? What is the Java framework's class could be in use?
since java 1.5,you can use java.net.Proxy class to create proxy.
Proxy proxy=new Proxy(Proxy.Type.HTTP, new InetSocketAddress("123.123.123.123", 8080);
URL url = new URL("http://www.example.com");
HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy);
uc.connect();
reference
The definitive reference for network proxy configuration in Java 5 is this Java Networking and Proxies page.
Yes proxy server is a web server...
Whenever u send a request through your browser to get some resource in the particular web server(say www.google.com),the request is send to the proxy server instead to sending the request directly to the google server..the proxy server process this request,send them to the gooogle server,receives the response and then send the response back to the browser.
Proxy server is basically used to corporate fields to restrict the accesss to specific websites,to keep a track of the internet used by a particular associate,Also it saves some commoonly used webpages in a cache file,so that when another request comes,then instead of connecting to the required server,it get the webpage fron the cache file..Hence it saves the time.Also it scans the incoming data from any server for malware before submitting it to the client(browser).To check if ur company is using proxy server,u can go to the internet explorer setting ->Connections ->LAN Settings

Connecting to a SOCKS5 proxy to do FTP/S in Java

I'm writing a job that will connect to a client's FTP/S server over my SOCKS5 proxy and I'm utilizing the Apache Commons Net package. The issue is that my SOCKS proxy is configured to not require authentication but I am still getting the following exception:
java.net.SocketException: SOCKS : authentication failed
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:443)
at java.net.Socket.connect(Socket.java:519)
I've tried setting the java.net.socks.username and password properties to empty strings but I still get it. Is there a way I can tell the code to not use authentication? Digging into the underlying source i almost think it's querying the proxy server for the authentication requirement, but I'm not sure.
Alright so the issue was that my SOCKS proxy was set up to ask for authentication but to also accept connections that did not authenticate. We use Dante and while programs like Filezilla are smart enough to iterate through all of the acceptable authentication methods, it seems like the java.net package only goes off the first method supplied. Since my authentication configuration in my sockd.conf file was as follows:
method: username none
user.notprivileged: nobody
java.net was demanding a username and password. I simply flipped the methods to "none username" and both Filezilla and java.net correctly pass through the proxy. It's a bit of an IT solution but whatever gets the code to work, right?

Categories