Proxify an application via loopback adapters and SSH - proxy

This is part programming, part sysadmin, so please excuse me if you feel that this should be over on serverfault.
I have an application that is not SOCKS aware and that we need to use through a firewall. We cannot modify the application to have SOCKS support either.
At the moment, we do this by aliasing the IPs the application talks to the loopback adapter on the host, then creating SSH tunnels out to another host. The IP's the application uses are hardcoded. Our SSH connections look like:
ssh -L 1.2.3.4:9999:1.2.3.4:9999 user#somehost
Where 1.2.3.x are aliases on the loopback.
So the application connects to the open port on the loopback, which gets sent out to the SSH host and onto the real 1.2.3.4.
It works, but the problem is that this application connects to quite a few IPs ( 50+ ), so we end up with 50 ssh connections out from the box.
We've tried to use several 'proxifying' apps, like tsocks and others but have had alot of issues with them ( the app is running on OS X and tsocks doesn't work so well, even with the patches )
Our idea was to write a daemon that listened on all interfaces on the specified port - it would then take the incoming packets from the application, scrape the packet info ( dst IP, port, payload ), recreate the packet and proxify it through a single SSH SOCKS connection ( ssh -D 1080 user#somehost ). That way, we only have 1 SSH connection that all the ports are being proxied through.
My question is - is this feasible? Is there something that I'm missing here? I've been combing through pfctl, ipfw, iptables docs, but I don't see any option to do it through those and this doesn't seem like it'd be the most difficult thing to code. It would recreate the packet based on the original destination IP and port, connect to the local SOCKs proxy and resend the packet as if it were the original application, but now with SOCKS support.
If I'm missing something that someone knows about that already does this, please let me know. I don't know socket programming or SOCKs too well, but this doesn't seem like it'd be too big of a project to tackle, but I'd like some opinions if I'm biting off way more that I should.
Thanks

If your application could add SOCKS client support, you can simply ssh -D lock_socks_port remote_machine, which will open up the local *lock_socks_port* as a SOCKS server at localhost, which can then connect to any host accesible by the remote machine.
Example: imagine you are using an untrusted wifi network without encryption. You can simply launch ssh -D 1082 home, and then configure your web browser to use localhost:1080 as SOCKS server. Of course, you need a SOCKS-enabled client. All the traffic would appear as coming from your gateway, and the connection would be opaque to those snooping the wifi.
You can also open a single ssh client with an indefinite number of LocalForward requests, which would be tunneled on top of a single ssh session.
Moreover, you can add ssh connections to an already-established ssh connection by using the ControlMaster and ControlPath options of ssh.

Related

How to create a vpn connection on a port and only use it selectively

This feels like a basic question, I'm sure other people needed something like this at some point however I couldn't find anything clear on this topic and I'm not very familiar to networking so I hope following makes sense (and sorry if I am butchering the terminology)
I often need to connect to a VPN server at work. At the moment I am using Cisco AnyConnect, which upon connection asks me the host server, my username, my password and routes all my traffic through the VPN afterwards.
The problem is, depending on what I'm doing I often need to jump back and forth to VPN (some applications need local network and others dont)
What would be perfect is to create one VPN connection and just keep it on a port without routing anything to it. Then I can use it as a proxy to selectively route my traffic through VPN (eg. I override http_proxy locally on one terminal instance and run applications that require VPN through there without having to jump back and forth). Furthermore if I create this connection from the terminal I can automate most of the process, with something like:
function callExecutableThroughVPN() {
if ! is_connected_to_vpn then
echo "coulnt find the vpn connection, will attempt to connect. enter password:"
# get password input here
setup_vpn_on_port_9876 # pass password input here
echo "setting proxy to 127.0.0.1:9876"
http_proxy=127.0.0.1:9876/
https_proxy=127.0.0.1:9876/
fi
./executable_that_need_vpn
}
Then I can simply stay on my network and use a wrapper like above for few processes that require their traffic re-routed.
So in summary, my question is: Is it possible to create a single VPN process through terminal to listen a local port, so I dont have to route all my traffic at once, and I can simply kill this process when I'm done
I recommend using SSH tunnel/Socks Proxy (see ssh -D) and tsocks wrapper. For http(s) proxies I recommend the proxychains tool.

websocket will not connect from remote server

I have a web page to control a thermostat on a raspberry pi, and I'm running into difficulties when trying to get websockets to work from a remote client. It seems to work fine when on LAN however. I'm obviously missing something (and likely something basic), but I can't seem to figure out what it is.
The pi's local ip is 192.168.1.134. The web page (served from apache server) has the URL http://192.168.1.134:8010/thermostat.html. The page starts up some javascript, which then tries to connect to the pi's main program using websockets via ws://192.168.1.134:9000. (the server on the pi is running libwebsockets). The websocket comes up, and it seems to work fine. I then tried to connect via a remote client (a cell phone, where wifi was turned off) from http:\\23.239.99.99:8010\thermostat.html. The html/js files load fine, but the web socket attempts to connect to uri ws:\\23.239.99.99:9000, and this fials.
As far as I can tell, the NAT seems to be configured properly:
name ext ext protocol int int ip addr interface
port port port port
start end start end
Thermostat3 8010 8010 TCP 8010 8010 192.168.1.134 eth3.1
Thermostat5 8000 8000 TCP/UDP 80 80 192.168.1.134 eth3.1
Thermostat_ws 9000 9000 TCP/UDP 9000 9000 192.168.1.134 eth3.1
I checked, and the router does not have any firewalls set up, neither does my modem. I didn't install a firewall on the pi (I checked, and there's no odd iptables rule). Does anyone know what I'm missing?
--- EDIT ---
I'm still stuck on this. I called my ISP and they assure me there are no firewalls on their servers. Is there any way to tell if port 9000 is being blocked, and by who?
Bind your apache server to 0.0.0.0 address to make it accessible from remote machines
Try this tool to determine if the port is inaccessible (use the custom port): http://www.whatsmyip.org/port-scanner/
Everything else looks fine. As a sanity check I would try putting the ws port to 8010 to see if that works. I would also recommend using a tool like Advanced Web Client to isolate networking issues.
This is interesting. I once had a similar problem. I set up a WebSocket (I was using a nodejs ws) and once I tried to access it from remote client I was not able to reach it with ws://yourip:port but instead I had to use http://yourip:port. I don't know if you have the same problem, mine was due to a proxy I was using.
I still have an advice for you how you might be able to solve your problem. I don't know how concerned you are about security but as far as I understood your idea you basically connect to your raspberry pi through a WebSocket and tell it to change the temperature.
Back when did a similar project I found it rather hard to secure my WebSocket connection. I was basically sending a password plus command through the WebSocket to my server which then checks wether the password is correct. Otherwise everyone on the internet could heat your house. Not cool...
But therefore, I had to tunnel the connection through https to prevent a middleware attack.
I quickly threw the towel and decided to go with a completely different solution. Basically I set up a nodejs express server (can easily be configured with a self signed certificate to use https or used behind a nginx/apache https server) and authenticated with username and password. When someone made a POST request to /api/thermostats?id=0 with a temperature request, the server checks if the user is authenticated and then executes a terminal command from within node.
Maybe this idea also fits your demands.

