I am trying to set up a transparent TCP proxy on Android for my dissertation, but am having some issues. I am using software that I found on this site - http://en.dfr.ch/free-software/java-tcp-proxy - the source is freely available.
I have extracted the source and created an Android application from it. The main bulk of the code is in the below loop.
while(!interrupted()) {
Socket serverSocket=srvSock.accept();
Log.e(TAG, "New incoming connection");
try {
serverSocket.setSoLinger(true,lingerTime);
Socket clientSocket=new Socket(dstAddr,dstPort);
clientSocket.setSoLinger(true,lingerTime);
Log.e(TAG, "Server socket and client socket created");
StreamCopyThread sToC=new StreamCopyThread(serverSocket,clientSocket, "BrowserSide");
StreamCopyThread cToS=new StreamCopyThread(clientSocket,serverSocket, "ServerSide");
Log.e(TAG, "Working threads created");
sToC.setPeer(cToS);
cToS.setPeer(sToC);
Log.e(TAG, "Peers defined");
synchronized(lock) {
connections.addElement(cToS);
connections.addElement(sToC);
sToC.start();
cToS.start();
Log.e(TAG, "Working threads running");
}
} catch(Exception xc) {
Log.e(TAG, header+":"+xc.getMessage());
// xc.printStackTrace();
}
}
srvSock.close();
Traffic is redirected from an IP to localhost where the proxy handles it. To do the redirect, I have used the following iptables rule:
iptables -t nat -A OUTPUT -p tcp --dport 80 -d [any ip] -j REDIRECT --to-port 8080
This seems to work in redirecting the traffic, however when the proxy is running, it seems to continuously creates new threads (connections) until it runs out of memory. With the logging, the output it similar to below. Where ... represents several loops of the above output logging before the error.
Working threads running
New incoming connection
Server socket and client socket created
Working threads created
Peers defined
BrowserSide-->611
Working threads running
...
/127.0.0.1:8080 <-> /[any ip]:80:Too many open files
I am really confused as to why it's not working properly. The same error appears when I try it in Ubuntu on a computer, but it works perfectly fine in Windows. I am thinking it may be an issue with iptables or some jvm/socket based issues in Linux. I am currently running iptables version 1.4.4.
Thank you in advance for taking your time to have a look at this problem.
You are more than likely initiating a connection in your code to the same port that is being redirected.
Consider:
iptables -t nat -I OUTPUT -p tcp --dport 80 -d [any ip] -m owner \! --gid-owner proxyrunner -j REDIRECT --to-port 8080
This will exclude programs running as group proxyrunner, make sure to execute your proxy accordingly:
sg proxyrunner 'java [...]'
Have you tried to run other Java proxies such as Little proxy with the same configuration?
http://dev.littleshoot.org/littleproxy/
Other open source proxies: http://proxies.xhaus.com/java/
Related
I have a java process on one of my machines listening on port 4502. I have created a tunnel using ngrok so that I can access the application on my development machine. The issue I'm facing is attaching a debugger to the remote JVM.
Here is the debug java configuration I'm using:
-agentlib:jdwp=transport=dt_socket,address=*:5005,server=y,suspend=n
Here is the ngrok configuration for the tunnel to the application:
ngrok http 4502
Here is the ngrok configuration for the tunnel to the JVM (I have also tried http protocol with no luck):
ngrok tcp 5005
ngrok outputs the following for the tcp tunnel:
Forwarding tcp://2.tcp.eu.ngrok.io:10928 -> 127.0.0.1:5005
Using IntelliJ, I configure the remote debugging like this:
Debugger mode: Attach to remote JVM
Host: tcp://2.tcp.eu.ngrok.io
Port: 10928
I get the following error when starting the debugger:
Error running 'Debug Author Desktop': Unable to open debugger port (tcp://2.tcp.eu.ngrok.io:10928): java.io.IOException "handshake failed - connection prematurally closed"
On the machine running the java process, I have made sure that the 5005 port is open before starting the process. On the machine using IntelliJ, I have made sure that the 10928 port is open. What must I do so that I can attach the debugger to the process running on my second machine? Any help would be appreciated.
I've found the solution. The issue was in the Remote Debugger configuration. When specifying the host, you must not include the protocol. Once I changed tcp://2.tcp.eu.ngrok.io to 2.tcp.eu.ngrok.io, it worked!
I want to run distributed load testing by jmeter, where servers(linux) are in the cloud and I have ability to start test from my local pc.
Is it even possible or client and servers should be in same subnet?
And in case its possible, may you provide me step by step guide how to achive this goal?
I have tired
https://jmeter.apache.org/usermanual/remote-test.html
https://cloud.google.com/community/tutorials/ssh-port-forwarding-set-up-load-testing-on-compute-engine?hl=ja
but I got error after error.
Before I disabled ssl verification, next error appeared:
error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
With disabled ssl verification I have next error:
Error in rconfigure() method java.rmi.MarshalException: error marshalling argume
nts; nested exception is:
java.net.SocketException: Connection reset by peer: socket write error
I have feeligs, like I making smth wrong with setting ip, port or firewall, but cant understand what
It is definitely possible to starts load agents (jmeter-server) from your local system. The only condition is that the traffic should not be blocked by firewall.
Based on your error, it looks like jmeter process is not having permission to open a port, port is already open (although there is a specific exception for this)
You can also try allowing all incoming traffic to your slaves (cloud linux boxes) and try running the test again.
According to the manual you mentioned all you need to do is just to take the following steps:
On your local machine set up the SSH tunnel:
ssh -L 24000:127.0.0.1:24000 -R 25000:127.0.0.1:25000 -L 26000:127.0.0.1:26000 username#hostname_of_cloud_machine
On the cloud machine launch the JMeter slave
./jmeter -s -Jserver.rmi.ssl.disable=true -Jserver_port=24000 -Jserver.rmi.localhostname=127.0.0.1 -Jserver.rmi.localport=26000 -j jmeter.log
Again on the local machine launch the JMeter master:
./jmeter -Jserver.rmi.ssl.disable=true -Jremote_hosts=127.0.0.1:24000 -Jclient.rmi.localport=25000 -Jmode=Statistical -n -t test.jmx -l result.jtl
You don't need to configure any firewalls as all the communication is happening over the SSH tunnel
More information:
Remote hosts and RMI configuration
Apache JMeter Properties Customization Guide
I'm trying to implement a "dynamic" proxy forward to access localhost from Internet, like Ngrok in pure Java.
This guy does essentially the same thing: https://serveo.net/#intro (but, without a client)
The idea would be to use the SAME port on the server, and make a dynamic proxy for each client, based on a subdomain
The problem is that the default implementation throws error on the second connection .. saying that the port is already open.
org.apache.sshd.common.forward.DefaultForwardingFilter # doBind
Who has an idea of how to implement this?
The advantage of this is that you do not even need a CLIENT like Ngrok for that ... just using normal ssh would be possible.
ssh -R http2:9000:localhost:8002 localhost -p 4440
ssh -R http2:pSERVER:localhost:pLOCAL localhost -p SSHD_PORT
an option I imagined, is to generate the ports dynamically on the server: IGNORING THE 'pSERVER' port, and creating an HttpProxy, to do the redirection for each port. But I find this very inefficient, I believe it would be possible to do only by analyzing the request header and making the redirects for the corresponding channels / connections
After too much headache.
The code is in very low quality, just a proof of concept that can be implemented.
The implemented idea was made by changing sshd-netty, and adding a function to unpack the http request and remove the HOST HEADER (this needs to be improved here).
Only 1 port on the server is used, and it is kind of a reverse proxy for clients ...
I would like the help of the developers to improve the code in question. My knowledge in Netty and Mina is very limited.
Appreciate:
Source: https://github.com/ricardojlrufino/sshd-dyn-tunneling
Testing: Open 2 connections:
ssh -v -R http1:9000:localhost:8001 localhost -p 4440
ssh -v -R http2:9000:localhost:8002 localhost -p 4440
Make requests:
curl -v -H "Host: http1" http1:9000
curl -v -H "Host: http2" http2:9000
Start test servers:
https://github.com/ricardojlrufino/sshd-dyn-tunneling/blob/tunel/src/test/resources/setup_remotes.sh
I'm trying to connect to a RMI registry that I have started on a remote server, but I get the following exception after a while:
java.rmi.ConnectException: Connection refused to host: *.*.*.*; nested exception is:
java.net.ConnectException: Connection timed out
By running the client localy on the server everything works, but I can't connect to it remotely; Not even from telnet. However, if I run
start rmiregistry 1337
I can connet to it remotely from telnet. I'm assuming that it's something I have to set up when I'm running the server code, but I have trouble finding out what it is.
This is part of the server code:
String codeBasePath = "file:/C:/*path*/build/classes";
System.setProperty("java.rmi.server.codebase", codeBasePath);
System.setProperty("java.rmi.server.hostname", *host IP*);
RemoteFileServer server = new FileServer();
Registry registry = LocateRegistry.createRegistry(PORT);
registry.bind(*name*, server);
System.out.println("Server ready");
Let me know if you need more info/code to help me figure it out.
Ok there is two options I can think of
1 - Did you give permission for incoming connections with a security policy. This step is quite simple actually see here: rmi run tutorial
2 - The port might be closed for outside from OS. For example if you are using linux you need to open the port from iptables like:
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1099 -j ACCEPT
iptables -A OUTPUT -m state --state NEW -m tcp -p tcp --dport 1099 -j ACCEPT
or if you use windows you can configure it from firewall.
If anything is unclear you can ask.
I want to access an RMI-Service from a remote Server.
Locally everything works fine. But from the remote side i get the following exception:
java.net.ConnectException: Connection timed out
I used IP-Tables, that the server believes the request comes to 127.0.0.1 and not to the public ip address xx.yy.zz
iptables -t nat -A PREROUTING -p tcp -d xx.yy.zz --dport 1099 -j DNAT --to-destination 127.0.0.1:1099
The server is started with "-Djava.rmi.server.hostname=127.0.0.1" as JVM-Argument.
Regards,
Markus
For me this looks like misuse of iptables. Do the following:
Make sure your application binds to the public address. For example by removing "-Djava.rmi.server.hostname=127.0.0.1".
If you still can't reach your app. Add a firewall rule to iptables something like:
$iptables -A INPUT -p tcp --dport 1099 -j ACCEPT
I suspect the DNAT only changes the destination of the packet, rather than the source. Wouldn't it make a lot more sense to make the RMI server accept packets from a trusted LAN or VPN, instead of trying to rewrite the packets using iptables?