Windows Tool or utility to validate remote TCP / UDP ports are accessible over the network?

I am trying to find somw Windows based tools that can help me validate TCP and UDP connection on remote machines.
My Problem (just one use case):
At work, I manage many clustered servers that I run load tests against. In order to get a rich test, I use Jmeter-Plugins which provides a Server agent that opens a TCP socket on port 4444 on a target remote machine: http://code.google.com/p/jmeter-plugins/wiki/PerfMonAgent
There are many times when I setup a new load test farm, that either the network, or the server configuration, or the ServerAgent itself can have issues and thus not allowing a Load test client to access that TCP connection.
The issue I have is that I dont know what part of the system is broken.
What I think I need:
I would like to know how I can open a TCP (not HTTP with cUrl), connection to a remote server to validate that the network allows the connection, as well as the Server firewall allows the given TCP connection to be accessed remotely.
What I have looked:
These are some of the tools I have looked at so far:
Nmap http://nmap.org
Ncat http://sourceforge.net/projects/nmap-ncat/
TCP/IP Builder http://www.drk.com.ar
Zenmap 6.01 and nmap might do the job I want, but some machines where not accessible to Zenmap when I know 100% that the server was accessible via HTTP, so that was strange.
I have looked at many tools and either they:
Dont allow remote connections
Dont seem to want to connect to a TCP socket
Or I dont understand the tools to accomplish the validation I stated above.
I would greatly appreciate all comment and suggestions to help with this re-occurring problem I face.
Mick,
Firebind.com can do what you'd like to do. Firebind is an Internet based server that can listen on any of the 65535 UDP or TCP ports. It uses a java based client to send traffic to and from the server from your machine.
Carl
www.firebind.com

Socket connection rerouting

Most proxy servers perform the job of forwarding data to an appropriate "real" server. However, I am in the process of designing a distributed system in which when the "proxy" receives a TCP/IP socket connection, the remote system actually connects with a real server which the proxy nominates. All subsequent data flows from remote to the real server.
So is it possible to "forward" the socket connection request so that the remote system connects with the real server?
(I am assuming for the moment that nothing further can be done with the remote system. Ie the proxy can't respond to the connection by sending the IP address of the actual server and the remote connections with that. )
This will be under vanilla Windows (not Server), so can't use cunning stuff like TCPCP.
I assume your "remote system" is the one that initiates connection attempts, i.e. client of the proxy.
If I get this right: when the "remote system" wants to connect somewhere, you want the "proxy server" to decide where the connection will really go ("real server"). When the decision is made, you don't want to involve the proxy server any further - the data of the connection should not pass the proxy, but go directly between the "remote system" and the "real server".
Problem is, if you want the connection to be truly direct, the "remote system" must know the IP address of of the "real server", and vice versa.
(I am assuming for the moment that nothing further can be done with
the remote system. Ie the proxy can't respond to the connection by
sending the IP address of the actual server and the remote connections
with that. )
Like I said, not possible. Why is it a problem to have the "proxy" send back the actual IP address?
Is it security - you want to make sure the connection really goes where the proxy wanted? If that's the case, you don't have an option - you have to compromise. Either the proxy forwards all the data, and it knows where the data is going, or let the client connect itself, but you don't have control where it connects.
Most networking problems can be solved as long as you have complete control over the entire network. Here, for instance, you could involve routers on the path between the "remote system" and the "real client", to make sure the connection is direct and that it goes where the proxy wanted. But this is complex, and probably not an option in practice (since you may not have control over those routers).
A compromise may be to have several "relay servers" distributed around the network that will forward the connections instead of having the actual proxy server forward them. When a proxy makes a decision, it finds the best (closest) relay server, tells it about the connection, then orders the client to connect to the relay server, which makes sure the connection goes where the proxy intended it to go.
There might be a way of doing this but you need to use a Windows driver to achieve it. I've not tried this when the connection comes from an IP other than localhost, but it might work.
Take a look at NetFilter SDK. There's a trial version which is fully functional up to 100000 TCP and UDP connections. The other possibility is to write a Windows driver yourself, but this is non-trivial.
http://www.netfiltersdk.com
Basically it works as follows:
1) You create a class which inherits from NF_EventHandler. In there you can provide your own implementation of methods like tcpConnectRequest to allow you to redirect TCP connections somewhere else.
2) You initialize the library with a call to nf_init. This provides the link between the driver and your proxy, as you provide an instance of your NF_EventHandler implementation to it.
There are also some example programs for you to see the redirection happening. For example, to redirect a connection on port 80 from process id 214 to 127.0.0.0:8081, you can run:
TcpRedirector.exe -p 80 -pid 214 -r 127.0.0.1:8081
For your proxy, this would be used as follows:
1) Connect from your client application to the proxy.
2) The connection request is intercepted by NetFilterSDK (tcpConnectRequest) and the connection endpoint is modified to connect to the server the proxy chooses. This is the crucial bit because your connection is coming from outside and this is the part that may not work.
Sounds like routing problem, one layer lower than TCP/IP;
You're actually looking for ARP like proxy:
I'd say you need to manage ARP packets, chekcing the ARP requests:
CLIENT -> WHOIS PROXY.MAC
PROXY -> PROXY.IP is SERVER.IP
Then normal socket connection via TCP/IP from client to server.

Ports with C++ Server/Client applications

If I create a c++ server/client application, the port I used to communicate does it need to be open on the router of the server and client machine
Or what other approach could I take? the client computer needs to receive information from the server but I am not able to have any ports opened because it is on a school network....
[edit]
Hmm My setup is a php page running on a server say when I press hello, the server makes a ssh connection through php and sends shell commands to the machine. The server is running off of a school server which I do have ssh access to and run all my things from there. The client computer will be my pc running off of the school wifi which is not connected to the server. The server will try to make a ssh connection to the public ip of my computer running off of the school wifi(no ports open/can ssh out but no ssh in). Will these methods you mention make this possible, in particular the connect.c since I can't run putty off of the server, and the connect.c I could call from the php.
The choice of language is highly irrelevant here.
There don't need to be ports 'open' on any router, unless your traffic must pass through it. On normal peer hosts in the same network (or subnet) there would hardly be any firewall policy, not even in schools.
Technically it is possible for the switch to block peer-2-peer traffic (meaning traffic not destined to the outgoing gateway), but that is not very usual.
Of course, if the school doesn't allow outbound (WAN) traffic on most ports, tough luck, and they're absolutely right :)
You can look at
ssh (with tunnels -L, -D and -R options, perhaps -o GatewayPorts on)
stunnel
connect.c
http-tunnel
All very readily googled
To establish a TCP/IP connection, only the server port needs to be accessible by the client. The connection is full-duplex, therefore data can flow from the client to the server and vice-versa.
If you are using UDP for your application, which is a connection-less protocol, what happens depends heavily on the firewall or router and whether it performs connection tracking for your service or not.
Unless you provide some additional information on your service and the network setup on both the client and the server side, we cannot provide more concrete information.

Resources